nfs-ganesha 1.4

fsal_unlink.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 
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 }