nfs-ganesha 1.4
|
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 */