nfs-ganesha 1.4

fsal_unlink.c

Go to the documentation of this file.
00001 /*
00002  * vim:expandtab:shiftwidth=4:tabstop=4:
00003  */
00004 
00014 #ifdef HAVE_CONFIG_H
00015 #include "config.h"
00016 #endif
00017 
00018 #include "fsal.h"
00019 #include "fsal_internal.h"
00020 #include "fsal_convert.h"
00021 #include <unistd.h>
00022 
00046 fsal_status_t LUSTREFSAL_unlink(fsal_handle_t * p_parent_directory_handle,        /* IN */
00047                                 fsal_name_t * p_object_name,    /* IN */
00048                                 fsal_op_context_t * p_context,    /* IN */
00049                                 fsal_attrib_list_t * p_parent_directory_attributes      /* [IN/OUT ] */
00050     )
00051 {
00052 
00053   fsal_status_t status;
00054   int rc, errsv;
00055   struct stat buffstat, buffstat_parent;
00056   fsal_path_t fsalpath;
00057 
00058   /* sanity checks. */
00059   if(!p_parent_directory_handle || !p_context || !p_object_name)
00060     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_unlink);
00061 
00062   /* build the FID path */
00063   status = fsal_internal_Handle2FidPath(p_context, p_parent_directory_handle, &fsalpath);
00064   if(FSAL_IS_ERROR(status))
00065     ReturnStatus(status, INDEX_FSAL_unlink);
00066 
00067   /* get directory metadata */
00068   TakeTokenFSCall();
00069   rc = lstat(fsalpath.path, &buffstat_parent);
00070   errsv = errno;
00071   ReleaseTokenFSCall();
00072   if(rc)
00073     {
00074       if(errsv == ENOENT)
00075         Return(ERR_FSAL_STALE, errsv, INDEX_FSAL_unlink);
00076       else
00077         Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_unlink);
00078     }
00079 
00080   /* build the child path */
00081   status = fsal_internal_appendNameToPath(&fsalpath, p_object_name);
00082   if(FSAL_IS_ERROR(status))
00083     ReturnStatus(status, INDEX_FSAL_unlink);
00084 
00085   /* get file metadata */
00086   TakeTokenFSCall();
00087   rc = lstat(fsalpath.path, &buffstat);
00088   errsv = errno;
00089   ReleaseTokenFSCall();
00090   if(rc)
00091     Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_unlink);
00092 
00093   /* check access rights */
00094 
00095   /* Sticky bit on the directory => the user who wants to delete the file must own it or its parent dir */
00096   if((buffstat_parent.st_mode & S_ISVTX)
00097      && buffstat_parent.st_uid != p_context->credential.user
00098      && buffstat.st_uid != p_context->credential.user && p_context->credential.user != 0)
00099     {
00100       Return(ERR_FSAL_ACCESS, 0, INDEX_FSAL_unlink);
00101     }
00102 
00103   /* client must be able to lookup the parent directory and modify it */
00104   status =
00105       fsal_internal_testAccess(p_context, FSAL_W_OK | FSAL_X_OK, &buffstat_parent, NULL);
00106   if(FSAL_IS_ERROR(status))
00107     ReturnStatus(status, INDEX_FSAL_unlink);
00108 
00109   /******************************
00110    * DELETE FROM THE FILESYSTEM *
00111    ******************************/
00112   TakeTokenFSCall();
00113   /* If the object to delete is a directory, use 'rmdir' to delete the object, else use 'unlink' */
00114   rc = (S_ISDIR(buffstat.st_mode)) ? rmdir(fsalpath.path) : unlink(fsalpath.path);
00115   errsv = errno;
00116   ReleaseTokenFSCall();
00117   if(rc)
00118     Return(posix2fsal_error(errsv), errsv, INDEX_FSAL_unlink);
00119 
00120   /***********************
00121    * FILL THE ATTRIBUTES *
00122    ***********************/
00123 
00124   if(p_parent_directory_attributes)
00125     {
00126       status =
00127           LUSTREFSAL_getattrs(p_parent_directory_handle, p_context,
00128                               p_parent_directory_attributes);
00129       if(FSAL_IS_ERROR(status))
00130         {
00131           FSAL_CLEAR_MASK(p_parent_directory_attributes->asked_attributes);
00132           FSAL_SET_MASK(p_parent_directory_attributes->asked_attributes,
00133                         FSAL_ATTR_RDATTR_ERR);
00134         }
00135     }
00136   /* OK */
00137   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_unlink);
00138 
00139 }