int fchmod(int fd, mode_t mode) { if (nfs_fd_list[fd].is_nfs == 1) { int ret; LD_NFS_DPRINTF(9, "fchmod(%d, %o)", fd, (int)mode); if ((ret = nfs_fchmod(nfs_fd_list[fd].nfs, nfs_fd_list[fd].fh, mode)) < 0) { errno = -ret; return -1; } return 0; } return real_fchmod(fd, mode); }
static void workspace_nfs_fsetattr(fuse_req_t req, struct workspace_fh_struct *fh, struct stat *st, int toset) { struct resource_struct *resource=fh->object->resource; struct net_nfs_export_struct *nfs_export=(struct net_nfs_export_struct *) resource->data; struct nfs_context *nfs_ctx=(struct nfs_context *) nfs_export->data; struct nfsfh *nfsfh=(struct nfsfh *) fh->handle.data; int result=0; struct inode_struct *inode=fh->entry->inode; logoutput("workspace_nfs_fsetattr"); if (toset & FUSE_SET_ATTR_MODE) { pthread_mutex_lock(&nfs_export->mutex); result=nfs_fchmod(nfs_ctx, nfsfh, st->st_mode); pthread_mutex_unlock(&nfs_export->mutex); if (result<0) { fuse_reply_err(req, -result); return; } else { inode->mode=st->st_mode; } } if (toset & (FUSE_SET_ATTR_UID | FUSE_SET_ATTR_GID)) { uid_t uid=inode->uid; gid_t gid=inode->gid; if (toset & FUSE_SET_ATTR_UID) uid=st->st_uid; if (toset & FUSE_SET_ATTR_GID) gid=st->st_gid; pthread_mutex_lock(&nfs_export->mutex); result=nfs_fchown(nfs_ctx, nfsfh, uid, gid); pthread_mutex_unlock(&nfs_export->mutex); if (result<0) { fuse_reply_err(req, -result); return; } else { if (toset & FUSE_SET_ATTR_UID) { inode->uid=st->st_uid; } else { st->st_uid=inode->uid; } if (toset & FUSE_SET_ATTR_GID) { inode->gid=st->st_gid; } else { st->st_gid=inode->gid; } } } if (toset & FUSE_SET_ATTR_SIZE) { pthread_mutex_lock(&nfs_export->mutex); result=nfs_ftruncate(nfs_ctx, nfsfh, st->st_size); pthread_mutex_unlock(&nfs_export->mutex); if (result<0) { fuse_reply_err(req, -result); return; } else { inode->size=st->st_size; } } if (toset & (FUSE_SET_ATTR_ATIME | FUSE_SET_ATTR_MTIME)) { logoutput("workspace_mfs_fsetattr: setting times through filehandle not supported yet"); } out: st->st_dev=0; st->st_ino=inode->ino; st->st_mode=inode->mode; st->st_nlink=inode->nlink; st->st_uid=inode->uid; st->st_gid=inode->gid; st->st_rdev=inode->rdev; st->st_size=inode->size; st->st_blksize=_DEFAULT_BLOCKSIZE; if (inode->size % st->st_blksize == 0) { st->st_blocks = inode->size / st->st_blksize; } else { st->st_blocks = 1 + inode->size / st->st_blksize; } memcpy(&st->st_mtim, &inode->mtim, sizeof(struct timespec)); memcpy(&st->st_ctim, &inode->ctim, sizeof(struct timespec)); st->st_atim.tv_sec=0; st->st_atim.tv_nsec=0; fuse_reply_attr(req, st, fs_options.attr_timeout); }