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 #ifdef _SOLARIS 00019 #include "solaris_port.h" 00020 #endif 00021 00022 #include "fsal.h" 00023 #include "fsal_internal.h" 00024 #include "fsal_convert.h" 00025 #include "namespace.h" 00026 00048 fsal_status_t FUSEFSAL_getattrs(fsal_handle_t *handle, /* IN */ 00049 fsal_op_context_t * p_context, /* IN */ 00050 fsal_attrib_list_t * object_attributes /* IN/OUT */ 00051 ) 00052 { 00053 fusefsal_handle_t * filehandle = (fusefsal_handle_t *)handle; 00054 int rc; 00055 fsal_status_t status; 00056 struct stat obj_stat; 00057 char object_path[FSAL_MAX_PATH_LEN]; 00058 00059 /* sanity checks. 00060 * note : object_attributes is mandatory in FSAL_getattrs. 00061 */ 00062 if(!filehandle || !p_context || !object_attributes) 00063 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_getattrs); 00064 00065 /* get the full path for the object */ 00066 rc = NamespacePath(filehandle->data.inode, filehandle->data.device, filehandle->data.validator, 00067 object_path); 00068 if(rc) 00069 Return(ERR_FSAL_STALE, rc, INDEX_FSAL_getattrs); 00070 00071 /* set context for the next operation, so it can be retrieved by FS thread */ 00072 fsal_set_thread_context(p_context); 00073 00074 if(p_fs_ops->getattr) 00075 { 00076 TakeTokenFSCall(); 00077 00078 rc = p_fs_ops->getattr(object_path, &obj_stat); 00079 00080 ReleaseTokenFSCall(); 00081 00082 if(rc) 00083 Return(fuse2fsal_error(rc, TRUE), rc, INDEX_FSAL_getattrs); 00084 } 00085 else 00086 { 00087 /* return void attributes... 00088 * Actually, should never occur since getattr 00089 * is needed for building entry's handle. 00090 */ 00091 00092 LogDebug(COMPONENT_FSAL, 00093 "FSAL_getattr WARNING: getattr is not implemented on this filesystem! Returning dummy values."); 00094 00095 obj_stat.st_dev = filehandle->data.device; 00096 obj_stat.st_ino = filehandle->data.inode; 00097 obj_stat.st_mode = S_IFDIR | S_IRWXU | S_IRWXG | S_IRWXO; 00098 obj_stat.st_nlink = 1; 00099 obj_stat.st_uid = 0; 00100 obj_stat.st_gid = 0; 00101 obj_stat.st_rdev = 0; 00102 obj_stat.st_size = 0; 00103 obj_stat.st_blksize = 512; 00104 obj_stat.st_blocks = 0; 00105 obj_stat.st_atime = time(NULL); 00106 obj_stat.st_mtime = time(NULL); 00107 obj_stat.st_ctime = time(NULL); 00108 } 00109 00110 /* convert to FSAL attributes */ 00111 00112 status = posix2fsal_attributes(&obj_stat, object_attributes); 00113 00114 if(FSAL_IS_ERROR(status)) 00115 { 00116 FSAL_CLEAR_MASK(object_attributes->asked_attributes); 00117 FSAL_SET_MASK(object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 00118 Return(status.major, status.minor, INDEX_FSAL_getattrs); 00119 } 00120 00121 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_getattrs); 00122 00123 } 00124 00158 fsal_status_t FUSEFSAL_setattrs(fsal_handle_t *handle, /* IN */ 00159 fsal_op_context_t * p_context, /* IN */ 00160 fsal_attrib_list_t * attrib_set, /* IN */ 00161 fsal_attrib_list_t * object_attributes /* [ IN/OUT ] */ 00162 ) 00163 { 00164 fusefsal_handle_t * filehandle = (fusefsal_handle_t *)handle; 00165 int rc; 00166 fsal_status_t status; 00167 fsal_attrib_list_t attrs; 00168 fsal_attrib_list_t tmp_attrs; 00169 char object_path[FSAL_MAX_PATH_LEN]; 00170 00171 /* sanity checks. 00172 * note : object_attributes is optional. 00173 */ 00174 if(!filehandle || !p_context || !attrib_set) 00175 Return(ERR_FSAL_FAULT, 0, INDEX_FSAL_setattrs); 00176 00177 /* local copy of attributes */ 00178 attrs = *attrib_set; 00179 00180 /* First, check that FSAL attributes changes are allowed. */ 00181 00182 /* Is it allowed to change times ? */ 00183 00184 if(!global_fs_info.cansettime) 00185 { 00186 00187 if(attrs.asked_attributes 00188 & (FSAL_ATTR_ATIME | FSAL_ATTR_CREATION | FSAL_ATTR_CTIME | FSAL_ATTR_MTIME)) 00189 { 00190 00191 /* handled as an unsettable attribute. */ 00192 Return(ERR_FSAL_INVAL, 0, INDEX_FSAL_setattrs); 00193 } 00194 00195 } 00196 00197 /* apply umask, if mode attribute is to be changed */ 00198 00199 if(FSAL_TEST_MASK(attrs.asked_attributes, FSAL_ATTR_MODE)) 00200 { 00201 attrs.mode &= (~global_fs_info.umask); 00202 } 00203 00204 /* get the path for this entry */ 00205 00206 rc = NamespacePath(filehandle->data.inode, filehandle->data.device, filehandle->data.validator, 00207 object_path); 00208 if(rc) 00209 Return(ERR_FSAL_STALE, rc, INDEX_FSAL_setattrs); 00210 00211 /* set context for the next operation, so it can be retrieved by FS thread */ 00212 fsal_set_thread_context(p_context); 00213 00214 /********** 00215 * CHMOD * 00216 **********/ 00217 if(FSAL_TEST_MASK(attrs.asked_attributes, FSAL_ATTR_MODE)) 00218 { 00219 /* /!\ this must be ignored for symlinks */ 00220 /* We must retrieve initial value of atime and mtime because 00221 * utimens changes both of them */ 00222 fsal_status_t status; 00223 00224 FSAL_CLEAR_MASK(tmp_attrs.asked_attributes); 00225 FSAL_SET_MASK(tmp_attrs.asked_attributes, FSAL_ATTR_TYPE); 00226 00227 status = FUSEFSAL_getattrs(filehandle, p_context, &tmp_attrs); 00228 00229 if(FSAL_IS_ERROR(status)) 00230 Return(status.major, status.minor, INDEX_FSAL_setattrs); 00231 00232 if((tmp_attrs.type != FSAL_TYPE_LNK) && (p_fs_ops->chmod != NULL)) 00233 { 00234 TakeTokenFSCall(); 00235 rc = p_fs_ops->chmod(object_path, fsal2unix_mode(attrs.mode)); 00236 ReleaseTokenFSCall(); 00237 00238 LogFullDebug(COMPONENT_FSAL, "chmod: status = %d", rc); 00239 00240 if(rc) 00241 Return(fuse2fsal_error(rc, TRUE), rc, INDEX_FSAL_setattrs); 00242 } 00243 /* else : ignored */ 00244 00245 } 00246 00247 /************* 00248 * TRUNCATE * 00249 *************/ 00250 if(FSAL_TEST_MASK(attrs.asked_attributes, FSAL_ATTR_SIZE)) 00251 { 00252 00253 if(p_fs_ops->truncate) 00254 { 00255 TakeTokenFSCall(); 00256 rc = p_fs_ops->truncate(object_path, (off_t) attrs.filesize); 00257 ReleaseTokenFSCall(); 00258 00259 LogFullDebug(COMPONENT_FSAL, "truncate: status = %d", rc); 00260 00261 if(rc) 00262 Return(fuse2fsal_error(rc, TRUE), rc, INDEX_FSAL_setattrs); 00263 } 00264 /* else : ignored */ 00265 00266 } 00267 00268 /*********** 00269 * CHOWN * 00270 ***********/ 00271 if(FSAL_TEST_MASK(attrs.asked_attributes, FSAL_ATTR_OWNER)) 00272 { 00273 if((p_context->credential.user != 0) && (p_context->credential.user != attrs.owner)) 00274 { 00275 LogEvent(COMPONENT_FSAL, 00276 "FSAL_setattr: Denied user %d to change object's owner to %d", 00277 p_context->credential.user, attrs.owner); 00278 Return(ERR_FSAL_PERM, 0, INDEX_FSAL_setattrs); 00279 } 00280 } 00281 00282 if(FSAL_TEST_MASK(attrs.asked_attributes, FSAL_ATTR_GROUP)) 00283 { 00284 if((p_context->credential.user != 0) 00285 && (p_context->credential.group != attrs.group)) 00286 { 00287 LogEvent(COMPONENT_FSAL, 00288 "FSAL_setattr: Denied user %d (group %d) to change object's group to %d", 00289 p_context->credential.user, p_context->credential.group, 00290 attrs.group); 00291 Return(ERR_FSAL_PERM, 0, INDEX_FSAL_setattrs); 00292 } 00293 } 00294 00295 if(FSAL_TEST_MASK(attrs.asked_attributes, FSAL_ATTR_OWNER | FSAL_ATTR_GROUP)) 00296 { 00297 if(p_fs_ops->chown) 00298 { 00299 TakeTokenFSCall(); 00300 rc = p_fs_ops->chown(object_path, 00301 FSAL_TEST_MASK(attrs.asked_attributes, 00302 FSAL_ATTR_OWNER) ? (uid_t) attrs.owner : -1, 00303 FSAL_TEST_MASK(attrs.asked_attributes, 00304 FSAL_ATTR_GROUP) ? (gid_t) attrs.group : 00305 -1); 00306 ReleaseTokenFSCall(); 00307 00308 LogFullDebug(COMPONENT_FSAL, "chown: status = %d", rc); 00309 00310 if(rc) 00311 Return(fuse2fsal_error(rc, TRUE), rc, INDEX_FSAL_setattrs); 00312 } 00313 /* else : ignored */ 00314 } 00315 00316 /*********** 00317 * UTIME * 00318 ***********/ 00319 if(FSAL_TEST_MASK(attrs.asked_attributes, FSAL_ATTR_ATIME | FSAL_ATTR_MTIME)) 00320 { 00321 00322 /* We must retrieve initial value of atime and mtime because 00323 * utimens changes both of them */ 00324 fsal_status_t status; 00325 00326 FSAL_CLEAR_MASK(tmp_attrs.asked_attributes); 00327 FSAL_SET_MASK(tmp_attrs.asked_attributes, FSAL_ATTR_ATIME); 00328 FSAL_SET_MASK(tmp_attrs.asked_attributes, FSAL_ATTR_MTIME); 00329 00330 status = FUSEFSAL_getattrs(filehandle, p_context, &tmp_attrs); 00331 00332 if(FSAL_IS_ERROR(status)) 00333 Return(status.major, status.minor, INDEX_FSAL_setattrs); 00334 00335 /* utimens is provided */ 00336 00337 if(p_fs_ops->utimens) 00338 { 00339 struct timespec tv[2]; 00340 00341 tv[0].tv_sec = 00342 (FSAL_TEST_MASK(attrs.asked_attributes, FSAL_ATTR_ATIME) ? (time_t) 00343 attrs.atime.seconds : tmp_attrs.atime.seconds); 00344 tv[0].tv_nsec = 00345 (FSAL_TEST_MASK(attrs.asked_attributes, FSAL_ATTR_ATIME) ? (time_t) 00346 attrs.atime.nseconds : tmp_attrs.atime.nseconds); 00347 00348 tv[1].tv_sec = 00349 (FSAL_TEST_MASK(attrs.asked_attributes, FSAL_ATTR_MTIME) ? (time_t) 00350 attrs.mtime.seconds : tmp_attrs.mtime.seconds); 00351 tv[1].tv_nsec = 00352 (FSAL_TEST_MASK(attrs.asked_attributes, FSAL_ATTR_MTIME) ? (time_t) 00353 attrs.mtime.nseconds : tmp_attrs.mtime.nseconds); 00354 00355 TakeTokenFSCall(); 00356 rc = p_fs_ops->utimens(object_path, tv); 00357 ReleaseTokenFSCall(); 00358 00359 LogFullDebug(COMPONENT_FSAL, "utimens: status = %d", rc); 00360 00361 if(rc) 00362 Return(fuse2fsal_error(rc, TRUE), rc, INDEX_FSAL_setattrs); 00363 } 00364 else if(p_fs_ops->utime) 00365 { 00366 /* utime is provided */ 00367 struct utimbuf utb; 00368 00369 utb.actime = 00370 (FSAL_TEST_MASK(attrs.asked_attributes, FSAL_ATTR_ATIME) ? (time_t) 00371 attrs.atime.seconds : tmp_attrs.atime.seconds); 00372 utb.modtime = 00373 (FSAL_TEST_MASK(attrs.asked_attributes, FSAL_ATTR_MTIME) ? (time_t) 00374 attrs.mtime.seconds : tmp_attrs.mtime.seconds); 00375 00376 TakeTokenFSCall(); 00377 rc = p_fs_ops->utime(object_path, &utb); 00378 ReleaseTokenFSCall(); 00379 00380 LogFullDebug(COMPONENT_FSAL, "utime: status = %d", rc); 00381 00382 if(rc) 00383 Return(fuse2fsal_error(rc, TRUE), rc, INDEX_FSAL_setattrs); 00384 } 00385 /* else : ignored */ 00386 00387 } 00388 00389 /* atime/mtime */ 00390 /* Optionaly fill output attributes. */ 00391 if(object_attributes) 00392 { 00393 00394 status = FUSEFSAL_getattrs(filehandle, p_context, object_attributes); 00395 00396 /* on error, we set a special bit in the mask. */ 00397 if(FSAL_IS_ERROR(status)) 00398 { 00399 FSAL_CLEAR_MASK(object_attributes->asked_attributes); 00400 FSAL_SET_MASK(object_attributes->asked_attributes, FSAL_ATTR_RDATTR_ERR); 00401 } 00402 00403 } 00404 00405 Return(ERR_FSAL_NO_ERROR, 0, INDEX_FSAL_setattrs); 00406 00407 } /* FSAL_setattrs */