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 
00057 fsal_status_t FSAL_lookup(fsal_handle_t * parent_directory_handle,      /* IN */
00058                           fsal_name_t * p_filename,     /* IN */
00059                           fsal_op_context_t * p_context,        /* IN */
00060                           fsal_handle_t * object_handle,        /* OUT */
00061                           fsal_attrib_list_t * object_attributes        /* [ IN/OUT ] */
00062     )
00063 {
00064 
00065   int rc;
00066   fsal_status_t status;
00067 
00068   /* sanity checks
00069    * note : object_attributes is optionnal
00070    *        parent_directory_handle may be null for getting FS root.
00071    */
00072   if(!object_handle || !p_context)
00073     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup);
00074 
00075   /* retrieves root handle */
00076 
00077   if(!parent_directory_handle)
00078     {
00079 
00080       /* check that p_filename is NULL,
00081        * else, parent_directory_handle should not
00082        * be NULL.
00083        */
00084       if(p_filename != NULL)
00085         Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup);
00086 
00087       /* >> retrieve root handle filehandle here << */
00088 
00089       /* >> retrieves root attributes, if asked << */
00090 
00091       if(object_attributes)
00092         {
00093           fsal_status_t status;
00094 
00095           status = FSAL_getattrs(object_handle, p_context, object_attributes);
00096 
00097           /* On error, we set a flag in the returned attributes */
00098 
00099           if(FSAL_IS_ERROR(status))
00100             {
00101               FSAL_CLEAR_MASK(object_attributes->asked_attributes);
00102               FSAL_SET_MASK(object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00103             }
00104         }
00105 
00106     }
00107   else                          /* this is a real lookup(parent, name)  */
00108     {
00109 
00110       /* the filename should not be null */
00111       if(p_filename == NULL)
00112         Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup);
00113 
00114       /* >> Be careful about junction crossing, symlinks, hardlinks,...
00115        * You may check the parent type if it's sored into the handle <<
00116        */
00117 
00118       switch (parent_directory_handle->object_type_reminder)
00119         {
00120         case FSAL_TYPE_DIR:
00121           /* OK */
00122           break;
00123 
00124         case FSAL_TYPE_JUNCTION:
00125           /* This is a junction */
00126           Return(ERR_FSAL_XDEV, 0, INDEX_FSAL_lookup);
00127 
00128         case FSAL_TYPE_FILE:
00129         case FSAL_TYPE_LNK:
00130         case FSAL_TYPE_XATTR:
00131           /* not a directory */
00132           Return(ERR_FSAL_NOTDIR, 0, INDEX_FSAL_lookup);
00133 
00134         default:
00135           Return(ERR_FSAL_SERVERFAULT, 0, INDEX_FSAL_lookup);
00136         }
00137 
00138       TakeTokenFSCall();
00139 
00140       /* >> Call your filesystem lookup function here << */
00141       /* >> Be carefull you don't traverse junction nor follow symlinks << */
00142 
00143       ReleaseTokenFSCall();
00144 
00145       /* >> convert the error code and return on error << */
00146 
00147       /* >> set output handle << */
00148 
00149       if(object_attributes)
00150         {
00151           /* >> fill object attributes if asked << */
00152         }
00153 
00154     }
00155 
00156   /* lookup complete ! */
00157   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookup);
00158 
00159 }
00160 
00188 fsal_status_t FSAL_lookupJunction(fsal_handle_t * p_junction_handle,    /* IN */
00189                                   fsal_op_context_t * p_context,        /* IN */
00190                                   fsal_handle_t * p_fsoot_handle,       /* OUT */
00191                                   fsal_attrib_list_t * p_fsroot_attributes      /* [ IN/OUT ] */
00192     )
00193 {
00194   int rc;
00195   fsal_status_t status;
00196 
00197   /* sanity checks
00198    * note : p_fsroot_attributes is optionnal
00199    */
00200   if(!p_junction_handle || !p_fsoot_handle || !p_context)
00201     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookupJunction);
00202 
00203   /* >> you can also check object type if it is in stored in the handle << */
00204 
00205   if(p_junction_handle->object_type_reminder != FSAL_TYPE_JUNCTION)
00206     Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_lookupJunction);
00207 
00208   TakeTokenFSCall();
00209 
00210   /* >> traverse the junction here << */
00211 
00212   ReleaseTokenFSCall();
00213 
00214   /* >> convert the error code and return on error << */
00215 
00216   /* >> set output handle << */
00217 
00218   if(p_fsroot_attributes)
00219     {
00220 
00221       /* >> fill output attributes if asked << */
00222 
00223     }
00224 
00225   /* lookup complete ! */
00226   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupJunction);
00227 }
00228 
00263 fsal_status_t FSAL_lookupPath(fsal_path_t * p_path,     /* IN */
00264                               fsal_op_context_t * p_context,    /* IN */
00265                               fsal_handle_t * object_handle,    /* OUT */
00266                               fsal_attrib_list_t * object_attributes    /* [ IN/OUT ] */
00267     )
00268 {
00269   fsal_name_t obj_name = FSAL_NAME_INITIALIZER; /* empty string */
00270   char *ptr_str;
00271   fsal_handle_t out_hdl;
00272   fsal_status_t status;
00273   int b_is_last = FALSE;        /* is it the last lookup ? */
00274 
00275 /*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
00276  *  this function may be adapted to most FSALs
00277  *<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
00278 
00279   /* sanity checks
00280    * note : object_attributes is optionnal.
00281    */
00282 
00283   if(!object_handle || !p_context || !p_path)
00284     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookupPath);
00285 
00286   /* test whether the path begins with a slash */
00287 
00288   if(p_path->path[0] != '/')
00289     Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_lookupPath);
00290 
00291   /* the pointer now points on the next name in the path,
00292    * skipping slashes.
00293    */
00294 
00295   ptr_str = p_path->path + 1;
00296   while(ptr_str[0] == '/')
00297     ptr_str++;
00298 
00299   /* is the next name empty ? */
00300 
00301   if(ptr_str[0] == '\0')
00302     b_is_last = TRUE;
00303 
00304   /* retrieves root directory */
00305 
00306   status = FSAL_lookup(NULL,    /* looking up for root */
00307                        NULL,    /* empty string to get root handle */
00308                        p_context,       /* user's credentials */
00309                        &out_hdl,        /* output root handle */
00310                        /* retrieves attributes if this is the last lookup : */
00311                        (b_is_last ? object_attributes : NULL));
00312 
00313   if(FSAL_IS_ERROR(status))
00314     Return(status.major, status.minor, INDEX_FSAL_lookupPath);
00315 
00316   /* exits if this was the last lookup */
00317 
00318   if(b_is_last)
00319     {
00320       (*object_handle) = out_hdl;
00321       Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupPath);
00322     }
00323 
00324   /* proceed a step by step lookup */
00325 
00326   while(ptr_str[0])
00327     {
00328 
00329       fsal_handle_t in_hdl;
00330       char *dest_ptr;
00331 
00332       /* preparing lookup */
00333 
00334       in_hdl = out_hdl;
00335 
00336       /* compute next name */
00337       obj_name.len = 0;
00338       dest_ptr = obj_name.name;
00339       while(ptr_str[0] != '\0' && ptr_str[0] != '/')
00340         {
00341           dest_ptr[0] = ptr_str[0];
00342           dest_ptr++;
00343           ptr_str++;
00344           obj_name.len++;
00345         }
00346       /* final null char */
00347       dest_ptr[0] = '\0';
00348 
00349       /* skip multiple slashes */
00350       while(ptr_str[0] == '/')
00351         ptr_str++;
00352 
00353       /* is the next name empty ? */
00354       if(ptr_str[0] == '\0')
00355         b_is_last = TRUE;
00356 
00357       /*call to FSAL_lookup */
00358       status = FSAL_lookup(&in_hdl,     /* parent directory handle */
00359                            &obj_name,   /* object name */
00360                            p_context,   /* user's credentials */
00361                            &out_hdl,    /* output root handle */
00362                            /* retrieves attributes if this is the last lookup : */
00363                            (b_is_last ? object_attributes : NULL));
00364 
00365       if(FSAL_IS_ERROR(status))
00366         Return(status.major, status.minor, INDEX_FSAL_lookupPath);
00367 
00368       /* if the target object is a junction, an we allow cross junction lookups,
00369        * we cross it.
00370        */
00371       if(global_fs_info.auth_exportpath_xdev
00372          && (out_hdl.object_type_reminder == FSAL_TYPE_JUNCTION))
00373         {
00374           fsal_handle_t tmp_hdl;
00375 
00376           tmp_hdl = out_hdl;
00377 
00378           /*call to FSAL_lookup */
00379           status = FSAL_lookupJunction(&tmp_hdl,        /* object handle */
00380                                        p_context,       /* user's credentials */
00381                                        &out_hdl,        /* output root handle */
00382                                        /* retrieves attributes if this is the last lookup : */
00383                                        (b_is_last ? object_attributes : NULL));
00384 
00385         }
00386 
00387       /* ptr_str is ok, we are ready for next loop */
00388     }
00389 
00390   (*object_handle) = out_hdl;
00391   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupPath);
00392 
00393 }