nfs-ganesha 1.4

fsal_attrs.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 "fsal_common.h"
00022 
00023 #include <string.h>
00024 #include <fcntl.h>
00025 
00047 fsal_status_t ZFSFSAL_getattrs(fsal_handle_t * fhandle, /* IN */
00048                                fsal_op_context_t * p_context,      /* IN */
00049                                fsal_attrib_list_t * object_attributes      /* IN/OUT */
00050     )
00051 {
00052   int rc, type;
00053   struct stat fstat;
00054   creden_t cred;
00055   zfsfsal_handle_t *filehandle = (zfsfsal_handle_t *)fhandle;
00056 
00057   /* sanity checks.
00058    * note : object_attributes is mandatory in ZFSFSAL_getattrs.
00059    */
00060   if(!filehandle || !p_context || !object_attributes)
00061     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_getattrs);
00062 
00063   cred.uid = p_context->credential.user;
00064   cred.gid = p_context->credential.group;
00065   TakeTokenFSCall();
00066 
00067   if(filehandle->data.zfs_handle.inode == ZFS_SNAP_DIR_INODE &&
00068      filehandle->data.zfs_handle.generation == 0)
00069   {
00070     memset(&fstat, 0, sizeof(fstat));
00071     fstat.st_mode = S_IFDIR | 0755;
00072     fstat.st_ino = ZFS_SNAP_DIR_INODE;
00073     fstat.st_nlink = 2;
00074     fstat.st_ctime = time(NULL);
00075     fstat.st_atime = fstat.st_ctime;
00076     fstat.st_mtime = fstat.st_ctime;
00077     rc = 0;
00078   }
00079   else
00080   {
00081     /* Get the right VFS */
00082     ZFSFSAL_VFS_RDLock();
00083     libzfswrap_vfs_t *p_vfs = ZFSFSAL_GetVFS(filehandle);
00084     if(!p_vfs)
00085       rc = ENOENT;
00086     else
00087       rc = libzfswrap_getattr(p_vfs, &cred,
00088                               filehandle->data.zfs_handle, &fstat, &type);
00089     ZFSFSAL_VFS_Unlock();
00090   }
00091 
00092   // Set st_dev to be the snapshot number.
00093   fstat.st_dev = filehandle->data.i_snap;
00094 
00095   ReleaseTokenFSCall();
00096 
00097   /* >> convert error code, and return on error << */
00098   if(rc)
00099     Return(posix2fsal_error(rc), 0, INDEX_FSAL_getattrs);
00100 
00101   /* >> convert your filesystem attributes to FSAL attributes << */
00102   fsal_status_t st = posix2fsal_attributes(&fstat, object_attributes);
00103   if(FSAL_IS_ERROR(st))
00104     {
00105       FSAL_CLEAR_MASK(object_attributes->asked_attributes);
00106       FSAL_SET_MASK(object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00107       Return(st.major, st.minor, INDEX_FSAL_getattrs);
00108     }
00109 
00110   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_getattrs);
00111 
00112 }
00113 
00147 fsal_status_t ZFSFSAL_setattrs(fsal_handle_t * fhandle, /* IN */
00148                                fsal_op_context_t * p_context,      /* IN */
00149                                fsal_attrib_list_t * attrib_set,    /* IN */
00150                                fsal_attrib_list_t * object_attributes      /* [ IN/OUT ] */
00151     )
00152 {
00153   int rc;
00154   fsal_status_t status;
00155   fsal_attrib_list_t attrs;
00156   creden_t cred;
00157   zfsfsal_handle_t * filehandle = (zfsfsal_handle_t *)fhandle;
00158 
00159   /* sanity checks.
00160    * note : object_attributes is optional.
00161    */
00162   if(!filehandle || !p_context || !attrib_set)
00163     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_setattrs);
00164 
00165   if(filehandle->data.i_snap != 0)
00166   {
00167     LogDebug(COMPONENT_FSAL, "Trying to change the attributes of an object inside a snapshot");
00168     Return(ERR_FSAL_ROFS, 0, INDEX_FSAL_setattrs);
00169   }
00170 
00171   /* local copy of attributes */
00172   attrs = *attrib_set;
00173 
00174   /* First, check that FSAL attributes changes are allowed. */
00175 
00176   /* Is it allowed to change times ? */
00177 
00178   if(!global_fs_info.cansettime)
00179     {
00180 
00181       if(attrs.asked_attributes
00182          & (FSAL_ATTR_ATIME | FSAL_ATTR_CREATION | FSAL_ATTR_CTIME | FSAL_ATTR_MTIME))
00183         {
00184 
00185           /* handled as an unsettable attribute. */
00186           Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_setattrs);
00187         }
00188 
00189     }
00190 
00191   /* apply umask, if mode attribute is to be changed */
00192 
00193   if(FSAL_TEST_MASK(attrs.asked_attributes, FSAL_ATTR_MODE))
00194     {
00195       attrs.mode &= (~global_fs_info.umask);
00196     }
00197 
00198   /* >> Then, convert the attribute set to your FS format << */
00199   int flags = 0;
00200   struct stat stats = { 0 };
00201   if(FSAL_TEST_MASK(attrs.asked_attributes, FSAL_ATTR_MODE))
00202   {
00203     flags |= LZFSW_ATTR_MODE;
00204     stats.st_mode = fsal2unix_mode(attrs.mode);
00205   }
00206   if(FSAL_TEST_MASK(attrs.asked_attributes, FSAL_ATTR_OWNER))
00207   {
00208     flags |= LZFSW_ATTR_UID;
00209     stats.st_uid = attrs.owner;
00210   }
00211   if(FSAL_TEST_MASK(attrs.asked_attributes, FSAL_ATTR_GROUP))
00212   {
00213     flags |= LZFSW_ATTR_GID;
00214     stats.st_gid = attrs.group;
00215   }
00216   if(FSAL_TEST_MASK(attrs.asked_attributes, FSAL_ATTR_ATIME))
00217   {
00218     flags |= LZFSW_ATTR_ATIME;
00219     stats.st_atime = attrs.atime.seconds;
00220   }
00221   if(FSAL_TEST_MASK(attrs.asked_attributes, FSAL_ATTR_MTIME))
00222   {
00223     flags |= LZFSW_ATTR_MTIME;
00224     stats.st_mtime = attrs.mtime.seconds;
00225   }
00226 
00227   cred.uid = p_context->credential.user;
00228   cred.gid = p_context->credential.group;
00229 
00230   TakeTokenFSCall();
00231 
00232   struct stat new_stat = { 0 };
00234   rc = libzfswrap_setattr(((zfsfsal_op_context_t *)p_context)->export_context->p_vfs, &cred,
00235                           filehandle->data.zfs_handle, &stats, flags, &new_stat);
00236 
00237   ReleaseTokenFSCall();
00238 
00239   /* >> convert error code, and return on error << */
00240   if(rc)
00241     Return(posix2fsal_error(rc), 0, INDEX_FSAL_setattrs);
00242 
00243   /* >> Optionaly fill output attributes.
00244    * If your filesystem setattr call doesn't
00245    * return object attributes, you may do something
00246    * like that : << */
00247 
00248   if(object_attributes)
00249     {
00250 
00251       status = ZFSFSAL_getattrs((zfsfsal_handle_t *)filehandle, p_context, object_attributes);
00252 
00253       /* on error, we set a special bit in the mask. */
00254       if(FSAL_IS_ERROR(status))
00255         {
00256           FSAL_CLEAR_MASK(object_attributes->asked_attributes);
00257           FSAL_SET_MASK(object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR);
00258         }
00259 
00260     }
00261 
00262   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_setattrs);
00263 
00264 }
00265 
00285 fsal_status_t ZFSFSAL_getextattrs(fsal_handle_t * p_filehandle, /* IN */
00286                                   fsal_op_context_t * p_context,        /* IN */
00287                                   fsal_extattrib_list_t * p_object_attributes /* OUT */
00288     )
00289 {
00290   /* sanity checks.
00291    * note : object_attributes is mandatory in FSAL_getattrs.
00292    */
00293   if(!p_filehandle || !p_context || !p_object_attributes)
00294     Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_getattrs);
00295 
00296   if( p_object_attributes->asked_attributes & FSAL_ATTR_GENERATION )
00297     p_object_attributes->generation
00298             = ((zfsfsal_handle_t *)p_filehandle)->data.zfs_handle.generation;
00299 
00300   Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_getextattrs);
00301 } /* ZFSFSAL_getextattrs */