nfs-ganesha 1.4

fsal_unlink.c

Go to the documentation of this file.
00001 /*
00002  * vim:expandtab:shiftwidth=8:tabstop=8:
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 "namespace.h"
00022 #include "fsal_common.h"
00023 
00053 fsal_status_t FUSEFSAL_unlink(fsal_handle_t * parent,     /* IN */
00054                               fsal_name_t * p_object_name,      /* IN */
00055                               fsal_op_context_t * p_context,        /* IN */
00056                               fsal_attrib_list_t * parentdir_attributes /* [IN/OUT ] */
00057     )
00058 {
00059 
00060   int rc;
00061   fsal_status_t st;
00062   char parent_path[FSAL_MAX_PATH_LEN];
00063   char child_path[FSAL_MAX_PATH_LEN];
00064   struct stat stbuff;
00065   fusefsal_handle_t * parentdir_handle = (fusefsal_handle_t *)parent;
00066 
00067   /* sanity checks.
00068    * note : parentdir_attributes are optional.
00069    *        parentdir_handle is mandatory,
00070    *        because, we do not allow to delete FS root !
00071    */
00072   if(!parentdir_handle || !p_context || !p_object_name)
00073     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_unlink);
00074 
00075   /* set current FS context */
00076   fsal_set_thread_context(p_context);
00077 
00078   /* get parent directory path */
00079 
00080   rc = NamespacePath(parentdir_handle->data.inode,
00081                      parentdir_handle->data.device, parentdir_handle->data.validator, parent_path);
00082   if(rc)
00083     Return(ERR_FSAL_STALE, rc, INDEX_FSAL_unlink);
00084 
00085   /* We have to know what type of entry it is,
00086    * to switch between "unlink" and "rmdir".
00087    *
00088    * To do this, do a getattr.
00089    */
00090   FSAL_internal_append_path(child_path, parent_path, p_object_name->name);
00091 
00092   TakeTokenFSCall();
00093   rc = p_fs_ops->getattr(child_path, &stbuff);
00094   ReleaseTokenFSCall();
00095 
00096   if(rc)
00097     Return(fuse2fsal_error(rc, FALSE), rc, INDEX_FSAL_unlink);
00098 
00099   /* check type */
00100 
00101   if(posix2fsal_type(stbuff.st_mode) == FSAL_TYPE_DIR)
00102     {
00103       /* proceed rmdir call */
00104 
00105       /* operation not provided by filesystem */
00106       if(!p_fs_ops->rmdir)
00107         Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_unlink);
00108 
00109       TakeTokenFSCall();
00110       rc = p_fs_ops->rmdir(child_path);
00111       ReleaseTokenFSCall();
00112 
00113     }
00114   else
00115     {
00116       /* proceed unlink call */
00117 
00118       /* operation not provided by filesystem */
00119       if(!p_fs_ops->unlink)
00120         Return(ERR_FSAL_NOTSUPP, 0, INDEX_FSAL_unlink);
00121 
00122       TakeTokenFSCall();
00123       rc = p_fs_ops->unlink(child_path);
00124       ReleaseTokenFSCall();
00125 
00126     }
00127 
00128   if(rc == 0 || rc == -ENOENT)
00129     {
00130       /* remove the entry from namespace */
00131       NamespaceRemove(parentdir_handle->data.inode, parentdir_handle->data.device,
00132                       parentdir_handle->data.validator, p_object_name->name);
00133     }
00134 
00135   if(rc)
00136     Return(fuse2fsal_error(rc, FALSE), rc, INDEX_FSAL_unlink);
00137 
00138   if(parentdir_attributes)
00139     {
00140       st = FUSEFSAL_getattrs(parentdir_handle, p_context, parentdir_attributes);
00141 
00142       /* On error, we set a flag in the returned attributes */
00143 
00144       if(FSAL_IS_ERROR(st))
00145         {
00146           FSAL_CLEAR_MASK(parentdir_attributes->asked_attributes);
00147           FSAL_SET_MASK(parentdir_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00148         }
00149     }
00150 
00151   /* OK */
00152   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_unlink);
00153 
00154 }