mirror of
https://github.com/torvalds/linux.git
synced 2026-07-27 09:36:22 +02:00
fuse: simplify fuse_dev_ioctl_clone()
Don't need to check if the new device file is already initialized, since fuse_dev_install_with_pq() will do that anyway. Make fuse_dev_install_with_pq() return a boolean value indicating success so that fuse_dev_ioctl_clone() can return an error in case of failure. Move aborting the connection (setting fc->connected to zero) to fuse_dev_install(), because it is not needed when the clone ioctl fails. Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
This commit is contained in:
parent
48649c0603
commit
a636077231
|
|
@ -454,12 +454,15 @@ struct fuse_dev *fuse_dev_alloc(void)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(fuse_dev_alloc);
|
||||
|
||||
static void fuse_dev_install_with_pq(struct fuse_dev *fud, struct fuse_chan *fch,
|
||||
/*
|
||||
* Installs @fch into @fud, return true on success. "Consumes" @pq in either case.
|
||||
*/
|
||||
static bool fuse_dev_install_with_pq(struct fuse_dev *fud, struct fuse_chan *fch,
|
||||
struct list_head *pq)
|
||||
{
|
||||
struct fuse_chan *old_fch;
|
||||
|
||||
spin_lock(&fch->lock);
|
||||
guard(spinlock)(&fch->lock);
|
||||
/*
|
||||
* Pairs with:
|
||||
* - xchg() in fuse_dev_release()
|
||||
|
|
@ -472,18 +475,17 @@ static void fuse_dev_install_with_pq(struct fuse_dev *fud, struct fuse_chan *fch
|
|||
* - it was already set to a different fc
|
||||
* - it was set to disconneted
|
||||
*/
|
||||
fch->connected = 0;
|
||||
kfree(pq);
|
||||
} else {
|
||||
if (pq) {
|
||||
WARN_ON(fud->pq.processing);
|
||||
fud->pq.processing = pq;
|
||||
}
|
||||
list_add_tail(&fud->entry, &fch->devices);
|
||||
fuse_conn_get(fch->conn);
|
||||
wake_up_all(&fuse_dev_waitq);
|
||||
return false;
|
||||
}
|
||||
spin_unlock(&fch->lock);
|
||||
if (pq) {
|
||||
WARN_ON(fud->pq.processing);
|
||||
fud->pq.processing = pq;
|
||||
}
|
||||
list_add_tail(&fud->entry, &fch->devices);
|
||||
fuse_conn_get(fch->conn);
|
||||
wake_up_all(&fuse_dev_waitq);
|
||||
return true;
|
||||
}
|
||||
|
||||
void fuse_dev_install(struct fuse_dev *fud, struct fuse_chan *fch)
|
||||
|
|
@ -491,7 +493,10 @@ void fuse_dev_install(struct fuse_dev *fud, struct fuse_chan *fch)
|
|||
struct list_head *pq = fch->pq_prealloc;
|
||||
|
||||
fch->pq_prealloc = NULL;
|
||||
fuse_dev_install_with_pq(fud, fch, pq);
|
||||
if (!fuse_dev_install_with_pq(fud, fch, pq)) {
|
||||
/* Channel is not usable without a dev */
|
||||
fuse_chan_abort(fch, false);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(fuse_dev_install);
|
||||
|
||||
|
|
@ -2297,15 +2302,13 @@ static long fuse_dev_ioctl_clone(struct file *file, __u32 __user *argp)
|
|||
if (IS_ERR(fud))
|
||||
return PTR_ERR(fud);
|
||||
|
||||
new_fud = fuse_file_to_fud(file);
|
||||
if (fuse_dev_chan_get(new_fud))
|
||||
return -EINVAL;
|
||||
|
||||
pq = fuse_pqueue_alloc();
|
||||
if (!pq)
|
||||
return -ENOMEM;
|
||||
|
||||
fuse_dev_install_with_pq(new_fud, fud->chan, pq);
|
||||
new_fud = fuse_file_to_fud(file);
|
||||
if (!fuse_dev_install_with_pq(new_fud, fud->chan, pq))
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user