Skip to content

Commit 7fd3abf

Browse files
rhvgoyalMiklos Szeredi
authored andcommitted
virtiofs: do not use fuse_fill_super_common() for device installation
fuse_fill_super_common() allocates and installs one fuse_device. Hence virtiofs allocates and install all fuse devices by itself except one. This makes logic little twisted. There does not seem to be any real need that why virtiofs can't allocate and install all fuse devices itself. So opt out of fuse device allocation and installation while calling fuse_fill_super_common(). Regular fuse still wants fuse_fill_super_common() to install fuse_device. It needs to prevent against races where two mounters are trying to mount fuse using same fd. In that case one will succeed while other will get -EINVAL. virtiofs does not have this issue because sget_fc() resolves the race w.r.t multiple mounters and only one instance of virtio_fs_fill_super() should be in progress for same filesystem. Signed-off-by: Vivek Goyal <[email protected]> Signed-off-by: Miklos Szeredi <[email protected]>
1 parent 5157da2 commit 7fd3abf

File tree

2 files changed

+15
-13
lines changed

2 files changed

+15
-13
lines changed

fs/fuse/inode.c

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1113,7 +1113,7 @@ EXPORT_SYMBOL_GPL(fuse_dev_free);
11131113

11141114
int fuse_fill_super_common(struct super_block *sb, struct fuse_fs_context *ctx)
11151115
{
1116-
struct fuse_dev *fud;
1116+
struct fuse_dev *fud = NULL;
11171117
struct fuse_conn *fc = get_fuse_conn_super(sb);
11181118
struct inode *root;
11191119
struct dentry *root_dentry;
@@ -1155,9 +1155,12 @@ int fuse_fill_super_common(struct super_block *sb, struct fuse_fs_context *ctx)
11551155
if (sb->s_user_ns != &init_user_ns)
11561156
sb->s_xattr = fuse_no_acl_xattr_handlers;
11571157

1158-
fud = fuse_dev_alloc_install(fc);
1159-
if (!fud)
1160-
goto err;
1158+
if (ctx->fudptr) {
1159+
err = -ENOMEM;
1160+
fud = fuse_dev_alloc_install(fc);
1161+
if (!fud)
1162+
goto err;
1163+
}
11611164

11621165
fc->dev = sb->s_dev;
11631166
fc->sb = sb;
@@ -1191,7 +1194,7 @@ int fuse_fill_super_common(struct super_block *sb, struct fuse_fs_context *ctx)
11911194

11921195
mutex_lock(&fuse_mutex);
11931196
err = -EINVAL;
1194-
if (*ctx->fudptr)
1197+
if (ctx->fudptr && *ctx->fudptr)
11951198
goto err_unlock;
11961199

11971200
err = fuse_ctl_add_conn(fc);
@@ -1200,15 +1203,17 @@ int fuse_fill_super_common(struct super_block *sb, struct fuse_fs_context *ctx)
12001203

12011204
list_add_tail(&fc->entry, &fuse_conn_list);
12021205
sb->s_root = root_dentry;
1203-
*ctx->fudptr = fud;
1206+
if (ctx->fudptr)
1207+
*ctx->fudptr = fud;
12041208
mutex_unlock(&fuse_mutex);
12051209
return 0;
12061210

12071211
err_unlock:
12081212
mutex_unlock(&fuse_mutex);
12091213
dput(root_dentry);
12101214
err_dev_free:
1211-
fuse_dev_free(fud);
1215+
if (fud)
1216+
fuse_dev_free(fud);
12121217
err:
12131218
return err;
12141219
}

fs/fuse/virtio_fs.c

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1103,26 +1103,23 @@ static int virtio_fs_fill_super(struct super_block *sb)
11031103

11041104
err = -ENOMEM;
11051105
/* Allocate fuse_dev for hiprio and notification queues */
1106-
for (i = 0; i < VQ_REQUEST; i++) {
1106+
for (i = 0; i < fs->nvqs; i++) {
11071107
struct virtio_fs_vq *fsvq = &fs->vqs[i];
11081108

11091109
fsvq->fud = fuse_dev_alloc();
11101110
if (!fsvq->fud)
11111111
goto err_free_fuse_devs;
11121112
}
11131113

1114-
ctx.fudptr = (void **)&fs->vqs[VQ_REQUEST].fud;
1114+
/* virtiofs allocates and installs its own fuse devices */
1115+
ctx.fudptr = NULL;
11151116
err = fuse_fill_super_common(sb, &ctx);
11161117
if (err < 0)
11171118
goto err_free_fuse_devs;
11181119

1119-
fc = fs->vqs[VQ_REQUEST].fud->fc;
1120-
11211120
for (i = 0; i < fs->nvqs; i++) {
11221121
struct virtio_fs_vq *fsvq = &fs->vqs[i];
11231122

1124-
if (i == VQ_REQUEST)
1125-
continue; /* already initialized */
11261123
fuse_dev_install(fsvq->fud, fc);
11271124
}
11281125

0 commit comments

Comments
 (0)