Commit c103b21c authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse

Pull fuse update from Miklos Szeredi:
 "The first part makes sure we don't hold up umount with pending async
  requests.  In addition to being a cleanup, this is a small behavioral
  change (for the better) and unlikely to break anything.

  The second part prepares for a cleanup of the fuse device I/O code by
  adding a helper for simple request submission, with some savings in
  line numbers already realized"

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mszeredi/fuse:
  fuse: use file_inode() in fuse_file_fallocate()
  fuse: introduce fuse_simple_request() helper
  fuse: reduce max out args
  fuse: hold inode instead of path after release
  fuse: flush requests on umount
  fuse: don't wake up reserved req in fuse_conn_kill()
parents 603ba7e4 1c68271c
...@@ -415,7 +415,7 @@ static void cuse_process_init_reply(struct fuse_conn *fc, struct fuse_req *req) ...@@ -415,7 +415,7 @@ static void cuse_process_init_reply(struct fuse_conn *fc, struct fuse_req *req)
err_region: err_region:
unregister_chrdev_region(devt, 1); unregister_chrdev_region(devt, 1);
err: err:
fuse_conn_kill(fc); fuse_abort_conn(fc);
goto out; goto out;
} }
......
...@@ -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)
{ {
......
This diff is collapsed.
This diff is collapsed.
...@@ -213,7 +213,7 @@ struct fuse_out { ...@@ -213,7 +213,7 @@ struct fuse_out {
unsigned numargs; unsigned numargs;
/** Array of arguments */ /** Array of arguments */
struct fuse_arg args[3]; struct fuse_arg args[2];
}; };
/** FUSE page descriptor */ /** FUSE page descriptor */
...@@ -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,
...@@ -305,11 +324,8 @@ struct fuse_req { ...@@ -305,11 +324,8 @@ struct fuse_req {
/** Data for asynchronous requests */ /** Data for asynchronous requests */
union { union {
struct { struct {
union { struct fuse_release_in in;
struct fuse_release_in in; struct inode *inode;
struct work_struct work;
};
struct path path;
} release; } release;
struct fuse_init_in init_in; struct fuse_init_in init_in;
struct fuse_init_out init_out; struct fuse_init_out init_out;
...@@ -324,7 +340,6 @@ struct fuse_req { ...@@ -324,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 */
...@@ -753,15 +768,6 @@ struct fuse_req *fuse_get_req_for_background(struct fuse_conn *fc, ...@@ -753,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
*/ */
...@@ -779,6 +785,11 @@ void fuse_put_request(struct fuse_conn *fc, struct fuse_req *req); ...@@ -779,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
*/ */
...@@ -804,8 +815,6 @@ void fuse_invalidate_atime(struct inode *inode); ...@@ -804,8 +815,6 @@ void fuse_invalidate_atime(struct inode *inode);
*/ */
struct fuse_conn *fuse_conn_get(struct fuse_conn *fc); struct fuse_conn *fuse_conn_get(struct fuse_conn *fc);
void fuse_conn_kill(struct fuse_conn *fc);
/** /**
* Initialize fuse_conn * Initialize fuse_conn
*/ */
......
...@@ -376,28 +376,13 @@ static void fuse_bdi_destroy(struct fuse_conn *fc) ...@@ -376,28 +376,13 @@ static void fuse_bdi_destroy(struct fuse_conn *fc)
bdi_destroy(&fc->bdi); bdi_destroy(&fc->bdi);
} }
void fuse_conn_kill(struct fuse_conn *fc)
{
spin_lock(&fc->lock);
fc->connected = 0;
fc->blocked = 0;
fc->initialized = 1;
spin_unlock(&fc->lock);
/* Flush all readers on this fs */
kill_fasync(&fc->fasync, SIGIO, POLL_IN);
wake_up_all(&fc->waitq);
wake_up_all(&fc->blocked_waitq);
wake_up_all(&fc->reserved_req_waitq);
}
EXPORT_SYMBOL_GPL(fuse_conn_kill);
static void fuse_put_super(struct super_block *sb) static void fuse_put_super(struct super_block *sb)
{ {
struct fuse_conn *fc = get_fuse_conn_super(sb); struct fuse_conn *fc = get_fuse_conn_super(sb);
fuse_send_destroy(fc); fuse_send_destroy(fc);
fuse_conn_kill(fc); fuse_abort_conn(fc);
mutex_lock(&fuse_mutex); mutex_lock(&fuse_mutex);
list_del(&fc->entry); list_del(&fc->entry);
fuse_ctl_remove_conn(fc); fuse_ctl_remove_conn(fc);
...@@ -425,7 +410,7 @@ static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf) ...@@ -425,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;
...@@ -434,23 +419,17 @@ static int fuse_statfs(struct dentry *dentry, struct kstatfs *buf) ...@@ -434,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%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment