nfs-ganesha 1.4
|
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 }