nfs-ganesha 1.4

fsal_lookup.c

Go to the documentation of this file.
00001 /*
00002  * vim:expandtab:shiftwidth=8:tabstop=8:
00003  */
00004 
00013 #ifdef HAVE_CONFIG_H
00014 #include "config.h"
00015 #endif
00016 
00017 #include "fsal.h"
00018 #include "fsal_internal.h"
00019 #include "fsal_convert.h"
00020 #include "fsal_common.h"
00021 #include "HPSSclapiExt/hpssclapiext.h"
00022 
00023 #include <hpss_errno.h>
00024 
00060 fsal_status_t HPSSFSAL_lookup(hpssfsal_handle_t * parent_directory_handle,      /* IN */
00061                               fsal_name_t * p_filename, /* IN */
00062                               hpssfsal_op_context_t * p_context,        /* IN */
00063                               hpssfsal_handle_t * object_handle,        /* OUT */
00064                               fsal_attrib_list_t * object_attributes    /* [ IN/OUT ] */
00065     )
00066 {
00067 
00068   int rc;
00069   fsal_status_t status;
00070   hpss_fileattr_t root_attr;
00071 
00072   ns_ObjHandle_t obj_hdl;
00073   hpss_Attrs_t obj_attr;
00074 
00075   /* sanity checks
00076    * note : object_attributes is optionnal
00077    *        parent_directory_handle may be null for getting FS root.
00078    */
00079   if(!object_handle || !p_context)
00080     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup);
00081 
00082   if(!parent_directory_handle)
00083     {
00084 
00085       /* check that p_filename is NULL,
00086        * else, parent_directory_handle should not
00087        * be NULL.
00088        */
00089       if(p_filename != NULL)
00090         Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup);
00091 
00092       /* root handle = fileset root handle */
00093       object_handle->data.obj_type =
00094           hpss2fsal_type(p_context->export_context->fileset_root_handle.Type);
00095       object_handle->data.ns_handle = p_context->export_context->fileset_root_handle;
00096 
00097       /* retrieves root attributes, if asked. */
00098       if(object_attributes)
00099         {
00100           fsal_status_t status;
00101 
00102           status = HPSSFSAL_getattrs(object_handle, p_context, object_attributes);
00103 
00104           /* On error, we set a flag in the returned attributes */
00105 
00106           if(FSAL_IS_ERROR(status))
00107             {
00108               FSAL_CLEAR_MASK(object_attributes->asked_attributes);
00109               FSAL_SET_MASK(object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00110             }
00111         }
00112 
00113     }
00114   else
00115     {
00116 
00117       /* the filename should not be null */
00118       if(p_filename == NULL)
00119         Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup);
00120 
00121       /* Be careful about junction crossing, symlinks, hardlinks,... */
00122 
00123       switch (parent_directory_handle->data.obj_type)
00124         {
00125         case FSAL_TYPE_DIR:
00126           /* OK */
00127           break;
00128 
00129         case FSAL_TYPE_JUNCTION:
00130           /* This is a junction */
00131           Return(ERR_FSAL_XDEV, 0, INDEX_FSAL_lookup);
00132 
00133         case FSAL_TYPE_FILE:
00134         case FSAL_TYPE_LNK:
00135         case FSAL_TYPE_XATTR:
00136           /* not a directory */
00137           Return(ERR_FSAL_NOTDIR, 0, INDEX_FSAL_lookup);
00138 
00139         default:
00140           Return(ERR_FSAL_SERVERFAULT, 0, INDEX_FSAL_lookup);
00141         }
00142 
00143       /* call to HPSS client api */
00144       /* We use hpss_GetRawAttrHandle for not chasing junctions nor symlinks. */
00145 
00146       TakeTokenFSCall();
00147 
00148       rc = HPSSFSAL_GetRawAttrHandle(&(parent_directory_handle->data.ns_handle), p_filename->name, &p_context->credential.hpss_usercred, FALSE,      /* don't traverse junctions */
00149                                      &obj_hdl, NULL, &obj_attr);
00150 
00151       ReleaseTokenFSCall();
00152 
00158       if(rc == HPSS_ENOTDIR)
00159         {
00160           if(HPSSFSAL_IsStaleHandle(&parent_directory_handle->data.ns_handle,
00161                                     &p_context->credential.hpss_usercred))
00162             {
00163               Return(ERR_FSAL_STALE, -rc, INDEX_FSAL_lookup);
00164             }
00165         }
00166 
00167       if(rc)
00168         Return(hpss2fsal_error(rc), -rc, INDEX_FSAL_lookup);
00169 
00170       /* set output handle */
00171       memset( (char *)object_handle, 0, sizeof( hpssfsal_handle_t ) ) ;
00172       object_handle->data.obj_type = hpss2fsal_type(obj_hdl.Type);
00173       object_handle->data.ns_handle = obj_hdl;
00174 
00175       if(object_attributes)
00176         {
00177 
00178           /* convert hpss attributes to fsal attributes */
00179 
00180           status = hpss2fsal_attributes(&obj_hdl, &obj_attr, object_attributes);
00181 
00182           if(FSAL_IS_ERROR(status))
00183             Return(status.major, status.minor, INDEX_FSAL_lookup);
00184 
00185         }
00186 
00187     }
00188 
00189   /* lookup complete ! */
00190   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookup);
00191 
00192 }
00193 
00221 fsal_status_t HPSSFSAL_lookupJunction(hpssfsal_handle_t * p_junction_handle,    /* IN */
00222                                       hpssfsal_op_context_t * p_context,        /* IN */
00223                                       hpssfsal_handle_t * p_fsoot_handle,       /* OUT */
00224                                       fsal_attrib_list_t * p_fsroot_attributes  /* [ IN/OUT ] */
00225     )
00226 {
00227   int rc;
00228   fsal_status_t status;
00229   hpss_Attrs_t root_attr;
00230 
00231   /* sanity checks
00232    * note : p_fsroot_attributes is optionnal
00233    */
00234   if(!p_junction_handle || !p_fsoot_handle || !p_context)
00235     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookupJunction);
00236 
00237   if(p_junction_handle->data.obj_type != FSAL_TYPE_JUNCTION)
00238     Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_lookupJunction);
00239 
00240   /* call to HPSS client api */
00241   /* We use hpss_GetRawAttrHandle for chasing junctions. */
00242 
00243   TakeTokenFSCall();
00244 
00245   rc = HPSSFSAL_GetRawAttrHandle(&(p_junction_handle->data.ns_handle), NULL, &p_context->credential.hpss_usercred, TRUE,     /* do traverse junctions !!! */
00246                                  NULL, NULL, &root_attr);
00247 
00248   ReleaseTokenFSCall();
00249 
00250   if(rc)
00251     Return(hpss2fsal_error(rc), -rc, INDEX_FSAL_lookupJunction);
00252 
00253   /* set output handle */
00254   p_fsoot_handle->data.obj_type = hpss2fsal_type(root_attr.FilesetHandle.Type);
00255   p_fsoot_handle->data.ns_handle = root_attr.FilesetHandle;
00256 
00257   if(p_fsroot_attributes)
00258     {
00259 
00260       /* convert hpss attributes to fsal attributes */
00261 
00262       status = hpss2fsal_attributes(&root_attr.FilesetHandle,
00263                                     &root_attr, p_fsroot_attributes);
00264 
00265       if(FSAL_IS_ERROR(status))
00266         Return(status.major, status.minor, INDEX_FSAL_lookupJunction);
00267 
00268     }
00269 
00270   /* lookup complete ! */
00271   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupJunction);
00272 }
00273 
00308 fsal_status_t HPSSFSAL_lookupPath(fsal_path_t * p_path, /* IN */
00309                                   hpssfsal_op_context_t * p_context,    /* IN */
00310                                   hpssfsal_handle_t * object_handle,    /* OUT */
00311                                   fsal_attrib_list_t * object_attributes        /* [ IN/OUT ] */
00312     )
00313 {
00314   fsal_name_t obj_name = FSAL_NAME_INITIALIZER; /* empty string */
00315   char *ptr_str;
00316   hpssfsal_handle_t out_hdl;
00317   fsal_status_t status;
00318   int b_is_last = FALSE;        /* is it the last lookup ? */
00319 
00320   /* sanity checks
00321    * note : object_attributes is optionnal.
00322    */
00323 
00324   if(!object_handle || !p_context || !p_path)
00325     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookupPath);
00326 
00327   /* test whether the path begins with a slash */
00328 
00329   if(p_path->path[0] != '/')
00330     Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_lookupPath);
00331 
00332   /* the pointer now points on the next name in the path,
00333    * skipping slashes.
00334    */
00335 
00336   ptr_str = p_path->path + 1;
00337   while(ptr_str[0] == '/')
00338     ptr_str++;
00339 
00340   /* is the next name empty ? */
00341 
00342   if(ptr_str[0] == '\0')
00343     b_is_last = TRUE;
00344 
00345   /* retrieves root directory */
00346 
00347   status = HPSSFSAL_lookup(NULL,        /* looking up for root */
00348                            NULL,        /* empty string to get root handle */
00349                            p_context,   /* user's credentials */
00350                            &out_hdl,    /* output root handle */
00351                            /* retrieves attributes if this is the last lookup : */
00352                            (b_is_last ? object_attributes : NULL));
00353 
00354   if(FSAL_IS_ERROR(status))
00355     Return(status.major, status.minor, INDEX_FSAL_lookupPath);
00356 
00357   /* exits if this was the last lookup */
00358 
00359   if(b_is_last)
00360     {
00361       (*object_handle) = out_hdl;
00362       Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupPath);
00363     }
00364 
00365   /* proceed a step by step lookup */
00366 
00367   while(ptr_str[0])
00368     {
00369 
00370       hpssfsal_handle_t in_hdl;
00371       char *dest_ptr;
00372 
00373       /* preparing lookup */
00374 
00377       in_hdl = out_hdl;
00378 
00379       /* compute next name */
00380       obj_name.len = 0;
00381       dest_ptr = obj_name.name;
00382       while(ptr_str[0] != '\0' && ptr_str[0] != '/')
00383         {
00384           dest_ptr[0] = ptr_str[0];
00385           dest_ptr++;
00386           ptr_str++;
00387           obj_name.len++;
00388         }
00389       /* final null char */
00390       dest_ptr[0] = '\0';
00391 
00392       /* skip multiple slashes */
00393       while(ptr_str[0] == '/')
00394         ptr_str++;
00395 
00396       /* is the next name empty ? */
00397       if(ptr_str[0] == '\0')
00398         b_is_last = TRUE;
00399 
00400       /*call to FSAL_lookup */
00401       status = HPSSFSAL_lookup(&in_hdl, /* parent directory handle */
00402                                &obj_name,       /* object name */
00403                                p_context,       /* user's credentials */
00404                                &out_hdl,        /* output root handle */
00405                                /* retrieves attributes if this is the last lookup : */
00406                                (b_is_last ? object_attributes : NULL));
00407 
00408       if(FSAL_IS_ERROR(status))
00409         Return(status.major, status.minor, INDEX_FSAL_lookupPath);
00410 
00411       /* if the target object is a junction, an we allow cross junction lookups,
00412        * we cross it.
00413        */
00414       if(global_fs_info.auth_exportpath_xdev && (out_hdl.data.obj_type == FSAL_TYPE_JUNCTION))
00415         {
00416           hpssfsal_handle_t tmp_hdl;
00417 
00418           tmp_hdl = out_hdl;
00419 
00420           /*call to FSAL_lookup */
00421           status = HPSSFSAL_lookupJunction(&tmp_hdl,    /* object handle */
00422                                            p_context,   /* user's credentials */
00423                                            &out_hdl,    /* output root handle */
00424                                            /* retrieves attributes if this is the last lookup : */
00425                                            (b_is_last ? object_attributes : NULL));
00426 
00427         }
00428 
00429       /* ptr_str is ok, we are ready for next loop */
00430     }
00431 
00432   (*object_handle) = out_hdl;
00433   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupPath);
00434 
00435 }