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 XFSFSAL_lookup(fsal_handle_t * parent_handle,      /* IN */
00071                              fsal_name_t * p_filename,  /* IN */
00072                              fsal_op_context_t * context,  /* IN */
00073                              fsal_handle_t * object_handle,        /* OUT */
00074                              fsal_attrib_list_t * p_object_attributes   /* [ IN/OUT ] */
00075     )
00076 {
00077   xfsfsal_handle_t * p_parent_directory_handle = (xfsfsal_handle_t *)parent_handle;
00078   xfsfsal_op_context_t * p_context = (xfsfsal_op_context_t *)context;
00079   xfsfsal_handle_t * p_object_handle = (xfsfsal_handle_t *)object_handle;
00080   int rc = 0 , errsv = 0 ;
00081   fsal_status_t status;
00082   struct stat buffstat;
00083 
00084   int parentfd;
00085 
00086   /* sanity checks
00087    * note : object_attributes is optionnal
00088    *        parent_directory_handle may be null for getting FS root.
00089    */
00090   if(!p_object_handle || !p_context)
00091     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup);
00092 
00093   /* filename AND parent handle are NULL => lookup "/" */
00094   if((p_parent_directory_handle && !p_filename)
00095      || (!p_parent_directory_handle && p_filename))
00096     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup);
00097 
00098   /* get information about root */
00099   if(!p_parent_directory_handle)
00100     {
00101       /* get handle for the mount point  */
00102       memcpy(p_object_handle->data.handle_val, p_context->export_context->mnt_handle_val,
00103              p_context->export_context->mnt_handle_len);
00104       p_object_handle->data.handle_len = p_context->export_context->mnt_handle_len;
00105 
00106       /* get attributes, if asked */
00107       if(p_object_attributes)
00108         {
00109           status = XFSFSAL_getattrs(p_object_handle, p_context, p_object_attributes);
00110           if(FSAL_IS_ERROR(status))
00111             {
00112               FSAL_CLEAR_MASK(p_object_attributes->asked_attributes);
00113               FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00114             }
00115         }
00116       /* Done */
00117       Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookup);
00118     }
00119 
00120   /* retrieve directory attributes */
00121   TakeTokenFSCall();
00122   status =
00123       fsal_internal_handle2fd(context, parent_handle, &parentfd, O_RDONLY);
00124   ReleaseTokenFSCall();
00125   if(FSAL_IS_ERROR(status))
00126     ReturnStatus(status, INDEX_FSAL_lookup);
00127 
00128   /* get directory metadata */
00129   TakeTokenFSCall();
00130   rc = fstat(parentfd, &buffstat);
00131   errsv = errno;
00132   ReleaseTokenFSCall();
00133 
00134   if(rc)
00135     {
00136       close( parentfd ) ;
00137 
00138       if(errsv == ENOENT)
00139         Return(ERR_FSAL_STALE, errsv, INDEX_FSAL_lookup);
00140       else
00141         Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_lookup);
00142     }
00143 
00144   /* Be careful about junction crossing, symlinks, hardlinks,... */
00145   switch (posix2fsal_type(buffstat.st_mode))
00146     {
00147     case FSAL_TYPE_DIR:
00148       // OK
00149       break;
00150 
00151     case FSAL_TYPE_JUNCTION:
00152       close( parentfd ) ;
00153       // This is a junction
00154       Return(ERR_FSAL_XDEV, 0, INDEX_FSAL_lookup);
00155 
00156     case FSAL_TYPE_FILE:
00157     case FSAL_TYPE_LNK:
00158     case FSAL_TYPE_XATTR:
00159       close( parentfd ) ;
00160       // not a directory 
00161       Return(ERR_FSAL_NOTDIR, 0, INDEX_FSAL_lookup);
00162 
00163     default:
00164       close( parentfd ) ;
00165       Return(ERR_FSAL_SERVERFAULT, 0, INDEX_FSAL_lookup);
00166     }
00167 
00168   LogFullDebug(COMPONENT_FSAL, "lookup of inode=%"PRIu64"/%s", buffstat.st_ino,
00169           p_filename->name);
00170 
00171   /* check rights to enter into the directory */
00172   status = fsal_check_access(context, FSAL_X_OK, &buffstat, NULL);
00173   if(FSAL_IS_ERROR(status))
00174     ReturnStatus(status, INDEX_FSAL_lookup);
00175   
00176   status = xfsfsal_stat_by_name(context, parentfd, p_filename->name,
00177                                 object_handle, p_object_attributes);
00178   close(parentfd);
00179 
00180   ReturnStatus(status, INDEX_FSAL_lookup);
00181 }
00182 
00205 fsal_status_t XFSFSAL_lookupPath(fsal_path_t * p_path,  /* IN */
00206                                  fsal_op_context_t * p_context,      /* IN */
00207                                  fsal_handle_t * object_handle,      /* OUT */
00208                                  fsal_attrib_list_t * p_object_attributes       /* [ IN/OUT ] */
00209     )
00210 {
00211   fsal_status_t status;
00212 
00213   /* sanity checks
00214    * note : object_attributes is optionnal.
00215    */
00216 
00217   if(!object_handle || !p_context || !p_path)
00218     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookupPath);
00219 
00220   /* test whether the path begins with a slash */
00221 
00222   if(p_path->path[0] != '/')
00223     Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_lookupPath);
00224 
00225   /* directly call the lookup function */
00226 
00227   status = fsal_internal_Path2Handle(p_context, p_path, object_handle);
00228   if(FSAL_IS_ERROR(status))
00229     ReturnStatus(status, INDEX_FSAL_lookupPath);
00230 
00231   /* get object attributes */
00232   if(p_object_attributes)
00233     {
00234       status = XFSFSAL_getattrs(object_handle, p_context, p_object_attributes);
00235       if(FSAL_IS_ERROR(status))
00236         {
00237           FSAL_CLEAR_MASK(p_object_attributes->asked_attributes);
00238           FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00239         }
00240     }
00241 
00242   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupPath);
00243 
00244 }
00245 
00269 fsal_status_t XFSFSAL_lookupJunction(fsal_handle_t * p_junction_handle,      /* IN */
00270                                      fsal_op_context_t * p_context,  /* IN */
00271                                      fsal_handle_t * p_fsoot_handle, /* OUT */
00272                                      fsal_attrib_list_t * p_fsroot_attributes   /* [ IN/OUT ] */
00273     )
00274 {
00275   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupJunction);
00276 }