Split function fuse_do_statx(), so that we get two helper functions: one to initialise the arguments and another to update the attributes and statistics. This will allow compound operations to re-use these two helpers. Signed-off-by: Luis Henriques --- fs/fuse/dir.c | 88 +++++++++++++++++++++++++++++++-------------------- 1 file changed, 53 insertions(+), 35 deletions(-) diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 92c9ebfb4985..5c0f1364c392 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c @@ -1406,43 +1406,37 @@ static void fuse_statx_to_attr(struct fuse_statx *sx, struct fuse_attr *attr) attr->blksize = sx->blksize; } -static int fuse_do_statx(struct mnt_idmap *idmap, struct inode *inode, - struct file *file, struct kstat *stat) +static void fuse_statx_init(struct fuse_args *args, struct fuse_statx_in *inarg, + u64 nodeid, struct fuse_file *ff, + struct fuse_statx_out *outarg) { - int err; - struct fuse_attr attr; - struct fuse_statx *sx; - struct fuse_statx_in inarg; - struct fuse_statx_out outarg; - struct fuse_mount *fm = get_fuse_mount(inode); - u64 attr_version = fuse_get_attr_version(fm->fc); - FUSE_ARGS(args); - - memset(&inarg, 0, sizeof(inarg)); - memset(&outarg, 0, sizeof(outarg)); - /* Directories have separate file-handle space */ - if (file && S_ISREG(inode->i_mode)) { - struct fuse_file *ff = file->private_data; + memset(inarg, 0, sizeof(*inarg)); + memset(outarg, 0, sizeof(*outarg)); - inarg.getattr_flags |= FUSE_GETATTR_FH; - inarg.fh = ff->fh; + if (ff) { + inarg->getattr_flags |= FUSE_GETATTR_FH; + inarg->fh = ff->fh; } /* For now leave sync hints as the default, request all stats. */ - inarg.sx_flags = 0; - inarg.sx_mask = STATX_BASIC_STATS | STATX_BTIME; - args.opcode = FUSE_STATX; - args.nodeid = get_node_id(inode); - args.in_numargs = 1; - args.in_args[0].size = sizeof(inarg); - args.in_args[0].value = &inarg; - args.out_numargs = 1; - args.out_args[0].size = sizeof(outarg); - args.out_args[0].value = &outarg; - err = fuse_simple_request(fm, &args); - if (err) - return err; + inarg->sx_flags = 0; + inarg->sx_mask = STATX_BASIC_STATS | STATX_BTIME; + args->opcode = FUSE_STATX; + args->nodeid = nodeid; + args->in_numargs = 1; + args->in_args[0].size = sizeof(*inarg); + args->in_args[0].value = inarg; + args->out_numargs = 1; + args->out_args[0].size = sizeof(*outarg); + args->out_args[0].value = outarg; +} + +static int fuse_statx_update(struct mnt_idmap *idmap, + struct fuse_statx_out *outarg, struct inode *inode, + u64 attr_version, struct kstat *stat) +{ + struct fuse_statx *sx = &outarg->stat; + struct fuse_attr attr; - sx = &outarg.stat; if (((sx->mask & STATX_SIZE) && !fuse_valid_size(sx->size)) || ((sx->mask & STATX_TYPE) && (!fuse_valid_type(sx->mode) || inode_wrong_type(inode, sx->mode)))) { @@ -1450,10 +1444,10 @@ static int fuse_do_statx(struct mnt_idmap *idmap, struct inode *inode, return -EIO; } - fuse_statx_to_attr(&outarg.stat, &attr); + fuse_statx_to_attr(sx, &attr); if ((sx->mask & STATX_BASIC_STATS) == STATX_BASIC_STATS) { - fuse_change_attributes(inode, &attr, &outarg.stat, - ATTR_TIMEOUT(&outarg), attr_version); + fuse_change_attributes(inode, &attr, sx, + ATTR_TIMEOUT(outarg), attr_version); } if (stat) { @@ -1467,6 +1461,30 @@ static int fuse_do_statx(struct mnt_idmap *idmap, struct inode *inode, return 0; } +static int fuse_do_statx(struct mnt_idmap *idmap, struct inode *inode, + struct file *file, struct kstat *stat) +{ + int err; + struct fuse_statx_in inarg; + struct fuse_statx_out outarg; + struct fuse_mount *fm = get_fuse_mount(inode); + struct fuse_file *ff = NULL; + u64 attr_version = fuse_get_attr_version(fm->fc); + FUSE_ARGS(args); + + /* Directories have separate file-handle space */ + if (file && S_ISREG(inode->i_mode)) + ff = file->private_data; + + fuse_statx_init(&args, &inarg, get_node_id(inode), ff, &outarg); + + err = fuse_simple_request(fm, &args); + if (err) + return err; + + return fuse_statx_update(idmap, &outarg, inode, attr_version, stat); +} + /* * Helper function to initialize fuse_args for GETATTR operations */