提交 7078187a 编写于 作者: M Miklos Szeredi

fuse: introduce fuse_simple_request() helper

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: NMiklos Szeredi <mszeredi@suse.cz>
上级 f704dcb5
...@@ -511,6 +511,35 @@ void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req) ...@@ -511,6 +511,35 @@ void fuse_request_send(struct fuse_conn *fc, struct fuse_req *req)
} }
EXPORT_SYMBOL_GPL(fuse_request_send); 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, static void fuse_request_send_nowait_locked(struct fuse_conn *fc,
struct fuse_req *req) struct fuse_req *req)
{ {
......
此差异已折叠。
...@@ -24,30 +24,22 @@ static int fuse_send_open(struct fuse_conn *fc, u64 nodeid, struct file *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) int opcode, struct fuse_open_out *outargp)
{ {
struct fuse_open_in inarg; struct fuse_open_in inarg;
struct fuse_req *req; FUSE_ARGS(args);
int err;
req = fuse_get_req_nopages(fc);
if (IS_ERR(req))
return PTR_ERR(req);
memset(&inarg, 0, sizeof(inarg)); memset(&inarg, 0, sizeof(inarg));
inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY); inarg.flags = file->f_flags & ~(O_CREAT | O_EXCL | O_NOCTTY);
if (!fc->atomic_o_trunc) if (!fc->atomic_o_trunc)
inarg.flags &= ~O_TRUNC; inarg.flags &= ~O_TRUNC;
req->in.h.opcode = opcode; args.in.h.opcode = opcode;
req->in.h.nodeid = nodeid; args.in.h.nodeid = nodeid;
req->in.numargs = 1; args.in.numargs = 1;
req->in.args[0].size = sizeof(inarg); args.in.args[0].size = sizeof(inarg);
req->in.args[0].value = &inarg; args.in.args[0].value = &inarg;
req->out.numargs = 1; args.out.numargs = 1;
req->out.args[0].size = sizeof(*outargp); args.out.args[0].size = sizeof(*outargp);
req->out.args[0].value = outargp; args.out.args[0].value = outargp;
fuse_request_send(fc, req);
err = req->out.h.error;
fuse_put_request(fc, req);
return err; return fuse_simple_request(fc, &args);
} }
struct fuse_file *fuse_file_alloc(struct fuse_conn *fc) 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, ...@@ -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 inode *inode = file->f_mapping->host;
struct fuse_conn *fc = get_fuse_conn(inode); struct fuse_conn *fc = get_fuse_conn(inode);
struct fuse_file *ff = file->private_data; struct fuse_file *ff = file->private_data;
struct fuse_req *req; FUSE_ARGS(args);
struct fuse_fsync_in inarg; struct fuse_fsync_in inarg;
int err; int err;
...@@ -477,23 +469,15 @@ int fuse_fsync_common(struct file *file, loff_t start, loff_t end, ...@@ -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)) if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir))
goto out; goto out;
req = fuse_get_req_nopages(fc);
if (IS_ERR(req)) {
err = PTR_ERR(req);
goto out;
}
memset(&inarg, 0, sizeof(inarg)); memset(&inarg, 0, sizeof(inarg));
inarg.fh = ff->fh; inarg.fh = ff->fh;
inarg.fsync_flags = datasync ? 1 : 0; inarg.fsync_flags = datasync ? 1 : 0;
req->in.h.opcode = isdir ? FUSE_FSYNCDIR : FUSE_FSYNC; args.in.h.opcode = isdir ? FUSE_FSYNCDIR : FUSE_FSYNC;
req->in.h.nodeid = get_node_id(inode); args.in.h.nodeid = get_node_id(inode);
req->in.numargs = 1; args.in.numargs = 1;
req->in.args[0].size = sizeof(inarg); args.in.args[0].size = sizeof(inarg);
req->in.args[0].value = &inarg; args.in.args[0].value = &inarg;
fuse_request_send(fc, req); err = fuse_simple_request(fc, &args);
err = req->out.h.error;
fuse_put_request(fc, req);
if (err == -ENOSYS) { if (err == -ENOSYS) {
if (isdir) if (isdir)
fc->no_fsyncdir = 1; fc->no_fsyncdir = 1;
...@@ -2127,49 +2111,44 @@ static int convert_fuse_file_lock(const struct fuse_file_lock *ffl, ...@@ -2127,49 +2111,44 @@ static int convert_fuse_file_lock(const struct fuse_file_lock *ffl,
return 0; 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, 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 inode *inode = file_inode(file);
struct fuse_conn *fc = get_fuse_conn(inode); struct fuse_conn *fc = get_fuse_conn(inode);
struct fuse_file *ff = file->private_data; struct fuse_file *ff = file->private_data;
struct fuse_lk_in *arg = &req->misc.lk_in;
memset(inarg, 0, sizeof(*inarg));
arg->fh = ff->fh; inarg->fh = ff->fh;
arg->owner = fuse_lock_owner_id(fc, fl->fl_owner); inarg->owner = fuse_lock_owner_id(fc, fl->fl_owner);
arg->lk.start = fl->fl_start; inarg->lk.start = fl->fl_start;
arg->lk.end = fl->fl_end; inarg->lk.end = fl->fl_end;
arg->lk.type = fl->fl_type; inarg->lk.type = fl->fl_type;
arg->lk.pid = pid; inarg->lk.pid = pid;
if (flock) if (flock)
arg->lk_flags |= FUSE_LK_FLOCK; inarg->lk_flags |= FUSE_LK_FLOCK;
req->in.h.opcode = opcode; args->in.h.opcode = opcode;
req->in.h.nodeid = get_node_id(inode); args->in.h.nodeid = get_node_id(inode);
req->in.numargs = 1; args->in.numargs = 1;
req->in.args[0].size = sizeof(*arg); args->in.args[0].size = sizeof(*inarg);
req->in.args[0].value = arg; args->in.args[0].value = inarg;
} }
static int fuse_getlk(struct file *file, struct file_lock *fl) static int fuse_getlk(struct file *file, struct file_lock *fl)
{ {
struct inode *inode = file_inode(file); struct inode *inode = file_inode(file);
struct fuse_conn *fc = get_fuse_conn(inode); 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; struct fuse_lk_out outarg;
int err; int err;
req = fuse_get_req_nopages(fc); fuse_lk_fill(&args, file, fl, FUSE_GETLK, 0, 0, &inarg);
if (IS_ERR(req)) args.out.numargs = 1;
return PTR_ERR(req); args.out.args[0].size = sizeof(outarg);
args.out.args[0].value = &outarg;
fuse_lk_fill(req, file, fl, FUSE_GETLK, 0, 0); err = fuse_simple_request(fc, &args);
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);
if (!err) if (!err)
err = convert_fuse_file_lock(&outarg.lk, fl); 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) ...@@ -2180,7 +2159,8 @@ static int fuse_setlk(struct file *file, struct file_lock *fl, int flock)
{ {
struct inode *inode = file_inode(file); struct inode *inode = file_inode(file);
struct fuse_conn *fc = get_fuse_conn(inode); 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; int opcode = (fl->fl_flags & FL_SLEEP) ? FUSE_SETLKW : FUSE_SETLK;
pid_t pid = fl->fl_type != F_UNLCK ? current->tgid : 0; pid_t pid = fl->fl_type != F_UNLCK ? current->tgid : 0;
int err; int err;
...@@ -2194,17 +2174,13 @@ static int fuse_setlk(struct file *file, struct file_lock *fl, int flock) ...@@ -2194,17 +2174,13 @@ static int fuse_setlk(struct file *file, struct file_lock *fl, int flock)
if (fl->fl_flags & FL_CLOSE) if (fl->fl_flags & FL_CLOSE)
return 0; return 0;
req = fuse_get_req_nopages(fc); fuse_lk_fill(&args, file, fl, opcode, pid, flock, &inarg);
if (IS_ERR(req)) err = fuse_simple_request(fc, &args);
return PTR_ERR(req);
fuse_lk_fill(req, file, fl, opcode, pid, flock);
fuse_request_send(fc, req);
err = req->out.h.error;
/* locking is restartable */ /* locking is restartable */
if (err == -EINTR) if (err == -EINTR)
err = -ERESTARTSYS; err = -ERESTARTSYS;
fuse_put_request(fc, req);
return err; return err;
} }
...@@ -2254,7 +2230,7 @@ static sector_t fuse_bmap(struct address_space *mapping, sector_t block) ...@@ -2254,7 +2230,7 @@ static sector_t fuse_bmap(struct address_space *mapping, sector_t block)
{ {
struct inode *inode = mapping->host; struct inode *inode = mapping->host;
struct fuse_conn *fc = get_fuse_conn(inode); struct fuse_conn *fc = get_fuse_conn(inode);
struct fuse_req *req; FUSE_ARGS(args);
struct fuse_bmap_in inarg; struct fuse_bmap_in inarg;
struct fuse_bmap_out outarg; struct fuse_bmap_out outarg;
int err; int err;
...@@ -2262,24 +2238,18 @@ static sector_t fuse_bmap(struct address_space *mapping, sector_t block) ...@@ -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) if (!inode->i_sb->s_bdev || fc->no_bmap)
return 0; return 0;
req = fuse_get_req_nopages(fc);
if (IS_ERR(req))
return 0;
memset(&inarg, 0, sizeof(inarg)); memset(&inarg, 0, sizeof(inarg));
inarg.block = block; inarg.block = block;
inarg.blocksize = inode->i_sb->s_blocksize; inarg.blocksize = inode->i_sb->s_blocksize;
req->in.h.opcode = FUSE_BMAP; args.in.h.opcode = FUSE_BMAP;
req->in.h.nodeid = get_node_id(inode); args.in.h.nodeid = get_node_id(inode);
req->in.numargs = 1; args.in.numargs = 1;
req->in.args[0].size = sizeof(inarg); args.in.args[0].size = sizeof(inarg);
req->in.args[0].value = &inarg; args.in.args[0].value = &inarg;
req->out.numargs = 1; args.out.numargs = 1;
req->out.args[0].size = sizeof(outarg); args.out.args[0].size = sizeof(outarg);
req->out.args[0].value = &outarg; args.out.args[0].value = &outarg;
fuse_request_send(fc, req); err = fuse_simple_request(fc, &args);
err = req->out.h.error;
fuse_put_request(fc, req);
if (err == -ENOSYS) if (err == -ENOSYS)
fc->no_bmap = 1; fc->no_bmap = 1;
...@@ -2747,7 +2717,7 @@ unsigned fuse_file_poll(struct file *file, poll_table *wait) ...@@ -2747,7 +2717,7 @@ unsigned fuse_file_poll(struct file *file, poll_table *wait)
struct fuse_conn *fc = ff->fc; struct fuse_conn *fc = ff->fc;
struct fuse_poll_in inarg = { .fh = ff->fh, .kh = ff->kh }; struct fuse_poll_in inarg = { .fh = ff->fh, .kh = ff->kh };
struct fuse_poll_out outarg; struct fuse_poll_out outarg;
struct fuse_req *req; FUSE_ARGS(args);
int err; int err;
if (fc->no_poll) if (fc->no_poll)
...@@ -2765,21 +2735,15 @@ unsigned fuse_file_poll(struct file *file, poll_table *wait) ...@@ -2765,21 +2735,15 @@ unsigned fuse_file_poll(struct file *file, poll_table *wait)
fuse_register_polled_file(fc, ff); fuse_register_polled_file(fc, ff);
} }
req = fuse_get_req_nopages(fc); args.in.h.opcode = FUSE_POLL;
if (IS_ERR(req)) args.in.h.nodeid = ff->nodeid;
return POLLERR; args.in.numargs = 1;
args.in.args[0].size = sizeof(inarg);
req->in.h.opcode = FUSE_POLL; args.in.args[0].value = &inarg;
req->in.h.nodeid = ff->nodeid; args.out.numargs = 1;
req->in.numargs = 1; args.out.args[0].size = sizeof(outarg);
req->in.args[0].size = sizeof(inarg); args.out.args[0].value = &outarg;
req->in.args[0].value = &inarg; err = fuse_simple_request(fc, &args);
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);
if (!err) if (!err)
return outarg.revents; return outarg.revents;
...@@ -2923,7 +2887,7 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, ...@@ -2923,7 +2887,7 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
struct inode *inode = file->f_inode; struct inode *inode = file->f_inode;
struct fuse_inode *fi = get_fuse_inode(inode); struct fuse_inode *fi = get_fuse_inode(inode);
struct fuse_conn *fc = ff->fc; struct fuse_conn *fc = ff->fc;
struct fuse_req *req; FUSE_ARGS(args);
struct fuse_fallocate_in inarg = { struct fuse_fallocate_in inarg = {
.fh = ff->fh, .fh = ff->fh,
.offset = offset, .offset = offset,
...@@ -2956,25 +2920,16 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, ...@@ -2956,25 +2920,16 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset,
if (!(mode & FALLOC_FL_KEEP_SIZE)) if (!(mode & FALLOC_FL_KEEP_SIZE))
set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state);
req = fuse_get_req_nopages(fc); args.in.h.opcode = FUSE_FALLOCATE;
if (IS_ERR(req)) { args.in.h.nodeid = ff->nodeid;
err = PTR_ERR(req); args.in.numargs = 1;
goto out; args.in.args[0].size = sizeof(inarg);
} args.in.args[0].value = &inarg;
err = fuse_simple_request(fc, &args);
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;
if (err == -ENOSYS) { if (err == -ENOSYS) {
fc->no_fallocate = 1; fc->no_fallocate = 1;
err = -EOPNOTSUPP; err = -EOPNOTSUPP;
} }
fuse_put_request(fc, req);
if (err) if (err)
goto out; goto out;
......
...@@ -222,6 +222,25 @@ struct fuse_page_desc { ...@@ -222,6 +222,25 @@ struct fuse_page_desc {
unsigned int offset; 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 */ /** The request state */
enum fuse_req_state { enum fuse_req_state {
FUSE_REQ_INIT = 0, FUSE_REQ_INIT = 0,
...@@ -321,7 +340,6 @@ struct fuse_req { ...@@ -321,7 +340,6 @@ struct fuse_req {
struct fuse_req *next; struct fuse_req *next;
} write; } write;
struct fuse_notify_retrieve_in retrieve_in; struct fuse_notify_retrieve_in retrieve_in;
struct fuse_lk_in lk_in;
} misc; } misc;
/** page vector */ /** page vector */
...@@ -750,15 +768,6 @@ struct fuse_req *fuse_get_req_for_background(struct fuse_conn *fc, ...@@ -750,15 +768,6 @@ struct fuse_req *fuse_get_req_for_background(struct fuse_conn *fc,
*/ */
void __fuse_get_request(struct fuse_req *req); 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 * 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); ...@@ -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); 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 * Send a request in the background
*/ */
......
...@@ -410,7 +410,7 @@ static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf) ...@@ -410,7 +410,7 @@ static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf)
{ {
struct super_block *sb = dentry->d_sb; struct super_block *sb = dentry->d_sb;
struct fuse_conn *fc = get_fuse_conn_super(sb); struct fuse_conn *fc = get_fuse_conn_super(sb);
struct fuse_req *req; FUSE_ARGS(args);
struct fuse_statfs_out outarg; struct fuse_statfs_out outarg;
int err; int err;
...@@ -419,23 +419,17 @@ static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf) ...@@ -419,23 +419,17 @@ static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf)
return 0; return 0;
} }
req = fuse_get_req_nopages(fc);
if (IS_ERR(req))
return PTR_ERR(req);
memset(&outarg, 0, sizeof(outarg)); memset(&outarg, 0, sizeof(outarg));
req->in.numargs = 0; args.in.numargs = 0;
req->in.h.opcode = FUSE_STATFS; args.in.h.opcode = FUSE_STATFS;
req->in.h.nodeid = get_node_id(dentry->d_inode); args.in.h.nodeid = get_node_id(dentry->d_inode);
req->out.numargs = 1; args.out.numargs = 1;
req->out.args[0].size = args.out.args[0].size =
fc->minor < 4 ? FUSE_COMPAT_STATFS_SIZE : sizeof(outarg); fc->minor < 4 ? FUSE_COMPAT_STATFS_SIZE : sizeof(outarg);
req->out.args[0].value = &outarg; args.out.args[0].value = &outarg;
fuse_request_send(fc, req); err = fuse_simple_request(fc, &args);
err = req->out.h.error;
if (!err) if (!err)
convert_fuse_statfs(buf, &outarg.st); convert_fuse_statfs(buf, &outarg.st);
fuse_put_request(fc, req);
return err; return err;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册