nfs-ganesha 1.4

fsal_lookup.c

Go to the documentation of this file.
00001 /*
00002  * vim:expandtab:shiftwidth=8:tabstop=8:
00003  *
00004  * Copyright CEA/DAM/DIF  (2008)
00005  * contributeur : Philippe DENIEL   philippe.deniel@cea.fr
00006  *                Thomas LEIBOVICI  thomas.leibovici@cea.fr
00007  *
00008  *
00009  * This program is free software; you can redistribute it and/or
00010  * modify it under the terms of the GNU Lesser General Public
00011  * License as published by the Free Software Foundation; either
00012  * version 3 of the License, or (at your option) any later version.
00013  *
00014  * This program is distributed in the hope that it will be useful,
00015  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00016  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017  * Lesser General Public License for more details.
00018  *
00019  * You should have received a copy of the GNU Lesser General Public
00020  * License along with this library; if not, write to the Free Software
00021  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00022  *
00023  * ------------- 
00024  */
00025 
00034 #ifdef HAVE_CONFIG_H
00035 #include "config.h"
00036 #endif
00037 
00038 #include <string.h>
00039 #include "fsal.h"
00040 #include "fsal_internal.h"
00041 #include "FSAL/access_check.h"
00042 #include "fsal_convert.h"
00043 
00070 fsal_status_t VFSFSAL_lookup(fsal_handle_t * p_parent_directory_handle,      /* IN */
00071                              fsal_name_t * p_filename,  /* IN */
00072                              fsal_op_context_t * p_context,  /* IN */
00073                              fsal_handle_t * p_object_handle,        /* OUT */
00074                              fsal_attrib_list_t * p_object_attributes   /* [ IN/OUT ] */
00075     )
00076 {
00077   vfsfsal_handle_t * vfs_handle = (vfsfsal_handle_t *)p_object_handle;
00078   vfsfsal_op_context_t *vfs_context = (vfsfsal_op_context_t *)p_context;
00079   int rc, errsv;
00080   fsal_status_t status;
00081   struct stat buffstat;
00082   int parentfd;
00083 
00084   /* sanity checks
00085    * note : object_attributes is optionnal
00086    *        parent_directory_handle may be null for getting FS root.
00087    */
00088   if(!p_object_handle || !p_context)
00089     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup);
00090 
00091   /* filename AND parent handle are NULL => lookup "/" */
00092   if((p_parent_directory_handle && !p_filename)
00093      || (!p_parent_directory_handle && p_filename))
00094     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup);
00095 
00096   /* get information about root */
00097   if(!p_parent_directory_handle)
00098     {
00099       /* Copy the root handle */
00100       memcpy( (char *)&vfs_handle->data.vfs_handle,
00101              (char *)&vfs_context->export_context->root_handle,
00102               sizeof( vfs_file_handle_t ) ) ;
00103        
00104       /* get attributes, if asked */
00105       if(p_object_attributes)
00106         {
00107           status = VFSFSAL_getattrs(p_object_handle, p_context, p_object_attributes);
00108           if(FSAL_IS_ERROR(status))
00109             {
00110               FSAL_CLEAR_MASK(p_object_attributes->asked_attributes);
00111               FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00112             }
00113         }
00114       /* Done */
00115       Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookup);
00116     }
00117 
00118   /* retrieve directory attributes */
00119   TakeTokenFSCall();
00120   status =
00121       fsal_internal_handle2fd(p_context, p_parent_directory_handle, &parentfd, O_RDONLY);
00122   ReleaseTokenFSCall();
00123   if(FSAL_IS_ERROR(status))
00124     ReturnStatus(status, INDEX_FSAL_lookup);
00125 
00126   /* get directory metadata */
00127   TakeTokenFSCall();
00128   rc = fstat(parentfd, &buffstat);
00129   errsv = errno;
00130   ReleaseTokenFSCall();
00131 
00132   if(rc)
00133     {
00134       close( parentfd ) ;
00135 
00136       if(errsv == ENOENT)
00137         Return(ERR_FSAL_STALE, errsv, INDEX_FSAL_lookup);
00138       else
00139         Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_lookup);
00140     }
00141 
00142   /* Be careful about junction crossing, symlinks, hardlinks,... */
00143   switch (posix2fsal_type(buffstat.st_mode))
00144     {
00145     case FSAL_TYPE_DIR:
00146       // OK
00147       break;
00148 
00149     case FSAL_TYPE_JUNCTION:
00150       // This is a junction
00151       close( parentfd ) ;
00152       Return(ERR_FSAL_XDEV, 0, INDEX_FSAL_lookup);
00153 
00154     case FSAL_TYPE_FILE:
00155     case FSAL_TYPE_LNK:
00156     case FSAL_TYPE_XATTR:
00157       // not a directory 
00158       close( parentfd ) ;
00159       Return(ERR_FSAL_NOTDIR, 0, INDEX_FSAL_lookup);
00160 
00161     default:
00162       close( parentfd ) ;
00163       Return(ERR_FSAL_SERVERFAULT, 0, INDEX_FSAL_lookup);
00164     }
00165 
00166   LogFullDebug(COMPONENT_FSAL, "lookup of inode=%"PRIu64"/%s", buffstat.st_ino,
00167           p_filename->name);
00168 
00169   /* check rights to enter into the directory */
00170   status = fsal_check_access(p_context, FSAL_X_OK, &buffstat, NULL);
00171   if(FSAL_IS_ERROR(status))
00172     ReturnStatus(status, INDEX_FSAL_lookup);
00173 
00174    /* get file handle, it it exists */
00175   TakeTokenFSCall();
00176 
00177   vfs_handle->data.vfs_handle.handle_bytes = VFS_HANDLE_LEN ;
00178   if( vfs_name_by_handle_at( parentfd,  p_filename->name,
00179                              &vfs_handle->data.vfs_handle) != 0 )
00180    {
00181       errsv = errno;
00182       ReleaseTokenFSCall();
00183       close( parentfd ) ;
00184       Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_lookup);
00185    }
00186 
00187   ReleaseTokenFSCall();
00188   close( parentfd ) ;
00189 
00190 
00191   /* get object attributes */
00192   if(p_object_attributes)
00193     {
00194       status = VFSFSAL_getattrs(p_object_handle, p_context, p_object_attributes);
00195       if(FSAL_IS_ERROR(status))
00196         {
00197           FSAL_CLEAR_MASK(p_object_attributes->asked_attributes);
00198           FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00199         }
00200     }
00201 
00202   /* lookup complete ! */
00203   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookup);
00204 
00205 }
00206 
00229 fsal_status_t VFSFSAL_lookupPath(fsal_path_t * p_path,  /* IN */
00230                                  fsal_op_context_t * p_context,      /* IN */
00231                                  fsal_handle_t * object_handle,      /* OUT */
00232                                  fsal_attrib_list_t * p_object_attributes       /* [ IN/OUT ] */
00233     )
00234 {
00235   fsal_status_t status;
00236 
00237   /* sanity checks
00238    * note : object_attributes is optional.
00239    */
00240 
00241   if(!object_handle || !p_context || !p_path)
00242     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookupPath);
00243 
00244   /* test whether the path begins with a slash */
00245 
00246   if(p_path->path[0] != '/')
00247     Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_lookupPath);
00248 
00249   /* directly call the lookup function */
00250 
00251   status = fsal_internal_Path2Handle(p_context, p_path, object_handle);
00252   if(FSAL_IS_ERROR(status))
00253     ReturnStatus(status, INDEX_FSAL_lookupPath);
00254 
00255   /* get object attributes */
00256   if(p_object_attributes)
00257     {
00258       status = VFSFSAL_getattrs(object_handle, p_context, p_object_attributes);
00259       if(FSAL_IS_ERROR(status))
00260         {
00261           FSAL_CLEAR_MASK(p_object_attributes->asked_attributes);
00262           FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00263         }
00264     }
00265 
00266   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupPath);
00267 
00268 }
00269 
00293 fsal_status_t VFSFSAL_lookupJunction(fsal_handle_t * p_junction_handle,      /* IN */
00294                                      fsal_op_context_t * p_context,  /* IN */
00295                                      fsal_handle_t * p_fsoot_handle, /* OUT */
00296                                      fsal_attrib_list_t * p_fsroot_attributes   /* [ IN/OUT ] */
00297     )
00298 {
00299   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupJunction);
00300 }