nfs-ganesha 1.4
|
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 00035 #ifdef HAVE_CONFIG_H 00036 #include "config.h" 00037 #endif 00038 00039 #include "fsal.h" 00040 #include "fsal_internal.h" 00041 #include "fsal_convert.h" 00042 #include <unistd.h> 00043 00044 extern fsal_status_t gpfsfsal_xstat_2_fsal_attributes(gpfsfsal_xstat_t *p_buffxstat, 00045 fsal_attrib_list_t *p_fsalattr_out); 00046 00070 fsal_status_t GPFSFSAL_unlink(fsal_handle_t * p_parent_directory_handle, /* IN */ 00071 fsal_name_t * p_object_name, /* IN */ 00072 fsal_op_context_t * p_context, /* IN */ 00073 fsal_attrib_list_t * p_parent_directory_attributes /* [IN/OUT ] */ 00074 ) 00075 { 00076 00077 fsal_status_t status; 00078 gpfsfsal_xstat_t buffxstat; 00079 fsal_accessflags_t access_mask = 0; 00080 fsal_attrib_list_t parent_dir_attrs; 00081 00082 /* sanity checks. */ 00083 if(!p_parent_directory_handle || !p_context || !p_object_name) 00084 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_unlink); 00085 00086 /* get directory metadata */ 00087 parent_dir_attrs.asked_attributes = GPFS_SUPPORTED_ATTRIBUTES; 00088 status = GPFSFSAL_getattrs(p_parent_directory_handle, p_context, &parent_dir_attrs); 00089 if(FSAL_IS_ERROR(status)) 00090 ReturnStatus(status, INDEX_FSAL_unlink); 00091 00092 /* build the child path */ 00093 00094 /* get file metadata */ 00095 TakeTokenFSCall(); 00096 status = fsal_internal_stat_name(p_context, p_parent_directory_handle, 00097 p_object_name, &buffxstat.buffstat); 00098 ReleaseTokenFSCall(); 00099 if(FSAL_IS_ERROR(status)) 00100 ReturnStatus(status, INDEX_FSAL_unlink); 00101 00102 /* check access rights */ 00103 00104 /* Sticky bit on the directory => the user who wants to delete the file must own it or its parent dir */ 00105 if((fsal2unix_mode(parent_dir_attrs.mode) & S_ISVTX) 00106 && parent_dir_attrs.owner != p_context->credential.user 00107 && buffxstat.buffstat.st_uid != p_context->credential.user 00108 && p_context->credential.user != 0) 00109 { 00110 Return(ERR_FSAL_ACCESS, 0, INDEX_FSAL_unlink); 00111 } 00112 00113 /* client must be able to lookup the parent directory and modify it */ 00114 00115 /* Set both mode and ace4 mask */ 00116 access_mask = FSAL_MODE_MASK_SET(FSAL_W_OK | FSAL_X_OK) | 00117 FSAL_ACE4_MASK_SET(FSAL_ACE_PERM_DELETE_CHILD); 00118 00119 if(!p_context->export_context->fe_static_fs_info->accesscheck_support) 00120 status = fsal_internal_testAccess(p_context, access_mask, NULL, &parent_dir_attrs); 00121 else 00122 status = fsal_internal_access(p_context, p_parent_directory_handle, access_mask, 00123 &parent_dir_attrs); 00124 if(FSAL_IS_ERROR(status)) 00125 ReturnStatus(status, INDEX_FSAL_unlink); 00126 00127 /****************************** 00128 * DELETE FROM THE FILESYSTEM * 00129 ******************************/ 00130 TakeTokenFSCall(); 00131 status = fsal_internal_unlink(p_context, p_parent_directory_handle, 00132 p_object_name, &buffxstat.buffstat); 00133 ReleaseTokenFSCall(); 00134 00135 if(FSAL_IS_ERROR(status)) 00136 ReturnStatus(status, INDEX_FSAL_unlink); 00137 00138 /*********************** 00139 * FILL THE ATTRIBUTES * 00140 ***********************/ 00141 00142 if(p_parent_directory_attributes) 00143 { 00144 buffxstat.attr_valid = XATTR_STAT; 00145 status = gpfsfsal_xstat_2_fsal_attributes(&buffxstat, 00146 p_parent_directory_attributes); 00147 if(FSAL_IS_ERROR(status)) 00148 { 00149 FSAL_CLEAR_MASK(p_parent_directory_attributes->asked_attributes); 00150 FSAL_SET_MASK(p_parent_directory_attributes->asked_attributes, 00151 FSAL_ATTR_RDATTR_ERR); 00152 } 00153 } 00154 /* OK */ 00155 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_unlink); 00156 00157 }