static fsal_status_t setattrs(struct fsal_obj_handle *obj_hdl, const struct req_op_context *opctx, struct attrlist *attrs) { int rc = 0; fsal_status_t status = { ERR_FSAL_NO_ERROR, 0 }; struct stat sb; int mask = 0; struct glusterfs_export *glfs_export = container_of(obj_hdl->export, struct glusterfs_export, export); struct glusterfs_handle *objhandle = container_of(obj_hdl, struct glusterfs_handle, handle); #ifdef GLTIMING struct timespec s_time, e_time; now(&s_time); #endif memset(&sb, 0, sizeof(struct stat)); if (FSAL_TEST_MASK(attrs->mask, ATTR_SIZE)) { rc = glfs_h_truncate(glfs_export->gl_fs, objhandle->glhandle, attrs->filesize); if (rc != 0) { status = gluster2fsal_error(errno); goto out; } } if (FSAL_TEST_MASK(attrs->mask, ATTR_MODE)) { mask |= GLAPI_SET_ATTR_MODE; sb.st_mode = fsal2unix_mode(attrs->mode); } if (FSAL_TEST_MASK(attrs->mask, ATTR_OWNER)) { mask |= GLAPI_SET_ATTR_UID; sb.st_uid = attrs->owner; } if (FSAL_TEST_MASK(attrs->mask, ATTR_GROUP)) { mask |= GLAPI_SET_ATTR_GID; sb.st_gid = attrs->group; } if (FSAL_TEST_MASK(attrs->mask, ATTR_ATIME)) { mask |= GLAPI_SET_ATTR_ATIME; sb.st_atim = attrs->atime; } if (FSAL_TEST_MASK(attrs->mask, ATTR_ATIME_SERVER)) { mask |= GLAPI_SET_ATTR_ATIME; struct timespec timestamp; rc = clock_gettime(CLOCK_REALTIME, ×tamp); if (rc != 0) { status = gluster2fsal_error(errno); goto out; } sb.st_atim = timestamp; } if (FSAL_TEST_MASK(attrs->mask, ATTR_MTIME)) { mask |= GLAPI_SET_ATTR_MTIME; sb.st_mtim = attrs->mtime; } if (FSAL_TEST_MASK(attrs->mask, ATTR_MTIME_SERVER)) { mask |= GLAPI_SET_ATTR_MTIME; struct timespec timestamp; rc = clock_gettime(CLOCK_REALTIME, ×tamp); if (rc != 0) { status = gluster2fsal_error(rc); goto out; } sb.st_mtim = timestamp; } rc = glfs_h_setattrs(glfs_export->gl_fs, objhandle->glhandle, &sb, mask); if (rc != 0) { status = gluster2fsal_error(errno); goto out; } out: #ifdef GLTIMING now(&e_time); latency_update(&s_time, &e_time, lat_setattrs); #endif return status; }
static nfsstat4 pnfs_layout_commit(struct fsal_obj_handle *obj_pub, struct req_op_context *req_ctx, XDR *lou_body, const struct fsal_layoutcommit_arg *arg, struct fsal_layoutcommit_res *res) { /* Old stat, so we don't truncate file or reverse time */ struct stat old_stat; /* new stat to set time and size */ struct stat new_stat; struct glusterfs_export *glfs_export = container_of(op_ctx->fsal_export, struct glusterfs_export, export); struct glusterfs_handle *objhandle = container_of(obj_pub, struct glusterfs_handle, handle); /* Mask to determine exactly what gets set */ int mask = 0; int rc = 0; if (arg->type != LAYOUT4_NFSV4_1_FILES) { LogMajor(COMPONENT_PNFS, "Unsupported layout type: %x", arg->type); return NFS4ERR_UNKNOWN_LAYOUTTYPE; } /* Gets previous status of file in the MDS */ rc = glfs_h_stat(glfs_export->gl_fs, objhandle->glhandle, &old_stat); if (rc != 0) { LogMajor(COMPONENT_PNFS, "Commit layout, stat unsucessfully completed"); return NFS4ERR_INVAL; } memset(&new_stat, 0, sizeof(struct stat)); /* Set the new attributes for the file if it is changed */ if (arg->new_offset) { if (old_stat.st_size < arg->last_write + 1) { new_stat.st_size = arg->last_write + 1; res->size_supplied = true; res->new_size = arg->last_write + 1; rc = glfs_h_truncate(glfs_export->gl_fs, objhandle->glhandle, res->new_size); if (rc != 0) { LogMajor(COMPONENT_PNFS, "Commit layout, size changed unsucessfully completed"); return NFS4ERR_INVAL; } } } if ((arg->time_changed) && (arg->new_time.seconds > old_stat.st_mtime)) new_stat.st_mtime = arg->new_time.seconds; else new_stat.st_mtime = time(NULL); mask |= GLAPI_SET_ATTR_MTIME; rc = glfs_h_setattrs(glfs_export->gl_fs, objhandle->glhandle, &new_stat, mask); if (rc != 0) { LogMajor(COMPONENT_PNFS, "commit layout, setattr unsucessflly completed"); return NFS4ERR_INVAL; } res->commit_done = true; return NFS4_OK; }