Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fuse: Allow fuse_fill_super_common() for submounts

Submounts have their own superblock, which needs to be initialized.
However, they do not have a fuse_fs_context associated with them, and
the root node's attributes should be taken from the mountpoint's node.

Extend fuse_fill_super_common() to work for submounts by making the @ctx
parameter optional, and by adding a @submount_finode parameter.

(There is a plain "unsigned" in an existing code block that is being
indented by this commit. Extend it to "unsigned int" so checkpatch does
not complain.)

Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>

authored by

Max Reitz and committed by
Miklos Szeredi
1866d779 fcee216b

+96 -21
+8
fs/fuse/fuse_i.h
··· 1044 1044 */ 1045 1045 int fuse_fill_super_common(struct super_block *sb, struct fuse_fs_context *ctx); 1046 1046 1047 + /* 1048 + * Fill in superblock for submounts 1049 + * @sb: partially-initialized superblock to fill in 1050 + * @parent_fi: The fuse_inode of the parent filesystem where this submount is 1051 + * mounted 1052 + */ 1053 + int fuse_fill_super_submount(struct super_block *sb, 1054 + struct fuse_inode *parent_fi); 1047 1055 1048 1056 /* 1049 1057 * Remove the mount from the connection
+88 -21
fs/fuse/inode.c
··· 126 126 127 127 if (FUSE_IS_DAX(inode)) 128 128 fuse_dax_inode_cleanup(inode); 129 - fuse_queue_forget(fc, fi->forget, fi->nodeid, fi->nlookup); 130 - fi->forget = NULL; 129 + if (fi->nlookup) { 130 + fuse_queue_forget(fc, fi->forget, fi->nodeid, 131 + fi->nlookup); 132 + fi->forget = NULL; 133 + } 131 134 } 132 135 if (S_ISREG(inode->i_mode) && !is_bad_inode(inode)) { 133 136 WARN_ON(!list_empty(&fi->write_files)); ··· 1210 1207 } 1211 1208 EXPORT_SYMBOL_GPL(fuse_dev_free); 1212 1209 1210 + static void fuse_fill_attr_from_inode(struct fuse_attr *attr, 1211 + const struct fuse_inode *fi) 1212 + { 1213 + *attr = (struct fuse_attr){ 1214 + .ino = fi->inode.i_ino, 1215 + .size = fi->inode.i_size, 1216 + .blocks = fi->inode.i_blocks, 1217 + .atime = fi->inode.i_atime.tv_sec, 1218 + .mtime = fi->inode.i_mtime.tv_sec, 1219 + .ctime = fi->inode.i_ctime.tv_sec, 1220 + .atimensec = fi->inode.i_atime.tv_nsec, 1221 + .mtimensec = fi->inode.i_mtime.tv_nsec, 1222 + .ctimensec = fi->inode.i_ctime.tv_nsec, 1223 + .mode = fi->inode.i_mode, 1224 + .nlink = fi->inode.i_nlink, 1225 + .uid = fi->inode.i_uid.val, 1226 + .gid = fi->inode.i_gid.val, 1227 + .rdev = fi->inode.i_rdev, 1228 + .blksize = 1u << fi->inode.i_blkbits, 1229 + }; 1230 + } 1231 + 1232 + static void fuse_sb_defaults(struct super_block *sb) 1233 + { 1234 + sb->s_magic = FUSE_SUPER_MAGIC; 1235 + sb->s_op = &fuse_super_operations; 1236 + sb->s_xattr = fuse_xattr_handlers; 1237 + sb->s_maxbytes = MAX_LFS_FILESIZE; 1238 + sb->s_time_gran = 1; 1239 + sb->s_export_op = &fuse_export_operations; 1240 + sb->s_iflags |= SB_I_IMA_UNVERIFIABLE_SIGNATURE; 1241 + if (sb->s_user_ns != &init_user_ns) 1242 + sb->s_iflags |= SB_I_UNTRUSTED_MOUNTER; 1243 + sb->s_flags &= ~(SB_NOSEC | SB_I_VERSION); 1244 + 1245 + /* 1246 + * If we are not in the initial user namespace posix 1247 + * acls must be translated. 1248 + */ 1249 + if (sb->s_user_ns != &init_user_ns) 1250 + sb->s_xattr = fuse_no_acl_xattr_handlers; 1251 + } 1252 + 1253 + int fuse_fill_super_submount(struct super_block *sb, 1254 + struct fuse_inode *parent_fi) 1255 + { 1256 + struct fuse_mount *fm = get_fuse_mount_super(sb); 1257 + struct super_block *parent_sb = parent_fi->inode.i_sb; 1258 + struct fuse_attr root_attr; 1259 + struct inode *root; 1260 + 1261 + fuse_sb_defaults(sb); 1262 + fm->sb = sb; 1263 + 1264 + WARN_ON(sb->s_bdi != &noop_backing_dev_info); 1265 + sb->s_bdi = bdi_get(parent_sb->s_bdi); 1266 + 1267 + sb->s_xattr = parent_sb->s_xattr; 1268 + sb->s_time_gran = parent_sb->s_time_gran; 1269 + sb->s_blocksize = parent_sb->s_blocksize; 1270 + sb->s_blocksize_bits = parent_sb->s_blocksize_bits; 1271 + sb->s_subtype = kstrdup(parent_sb->s_subtype, GFP_KERNEL); 1272 + if (parent_sb->s_subtype && !sb->s_subtype) 1273 + return -ENOMEM; 1274 + 1275 + fuse_fill_attr_from_inode(&root_attr, parent_fi); 1276 + root = fuse_iget(sb, parent_fi->nodeid, 0, &root_attr, 0, 0); 1277 + /* 1278 + * This inode is just a duplicate, so it is not looked up and 1279 + * its nlookup should not be incremented. fuse_iget() does 1280 + * that, though, so undo it here. 1281 + */ 1282 + get_fuse_inode(root)->nlookup--; 1283 + sb->s_d_op = &fuse_dentry_operations; 1284 + sb->s_root = d_make_root(root); 1285 + if (!sb->s_root) 1286 + return -ENOMEM; 1287 + 1288 + return 0; 1289 + } 1290 + 1213 1291 int fuse_fill_super_common(struct super_block *sb, struct fuse_fs_context *ctx) 1214 1292 { 1215 1293 struct fuse_dev *fud = NULL; ··· 1304 1220 if (sb->s_flags & SB_MANDLOCK) 1305 1221 goto err; 1306 1222 1307 - sb->s_flags &= ~(SB_NOSEC | SB_I_VERSION); 1223 + fuse_sb_defaults(sb); 1308 1224 1309 1225 if (ctx->is_bdev) { 1310 1226 #ifdef CONFIG_BLOCK ··· 1319 1235 1320 1236 sb->s_subtype = ctx->subtype; 1321 1237 ctx->subtype = NULL; 1322 - sb->s_magic = FUSE_SUPER_MAGIC; 1323 - sb->s_op = &fuse_super_operations; 1324 - sb->s_xattr = fuse_xattr_handlers; 1325 - sb->s_maxbytes = MAX_LFS_FILESIZE; 1326 - sb->s_time_gran = 1; 1327 - sb->s_export_op = &fuse_export_operations; 1328 - sb->s_iflags |= SB_I_IMA_UNVERIFIABLE_SIGNATURE; 1329 - if (sb->s_user_ns != &init_user_ns) 1330 - sb->s_iflags |= SB_I_UNTRUSTED_MOUNTER; 1331 - 1332 - /* 1333 - * If we are not in the initial user namespace posix 1334 - * acls must be translated. 1335 - */ 1336 - if (sb->s_user_ns != &init_user_ns) 1337 - sb->s_xattr = fuse_no_acl_xattr_handlers; 1338 - 1339 1238 if (IS_ENABLED(CONFIG_FUSE_DAX)) { 1340 1239 err = fuse_dax_conn_alloc(fc, ctx->dax_dev); 1341 1240 if (err) ··· 1348 1281 fc->user_id = ctx->user_id; 1349 1282 fc->group_id = ctx->group_id; 1350 1283 fc->legacy_opts_show = ctx->legacy_opts_show; 1351 - fc->max_read = max_t(unsigned, 4096, ctx->max_read); 1284 + fc->max_read = max_t(unsigned int, 4096, ctx->max_read); 1352 1285 fc->destroy = ctx->destroy; 1353 1286 fc->no_control = ctx->no_control; 1354 1287 fc->no_force_umount = ctx->no_force_umount;