Signed-off-by: Miklos Szeredi --- fs/fuse/cuse.c | 2 +- fs/fuse/dev.c | 2 +- fs/fuse/fuse_i.h | 4 +++- fs/fuse/inode.c | 11 ++++++++--- fs/fuse/virtio_fs.c | 2 +- 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c index dfcb98a654d8..174333633471 100644 --- a/fs/fuse/cuse.c +++ b/fs/fuse/cuse.c @@ -527,7 +527,7 @@ static int cuse_channel_open(struct inode *inode, struct file *file) cc->fc.initialized = 1; rc = cuse_send_init(cc); if (rc) { - fuse_dev_free(fud); + fuse_dev_put(fud); return rc; } file->private_data = fud; diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index d114869d6900..69868f851e13 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c @@ -2548,7 +2548,7 @@ int fuse_dev_release(struct inode *inode, struct file *file) fuse_abort_conn(fc); } } - fuse_dev_free(fud); + fuse_dev_put(fud); return 0; } EXPORT_SYMBOL_GPL(fuse_dev_release); diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 739220d96b6f..0817fbe3ba43 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h @@ -576,6 +576,8 @@ struct fuse_pqueue { * Fuse device instance */ struct fuse_dev { + refcount_t ref; + bool sync_init; /** Fuse connection for this device */ @@ -1342,7 +1344,7 @@ void fuse_conn_put(struct fuse_conn *fc); struct fuse_dev *fuse_dev_alloc_install(struct fuse_conn *fc); struct fuse_dev *fuse_dev_alloc(void); void fuse_dev_install(struct fuse_dev *fud, struct fuse_conn *fc); -void fuse_dev_free(struct fuse_dev *fud); +void fuse_dev_put(struct fuse_dev *fud); int fuse_send_init(struct fuse_mount *fm); /** diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 92f56bd6ac23..5a823b574634 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c @@ -1622,6 +1622,7 @@ struct fuse_dev *fuse_dev_alloc(void) if (!fud) return NULL; + refcount_set(&fud->ref, 1); pq = kzalloc_objs(struct list_head, FUSE_PQ_HASH_SIZE); if (!pq) { kfree(fud); @@ -1657,10 +1658,14 @@ struct fuse_dev *fuse_dev_alloc_install(struct fuse_conn *fc) } EXPORT_SYMBOL_GPL(fuse_dev_alloc_install); -void fuse_dev_free(struct fuse_dev *fud) +void fuse_dev_put(struct fuse_dev *fud) { - struct fuse_conn *fc = fud->fc; + struct fuse_conn *fc; + + if (!refcount_dec_and_test(&fud->ref)) + return; + fc = smp_load_acquire(&fud->fc); if (fc) { spin_lock(&fc->lock); list_del(&fud->entry); @@ -1671,7 +1676,7 @@ void fuse_dev_free(struct fuse_dev *fud) kfree(fud->pq.processing); kfree(fud); } -EXPORT_SYMBOL_GPL(fuse_dev_free); +EXPORT_SYMBOL_GPL(fuse_dev_put); static void fuse_fill_attr_from_inode(struct fuse_attr *attr, const struct fuse_inode *fi) diff --git a/fs/fuse/virtio_fs.c b/fs/fuse/virtio_fs.c index f685916754ad..12300651a0f1 100644 --- a/fs/fuse/virtio_fs.c +++ b/fs/fuse/virtio_fs.c @@ -486,7 +486,7 @@ static void virtio_fs_free_devs(struct virtio_fs *fs) if (!fsvq->fud) continue; - fuse_dev_free(fsvq->fud); + fuse_dev_put(fsvq->fud); fsvq->fud = NULL; } } -- 2.53.0