fuse: introduce fuse_simple_request() helper
authorMiklos Szeredi <mszeredi@suse.cz>
Fri, 12 Dec 2014 08:49:05 +0000 (09:49 +0100)
committerMiklos Szeredi <mszeredi@suse.cz>
Fri, 12 Dec 2014 08:49:05 +0000 (09:49 +0100)
The following pattern is repeated many times:

req = fuse_get_req_nopages(fc);
/* Initialize req->(in|out).args */
fuse_request_send(fc, req);
err = req->out.h.error;
fuse_put_request(req);

Create a new replacement helper:

/* Initialize args */
err = fuse_simple_request(fc, &args);

In addition to reducing the code size, this will ease moving from the
complex arg-based to a simpler page-based I/O on the fuse device.

Signed-off-by: Miklos Szeredi <mszeredi@suse.cz>
fs/fuse/dev.c
fs/fuse/dir.c
fs/fuse/file.c
fs/fuse/fuse_i.h
fs/fuse/inode.c

index ca887314aba9deb6d59811f0d19b8c9b9a0381c3..ba1107977f2ecafa96cafc04f6498b3fb79a3145 100644 (file)
@@ -511,6 +511,35 @@ void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
 }
 EXPORT_SYMBOL_GPL(fuse_request_send);
 
+ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args)
+{
+       struct fuse_req *req;
+       ssize_t ret;
+
+       req = fuse_get_req(fc, 0);
+       if (IS_ERR(req))
+               return PTR_ERR(req);
+
+       req->in.h.opcode = args->in.h.opcode;
+       req->in.h.nodeid = args->in.h.nodeid;
+       req->in.numargs = args->in.numargs;
+       memcpy(req->in.args, args->in.args,
+              args->in.numargs * sizeof(struct fuse_in_arg));
+       req->out.argvar = args->out.argvar;
+       req->out.numargs = args->out.numargs;
+       memcpy(req->out.args, args->out.args,
+              args->out.numargs * sizeof(struct fuse_arg));
+       fuse_request_send(fc, req);
+       ret = req->out.h.error;
+       if (!ret && args->out.argvar) {
+               BUG_ON(args->out.numargs != 1);
+               ret = req->out.args[0].size;
+       }
+       fuse_put_request(fc, req);
+
+       return ret;
+}
+
 static void fuse_request_send_nowait_locked(struct fuse_conn *fc,
                                            struct fuse_req *req)
 {
index dbab798f5cafefd8e0ad848298a7baa0f1b70ad4..f7ae3f58c7fc5a5a7225246e85f069ade2321c7d 100644 (file)
@@ -145,22 +145,22 @@ static void fuse_invalidate_entry(struct dentry *entry)
        fuse_invalidate_entry_cache(entry);
 }
 
-static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_req *req,
+static void fuse_lookup_init(struct fuse_conn *fc, struct fuse_args *args,
                             u64 nodeid, struct qstr *name,
                             struct fuse_entry_out *outarg)
 {
        memset(outarg, 0, sizeof(struct fuse_entry_out));
-       req->in.h.opcode = FUSE_LOOKUP;
-       req->in.h.nodeid = nodeid;
-       req->in.numargs = 1;
-       req->in.args[0].size = name->len + 1;
-       req->in.args[0].value = name->name;
-       req->out.numargs = 1;
+       args->in.h.opcode = FUSE_LOOKUP;
+       args->in.h.nodeid = nodeid;
+       args->in.numargs = 1;
+       args->in.args[0].size = name->len + 1;
+       args->in.args[0].value = name->name;
+       args->out.numargs = 1;
        if (fc->minor < 9)
-               req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
+               args->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
        else
-               req->out.args[0].size = sizeof(struct fuse_entry_out);
-       req->out.args[0].value = outarg;
+               args->out.args[0].size = sizeof(struct fuse_entry_out);
+       args->out.args[0].value = outarg;
 }
 
 u64 fuse_get_attr_version(struct fuse_conn *fc)
