Loading fs/fuse/dir.c +47 −8 Original line number Diff line number Diff line Loading @@ -752,23 +752,26 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry) return err; } static int fuse_rename(struct inode *olddir, struct dentry *oldent, struct inode *newdir, struct dentry *newent) static int fuse_rename_common(struct inode *olddir, struct dentry *oldent, struct inode *newdir, struct dentry *newent, unsigned int flags, int opcode, size_t argsize) { int err; struct fuse_rename_in inarg; struct fuse_rename2_in inarg; struct fuse_conn *fc = get_fuse_conn(olddir); struct fuse_req *req = fuse_get_req_nopages(fc); struct fuse_req *req; req = fuse_get_req_nopages(fc); if (IS_ERR(req)) return PTR_ERR(req); memset(&inarg, 0, sizeof(inarg)); memset(&inarg, 0, argsize); inarg.newdir = get_node_id(newdir); req->in.h.opcode = FUSE_RENAME; inarg.flags = flags; req->in.h.opcode = opcode; req->in.h.nodeid = get_node_id(olddir); req->in.numargs = 3; req->in.args[0].size = sizeof(inarg); req->in.args[0].size = argsize; req->in.args[0].value = &inarg; req->in.args[1].size = oldent->d_name.len + 1; req->in.args[1].value = oldent->d_name.name; Loading @@ -782,12 +785,17 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent, fuse_invalidate_attr(oldent->d_inode); fuse_update_ctime(oldent->d_inode); if (flags & RENAME_EXCHANGE) { fuse_invalidate_attr(newent->d_inode); fuse_update_ctime(newent->d_inode); } fuse_invalidate_attr(olddir); if (olddir != newdir) fuse_invalidate_attr(newdir); /* newent will end up negative */ if (newent->d_inode) { if (!(flags & RENAME_EXCHANGE) && newent->d_inode) { fuse_invalidate_attr(newent->d_inode); fuse_invalidate_entry_cache(newent); fuse_update_ctime(newent->d_inode); Loading @@ -806,6 +814,36 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent, return err; } static int fuse_rename(struct inode *olddir, struct dentry *oldent, struct inode *newdir, struct dentry *newent) { return fuse_rename_common(olddir, oldent, newdir, newent, 0, FUSE_RENAME, sizeof(struct fuse_rename_in)); } static int fuse_rename2(struct inode *olddir, struct dentry *oldent, struct inode *newdir, struct dentry *newent, unsigned int flags) { struct fuse_conn *fc = get_fuse_conn(olddir); int err; if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE)) return -EINVAL; if (fc->no_rename2 || fc->minor < 23) return -EINVAL; err = fuse_rename_common(olddir, oldent, newdir, newent, flags, FUSE_RENAME2, sizeof(struct fuse_rename2_in)); if (err == -ENOSYS) { fc->no_rename2 = 1; err = -EINVAL; } return err; } static int fuse_link(struct dentry *entry, struct inode *newdir, struct dentry *newent) { Loading Loading @@ -1980,6 +2018,7 @@ static const struct inode_operations fuse_dir_inode_operations = { .unlink = fuse_unlink, .rmdir = fuse_rmdir, .rename = fuse_rename, .rename2 = fuse_rename2, .link = fuse_link, .setattr = fuse_setattr, .create = fuse_create, Loading fs/fuse/fuse_i.h +3 −0 Original line number Diff line number Diff line Loading @@ -542,6 +542,9 @@ struct fuse_conn { /** Is fallocate not implemented by fs? */ unsigned no_fallocate:1; /** Is rename with flags implemented by fs? */ unsigned no_rename2:1; /** Use enhanced/automatic page cache invalidation. */ unsigned auto_inval_data:1; Loading include/uapi/linux/fuse.h +8 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,7 @@ * - add reserved space to fuse_init_out * - add FATTR_CTIME * - add ctime and ctimensec to fuse_setattr_in * - add FUSE_RENAME2 request */ #ifndef _LINUX_FUSE_H Loading Loading @@ -353,6 +354,7 @@ enum fuse_opcode { FUSE_BATCH_FORGET = 42, FUSE_FALLOCATE = 43, FUSE_READDIRPLUS = 44, FUSE_RENAME2 = 45, /* CUSE specific operations */ CUSE_INIT = 4096, Loading Loading @@ -431,6 +433,12 @@ struct fuse_rename_in { uint64_t newdir; }; struct fuse_rename2_in { uint64_t newdir; uint32_t flags; uint32_t padding; }; struct fuse_link_in { uint64_t oldnodeid; }; Loading Loading
fs/fuse/dir.c +47 −8 Original line number Diff line number Diff line Loading @@ -752,23 +752,26 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry) return err; } static int fuse_rename(struct inode *olddir, struct dentry *oldent, struct inode *newdir, struct dentry *newent) static int fuse_rename_common(struct inode *olddir, struct dentry *oldent, struct inode *newdir, struct dentry *newent, unsigned int flags, int opcode, size_t argsize) { int err; struct fuse_rename_in inarg; struct fuse_rename2_in inarg; struct fuse_conn *fc = get_fuse_conn(olddir); struct fuse_req *req = fuse_get_req_nopages(fc); struct fuse_req *req; req = fuse_get_req_nopages(fc); if (IS_ERR(req)) return PTR_ERR(req); memset(&inarg, 0, sizeof(inarg)); memset(&inarg, 0, argsize); inarg.newdir = get_node_id(newdir); req->in.h.opcode = FUSE_RENAME; inarg.flags = flags; req->in.h.opcode = opcode; req->in.h.nodeid = get_node_id(olddir); req->in.numargs = 3; req->in.args[0].size = sizeof(inarg); req->in.args[0].size = argsize; req->in.args[0].value = &inarg; req->in.args[1].size = oldent->d_name.len + 1; req->in.args[1].value = oldent->d_name.name; Loading @@ -782,12 +785,17 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent, fuse_invalidate_attr(oldent->d_inode); fuse_update_ctime(oldent->d_inode); if (flags & RENAME_EXCHANGE) { fuse_invalidate_attr(newent->d_inode); fuse_update_ctime(newent->d_inode); } fuse_invalidate_attr(olddir); if (olddir != newdir) fuse_invalidate_attr(newdir); /* newent will end up negative */ if (newent->d_inode) { if (!(flags & RENAME_EXCHANGE) && newent->d_inode) { fuse_invalidate_attr(newent->d_inode); fuse_invalidate_entry_cache(newent); fuse_update_ctime(newent->d_inode); Loading @@ -806,6 +814,36 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent, return err; } static int fuse_rename(struct inode *olddir, struct dentry *oldent, struct inode *newdir, struct dentry *newent) { return fuse_rename_common(olddir, oldent, newdir, newent, 0, FUSE_RENAME, sizeof(struct fuse_rename_in)); } static int fuse_rename2(struct inode *olddir, struct dentry *oldent, struct inode *newdir, struct dentry *newent, unsigned int flags) { struct fuse_conn *fc = get_fuse_conn(olddir); int err; if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE)) return -EINVAL; if (fc->no_rename2 || fc->minor < 23) return -EINVAL; err = fuse_rename_common(olddir, oldent, newdir, newent, flags, FUSE_RENAME2, sizeof(struct fuse_rename2_in)); if (err == -ENOSYS) { fc->no_rename2 = 1; err = -EINVAL; } return err; } static int fuse_link(struct dentry *entry, struct inode *newdir, struct dentry *newent) { Loading Loading @@ -1980,6 +2018,7 @@ static const struct inode_operations fuse_dir_inode_operations = { .unlink = fuse_unlink, .rmdir = fuse_rmdir, .rename = fuse_rename, .rename2 = fuse_rename2, .link = fuse_link, .setattr = fuse_setattr, .create = fuse_create, Loading
fs/fuse/fuse_i.h +3 −0 Original line number Diff line number Diff line Loading @@ -542,6 +542,9 @@ struct fuse_conn { /** Is fallocate not implemented by fs? */ unsigned no_fallocate:1; /** Is rename with flags implemented by fs? */ unsigned no_rename2:1; /** Use enhanced/automatic page cache invalidation. */ unsigned auto_inval_data:1; Loading
include/uapi/linux/fuse.h +8 −0 Original line number Diff line number Diff line Loading @@ -100,6 +100,7 @@ * - add reserved space to fuse_init_out * - add FATTR_CTIME * - add ctime and ctimensec to fuse_setattr_in * - add FUSE_RENAME2 request */ #ifndef _LINUX_FUSE_H Loading Loading @@ -353,6 +354,7 @@ enum fuse_opcode { FUSE_BATCH_FORGET = 42, FUSE_FALLOCATE = 43, FUSE_READDIRPLUS = 44, FUSE_RENAME2 = 45, /* CUSE specific operations */ CUSE_INIT = 4096, Loading Loading @@ -431,6 +433,12 @@ struct fuse_rename_in { uint64_t newdir; }; struct fuse_rename2_in { uint64_t newdir; uint32_t flags; uint32_t padding; }; struct fuse_link_in { uint64_t oldnodeid; }; Loading