summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/fuse/file.c2
-rw-r--r--fs/fuse/fuse_i.h6
-rw-r--r--fs/fuse/inode.c28
3 files changed, 14 insertions, 22 deletions
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index f404e15357a6..53f2cc6970f1 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -279,7 +279,7 @@ void fuse_release_common(struct file *file, bool isdir)
* synchronous RELEASE is allowed (and desirable) in this case
* because the server can be trusted not to screw up.
*/
- fuse_file_put(ff, ff->fc->destroy_req != NULL, isdir);
+ fuse_file_put(ff, ff->fc->destroy, isdir);
}
static int fuse_open(struct inode *inode, struct file *file)
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h
index 43ae5b7f4dd4..73f70f3872e7 100644
--- a/fs/fuse/fuse_i.h
+++ b/fs/fuse/fuse_i.h
@@ -715,6 +715,9 @@ struct fuse_conn {
/** Does the filesystem support copy_file_range? */
unsigned no_copy_file_range:1;
+ /* Send DESTROY request */
+ unsigned int destroy:1;
+
/** The number of requests waiting for completion */
atomic_t num_waiting;
@@ -736,9 +739,6 @@ struct fuse_conn {
/** Key for lock owner ID scrambling */
u32 scramble_key[4];
- /** Reserved request for the DESTROY message */
- struct fuse_req *destroy_req;
-
/** Version counter for attribute changes */
atomic64_t attr_version;
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 2b9cc19fedcb..127984642a71 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -386,14 +386,13 @@ static void fuse_umount_begin(struct super_block *sb)
static void fuse_send_destroy(struct fuse_conn *fc)
{
- struct fuse_req *req = fc->destroy_req;
- if (req && fc->conn_init) {
- fc->destroy_req = NULL;
- req->in.h.opcode = FUSE_DESTROY;
- __set_bit(FR_FORCE, &req->flags);
- __clear_bit(FR_BACKGROUND, &req->flags);
- fuse_request_send(fc, req);
- fuse_put_request(fc, req);
+ if (fc->conn_init) {
+ FUSE_ARGS(args);
+
+ args.opcode = FUSE_DESTROY;
+ args.force = true;
+ args.nocreds = true;
+ fuse_simple_request(fc, &args);
}
}
@@ -640,8 +639,6 @@ EXPORT_SYMBOL_GPL(fuse_conn_init);
void fuse_conn_put(struct fuse_conn *fc)
{
if (refcount_dec_and_test(&fc->count)) {
- if (fc->destroy_req)
- fuse_request_free(fc->destroy_req);
put_pid_ns(fc->pid_ns);
put_user_ns(fc->user_ns);
fc->release(fc);
@@ -1171,6 +1168,7 @@ static int fuse_fill_super(struct super_block *sb, struct fs_context *fsc)
fc->user_id = ctx->user_id;
fc->group_id = ctx->group_id;
fc->max_read = max_t(unsigned, 4096, ctx->max_read);
+ fc->destroy = is_bdev;
/* Used by get_root_inode() */
sb->s_fs_info = fc;
@@ -1189,12 +1187,6 @@ static int fuse_fill_super(struct super_block *sb, struct fs_context *fsc)
goto err_put_root;
__set_bit(FR_BACKGROUND, &init_req->flags);
- if (is_bdev) {
- fc->destroy_req = fuse_request_alloc(0);
- if (!fc->destroy_req)
- goto err_free_init_req;
- }
-
mutex_lock(&fuse_mutex);
err = -EINVAL;
if (file->private_data)
@@ -1221,7 +1213,6 @@ static int fuse_fill_super(struct super_block *sb, struct fs_context *fsc)
err_unlock:
mutex_unlock(&fuse_mutex);
- err_free_init_req:
fuse_request_free(init_req);
err_put_root:
dput(root_dentry);
@@ -1287,7 +1278,8 @@ static void fuse_sb_destroy(struct super_block *sb)
struct fuse_conn *fc = get_fuse_conn_super(sb);
if (fc) {
- fuse_send_destroy(fc);
+ if (fc->destroy)
+ fuse_send_destroy(fc);
fuse_abort_conn(fc);
fuse_wait_aborted(fc);