@@ -200,9 +200,8 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
                goto invalid;
        else if (time_before64(fuse_dentry_time(entry), get_jiffies_64()) ||
                 (flags & LOOKUP_REVAL)) {
-               int err;
                struct fuse_entry_out outarg;
-               struct fuse_req *req;
+               FUSE_ARGS(args);
                struct fuse_forget_link *forget;
                u64 attr_version;
 
@@ -215,31 +214,23 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
                        goto out;
 
                fc = get_fuse_conn(inode);
-               req = fuse_get_req_nopages(fc);
-               ret = PTR_ERR(req);
-               if (IS_ERR(req))
-                       goto out;
 
                forget = fuse_alloc_forget();
-               if (!forget) {
-                       fuse_put_request(fc, req);
-                       ret = -ENOMEM;
+               ret = -ENOMEM;
+               if (!forget)
                        goto out;
-               }
 
                attr_version = fuse_get_attr_version(fc);
 
                parent = dget_parent(entry);
-               fuse_lookup_init(fc, req, get_node_id(parent->d_inode),
+               fuse_lookup_init(fc, &args, get_node_id(parent->d_inode),
                                 &entry->d_name, &outarg);
-               fuse_request_send(fc, req);
+               ret = fuse_simple_request(fc, &args);
                dput(parent);
-               err = req->out.h.error;
-               fuse_put_request(fc, req);
                /* Zero nodeid is same as -ENOENT */
-               if (!err && !outarg.nodeid)
-                       err = -ENOENT;
-               if (!err) {
+               if (!ret && !outarg.nodeid)
+                       ret = -ENOENT;
+               if (!ret) {
                        fi = get_fuse_inode(inode);
                        if (outarg.nodeid != get_node_id(inode)) {
                                fuse_queue_forget(fc, forget, outarg.nodeid, 1);
@@ -250,7 +241,9 @@ static int fuse_dentry_revalidate(struct dentry *entry, unsigned int flags)
                        spin_unlock(&fc->lock);
                }
                kfree(forget);
-               if (err || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
+               if (ret == -ENOMEM)
+                       goto out;
+               if (ret || (outarg.attr.mode ^ inode->i_mode) & S_IFMT)
                        goto invalid;
 
                fuse_change_attributes(inode, &outarg.attr,
@@ -296,7 +289,7 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name,
                     struct fuse_entry_out *outarg, struct inode **inode)
 {
        struct fuse_conn *fc = get_fuse_conn_super(sb);
-       struct fuse_req *req;
+       FUSE_ARGS(args);
        struct fuse_forget_link *forget;
        u64 attr_version;
        int err;
@@ -306,24 +299,16 @@ int fuse_lookup_name(struct super_block *sb, u64 nodeid, struct qstr *name,
        if (name->len > FUSE_NAME_MAX)
                goto out;
 
-       req = fuse_get_req_nopages(fc);
-       err = PTR_ERR(req);
-       if (IS_ERR(req))
-               goto out;
 
        forget = fuse_alloc_forget();
        err = -ENOMEM;
-       if (!forget) {
-               fuse_put_request(fc, req);
+       if (!forget)
                goto out;
-       }
 
        attr_version = fuse_get_attr_version(fc);
 
-       fuse_lookup_init(fc, req, nodeid, name, outarg);
-       fuse_request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
+       fuse_lookup_init(fc, &args, nodeid, name, outarg);
+       err = fuse_simple_request(fc, &args);
        /* Zero nodeid is same as -ENOENT, but with valid timeout */
        if (err || !outarg->nodeid)
                goto out_put_forget;
@@ -405,7 +390,7 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry,
        int err;
        struct inode *inode;
        struct fuse_conn *fc = get_fuse_conn(dir);
-       struct fuse_req *req;
+       FUSE_ARGS(args);
        struct fuse_forget_link *forget;
        struct fuse_create_in inarg;
        struct fuse_open_out outopen;
@@ -420,15 +405,10 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry,
        if (!forget)
                goto out_err;
 
-       req = fuse_get_req_nopages(fc);
-       err = PTR_ERR(req);
-       if (IS_ERR(req))
-               goto out_put_forget_req;
-
        err = -ENOMEM;
        ff = fuse_file_alloc(fc);
        if (!ff)
-               goto out_put_request;
+               goto out_put_forget_req;
 
        if (!fc->dont_mask)
                mode &= ~current_umask();
@@ -439,24 +419,23 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry,
        inarg.flags = flags;
        inarg.mode = mode;
        inarg.umask = current_umask();
-       req->in.h.opcode = FUSE_CREATE;
-       req->in.h.nodeid = get_node_id(dir);
-       req->in.numargs = 2;
-       req->in.args[0].size = fc->minor < 12 ? sizeof(struct fuse_open_in) :
+       args.in.h.opcode = FUSE_CREATE;
+       args.in.h.nodeid = get_node_id(dir);
+       args.in.numargs = 2;
+       args.in.args[0].size = fc->minor < 12 ? sizeof(struct fuse_open_in) :
                                                sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       req->in.args[1].size = entry->d_name.len + 1;
-       req->in.args[1].value = entry->d_name.name;
-       req->out.numargs = 2;
+       args.in.args[0].value = &inarg;
+       args.in.args[1].size = entry->d_name.len + 1;
+       args.in.args[1].value = entry->d_name.name;
+       args.out.numargs = 2;
        if (fc->minor < 9)
-               req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
+               args.out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
        else
-               req->out.args[0].size = sizeof(outentry);
-       req->out.args[0].value = &outentry;
-       req->out.args[1].size = sizeof(outopen);
-       req->out.args[1].value = &outopen;
-       fuse_request_send(fc, req);
-       err = req->out.h.error;
+               args.out.args[0].size = sizeof(outentry);
+       args.out.args[0].value = &outentry;
+       args.out.args[1].size = sizeof(outopen);
+       args.out.args[1].value = &outopen;
+       err = fuse_simple_request(fc, &args);
        if (err)
                goto out_free_ff;
 
@@ -464,7 +443,6 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry,
        if (!S_ISREG(outentry.attr.mode) || invalid_nodeid(outentry.nodeid))
                goto out_free_ff;
 
-       fuse_put_request(fc, req);
        ff->fh = outopen.fh;
        ff->nodeid = outentry.nodeid;
        ff->open_flags = outopen.open_flags;
@@ -492,8 +470,6 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry,
 
 out_free_ff:
        fuse_file_free(ff);
-out_put_request:
-       fuse_put_request(fc, req);
 out_put_forget_req:
        kfree(forget);
 out_err:
@@ -547,7 +523,7 @@ no_open:
 /*
  * Code shared between mknod, mkdir, symlink and link
  */
-static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
+static int create_new_entry(struct fuse_conn *fc, struct fuse_args *args,
                            struct inode *dir, struct dentry *entry,
                            umode_t mode)
 {
@@ -557,22 +533,18 @@ static int create_new_entry(struct fuse_conn *fc, struct fuse_req *req,
        struct fuse_forget_link *forget;
 
        forget = fuse_alloc_forget();
-       if (!forget) {
-               fuse_put_request(fc, req);
+       if (!forget)
                return -ENOMEM;
-       }
 
        memset(&outarg, 0, sizeof(outarg));
-       req->in.h.nodeid = get_node_id(dir);
-       req->out.numargs = 1;
+       args->in.h.nodeid = get_node_id(dir);
+       args->out.numargs = 1;
        if (fc->minor < 9)
-               req->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
+               args->out.args[0].size = FUSE_COMPAT_ENTRY_OUT_SIZE;
        else
-               req->out.args[0].size = sizeof(outarg);
-       req->out.args[0].value = &outarg;
-       fuse_request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
+               args->out.args[0].size = sizeof(outarg);
+       args->out.args[0].value = &outarg;
+       err = fuse_simple_request(fc, args);
        if (err)
                goto out_put_forget_req;
 
@@ -609,9 +581,7 @@ static int fuse_mknod(struct inode *dir, struct dentry *entry, umode_t mode,
 {
        struct fuse_mknod_in inarg;
        struct fuse_conn *fc = get_fuse_conn(dir);
-       struct fuse_req *req = fuse_get_req_nopages(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
+       FUSE_ARGS(args);
 
        if (!fc->dont_mask)
                mode &= ~current_umask();
@@ -620,14 +590,14 @@ static int fuse_mknod(struct inode *dir, struct dentry *entry, umode_t mode,
        inarg.mode = mode;
        inarg.rdev = new_encode_dev(rdev);
        inarg.umask = current_umask();
-       req->in.h.opcode = FUSE_MKNOD;
-       req->in.numargs = 2;
-       req->in.args[0].size = fc->minor < 12 ? FUSE_COMPAT_MKNOD_IN_SIZE :
+       args.in.h.opcode = FUSE_MKNOD;
+       args.in.numargs = 2;
+       args.in.args[0].size = fc->minor < 12 ? FUSE_COMPAT_MKNOD_IN_SIZE :
                                                sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       req->in.args[1].size = entry->d_name.len + 1;
-       req->in.args[1].value = entry->d_name.name;
-       return create_new_entry(fc, req, dir, entry, mode);
+       args.in.args[0].value = &inarg;
+       args.in.args[1].size = entry->d_name.len + 1;
+       args.in.args[1].value = entry->d_name.name;
+       return create_new_entry(fc, &args, dir, entry, mode);
 }
 
 static int fuse_create(struct inode *dir, struct dentry *entry, umode_t mode,
@@ -640,9 +610,7 @@ static int fuse_mkdir(struct inode *dir, struct dentry *entry, umode_t mode)
 {
        struct fuse_mkdir_in inarg;
        struct fuse_conn *fc = get_fuse_conn(dir);
-       struct fuse_req *req = fuse_get_req_nopages(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
+       FUSE_ARGS(args);
 
        if (!fc->dont_mask)
                mode &= ~current_umask();
@@ -650,13 +618,13 @@ static int fuse_mkdir(struct inode *dir, struct dentry *entry, umode_t mode)
        memset(&inarg, 0, sizeof(inarg));
        inarg.mode = mode;
        inarg.umask = current_umask();
-       req->in.h.opcode = FUSE_MKDIR;
-       req->in.numargs = 2;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       req->in.args[1].size = entry->d_name.len + 1;
-       req->in.args[1].value = entry->d_name.name;
-       return create_new_entry(fc, req, dir, entry, S_IFDIR);
+       args.in.h.opcode = FUSE_MKDIR;
+       args.in.numargs = 2;
+       args.in.args[0].size = sizeof(inarg);
+       args.in.args[0].value = &inarg;
+       args.in.args[1].size = entry->d_name.len + 1;
+       args.in.args[1].value = entry->d_name.name;
+       return create_new_entry(fc, &args, dir, entry, S_IFDIR);
 }
 
 static int fuse_symlink(struct inode *dir, struct dentry *entry,
@@ -664,17 +632,15 @@ static int fuse_symlink(struct inode *dir, struct dentry *entry,
 {
        struct fuse_conn *fc = get_fuse_conn(dir);
        unsigned len = strlen(link) + 1;
-       struct fuse_req *req = fuse_get_req_nopages(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
+       FUSE_ARGS(args);
 
-       req->in.h.opcode = FUSE_SYMLINK;
-       req->in.numargs = 2;
-       req->in.args[0].size = entry->d_name.len + 1;
-       req->in.args[0].value = entry->d_name.name;
-       req->in.args[1].size = len;
-       req->in.args[1].value = link;
-       return create_new_entry(fc, req, dir, entry, S_IFLNK);
+       args.in.h.opcode = FUSE_SYMLINK;
+       args.in.numargs = 2;
+       args.in.args[0].size = entry->d_name.len + 1;
+       args.in.args[0].value = entry->d_name.name;
+       args.in.args[1].size = len;
+       args.in.args[1].value = link;
+       return create_new_entry(fc, &args, dir, entry, S_IFLNK);
 }
 
 static inline void fuse_update_ctime(struct inode *inode)
@@ -689,18 +655,14 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry)
 {
        int err;
        struct fuse_conn *fc = get_fuse_conn(dir);
-       struct fuse_req *req = fuse_get_req_nopages(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       req->in.h.opcode = FUSE_UNLINK;
-       req->in.h.nodeid = get_node_id(dir);
-       req->in.numargs = 1;
-       req->in.args[0].size = entry->d_name.len + 1;
-       req->in.args[0].value = entry->d_name.name;
-       fuse_request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
+       FUSE_ARGS(args);
+
+       args.in.h.opcode = FUSE_UNLINK;
+       args.in.h.nodeid = get_node_id(dir);
+       args.in.numargs = 1;
+       args.in.args[0].size = entry->d_name.len + 1;
+       args.in.args[0].value = entry->d_name.name;
+       err = fuse_simple_request(fc, &args);
        if (!err) {
                struct inode *inode = entry->d_inode;
                struct fuse_inode *fi = get_fuse_inode(inode);
@@ -729,18 +691,14 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry)
 {
        int err;
        struct fuse_conn *fc = get_fuse_conn(dir);
-       struct fuse_req *req = fuse_get_req_nopages(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       req->in.h.opcode = FUSE_RMDIR;
-       req->in.h.nodeid = get_node_id(dir);
-       req->in.numargs = 1;
-       req->in.args[0].size = entry->d_name.len + 1;
-       req->in.args[0].value = entry->d_name.name;
-       fuse_request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
+       FUSE_ARGS(args);
+
+       args.in.h.opcode = FUSE_RMDIR;
+       args.in.h.nodeid = get_node_id(dir);
+       args.in.numargs = 1;
+       args.in.args[0].size = entry->d_name.len + 1;
+       args.in.args[0].value = entry->d_name.name;
+       err = fuse_simple_request(fc, &args);
        if (!err) {
                clear_nlink(entry->d_inode);
                fuse_invalidate_attr(dir);
@@ -757,27 +715,21 @@ static int fuse_rename_common(struct inode *olddir, struct dentry *oldent,
        int err;
        struct fuse_rename2_in inarg;
        struct fuse_conn *fc = get_fuse_conn(olddir);
-       struct fuse_req *req;
-
-       req = fuse_get_req_nopages(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
+       FUSE_ARGS(args);
 
        memset(&inarg, 0, argsize);
        inarg.newdir = get_node_id(newdir);
        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 = 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;
-       req->in.args[2].size = newent->d_name.len + 1;
-       req->in.args[2].value = newent->d_name.name;
-       fuse_request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
+       args.in.h.opcode = opcode;
+       args.in.h.nodeid = get_node_id(olddir);
+       args.in.numargs = 3;
+       args.in.args[0].size = argsize;
+       args.in.args[0].value = &inarg;
+       args.in.args[1].size = oldent->d_name.len + 1;
+       args.in.args[1].value = oldent->d_name.name;
+       args.in.args[2].size = newent->d_name.len + 1;
+       args.in.args[2].value = newent->d_name.name;
+       err = fuse_simple_request(fc, &args);
        if (!err) {
                /* ctime changes */
                fuse_invalidate_attr(oldent->d_inode);
@@ -849,19 +801,17 @@ static int fuse_link(struct dentry *entry, struct inode *newdir,
        struct fuse_link_in inarg;
        struct inode *inode = entry->d_inode;
        struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req = fuse_get_req_nopages(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
+       FUSE_ARGS(args);
 
        memset(&inarg, 0, sizeof(inarg));
        inarg.oldnodeid = get_node_id(inode);
-       req->in.h.opcode = FUSE_LINK;
-       req->in.numargs = 2;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       req->in.args[1].size = newent->d_name.len + 1;
-       req->in.args[1].value = newent->d_name.name;
-       err = create_new_entry(fc, req, newdir, newent, inode->i_mode);
+       args.in.h.opcode = FUSE_LINK;
+       args.in.numargs = 2;
+       args.in.args[0].size = sizeof(inarg);
+       args.in.args[0].value = &inarg;
+       args.in.args[1].size = newent->d_name.len + 1;
+       args.in.args[1].value = newent->d_name.name;
+       err = create_new_entry(fc, &args, newdir, newent, inode->i_mode);
        /* Contrary to "normal" filesystems it can happen that link
           makes two "logical" inodes point to the same "physical"
           inode.  We invalidate the attributes of the old one, so it
@@ -929,13 +879,9 @@ static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
        struct fuse_getattr_in inarg;
        struct fuse_attr_out outarg;
        struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req;
+       FUSE_ARGS(args);
        u64 attr_version;
 
-       req = fuse_get_req_nopages(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
        attr_version = fuse_get_attr_version(fc);
 
        memset(&inarg, 0, sizeof(inarg));
@@ -947,20 +893,18 @@ static int fuse_do_getattr(struct inode *inode, struct kstat *stat,
                inarg.getattr_flags |= FUSE_GETATTR_FH;
                inarg.fh = ff->fh;
        }
-       req->in.h.opcode = FUSE_GETATTR;
-       req->in.h.nodeid = get_node_id(inode);
-       req->in.numargs = 1;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       req->out.numargs = 1;
+       args.in.h.opcode = FUSE_GETATTR;
+       args.in.h.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;
        if (fc->minor < 9)
-               req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
+               args.out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
        else
-               req->out.args[0].size = sizeof(outarg);
-       req->out.args[0].value = &outarg;
-       fuse_request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
+               args.out.args[0].size = sizeof(outarg);
+       args.out.args[0].value = &outarg;
+       err = fuse_simple_request(fc, &args);
        if (!err) {
                if ((inode->i_mode ^ outarg.attr.mode) & S_IFMT) {
                        make_bad_inode(inode);
@@ -1102,7 +1046,7 @@ int fuse_allow_current_process(struct fuse_conn *fc)
 static int fuse_access(struct inode *inode, int mask)
 {
        struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req;
+       FUSE_ARGS(args);
        struct fuse_access_in inarg;
        int err;
 
@@ -1111,20 +1055,14 @@ static int fuse_access(struct inode *inode, int mask)
        if (fc->no_access)
                return 0;
 
-       req = fuse_get_req_nopages(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
        memset(&inarg, 0, sizeof(inarg));
        inarg.mask = mask & (MAY_READ | MAY_WRITE | MAY_EXEC);
-       req->in.h.opcode = FUSE_ACCESS;
-       req->in.h.nodeid = get_node_id(inode);
-       req->in.numargs = 1;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       fuse_request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
+       args.in.h.opcode = FUSE_ACCESS;
+       args.in.h.nodeid = get_node_id(inode);
+       args.in.numargs = 1;
+       args.in.args[0].size = sizeof(inarg);
+       args.in.args[0].value = &inarg;
+       err = fuse_simple_request(fc, &args);
        if (err == -ENOSYS) {
                fc->no_access = 1;
                err = 0;
@@ -1445,31 +1383,27 @@ static char *read_link(struct dentry *dentry)
 {
        struct inode *inode = dentry->d_inode;
        struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req = fuse_get_req_nopages(fc);
+       FUSE_ARGS(args);
        char *link;
-
-       if (IS_ERR(req))
-               return ERR_CAST(req);
+       ssize_t ret;
 
        link = (char *) __get_free_page(GFP_KERNEL);
-       if (!link) {
-               link = ERR_PTR(-ENOMEM);
-               goto out;
-       }
-       req->in.h.opcode = FUSE_READLINK;
-       req->in.h.nodeid = get_node_id(inode);
-       req->out.argvar = 1;
-       req->out.numargs = 1;
-       req->out.args[0].size = PAGE_SIZE - 1;
-       req->out.args[0].value = link;
-       fuse_request_send(fc, req);
-       if (req->out.h.error) {
+       if (!link)
+               return ERR_PTR(-ENOMEM);
+
+       args.in.h.opcode = FUSE_READLINK;
+       args.in.h.nodeid = get_node_id(inode);
+       args.out.argvar = 1;
+       args.out.numargs = 1;
+       args.out.args[0].size = PAGE_SIZE - 1;
+       args.out.args[0].value = link;
+       ret = fuse_simple_request(fc, &args);
+       if (ret < 0) {
                free_page((unsigned long) link);
-               link = ERR_PTR(req->out.h.error);
-       } else
-               link[req->out.args[0].size] = '\0';
- out:
-       fuse_put_request(fc, req);
+               link = ERR_PTR(ret);
+       } else {
+               link[ret] = '\0';
+       }
        fuse_invalidate_atime(inode);
        return link;
 }
@@ -1629,22 +1563,22 @@ void fuse_release_nowrite(struct inode *inode)
        spin_unlock(&fc->lock);
 }
 
-static void fuse_setattr_fill(struct fuse_conn *fc, struct fuse_req *req,
+static void fuse_setattr_fill(struct fuse_conn *fc, struct fuse_args *args,
                              struct inode *inode,
                              struct fuse_setattr_in *inarg_p,
                              struct fuse_attr_out *outarg_p)
 {
-       req->in.h.opcode = FUSE_SETATTR;
-       req->in.h.nodeid = get_node_id(inode);
-       req->in.numargs = 1;
-       req->in.args[0].size = sizeof(*inarg_p);
-       req->in.args[0].value = inarg_p;
-       req->out.numargs = 1;
+       args->in.h.opcode = FUSE_SETATTR;
+       args->in.h.nodeid = get_node_id(inode);
+       args->in.numargs = 1;
+       args->in.args[0].size = sizeof(*inarg_p);
+       args->in.args[0].value = inarg_p;
+       args->out.numargs = 1;
        if (fc->minor < 9)
-               req->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
+               args->out.args[0].size = FUSE_COMPAT_ATTR_OUT_SIZE;
        else
-               req->out.args[0].size = sizeof(*outarg_p);
-       req->out.args[0].value = outarg_p;
+               args->out.args[0].size = sizeof(*outarg_p);
+       args->out.args[0].value = outarg_p;
 }
 
 /*
@@ -1653,14 +1587,9 @@ static void fuse_setattr_fill(struct fuse_conn *fc, struct fuse_req *req,
 int fuse_flush_times(struct inode *inode, struct fuse_file *ff)
 {
        struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req;
+       FUSE_ARGS(args);
        struct fuse_setattr_in inarg;
        struct fuse_attr_out outarg;
-       int err;
-
-       req = fuse_get_req_nopages(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
 
        memset(&inarg, 0, sizeof(inarg));
        memset(&outarg, 0, sizeof(outarg));
@@ -1677,12 +1606,9 @@ int fuse_flush_times(struct inode *inode, struct fuse_file *ff)
                inarg.valid |= FATTR_FH;
                inarg.fh = ff->fh;
        }
-       fuse_setattr_fill(fc, req, inode, &inarg, &outarg);
-       fuse_request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
+       fuse_setattr_fill(fc, &args, inode, &inarg, &outarg);
 
-       return err;
+       return fuse_simple_request(fc, &args);
 }
 
 /*
@@ -1698,7 +1624,7 @@ int fuse_do_setattr(struct inode *inode, struct iattr *attr,
 {
        struct fuse_conn *fc = get_fuse_conn(inode);
        struct fuse_inode *fi = get_fuse_inode(inode);
-       struct fuse_req *req;
+       FUSE_ARGS(args);
        struct fuse_setattr_in inarg;
        struct fuse_attr_out outarg;
        bool is_truncate = false;
@@ -1723,10 +1649,6 @@ int fuse_do_setattr(struct inode *inode, struct iattr *attr,
        if (attr->ia_valid & ATTR_SIZE)
                is_truncate = true;
 
-       req = fuse_get_req_nopages(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
        if (is_truncate) {
                fuse_set_nowrite(inode);
                set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
@@ -1747,10 +1669,8 @@ int fuse_do_setattr(struct inode *inode, struct iattr *attr,
                inarg.valid |= FATTR_LOCKOWNER;
                inarg.lock_owner = fuse_lock_owner_id(fc, current->files);
        }
-       fuse_setattr_fill(fc, req, inode, &inarg, &outarg);
-       fuse_request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
+       fuse_setattr_fill(fc, &args, inode, &inarg, &outarg);
+       err = fuse_simple_request(fc, &args);
        if (err) {
                if (err == -EINTR)
                        fuse_invalidate_attr(inode);
@@ -1837,32 +1757,26 @@ static int fuse_setxattr(struct dentry *entry, const char *name,
 {
        struct inode *inode = entry->d_inode;
        struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req;
+       FUSE_ARGS(args);
        struct fuse_setxattr_in inarg;
        int err;
 
        if (fc->no_setxattr)
                return -EOPNOTSUPP;
 
-       req = fuse_get_req_nopages(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
        memset(&inarg, 0, sizeof(inarg));
        inarg.size = size;
        inarg.flags = flags;
-       req->in.h.opcode = FUSE_SETXATTR;
-       req->in.h.nodeid = get_node_id(inode);
-       req->in.numargs = 3;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       req->in.args[1].size = strlen(name) + 1;
-       req->in.args[1].value = name;
-       req->in.args[2].size = size;
-       req->in.args[2].value = value;
-       fuse_request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
+       args.in.h.opcode = FUSE_SETXATTR;
+       args.in.h.nodeid = get_node_id(inode);
+       args.in.numargs = 3;
+       args.in.args[0].size = sizeof(inarg);
+       args.in.args[0].value = &inarg;
+       args.in.args[1].size = strlen(name) + 1;
+       args.in.args[1].value = name;
+       args.in.args[2].size = size;
+       args.in.args[2].value = value;
+       err = fuse_simple_request(fc, &args);
        if (err == -ENOSYS) {
                fc->no_setxattr = 1;
                err = -EOPNOTSUPP;
@@ -1879,7 +1793,7 @@ static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
 {
        struct inode *inode = entry->d_inode;
        struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req;
+       FUSE_ARGS(args);
        struct fuse_getxattr_in inarg;
        struct fuse_getxattr_out outarg;
        ssize_t ret;
@@ -1887,40 +1801,32 @@ static ssize_t fuse_getxattr(struct dentry *entry, const char *name,
        if (fc->no_getxattr)
                return -EOPNOTSUPP;
 
-       req = fuse_get_req_nopages(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
        memset(&inarg, 0, sizeof(inarg));
        inarg.size = size;
-       req->in.h.opcode = FUSE_GETXATTR;
-       req->in.h.nodeid = get_node_id(inode);
-       req->in.numargs = 2;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       req->in.args[1].size = strlen(name) + 1;
-       req->in.args[1].value = name;
+       args.in.h.opcode = FUSE_GETXATTR;
+       args.in.h.nodeid = get_node_id(inode);
+       args.in.numargs = 2;
+       args.in.args[0].size = sizeof(inarg);
+       args.in.args[0].value = &inarg;
+       args.in.args[1].size = strlen(name) + 1;
+       args.in.args[1].value = name;
        /* This is really two different operations rolled into one */
-       req->out.numargs = 1;
+       args.out.numargs = 1;
        if (size) {
-               req->out.argvar = 1;
-               req->out.args[0].size = size;
-               req->out.args[0].value = value;
+               args.out.argvar = 1;
+               args.out.args[0].size = size;
+               args.out.args[0].value = value;
        } else {
-               req->out.args[0].size = sizeof(outarg);
-               req->out.args[0].value = &outarg;
+               args.out.args[0].size = sizeof(outarg);
+               args.out.args[0].value = &outarg;
        }
-       fuse_request_send(fc, req);
-       ret = req->out.h.error;
-       if (!ret)
-               ret = size ? req->out.args[0].size : outarg.size;
-       else {
-               if (ret == -ENOSYS) {
-                       fc->no_getxattr = 1;
-                       ret = -EOPNOTSUPP;
-               }
+       ret = fuse_simple_request(fc, &args);
+       if (!ret && !size)
+               ret = outarg.size;
+       if (ret == -ENOSYS) {
+               fc->no_getxattr = 1;
+               ret = -EOPNOTSUPP;
        }
-       fuse_put_request(fc, req);
        return ret;
 }
 
@@ -1928,7 +1834,7 @@ static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
 {
        struct inode *inode = entry->d_inode;
        struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req;
+       FUSE_ARGS(args);
        struct fuse_getxattr_in inarg;
        struct fuse_getxattr_out outarg;
        ssize_t ret;
@@ -1939,38 +1845,30 @@ static ssize_t fuse_listxattr(struct dentry *entry, char *list, size_t size)
        if (fc->no_listxattr)
                return -EOPNOTSUPP;
 
-       req = fuse_get_req_nopages(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
        memset(&inarg, 0, sizeof(inarg));
        inarg.size = size;
-       req->in.h.opcode = FUSE_LISTXATTR;
-       req->in.h.nodeid = get_node_id(inode);
-       req->in.numargs = 1;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
+       args.in.h.opcode = FUSE_LISTXATTR;
+       args.in.h.nodeid = get_node_id(inode);
+       args.in.numargs = 1;
+       args.in.args[0].size = sizeof(inarg);
+       args.in.args[0].value = &inarg;
        /* This is really two different operations rolled into one */
-       req->out.numargs = 1;
+       args.out.numargs = 1;
        if (size) {
-               req->out.argvar = 1;
-               req->out.args[0].size = size;
-               req->out.args[0].value = list;
+               args.out.argvar = 1;
+               args.out.args[0].size = size;
+               args.out.args[0].value = list;
        } else {
-               req->out.args[0].size = sizeof(outarg);
-               req->out.args[0].value = &outarg;
+               args.out.args[0].size = sizeof(outarg);
+               args.out.args[0].value = &outarg;
        }
-       fuse_request_send(fc, req);
-       ret = req->out.h.error;
-       if (!ret)
-               ret = size ? req->out.args[0].size : outarg.size;
-       else {
-               if (ret == -ENOSYS) {
-                       fc->no_listxattr = 1;
-                       ret = -EOPNOTSUPP;
-               }
+       ret = fuse_simple_request(fc, &args);
+       if (!ret && !size)
+               ret = outarg.size;
+       if (ret == -ENOSYS) {
+               fc->no_listxattr = 1;
+               ret = -EOPNOTSUPP;
        }
-       fuse_put_request(fc, req);
        return ret;
 }
 
@@ -1978,24 +1876,18 @@ static int fuse_removexattr(struct dentry *entry, const char *name)
 {
        struct inode *inode = entry->d_inode;
        struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req;
+       FUSE_ARGS(args);
        int err;
 
        if (fc->no_removexattr)
                return -EOPNOTSUPP;
 
-       req = fuse_get_req_nopages(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       req->in.h.opcode = FUSE_REMOVEXATTR;
-       req->in.h.nodeid = get_node_id(inode);
-       req->in.numargs = 1;
-       req->in.args[0].size = strlen(name) + 1;
-       req->in.args[0].value = name;
-       fuse_request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
+       args.in.h.opcode = FUSE_REMOVEXATTR;
+       args.in.h.nodeid = get_node_id(inode);
+       args.in.numargs = 1;
+       args.in.args[0].size = strlen(name) + 1;
+       args.in.args[0].value = name;
+       err = fuse_simple_request(fc, &args);
        if (err == -ENOSYS) {
                fc->no_removexattr = 1;
                err = -EOPNOTSUPP;
index 2d4ae68943bb70687a411d8c6f5c05e12492040c..e8729ac3076207d70b3362f5f1cc650eea6ff47d 100644 (file)
@@ -24,30 +24,22 @@ static int fuse_send_open(struct fuse_conn *fc, u64 nodeid, struct file *file,
                          int opcode, struct fuse_open_out *outargp)
 {
        struct fuse_open_in inarg;
-       struct fuse_req *req;
-       int err;
-
-       req = fuse_get_req_nopages(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
+       FUSE_ARGS(args);
 
        memset(&inarg, 0, sizeof(inarg));
        inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY);
        if (!fc->atomic_o_trunc)
                inarg.flags &= ~O_TRUNC;
-       req->in.h.opcode = opcode;
-       req->in.h.nodeid = nodeid;
-       req->in.numargs = 1;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       req->out.numargs = 1;
-       req->out.args[0].size = sizeof(*outargp);
-       req->out.args[0].value = outargp;
-       fuse_request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
+       args.in.h.opcode = opcode;
+       args.in.h.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(*outargp);
+       args.out.args[0].value = outargp;
 
-       return err;
+       return fuse_simple_request(fc, &args);
 }
 
 struct fuse_file *fuse_file_alloc(struct fuse_conn *fc)
@@ -451,7 +443,7 @@ int fuse_fsync_common(struct file *file, loff_t start, loff_t end,
        struct inode *inode = file->f_mapping->host;
        struct fuse_conn *fc = get_fuse_conn(inode);
        struct fuse_file *ff = file->private_data;
-       struct fuse_req *req;
+       FUSE_ARGS(args);
        struct fuse_fsync_in inarg;
        int err;
 
@@ -477,23 +469,15 @@ int fuse_fsync_common(struct file *file, loff_t start, loff_t end,
        if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir))
                goto out;
 
-       req = fuse_get_req_nopages(fc);
-       if (IS_ERR(req)) {
-               err = PTR_ERR(req);
-               goto out;
-       }
-
        memset(&inarg, 0, sizeof(inarg));
        inarg.fh = ff->fh;
        inarg.fsync_flags = datasync ? 1 : 0;
-       req->in.h.opcode = isdir ? FUSE_FSYNCDIR : FUSE_FSYNC;
-       req->in.h.nodeid = get_node_id(inode);
-       req->in.numargs = 1;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       fuse_request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
+       args.in.h.opcode = isdir ? FUSE_FSYNCDIR : FUSE_FSYNC;
+       args.in.h.nodeid = get_node_id(inode);
+       args.in.numargs = 1;
+       args.in.args[0].size = sizeof(inarg);
+       args.in.args[0].value = &inarg;
+       err = fuse_simple_request(fc, &args);
        if (err == -ENOSYS) {
                if (isdir)
                        fc->no_fsyncdir = 1;
@@ -2127,49 +2111,44 @@ static int convert_fuse_file_lock(const struct fuse_file_lock *ffl,
        return 0;
 }
 
-static void fuse_lk_fill(struct fuse_req *req, struct file *file,
+static void fuse_lk_fill(struct fuse_args *args, struct file *file,
                         const struct file_lock *fl, int opcode, pid_t pid,
-                        int flock)
+                        int flock, struct fuse_lk_in *inarg)
 {
        struct inode *inode = file_inode(file);
        struct fuse_conn *fc = get_fuse_conn(inode);
        struct fuse_file *ff = file->private_data;
-       struct fuse_lk_in *arg = &req->misc.lk_in;
-
-       arg->fh = ff->fh;
-       arg->owner = fuse_lock_owner_id(fc, fl->fl_owner);
-       arg->lk.start = fl->fl_start;
-       arg->lk.end = fl->fl_end;
-       arg->lk.type = fl->fl_type;
-       arg->lk.pid = pid;
+
+       memset(inarg, 0, sizeof(*inarg));
+       inarg->fh = ff->fh;
+       inarg->owner = fuse_lock_owner_id(fc, fl->fl_owner);
+       inarg->lk.start = fl->fl_start;
+       inarg->lk.end = fl->fl_end;
+       inarg->lk.type = fl->fl_type;
+       inarg->lk.pid = pid;
        if (flock)
-               arg->lk_flags |= FUSE_LK_FLOCK;
-       req->in.h.opcode = opcode;
-       req->in.h.nodeid = get_node_id(inode);
-       req->in.numargs = 1;
-       req->in.args[0].size = sizeof(*arg);
-       req->in.args[0].value = arg;
+               inarg->lk_flags |= FUSE_LK_FLOCK;
+       args->in.h.opcode = opcode;
+       args->in.h.nodeid = get_node_id(inode);
+       args->in.numargs = 1;
+       args->in.args[0].size = sizeof(*inarg);
+       args->in.args[0].value = inarg;
 }
 
 static int fuse_getlk(struct file *file, struct file_lock *fl)
 {
        struct inode *inode = file_inode(file);
        struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req;
+       FUSE_ARGS(args);
+       struct fuse_lk_in inarg;
        struct fuse_lk_out outarg;
        int err;
 
-       req = fuse_get_req_nopages(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
-       fuse_lk_fill(req, file, fl, FUSE_GETLK, 0, 0);
-       req->out.numargs = 1;
-       req->out.args[0].size = sizeof(outarg);
-       req->out.args[0].value = &outarg;
-       fuse_request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
+       fuse_lk_fill(&args, file, fl, FUSE_GETLK, 0, 0, &inarg);
+       args.out.numargs = 1;
+       args.out.args[0].size = sizeof(outarg);
+       args.out.args[0].value = &outarg;
+       err = fuse_simple_request(fc, &args);
        if (!err)
                err = convert_fuse_file_lock(&outarg.lk, fl);
 
@@ -2180,7 +2159,8 @@ static int fuse_setlk(struct file *file, struct file_lock *fl, int flock)
 {
        struct inode *inode = file_inode(file);
        struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req;
+       FUSE_ARGS(args);
+       struct fuse_lk_in inarg;
        int opcode = (fl->fl_flags & FL_SLEEP) ? FUSE_SETLKW : FUSE_SETLK;
        pid_t pid = fl->fl_type != F_UNLCK ? current->tgid : 0;
        int err;
@@ -2194,17 +2174,13 @@ static int fuse_setlk(struct file *file, struct file_lock *fl, int flock)
        if (fl->fl_flags & FL_CLOSE)
                return 0;
 
-       req = fuse_get_req_nopages(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
+       fuse_lk_fill(&args, file, fl, opcode, pid, flock, &inarg);
+       err = fuse_simple_request(fc, &args);
 
-       fuse_lk_fill(req, file, fl, opcode, pid, flock);
-       fuse_request_send(fc, req);
-       err = req->out.h.error;
        /* locking is restartable */
        if (err == -EINTR)
                err = -ERESTARTSYS;
-       fuse_put_request(fc, req);
+
        return err;
 }
 
@@ -2254,7 +2230,7 @@ static sector_t fuse_bmap(struct address_space *mapping, sector_t block)
 {
        struct inode *inode = mapping->host;
        struct fuse_conn *fc = get_fuse_conn(inode);
-       struct fuse_req *req;
+       FUSE_ARGS(args);
        struct fuse_bmap_in inarg;
        struct fuse_bmap_out outarg;
        int err;
@@ -2262,24 +2238,18 @@ static sector_t fuse_bmap(struct address_space *mapping, sector_t block)
        if (!inode->i_sb->s_bdev || fc->no_bmap)
                return 0;
 
-       req = fuse_get_req_nopages(fc);
-       if (IS_ERR(req))
-               return 0;
-
        memset(&inarg, 0, sizeof(inarg));
        inarg.block = block;
        inarg.blocksize = inode->i_sb->s_blocksize;
-       req->in.h.opcode = FUSE_BMAP;
-       req->in.h.nodeid = get_node_id(inode);
-       req->in.numargs = 1;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       req->out.numargs = 1;
-       req->out.args[0].size = sizeof(outarg);
-       req->out.args[0].value = &outarg;
-       fuse_request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
+       args.in.h.opcode = FUSE_BMAP;
+       args.in.h.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(fc, &args);
        if (err == -ENOSYS)
                fc->no_bmap = 1;
 
@@ -2747,7 +2717,7 @@ unsigned fuse_file_poll(struct file *file, poll_table *wait)
        struct fuse_conn *fc = ff->fc;
        struct fuse_poll_in inarg = { .fh = ff->fh, .kh = ff->kh };
        struct fuse_poll_out outarg;
-       struct fuse_req *req;
+       FUSE_ARGS(args);
        int err;
 
        if (fc->no_poll)
@@ -2765,21 +2735,15 @@ unsigned fuse_file_poll(struct file *file, poll_table *wait)
                fuse_register_polled_file(fc, ff);
        }
 
-       req = fuse_get_req_nopages(fc);
-       if (IS_ERR(req))
-               return POLLERR;
-
-       req->in.h.opcode = FUSE_POLL;
-       req->in.h.nodeid = ff->nodeid;
-       req->in.numargs = 1;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       req->out.numargs = 1;
-       req->out.args[0].size = sizeof(outarg);
-       req->out.args[0].value = &outarg;
-       fuse_request_send(fc, req);
-       err = req->out.h.error;
-       fuse_put_request(fc, req);
+       args.in.h.opcode = FUSE_POLL;
+       args.in.h.nodeid = ff->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;
+       err = fuse_simple_request(fc, &args);
 
        if (!err)
                return outarg.revents;
@@ -2923,7 +2887,7 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
        struct inode *inode = file->f_inode;
        struct fuse_inode *fi = get_fuse_inode(inode);
        struct fuse_conn *fc = ff->fc;
-       struct fuse_req *req;
+       FUSE_ARGS(args);
        struct fuse_fallocate_in inarg = {
                .fh = ff->fh,
                .offset = offset,
@@ -2956,25 +2920,16 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
        if (!(mode & FALLOC_FL_KEEP_SIZE))
                set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
 
-       req = fuse_get_req_nopages(fc);
-       if (IS_ERR(req)) {
-               err = PTR_ERR(req);
-               goto out;
-       }
-
-       req->in.h.opcode = FUSE_FALLOCATE;
-       req->in.h.nodeid = ff->nodeid;
-       req->in.numargs = 1;
-       req->in.args[0].size = sizeof(inarg);
-       req->in.args[0].value = &inarg;
-       fuse_request_send(fc, req);
-       err = req->out.h.error;
+       args.in.h.opcode = FUSE_FALLOCATE;
+       args.in.h.nodeid = ff->nodeid;
+       args.in.numargs = 1;
+       args.in.args[0].size = sizeof(inarg);
+       args.in.args[0].value = &inarg;
+       err = fuse_simple_request(fc, &args);
        if (err == -ENOSYS) {
                fc->no_fallocate = 1;
                err = -EOPNOTSUPP;
        }
-       fuse_put_request(fc, req);
-
        if (err)
                goto out;
 
index 351c098307b810c5791d49296d7380b5044c236f..e0fc6725d1d0d66a4c3c7dce595239631ba353b1 100644 (file)
@@ -222,6 +222,25 @@ struct fuse_page_desc {
        unsigned int offset;
 };
 
+struct fuse_args {
+       struct {
+               struct {
+                       uint32_t opcode;
+                       uint64_t nodeid;
+               } h;
+               unsigned numargs;
+               struct fuse_in_arg args[3];
+
+       } in;
+       struct {
+               unsigned argvar:1;
+               unsigned numargs;
+               struct fuse_arg args[2];
+       } out;
+};
+
+#define FUSE_ARGS(args) struct fuse_args args = {}
+
 /** The request state */
 enum fuse_req_state {
        FUSE_REQ_INIT = 0,
@@ -321,7 +340,6 @@ struct fuse_req {
                        struct fuse_req *next;
                } write;
                struct fuse_notify_retrieve_in retrieve_in;
-               struct fuse_lk_in lk_in;
        } misc;
 
        /** page vector */
@@ -750,15 +768,6 @@ struct fuse_req *fuse_get_req_for_background(struct fuse_conn *fc,
  */
 void __fuse_get_request(struct fuse_req *req);
 
-/**
- * Get a request, may fail with -ENOMEM,
- * useful for callers who doesn't use req->pages[]
- */
-static inline struct fuse_req *fuse_get_req_nopages(struct fuse_conn *fc)
-{
-       return fuse_get_req(fc, 0);
-}
-
 /**
  * Gets a requests for a file operation, always succeeds
  */
@@ -776,6 +785,11 @@ void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req);
  */
 void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req);
 
+/**
+ * Simple request sending that does request allocation and freeing
+ */
+ssize_t fuse_simple_request(struct fuse_conn *fc, struct fuse_args *args);
+
 /**
  * Send a request in the background
  */
index 616a791270b78ee022f1e4e38d07904d4c908e28..6749109f255da69a5c24825aab1f2a25140fbb47 100644 (file)
@@ -410,7 +410,7 @@ static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf)
 {
        struct super_block *sb = dentry->d_sb;
        struct fuse_conn *fc = get_fuse_conn_super(sb);
-       struct fuse_req *req;
+       FUSE_ARGS(args);
        struct fuse_statfs_out outarg;
        int err;
 
@@ -419,23 +419,17 @@ static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf)
                return 0;
        }
 
-       req = fuse_get_req_nopages(fc);
-       if (IS_ERR(req))
-               return PTR_ERR(req);
-
        memset(&outarg, 0, sizeof(outarg));
-       req->in.numargs = 0;
-       req->in.h.opcode = FUSE_STATFS;
-       req->in.h.nodeid = get_node_id(dentry->d_inode);
-       req->out.numargs = 1;
-       req->out.args[0].size =
+       args.in.numargs = 0;
+       args.in.h.opcode = FUSE_STATFS;
+       args.in.h.nodeid = get_node_id(dentry->d_inode);
+       args.out.numargs = 1;
+       args.out.args[0].size =
                fc->minor < 4 ? FUSE_COMPAT_STATFS_SIZE : sizeof(outarg);
-       req->out.args[0].value = &outarg;
-       fuse_request_send(fc, req);
-       err = req->out.h.error;
+       args.out.args[0].value = &outarg;
+       err = fuse_simple_request(fc, &args);
        if (!err)
                convert_fuse_statfs(buf, &outarg.st);
-       fuse_put_request(fc, req);
        return err;
 }