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_convert.h"
00042 
00070 fsal_status_t GPFSFSAL_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 * object_handle,      /* OUT */
00074                           fsal_attrib_list_t * p_object_attributes      /* [ IN/OUT ] */
00075     )
00076 {
00077   fsal_status_t status;
00078   int parentfd;
00079   fsal_accessflags_t access_mask = 0;
00080   fsal_attrib_list_t parent_dir_attrs;
00081   gpfsfsal_handle_t *p_object_handle = (gpfsfsal_handle_t *)object_handle;
00082 
00083   /* sanity checks
00084    * note : object_attributes is optional
00085    *        parent_directory_handle may be null for getting FS root.
00086    */
00087   if(!p_object_handle || !p_context)
00088     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup);
00089 
00090   /* filename AND parent handle are NULL => lookup "/" */
00091   if((p_parent_directory_handle && !p_filename)
00092      || (!p_parent_directory_handle && p_filename))
00093     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookup);
00094 
00095   /* get information about root */
00096   if(!p_parent_directory_handle)
00097     {
00098       gpfsfsal_handle_t *root_handle = &((gpfsfsal_op_context_t *)p_context)->export_context->mount_root_handle;
00099 
00100       /* get handle for the mount point  */
00101       memcpy(p_object_handle->data.handle.f_handle,
00102              root_handle->data.handle.f_handle,
00103              sizeof(root_handle->data.handle.handle_size));
00104       p_object_handle->data.handle.handle_size = root_handle->data.handle.handle_size;
00105       p_object_handle->data.handle.handle_key_size = root_handle->data.handle.handle_key_size;
00106 
00107       /* get attributes, if asked */
00108       if(p_object_attributes)
00109         {
00110           status = GPFSFSAL_getattrs(object_handle, p_context, p_object_attributes);
00111           if(FSAL_IS_ERROR(status))
00112             {
00113               FSAL_CLEAR_MASK(p_object_attributes->asked_attributes);
00114               FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00115             }
00116         }
00117       /* Done */
00118       Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookup);
00119     }
00120 
00121   /* retrieve directory attributes */
00122   TakeTokenFSCall();
00123   status =
00124       fsal_internal_handle2fd(p_context, p_parent_directory_handle, &parentfd, O_RDONLY);
00125   ReleaseTokenFSCall();
00126   if(FSAL_IS_ERROR(status))
00127     ReturnStatus(status, INDEX_FSAL_lookup);
00128 
00129   /* get directory metadata */
00130 
00131   parent_dir_attrs.asked_attributes = GPFS_SUPPORTED_ATTRIBUTES;
00132   status = GPFSFSAL_getattrs(p_parent_directory_handle, p_context, &parent_dir_attrs);
00133   if(FSAL_IS_ERROR(status))
00134     {
00135       close(parentfd);
00136       ReturnStatus(status, INDEX_FSAL_lookup);
00137     }
00138 
00139   /* Be careful about junction crossing, symlinks, hardlinks,... */
00140   switch (parent_dir_attrs.type)
00141     {
00142     case FSAL_TYPE_DIR:
00143       // OK
00144       break;
00145 
00146     case FSAL_TYPE_JUNCTION:
00147       // This is a junction
00148       close(parentfd);
00149       Return(ERR_FSAL_XDEV, 0, INDEX_FSAL_lookup);
00150 
00151     case FSAL_TYPE_FILE:
00152     case FSAL_TYPE_LNK:
00153     case FSAL_TYPE_XATTR:
00154       // not a directory 
00155       close(parentfd);
00156       Return(ERR_FSAL_NOTDIR, 0, INDEX_FSAL_lookup);
00157 
00158     default:
00159       close(parentfd);
00160       Return(ERR_FSAL_SERVERFAULT, 0, INDEX_FSAL_lookup);
00161     }
00162 
00163   //  LogFullDebug(COMPONENT_FSAL,
00164   //               "lookup of %#llx:%#x:%#x/%s", p_parent_directory_handle->seq,
00165   //               p_parent_directory_handle->oid, p_parent_directory_handle->ver,
00166   //               p_filename->name);
00167 
00168   /* check rights to enter into the directory */
00169 
00170   /* Set both mode and ace4 mask */
00171   access_mask = FSAL_MODE_MASK_SET(FSAL_R_OK | FSAL_X_OK) |
00172                 FSAL_ACE4_MASK_SET(FSAL_ACE_PERM_LIST_DIR);
00173 
00174   if(!p_context->export_context->fe_static_fs_info->accesscheck_support)
00175   status = fsal_internal_testAccess(p_context, access_mask, NULL, &parent_dir_attrs);
00176   else
00177     status = fsal_internal_access(p_context, p_parent_directory_handle, access_mask,
00178                                   &parent_dir_attrs);
00179   if(FSAL_IS_ERROR(status))
00180     {
00181       close(parentfd);
00182       ReturnStatus(status, INDEX_FSAL_lookup);
00183     }
00184 
00185   /* get file handle, it it exists */
00186   /* This might be a race, but it's the best we can currently do */
00187   status = fsal_internal_get_handle_at(parentfd, p_filename, object_handle);
00188   close(parentfd);
00189 
00190   if(FSAL_IS_ERROR(status))
00191     ReturnStatus(status, INDEX_FSAL_lookup);
00192 
00193   /* get object attributes */
00194   if(p_object_attributes)
00195     {
00196       status = GPFSFSAL_getattrs(object_handle, p_context, p_object_attributes);
00197       if(FSAL_IS_ERROR(status))
00198         {
00199           FSAL_CLEAR_MASK(p_object_attributes->asked_attributes);
00200           FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00201         }
00202     }
00203 
00204   /* lookup complete ! */
00205   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookup);
00206 }
00207 
00230 fsal_status_t GPFSFSAL_lookupPath(fsal_path_t * p_path,     /* IN */
00231                               fsal_op_context_t * p_context,    /* IN */
00232                               fsal_handle_t * object_handle,    /* OUT */
00233                               fsal_attrib_list_t * p_object_attributes  /* [ IN/OUT ] */
00234     )
00235 {
00236   fsal_status_t status;
00237 
00238   /* sanity checks
00239    * note : object_attributes is optionnal.
00240    */
00241 
00242   if(!object_handle || !p_context || !p_path)
00243     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_lookupPath);
00244 
00245   /* test whether the path begins with a slash */
00246 
00247   if(p_path->path[0] != '/')
00248     Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_lookupPath);
00249 
00250   /* directly call the lookup function */
00251 
00252   status = fsal_internal_get_handle(p_context, p_path, object_handle);
00253   if(FSAL_IS_ERROR(status))
00254     ReturnStatus(status, INDEX_FSAL_lookupPath);
00255 
00256   /* get object attributes */
00257   if(p_object_attributes)
00258     {
00259       status = GPFSFSAL_getattrs(object_handle, p_context, p_object_attributes);
00260       if(FSAL_IS_ERROR(status))
00261         {
00262           FSAL_CLEAR_MASK(p_object_attributes->asked_attributes);
00263           FSAL_SET_MASK(p_object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00264         }
00265     }
00266 
00267   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupPath);
00268 
00269 }
00270 
00294 fsal_status_t GPFSFSAL_lookupJunction(fsal_handle_t * p_junction_handle,    /* IN */
00295                                   fsal_op_context_t * p_context,        /* IN */
00296                                   fsal_handle_t * p_fsoot_handle,       /* OUT */
00297                                   fsal_attrib_list_t * p_fsroot_attributes      /* [ IN/OUT ] */
00298     )
00299 {
00300   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_lookupJunction);
00301 }