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

Merge branch 'work.mount2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull misc mount API conversions from Al Viro:
"Conversions to new API for shmem and friends and for mount_mtd()-using
filesystems.

As for the rest of the mount API conversions in -next, some of them
belong in the individual trees (e.g. binderfs one should definitely go
through android folks, after getting redone on top of their changes).
I'm going to drop those and send the rest (trivial ones + stuff ACKed
by maintainers) in a separate series - by that point they are
independent from each other.

Some stuff has already migrated into individual trees (NFS conversion,
for example, or FUSE stuff, etc.); those presumably will go through
the regular merges from corresponding trees."

* 'work.mount2' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
vfs: Make fs_parse() handle fs_param_is_fd-type params better
vfs: Convert ramfs, shmem, tmpfs, devtmpfs, rootfs to use the new mount API
shmem_parse_one(): switch to use of fs_parse()
shmem_parse_options(): take handling a single option into a helper
shmem_parse_options(): don't bother with mpol in separate variable
shmem_parse_options(): use a separate structure to keep the results
make shmem_fill_super() static
make ramfs_fill_super() static
devtmpfs: don't mix {ramfs,shmem}_fill_super() with mount_single()
vfs: Convert squashfs to use the new mount API
mtd: Kill mount_mtd()
vfs: Convert jffs2 to use the new mount API
vfs: Convert cramfs to use the new mount API
vfs: Convert romfs to use the new mount API
vfs: Add a single-or-reconfig keying to vfs_get_super()

+609 -594
+31 -11
drivers/base/devtmpfs.c
··· 56 56 } 57 57 __setup("devtmpfs.mount=", mount_param); 58 58 59 - static struct dentry *dev_mount(struct file_system_type *fs_type, int flags, 59 + static struct vfsmount *mnt; 60 + 61 + static struct dentry *public_dev_mount(struct file_system_type *fs_type, int flags, 60 62 const char *dev_name, void *data) 61 63 { 62 - #ifdef CONFIG_TMPFS 63 - return mount_single(fs_type, flags, data, shmem_fill_super); 64 - #else 65 - return mount_single(fs_type, flags, data, ramfs_fill_super); 66 - #endif 64 + struct super_block *s = mnt->mnt_sb; 65 + atomic_inc(&s->s_active); 66 + down_write(&s->s_umount); 67 + return dget(s->s_root); 67 68 } 69 + 70 + static struct file_system_type internal_fs_type = { 71 + .name = "devtmpfs", 72 + #ifdef CONFIG_TMPFS 73 + .init_fs_context = shmem_init_fs_context, 74 + .parameters = &shmem_fs_parameters, 75 + #else 76 + .init_fs_context = ramfs_init_fs_context, 77 + .parameters = &ramfs_fs_parameters, 78 + #endif 79 + .kill_sb = kill_litter_super, 80 + }; 68 81 69 82 static struct file_system_type dev_fs_type = { 70 83 .name = "devtmpfs", 71 - .mount = dev_mount, 72 - .kill_sb = kill_litter_super, 84 + .mount = public_dev_mount, 73 85 }; 74 86 75 87 #ifdef CONFIG_BLOCK ··· 390 378 391 379 static int devtmpfsd(void *p) 392 380 { 393 - char options[] = "mode=0755"; 394 381 int *err = p; 395 382 *err = ksys_unshare(CLONE_NEWNS); 396 383 if (*err) 397 384 goto out; 398 - *err = ksys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, options); 385 + *err = ksys_mount("devtmpfs", "/", "devtmpfs", MS_SILENT, NULL); 399 386 if (*err) 400 387 goto out; 401 388 ksys_chdir("/.."); /* will traverse into overmounted root */ ··· 431 420 */ 432 421 int __init devtmpfs_init(void) 433 422 { 434 - int err = register_filesystem(&dev_fs_type); 423 + char opts[] = "mode=0755"; 424 + int err; 425 + 426 + mnt = vfs_kern_mount(&internal_fs_type, 0, "devtmpfs", opts); 427 + if (IS_ERR(mnt)) { 428 + printk(KERN_ERR "devtmpfs: unable to create devtmpfs %ld\n", 429 + PTR_ERR(mnt)); 430 + return PTR_ERR(mnt); 431 + } 432 + err = register_filesystem(&dev_fs_type); 435 433 if (err) { 436 434 printk(KERN_ERR "devtmpfs: unable to register devtmpfs " 437 435 "type %i\n", err);
-189
drivers/mtd/mtdsuper.c
··· 194 194 EXPORT_SYMBOL_GPL(get_tree_mtd); 195 195 196 196 /* 197 - * compare superblocks to see if they're equivalent 198 - * - they are if the underlying MTD device is the same 199 - */ 200 - static int get_sb_mtd_compare(struct super_block *sb, void *_mtd) 201 - { 202 - struct mtd_info *mtd = _mtd; 203 - 204 - if (sb->s_mtd == mtd) { 205 - pr_debug("MTDSB: Match on device %d (\"%s\")\n", 206 - mtd->index, mtd->name); 207 - return 1; 208 - } 209 - 210 - pr_debug("MTDSB: No match, device %d (\"%s\"), device %d (\"%s\")\n", 211 - sb->s_mtd->index, sb->s_mtd->name, mtd->index, mtd->name); 212 - return 0; 213 - } 214 - 215 - /* 216 - * mark the superblock by the MTD device it is using 217 - * - set the device number to be the correct MTD block device for pesuperstence 218 - * of NFS exports 219 - */ 220 - static int get_sb_mtd_set(struct super_block *sb, void *_mtd) 221 - { 222 - struct mtd_info *mtd = _mtd; 223 - 224 - sb->s_mtd = mtd; 225 - sb->s_dev = MKDEV(MTD_BLOCK_MAJOR, mtd->index); 226 - sb->s_bdi = bdi_get(mtd_bdi); 227 - 228 - return 0; 229 - } 230 - 231 - /* 232 - * get a superblock on an MTD-backed filesystem 233 - */ 234 - static struct dentry *mount_mtd_aux(struct file_system_type *fs_type, int flags, 235 - const char *dev_name, void *data, 236 - struct mtd_info *mtd, 237 - int (*fill_super)(struct super_block *, void *, int)) 238 - { 239 - struct super_block *sb; 240 - int ret; 241 - 242 - sb = sget(fs_type, get_sb_mtd_compare, get_sb_mtd_set, flags, mtd); 243 - if (IS_ERR(sb)) 244 - goto out_error; 245 - 246 - if (sb->s_root) 247 - goto already_mounted; 248 - 249 - /* fresh new superblock */ 250 - pr_debug("MTDSB: New superblock for device %d (\"%s\")\n", 251 - mtd->index, mtd->name); 252 - 253 - ret = fill_super(sb, data, flags & SB_SILENT ? 1 : 0); 254 - if (ret < 0) { 255 - deactivate_locked_super(sb); 256 - return ERR_PTR(ret); 257 - } 258 - 259 - /* go */ 260 - sb->s_flags |= SB_ACTIVE; 261 - return dget(sb->s_root); 262 - 263 - /* new mountpoint for an already mounted superblock */ 264 - already_mounted: 265 - pr_debug("MTDSB: Device %d (\"%s\") is already mounted\n", 266 - mtd->index, mtd->name); 267 - put_mtd_device(mtd); 268 - return dget(sb->s_root); 269 - 270 - out_error: 271 - put_mtd_device(mtd); 272 - return ERR_CAST(sb); 273 - } 274 - 275 - /* 276 - * get a superblock on an MTD-backed filesystem by MTD device number 277 - */ 278 - static struct dentry *mount_mtd_nr(struct file_system_type *fs_type, int flags, 279 - const char *dev_name, void *data, int mtdnr, 280 - int (*fill_super)(struct super_block *, void *, int)) 281 - { 282 - struct mtd_info *mtd; 283 - 284 - mtd = get_mtd_device(NULL, mtdnr); 285 - if (IS_ERR(mtd)) { 286 - pr_debug("MTDSB: Device #%u doesn't appear to exist\n", mtdnr); 287 - return ERR_CAST(mtd); 288 - } 289 - 290 - return mount_mtd_aux(fs_type, flags, dev_name, data, mtd, fill_super); 291 - } 292 - 293 - /* 294 - * set up an MTD-based superblock 295 - */ 296 - struct dentry *mount_mtd(struct file_system_type *fs_type, int flags, 297 - const char *dev_name, void *data, 298 - int (*fill_super)(struct super_block *, void *, int)) 299 - { 300 - #ifdef CONFIG_BLOCK 301 - struct block_device *bdev; 302 - int ret, major; 303 - #endif 304 - int mtdnr; 305 - 306 - if (!dev_name) 307 - return ERR_PTR(-EINVAL); 308 - 309 - pr_debug("MTDSB: dev_name \"%s\"\n", dev_name); 310 - 311 - /* the preferred way of mounting in future; especially when 312 - * CONFIG_BLOCK=n - we specify the underlying MTD device by number or 313 - * by name, so that we don't require block device support to be present 314 - * in the kernel. */ 315 - if (dev_name[0] == 'm' && dev_name[1] == 't' && dev_name[2] == 'd') { 316 - if (dev_name[3] == ':') { 317 - struct mtd_info *mtd; 318 - 319 - /* mount by MTD device name */ 320 - pr_debug("MTDSB: mtd:%%s, name \"%s\"\n", 321 - dev_name + 4); 322 - 323 - mtd = get_mtd_device_nm(dev_name + 4); 324 - if (!IS_ERR(mtd)) 325 - return mount_mtd_aux( 326 - fs_type, flags, 327 - dev_name, data, mtd, 328 - fill_super); 329 - 330 - printk(KERN_NOTICE "MTD:" 331 - " MTD device with name \"%s\" not found.\n", 332 - dev_name + 4); 333 - 334 - } else if (isdigit(dev_name[3])) { 335 - /* mount by MTD device number name */ 336 - char *endptr; 337 - 338 - mtdnr = simple_strtoul(dev_name + 3, &endptr, 0); 339 - if (!*endptr) { 340 - /* It was a valid number */ 341 - pr_debug("MTDSB: mtd%%d, mtdnr %d\n", 342 - mtdnr); 343 - return mount_mtd_nr(fs_type, flags, 344 - dev_name, data, 345 - mtdnr, fill_super); 346 - } 347 - } 348 - } 349 - 350 - #ifdef CONFIG_BLOCK 351 - /* try the old way - the hack where we allowed users to mount 352 - * /dev/mtdblock$(n) but didn't actually _use_ the blockdev 353 - */ 354 - bdev = lookup_bdev(dev_name); 355 - if (IS_ERR(bdev)) { 356 - ret = PTR_ERR(bdev); 357 - pr_debug("MTDSB: lookup_bdev() returned %d\n", ret); 358 - return ERR_PTR(ret); 359 - } 360 - pr_debug("MTDSB: lookup_bdev() returned 0\n"); 361 - 362 - ret = -EINVAL; 363 - 364 - major = MAJOR(bdev->bd_dev); 365 - mtdnr = MINOR(bdev->bd_dev); 366 - bdput(bdev); 367 - 368 - if (major != MTD_BLOCK_MAJOR) 369 - goto not_an_MTD_device; 370 - 371 - return mount_mtd_nr(fs_type, flags, dev_name, data, mtdnr, fill_super); 372 - 373 - not_an_MTD_device: 374 - #endif /* CONFIG_BLOCK */ 375 - 376 - if (!(flags & SB_SILENT)) 377 - printk(KERN_NOTICE 378 - "MTD: Attempt to mount non-MTD device \"%s\"\n", 379 - dev_name); 380 - return ERR_PTR(-EINVAL); 381 - } 382 - 383 - EXPORT_SYMBOL_GPL(mount_mtd); 384 - 385 - /* 386 197 * destroy an MTD-based superblock 387 198 */ 388 199 void kill_mtd_super(struct super_block *sb)
+39 -30
fs/cramfs/inode.c
··· 24 24 #include <linux/blkdev.h> 25 25 #include <linux/mtd/mtd.h> 26 26 #include <linux/mtd/super.h> 27 + #include <linux/fs_context.h> 27 28 #include <linux/slab.h> 28 29 #include <linux/vfs.h> 29 30 #include <linux/mutex.h> ··· 507 506 kfree(sbi); 508 507 } 509 508 510 - static int cramfs_remount(struct super_block *sb, int *flags, char *data) 509 + static int cramfs_reconfigure(struct fs_context *fc) 511 510 { 512 - sync_filesystem(sb); 513 - *flags |= SB_RDONLY; 511 + sync_filesystem(fc->root->d_sb); 512 + fc->sb_flags |= SB_RDONLY; 514 513 return 0; 515 514 } 516 515 517 - static int cramfs_read_super(struct super_block *sb, 518 - struct cramfs_super *super, int silent) 516 + static int cramfs_read_super(struct super_block *sb, struct fs_context *fc, 517 + struct cramfs_super *super) 519 518 { 520 519 struct cramfs_sb_info *sbi = CRAMFS_SB(sb); 521 520 unsigned long root_offset; 521 + bool silent = fc->sb_flags & SB_SILENT; 522 522 523 523 /* We don't know the real size yet */ 524 524 sbi->size = PAGE_SIZE; ··· 534 532 /* check for wrong endianness */ 535 533 if (super->magic == CRAMFS_MAGIC_WEND) { 536 534 if (!silent) 537 - pr_err("wrong endianness\n"); 535 + errorf(fc, "cramfs: wrong endianness"); 538 536 return -EINVAL; 539 537 } 540 538 ··· 546 544 mutex_unlock(&read_mutex); 547 545 if (super->magic != CRAMFS_MAGIC) { 548 546 if (super->magic == CRAMFS_MAGIC_WEND && !silent) 549 - pr_err("wrong endianness\n"); 547 + errorf(fc, "cramfs: wrong endianness"); 550 548 else if (!silent) 551 - pr_err("wrong magic\n"); 549 + errorf(fc, "cramfs: wrong magic"); 552 550 return -EINVAL; 553 551 } 554 552 } 555 553 556 554 /* get feature flags first */ 557 555 if (super->flags & ~CRAMFS_SUPPORTED_FLAGS) { 558 - pr_err("unsupported filesystem features\n"); 556 + errorf(fc, "cramfs: unsupported filesystem features"); 559 557 return -EINVAL; 560 558 } 561 559 562 560 /* Check that the root inode is in a sane state */ 563 561 if (!S_ISDIR(super->root.mode)) { 564 - pr_err("root is not a directory\n"); 562 + errorf(fc, "cramfs: root is not a directory"); 565 563 return -EINVAL; 566 564 } 567 565 /* correct strange, hard-coded permissions of mkcramfs */ ··· 580 578 sbi->magic = super->magic; 581 579 sbi->flags = super->flags; 582 580 if (root_offset == 0) 583 - pr_info("empty filesystem"); 581 + infof(fc, "cramfs: empty filesystem"); 584 582 else if (!(super->flags & CRAMFS_FLAG_SHIFTED_ROOT_OFFSET) && 585 583 ((root_offset != sizeof(struct cramfs_super)) && 586 584 (root_offset != 512 + sizeof(struct cramfs_super)))) 587 585 { 588 - pr_err("bad root offset %lu\n", root_offset); 586 + errorf(fc, "cramfs: bad root offset %lu", root_offset); 589 587 return -EINVAL; 590 588 } 591 589 ··· 611 609 return 0; 612 610 } 613 611 614 - static int cramfs_blkdev_fill_super(struct super_block *sb, void *data, 615 - int silent) 612 + static int cramfs_blkdev_fill_super(struct super_block *sb, struct fs_context *fc) 616 613 { 617 614 struct cramfs_sb_info *sbi; 618 615 struct cramfs_super super; ··· 626 625 for (i = 0; i < READ_BUFFERS; i++) 627 626 buffer_blocknr[i] = -1; 628 627 629 - err = cramfs_read_super(sb, &super, silent); 628 + err = cramfs_read_super(sb, fc, &super); 630 629 if (err) 631 630 return err; 632 631 return cramfs_finalize_super(sb, &super.root); 633 632 } 634 633 635 - static int cramfs_mtd_fill_super(struct super_block *sb, void *data, 636 - int silent) 634 + static int cramfs_mtd_fill_super(struct super_block *sb, struct fs_context *fc) 637 635 { 638 636 struct cramfs_sb_info *sbi; 639 637 struct cramfs_super super; ··· 654 654 655 655 pr_info("checking physical address %pap for linear cramfs image\n", 656 656 &sbi->linear_phys_addr); 657 - err = cramfs_read_super(sb, &super, silent); 657 + err = cramfs_read_super(sb, fc, &super); 658 658 if (err) 659 659 return err; 660 660 ··· 949 949 }; 950 950 951 951 static const struct super_operations cramfs_ops = { 952 - .remount_fs = cramfs_remount, 953 952 .statfs = cramfs_statfs, 954 953 }; 955 954 956 - static struct dentry *cramfs_mount(struct file_system_type *fs_type, int flags, 957 - const char *dev_name, void *data) 955 + static int cramfs_get_tree(struct fs_context *fc) 958 956 { 959 - struct dentry *ret = ERR_PTR(-ENOPROTOOPT); 957 + int ret = -ENOPROTOOPT; 960 958 961 959 if (IS_ENABLED(CONFIG_CRAMFS_MTD)) { 962 - ret = mount_mtd(fs_type, flags, dev_name, data, 963 - cramfs_mtd_fill_super); 964 - if (!IS_ERR(ret)) 960 + ret = get_tree_mtd(fc, cramfs_mtd_fill_super); 961 + if (ret < 0) 965 962 return ret; 966 963 } 967 - if (IS_ENABLED(CONFIG_CRAMFS_BLOCKDEV)) { 968 - ret = mount_bdev(fs_type, flags, dev_name, data, 969 - cramfs_blkdev_fill_super); 970 - } 964 + if (IS_ENABLED(CONFIG_CRAMFS_BLOCKDEV)) 965 + ret = get_tree_bdev(fc, cramfs_blkdev_fill_super); 971 966 return ret; 967 + } 968 + 969 + static const struct fs_context_operations cramfs_context_ops = { 970 + .get_tree = cramfs_get_tree, 971 + .reconfigure = cramfs_reconfigure, 972 + }; 973 + 974 + /* 975 + * Set up the filesystem mount context. 976 + */ 977 + static int cramfs_init_fs_context(struct fs_context *fc) 978 + { 979 + fc->ops = &cramfs_context_ops; 980 + return 0; 972 981 } 973 982 974 983 static struct file_system_type cramfs_fs_type = { 975 984 .owner = THIS_MODULE, 976 985 .name = "cramfs", 977 - .mount = cramfs_mount, 986 + .init_fs_context = cramfs_init_fs_context, 978 987 .kill_sb = cramfs_kill_sb, 979 988 .fs_flags = FS_REQUIRES_DEV, 980 989 };
+16 -2
fs/fs_parser.c
··· 204 204 goto okay; 205 205 206 206 case fs_param_is_fd: { 207 - if (param->type != fs_value_is_file) 207 + switch (param->type) { 208 + case fs_value_is_string: 209 + if (!result->has_value) 210 + goto bad_value; 211 + 212 + ret = kstrtouint(param->string, 0, &result->uint_32); 213 + break; 214 + case fs_value_is_file: 215 + result->uint_32 = param->dirfd; 216 + ret = 0; 217 + default: 208 218 goto bad_value; 209 - goto okay; 219 + } 220 + 221 + if (result->uint_32 > INT_MAX) 222 + goto bad_value; 223 + goto maybe_okay; 210 224 } 211 225 212 226 case fs_param_is_blockdev:
+11 -10
fs/jffs2/fs.c
··· 17 17 #include <linux/sched.h> 18 18 #include <linux/cred.h> 19 19 #include <linux/fs.h> 20 + #include <linux/fs_context.h> 20 21 #include <linux/list.h> 21 22 #include <linux/mtd/mtd.h> 22 23 #include <linux/pagemap.h> ··· 185 184 if (ivalid & ATTR_SIZE && inode->i_size > iattr->ia_size) { 186 185 truncate_setsize(inode, iattr->ia_size); 187 186 inode->i_blocks = (inode->i_size + 511) >> 9; 188 - } 187 + } 189 188 190 189 return 0; 191 190 } ··· 392 391 jffs2_do_setattr(inode, &iattr); 393 392 } 394 393 395 - int jffs2_do_remount_fs(struct super_block *sb, int *flags, char *data) 394 + int jffs2_do_remount_fs(struct super_block *sb, struct fs_context *fc) 396 395 { 397 396 struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); 398 397 ··· 410 409 mutex_unlock(&c->alloc_sem); 411 410 } 412 411 413 - if (!(*flags & SB_RDONLY)) 412 + if (!(fc->sb_flags & SB_RDONLY)) 414 413 jffs2_start_garbage_collect_thread(c); 415 414 416 - *flags |= SB_NOATIME; 415 + fc->sb_flags |= SB_NOATIME; 417 416 return 0; 418 417 } 419 418 ··· 510 509 return hashsize; 511 510 } 512 511 513 - int jffs2_do_fill_super(struct super_block *sb, void *data, int silent) 512 + int jffs2_do_fill_super(struct super_block *sb, struct fs_context *fc) 514 513 { 515 514 struct jffs2_sb_info *c; 516 515 struct inode *root_i; ··· 525 524 526 525 #ifndef CONFIG_JFFS2_FS_WRITEBUFFER 527 526 if (c->mtd->type == MTD_NANDFLASH) { 528 - pr_err("Cannot operate on NAND flash unless jffs2 NAND support is compiled in\n"); 527 + errorf(fc, "Cannot operate on NAND flash unless jffs2 NAND support is compiled in"); 529 528 return -EINVAL; 530 529 } 531 530 if (c->mtd->type == MTD_DATAFLASH) { 532 - pr_err("Cannot operate on DataFlash unless jffs2 DataFlash support is compiled in\n"); 531 + errorf(fc, "Cannot operate on DataFlash unless jffs2 DataFlash support is compiled in"); 533 532 return -EINVAL; 534 533 } 535 534 #endif ··· 543 542 */ 544 543 if ((c->sector_size * blocks) != c->flash_size) { 545 544 c->flash_size = c->sector_size * blocks; 546 - pr_info("Flash size not aligned to erasesize, reducing to %dKiB\n", 547 - c->flash_size / 1024); 545 + infof(fc, "Flash size not aligned to erasesize, reducing to %dKiB", 546 + c->flash_size / 1024); 548 547 } 549 548 550 549 if (c->flash_size < 5*c->sector_size) { 551 - pr_err("Too few erase blocks (%d)\n", 550 + errorf(fc, "Too few erase blocks (%d)", 552 551 c->flash_size / c->sector_size); 553 552 return -EINVAL; 554 553 }
+2 -2
fs/jffs2/os-linux.h
··· 172 172 struct inode *jffs2_new_inode (struct inode *dir_i, umode_t mode, 173 173 struct jffs2_raw_inode *ri); 174 174 int jffs2_statfs (struct dentry *, struct kstatfs *); 175 - int jffs2_do_remount_fs(struct super_block *, int *, char *); 176 - int jffs2_do_fill_super(struct super_block *sb, void *data, int silent); 175 + int jffs2_do_remount_fs(struct super_block *sb, struct fs_context *fc); 176 + int jffs2_do_fill_super(struct super_block *sb, struct fs_context *fc); 177 177 void jffs2_gc_release_inode(struct jffs2_sb_info *c, 178 178 struct jffs2_inode_info *f); 179 179 struct jffs2_inode_info *jffs2_gc_fetch_inode(struct jffs2_sb_info *c,
+83 -89
fs/jffs2/super.c
··· 19 19 #include <linux/fs.h> 20 20 #include <linux/err.h> 21 21 #include <linux/mount.h> 22 - #include <linux/parser.h> 22 + #include <linux/fs_context.h> 23 + #include <linux/fs_parser.h> 23 24 #include <linux/jffs2.h> 24 25 #include <linux/pagemap.h> 25 26 #include <linux/mtd/super.h> ··· 158 157 /* 159 158 * JFFS2 mount options. 160 159 * 160 + * Opt_source: The source device 161 161 * Opt_override_compr: override default compressor 162 162 * Opt_rp_size: size of reserved pool in KiB 163 - * Opt_err: just end of array marker 164 163 */ 165 164 enum { 165 + Opt_source, 166 166 Opt_override_compr, 167 167 Opt_rp_size, 168 - Opt_err, 169 168 }; 170 169 171 - static const match_table_t tokens = { 172 - {Opt_override_compr, "compr=%s"}, 173 - {Opt_rp_size, "rp_size=%u"}, 174 - {Opt_err, NULL}, 170 + static const struct fs_parameter_spec jffs2_param_specs[] = { 171 + fsparam_string ("source", Opt_source), 172 + fsparam_enum ("compr", Opt_override_compr), 173 + fsparam_u32 ("rp_size", Opt_rp_size), 174 + {} 175 175 }; 176 176 177 - static int jffs2_parse_options(struct jffs2_sb_info *c, char *data) 178 - { 179 - substring_t args[MAX_OPT_ARGS]; 180 - char *p, *name; 181 - unsigned int opt; 182 - 183 - if (!data) 184 - return 0; 185 - 186 - while ((p = strsep(&data, ","))) { 187 - int token; 188 - 189 - if (!*p) 190 - continue; 191 - 192 - token = match_token(p, tokens, args); 193 - switch (token) { 194 - case Opt_override_compr: 195 - name = match_strdup(&args[0]); 196 - 197 - if (!name) 198 - return -ENOMEM; 199 - if (!strcmp(name, "none")) 200 - c->mount_opts.compr = JFFS2_COMPR_MODE_NONE; 177 + static const struct fs_parameter_enum jffs2_param_enums[] = { 178 + { Opt_override_compr, "none", JFFS2_COMPR_MODE_NONE }, 201 179 #ifdef CONFIG_JFFS2_LZO 202 - else if (!strcmp(name, "lzo")) 203 - c->mount_opts.compr = JFFS2_COMPR_MODE_FORCELZO; 180 + { Opt_override_compr, "lzo", JFFS2_COMPR_MODE_FORCELZO }, 204 181 #endif 205 182 #ifdef CONFIG_JFFS2_ZLIB 206 - else if (!strcmp(name, "zlib")) 207 - c->mount_opts.compr = 208 - JFFS2_COMPR_MODE_FORCEZLIB; 183 + { Opt_override_compr, "zlib", JFFS2_COMPR_MODE_FORCEZLIB }, 209 184 #endif 210 - else { 211 - pr_err("Error: unknown compressor \"%s\"\n", 212 - name); 213 - kfree(name); 214 - return -EINVAL; 215 - } 216 - kfree(name); 217 - c->mount_opts.override_compr = true; 218 - break; 219 - case Opt_rp_size: 220 - if (match_int(&args[0], &opt)) 221 - return -EINVAL; 222 - opt *= 1024; 223 - if (opt > c->mtd->size) { 224 - pr_warn("Too large reserve pool specified, max " 225 - "is %llu KB\n", c->mtd->size / 1024); 226 - return -EINVAL; 227 - } 228 - c->mount_opts.rp_size = opt; 229 - break; 230 - default: 231 - pr_err("Error: unrecognized mount option '%s' or missing value\n", 232 - p); 233 - return -EINVAL; 234 - } 185 + {} 186 + }; 187 + 188 + const struct fs_parameter_description jffs2_fs_parameters = { 189 + .name = "jffs2", 190 + .specs = jffs2_param_specs, 191 + .enums = jffs2_param_enums, 192 + }; 193 + 194 + static int jffs2_parse_param(struct fs_context *fc, struct fs_parameter *param) 195 + { 196 + struct fs_parse_result result; 197 + struct jffs2_sb_info *c = fc->s_fs_info; 198 + int opt; 199 + 200 + opt = fs_parse(fc, &jffs2_fs_parameters, param, &result); 201 + if (opt < 0) 202 + return opt; 203 + 204 + switch (opt) { 205 + case Opt_override_compr: 206 + c->mount_opts.compr = result.uint_32; 207 + c->mount_opts.override_compr = true; 208 + break; 209 + case Opt_rp_size: 210 + if (result.uint_32 > UINT_MAX / 1024) 211 + return invalf(fc, "jffs2: rp_size unrepresentable"); 212 + opt = result.uint_32 * 1024; 213 + if (opt > c->mtd->size) 214 + return invalf(fc, "jffs2: Too large reserve pool specified, max is %llu KB", 215 + c->mtd->size / 1024); 216 + c->mount_opts.rp_size = opt; 217 + break; 218 + default: 219 + return -EINVAL; 235 220 } 236 221 237 222 return 0; 238 223 } 239 224 240 - static int jffs2_remount_fs(struct super_block *sb, int *flags, char *data) 225 + static int jffs2_reconfigure(struct fs_context *fc) 241 226 { 242 - struct jffs2_sb_info *c = JFFS2_SB_INFO(sb); 243 - int err; 227 + struct super_block *sb = fc->root->d_sb; 244 228 245 229 sync_filesystem(sb); 246 - err = jffs2_parse_options(c, data); 247 - if (err) 248 - return -EINVAL; 249 - 250 - return jffs2_do_remount_fs(sb, flags, data); 230 + return jffs2_do_remount_fs(sb, fc); 251 231 } 252 232 253 233 static const struct super_operations jffs2_super_operations = ··· 237 255 .free_inode = jffs2_free_inode, 238 256 .put_super = jffs2_put_super, 239 257 .statfs = jffs2_statfs, 240 - .remount_fs = jffs2_remount_fs, 241 258 .evict_inode = jffs2_evict_inode, 242 259 .dirty_inode = jffs2_dirty_inode, 243 260 .show_options = jffs2_show_options, ··· 246 265 /* 247 266 * fill in the superblock 248 267 */ 249 - static int jffs2_fill_super(struct super_block *sb, void *data, int silent) 268 + static int jffs2_fill_super(struct super_block *sb, struct fs_context *fc) 250 269 { 251 - struct jffs2_sb_info *c; 252 - int ret; 270 + struct jffs2_sb_info *c = sb->s_fs_info; 253 271 254 272 jffs2_dbg(1, "jffs2_get_sb_mtd():" 255 273 " New superblock for device %d (\"%s\")\n", 256 274 sb->s_mtd->index, sb->s_mtd->name); 257 275 258 - c = kzalloc(sizeof(*c), GFP_KERNEL); 259 - if (!c) 260 - return -ENOMEM; 261 - 262 276 c->mtd = sb->s_mtd; 263 277 c->os_priv = sb; 264 - sb->s_fs_info = c; 265 - 266 - ret = jffs2_parse_options(c, data); 267 - if (ret) 268 - return -EINVAL; 269 278 270 279 /* Initialize JFFS2 superblock locks, the further initialization will 271 280 * be done later */ ··· 273 302 #ifdef CONFIG_JFFS2_FS_POSIX_ACL 274 303 sb->s_flags |= SB_POSIXACL; 275 304 #endif 276 - ret = jffs2_do_fill_super(sb, data, silent); 277 - return ret; 305 + return jffs2_do_fill_super(sb, fc); 278 306 } 279 307 280 - static struct dentry *jffs2_mount(struct file_system_type *fs_type, 281 - int flags, const char *dev_name, 282 - void *data) 308 + static int jffs2_get_tree(struct fs_context *fc) 283 309 { 284 - return mount_mtd(fs_type, flags, dev_name, data, jffs2_fill_super); 310 + return get_tree_mtd(fc, jffs2_fill_super); 311 + } 312 + 313 + static void jffs2_free_fc(struct fs_context *fc) 314 + { 315 + kfree(fc->s_fs_info); 316 + } 317 + 318 + static const struct fs_context_operations jffs2_context_ops = { 319 + .free = jffs2_free_fc, 320 + .parse_param = jffs2_parse_param, 321 + .get_tree = jffs2_get_tree, 322 + .reconfigure = jffs2_reconfigure, 323 + }; 324 + 325 + static int jffs2_init_fs_context(struct fs_context *fc) 326 + { 327 + struct jffs2_sb_info *ctx; 328 + 329 + ctx = kzalloc(sizeof(struct jffs2_sb_info), GFP_KERNEL); 330 + if (!ctx) 331 + return -ENOMEM; 332 + 333 + fc->s_fs_info = ctx; 334 + fc->ops = &jffs2_context_ops; 335 + return 0; 285 336 } 286 337 287 338 static void jffs2_put_super (struct super_block *sb) ··· 340 347 static struct file_system_type jffs2_fs_type = { 341 348 .owner = THIS_MODULE, 342 349 .name = "jffs2", 343 - .mount = jffs2_mount, 350 + .init_fs_context = jffs2_init_fs_context, 351 + .parameters = &jffs2_fs_parameters, 344 352 .kill_sb = jffs2_kill_sb, 345 353 }; 346 354 MODULE_ALIAS_FS("jffs2");
+57 -40
fs/ramfs/inode.c
··· 36 36 #include <linux/magic.h> 37 37 #include <linux/slab.h> 38 38 #include <linux/uaccess.h> 39 + #include <linux/fs_context.h> 40 + #include <linux/fs_parser.h> 39 41 #include "internal.h" 40 42 41 43 struct ramfs_mount_opts { ··· 177 175 .show_options = ramfs_show_options, 178 176 }; 179 177 180 - enum { 178 + enum ramfs_param { 181 179 Opt_mode, 182 - Opt_err 183 180 }; 184 181 185 - static const match_table_t tokens = { 186 - {Opt_mode, "mode=%o"}, 187 - {Opt_err, NULL} 182 + static const struct fs_parameter_spec ramfs_param_specs[] = { 183 + fsparam_u32oct("mode", Opt_mode), 184 + {} 188 185 }; 189 186 190 - static int ramfs_parse_options(char *data, struct ramfs_mount_opts *opts) 187 + const struct fs_parameter_description ramfs_fs_parameters = { 188 + .name = "ramfs", 189 + .specs = ramfs_param_specs, 190 + }; 191 + 192 + static int ramfs_parse_param(struct fs_context *fc, struct fs_parameter *param) 191 193 { 192 - substring_t args[MAX_OPT_ARGS]; 193 - int option; 194 - int token; 195 - char *p; 194 + struct fs_parse_result result; 195 + struct ramfs_fs_info *fsi = fc->s_fs_info; 196 + int opt; 196 197 197 - opts->mode = RAMFS_DEFAULT_MODE; 198 - 199 - while ((p = strsep(&data, ",")) != NULL) { 200 - if (!*p) 201 - continue; 202 - 203 - token = match_token(p, tokens, args); 204 - switch (token) { 205 - case Opt_mode: 206 - if (match_octal(&args[0], &option)) 207 - return -EINVAL; 208 - opts->mode = option & S_IALLUGO; 209 - break; 198 + opt = fs_parse(fc, &ramfs_fs_parameters, param, &result); 199 + if (opt < 0) { 210 200 /* 211 201 * We might like to report bad mount options here; 212 202 * but traditionally ramfs has ignored all mount options, 213 203 * and as it is used as a !CONFIG_SHMEM simple substitute 214 204 * for tmpfs, better continue to ignore other mount options. 215 205 */ 216 - } 206 + if (opt == -ENOPARAM) 207 + opt = 0; 208 + return opt; 209 + } 210 + 211 + switch (opt) { 212 + case Opt_mode: 213 + fsi->mount_opts.mode = result.uint_32 & S_IALLUGO; 214 + break; 217 215 } 218 216 219 217 return 0; 220 218 } 221 219 222 - int ramfs_fill_super(struct super_block *sb, void *data, int silent) 220 + static int ramfs_fill_super(struct super_block *sb, struct fs_context *fc) 223 221 { 224 - struct ramfs_fs_info *fsi; 222 + struct ramfs_fs_info *fsi = sb->s_fs_info; 225 223 struct inode *inode; 226 - int err; 227 - 228 - fsi = kzalloc(sizeof(struct ramfs_fs_info), GFP_KERNEL); 229 - sb->s_fs_info = fsi; 230 - if (!fsi) 231 - return -ENOMEM; 232 - 233 - err = ramfs_parse_options(data, &fsi->mount_opts); 234 - if (err) 235 - return err; 236 224 237 225 sb->s_maxbytes = MAX_LFS_FILESIZE; 238 226 sb->s_blocksize = PAGE_SIZE; ··· 239 247 return 0; 240 248 } 241 249 242 - struct dentry *ramfs_mount(struct file_system_type *fs_type, 243 - int flags, const char *dev_name, void *data) 250 + static int ramfs_get_tree(struct fs_context *fc) 244 251 { 245 - return mount_nodev(fs_type, flags, data, ramfs_fill_super); 252 + return get_tree_nodev(fc, ramfs_fill_super); 253 + } 254 + 255 + static void ramfs_free_fc(struct fs_context *fc) 256 + { 257 + kfree(fc->s_fs_info); 258 + } 259 + 260 + static const struct fs_context_operations ramfs_context_ops = { 261 + .free = ramfs_free_fc, 262 + .parse_param = ramfs_parse_param, 263 + .get_tree = ramfs_get_tree, 264 + }; 265 + 266 + int ramfs_init_fs_context(struct fs_context *fc) 267 + { 268 + struct ramfs_fs_info *fsi; 269 + 270 + fsi = kzalloc(sizeof(*fsi), GFP_KERNEL); 271 + if (!fsi) 272 + return -ENOMEM; 273 + 274 + fsi->mount_opts.mode = RAMFS_DEFAULT_MODE; 275 + fc->s_fs_info = fsi; 276 + fc->ops = &ramfs_context_ops; 277 + return 0; 246 278 } 247 279 248 280 static void ramfs_kill_sb(struct super_block *sb) ··· 277 261 278 262 static struct file_system_type ramfs_fs_type = { 279 263 .name = "ramfs", 280 - .mount = ramfs_mount, 264 + .init_fs_context = ramfs_init_fs_context, 265 + .parameters = &ramfs_fs_parameters, 281 266 .kill_sb = ramfs_kill_sb, 282 267 .fs_flags = FS_USERNS_MOUNT, 283 268 };
+28 -18
fs/romfs/super.c
··· 65 65 #include <linux/slab.h> 66 66 #include <linux/init.h> 67 67 #include <linux/blkdev.h> 68 - #include <linux/parser.h> 68 + #include <linux/fs_context.h> 69 69 #include <linux/mount.h> 70 70 #include <linux/namei.h> 71 71 #include <linux/statfs.h> ··· 423 423 /* 424 424 * remounting must involve read-only 425 425 */ 426 - static int romfs_remount(struct super_block *sb, int *flags, char *data) 426 + static int romfs_reconfigure(struct fs_context *fc) 427 427 { 428 - sync_filesystem(sb); 429 - *flags |= SB_RDONLY; 428 + sync_filesystem(fc->root->d_sb); 429 + fc->sb_flags |= SB_RDONLY; 430 430 return 0; 431 431 } 432 432 ··· 434 434 .alloc_inode = romfs_alloc_inode, 435 435 .free_inode = romfs_free_inode, 436 436 .statfs = romfs_statfs, 437 - .remount_fs = romfs_remount, 438 437 }; 439 438 440 439 /* ··· 456 457 /* 457 458 * fill in the superblock 458 459 */ 459 - static int romfs_fill_super(struct super_block *sb, void *data, int silent) 460 + static int romfs_fill_super(struct super_block *sb, struct fs_context *fc) 460 461 { 461 462 struct romfs_super_block *rsb; 462 463 struct inode *root; ··· 505 506 506 507 if (rsb->word0 != ROMSB_WORD0 || rsb->word1 != ROMSB_WORD1 || 507 508 img_size < ROMFH_SIZE) { 508 - if (!silent) 509 - pr_warn("VFS: Can't find a romfs filesystem on dev %s.\n", 509 + if (!(fc->sb_flags & SB_SILENT)) 510 + errorf(fc, "VFS: Can't find a romfs filesystem on dev %s.\n", 510 511 sb->s_id); 511 512 goto error_rsb_inval; 512 513 } ··· 519 520 storage = sb->s_mtd ? "MTD" : "the block layer"; 520 521 521 522 len = strnlen(rsb->name, ROMFS_MAXFN); 522 - if (!silent) 523 + if (!(fc->sb_flags & SB_SILENT)) 523 524 pr_notice("Mounting image '%*.*s' through %s\n", 524 525 (unsigned) len, (unsigned) len, rsb->name, storage); 525 526 ··· 549 550 /* 550 551 * get a superblock for mounting 551 552 */ 552 - static struct dentry *romfs_mount(struct file_system_type *fs_type, 553 - int flags, const char *dev_name, 554 - void *data) 553 + static int romfs_get_tree(struct fs_context *fc) 555 554 { 556 - struct dentry *ret = ERR_PTR(-EINVAL); 555 + int ret = -EINVAL; 557 556 558 557 #ifdef CONFIG_ROMFS_ON_MTD 559 - ret = mount_mtd(fs_type, flags, dev_name, data, romfs_fill_super); 558 + ret = get_tree_mtd(fc, romfs_fill_super); 560 559 #endif 561 560 #ifdef CONFIG_ROMFS_ON_BLOCK 562 - if (ret == ERR_PTR(-EINVAL)) 563 - ret = mount_bdev(fs_type, flags, dev_name, data, 564 - romfs_fill_super); 561 + if (ret == -EINVAL) 562 + ret = get_tree_bdev(fc, romfs_fill_super); 565 563 #endif 566 564 return ret; 565 + } 566 + 567 + static const struct fs_context_operations romfs_context_ops = { 568 + .get_tree = romfs_get_tree, 569 + .reconfigure = romfs_reconfigure, 570 + }; 571 + 572 + /* 573 + * Set up the filesystem mount context. 574 + */ 575 + static int romfs_init_fs_context(struct fs_context *fc) 576 + { 577 + fc->ops = &romfs_context_ops; 578 + return 0; 567 579 } 568 580 569 581 /* ··· 599 589 static struct file_system_type romfs_fs_type = { 600 590 .owner = THIS_MODULE, 601 591 .name = "romfs", 602 - .mount = romfs_mount, 592 + .init_fs_context = romfs_init_fs_context, 603 593 .kill_sb = romfs_kill_sb, 604 594 .fs_flags = FS_REQUIRES_DEV, 605 595 };
+55 -45
fs/squashfs/super.c
··· 17 17 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 18 18 19 19 #include <linux/fs.h> 20 + #include <linux/fs_context.h> 20 21 #include <linux/vfs.h> 21 22 #include <linux/slab.h> 22 23 #include <linux/mutex.h> ··· 37 36 static struct file_system_type squashfs_fs_type; 38 37 static const struct super_operations squashfs_super_ops; 39 38 40 - static const struct squashfs_decompressor *supported_squashfs_filesystem(short 41 - major, short minor, short id) 39 + static const struct squashfs_decompressor *supported_squashfs_filesystem( 40 + struct fs_context *fc, 41 + short major, short minor, short id) 42 42 { 43 43 const struct squashfs_decompressor *decompressor; 44 44 45 45 if (major < SQUASHFS_MAJOR) { 46 - ERROR("Major/Minor mismatch, older Squashfs %d.%d " 47 - "filesystems are unsupported\n", major, minor); 46 + errorf(fc, "Major/Minor mismatch, older Squashfs %d.%d " 47 + "filesystems are unsupported", major, minor); 48 48 return NULL; 49 49 } else if (major > SQUASHFS_MAJOR || minor > SQUASHFS_MINOR) { 50 - ERROR("Major/Minor mismatch, trying to mount newer " 51 - "%d.%d filesystem\n", major, minor); 52 - ERROR("Please update your kernel\n"); 50 + errorf(fc, "Major/Minor mismatch, trying to mount newer " 51 + "%d.%d filesystem", major, minor); 52 + errorf(fc, "Please update your kernel"); 53 53 return NULL; 54 54 } 55 55 56 56 decompressor = squashfs_lookup_decompressor(id); 57 57 if (!decompressor->supported) { 58 - ERROR("Filesystem uses \"%s\" compression. This is not " 59 - "supported\n", decompressor->name); 58 + errorf(fc, "Filesystem uses \"%s\" compression. This is not supported", 59 + decompressor->name); 60 60 return NULL; 61 61 } 62 62 ··· 65 63 } 66 64 67 65 68 - static int squashfs_fill_super(struct super_block *sb, void *data, int silent) 66 + static int squashfs_fill_super(struct super_block *sb, struct fs_context *fc) 69 67 { 70 68 struct squashfs_sb_info *msblk; 71 69 struct squashfs_super_block *sblk = NULL; ··· 100 98 sblk = squashfs_read_table(sb, SQUASHFS_START, sizeof(*sblk)); 101 99 102 100 if (IS_ERR(sblk)) { 103 - ERROR("unable to read squashfs_super_block\n"); 101 + errorf(fc, "unable to read squashfs_super_block"); 104 102 err = PTR_ERR(sblk); 105 103 sblk = NULL; 106 104 goto failed_mount; ··· 111 109 /* Check it is a SQUASHFS superblock */ 112 110 sb->s_magic = le32_to_cpu(sblk->s_magic); 113 111 if (sb->s_magic != SQUASHFS_MAGIC) { 114 - if (!silent) 115 - ERROR("Can't find a SQUASHFS superblock on %pg\n", 116 - sb->s_bdev); 112 + if (!(fc->sb_flags & SB_SILENT)) 113 + errorf(fc, "Can't find a SQUASHFS superblock on %pg", 114 + sb->s_bdev); 117 115 goto failed_mount; 118 116 } 119 117 120 118 /* Check the MAJOR & MINOR versions and lookup compression type */ 121 119 msblk->decompressor = supported_squashfs_filesystem( 120 + fc, 122 121 le16_to_cpu(sblk->s_major), 123 122 le16_to_cpu(sblk->s_minor), 124 123 le16_to_cpu(sblk->compression)); ··· 136 133 /* Check block size for sanity */ 137 134 msblk->block_size = le32_to_cpu(sblk->block_size); 138 135 if (msblk->block_size > SQUASHFS_FILE_MAX_SIZE) 139 - goto failed_mount; 136 + goto insanity; 140 137 141 138 /* 142 139 * Check the system page size is not larger than the filesystem 143 140 * block size (by default 128K). This is currently not supported. 144 141 */ 145 142 if (PAGE_SIZE > msblk->block_size) { 146 - ERROR("Page size > filesystem block size (%d). This is " 147 - "currently not supported!\n", msblk->block_size); 143 + errorf(fc, "Page size > filesystem block size (%d). This is " 144 + "currently not supported!", msblk->block_size); 148 145 goto failed_mount; 149 146 } 150 147 ··· 155 152 156 153 /* Check that block_size and block_log match */ 157 154 if (msblk->block_size != (1 << msblk->block_log)) 158 - goto failed_mount; 155 + goto insanity; 159 156 160 157 /* Check the root inode for sanity */ 161 158 root_inode = le64_to_cpu(sblk->root_inode); 162 159 if (SQUASHFS_INODE_OFFSET(root_inode) > SQUASHFS_METADATA_SIZE) 163 - goto failed_mount; 160 + goto insanity; 164 161 165 162 msblk->inode_table = le64_to_cpu(sblk->inode_table_start); 166 163 msblk->directory_table = le64_to_cpu(sblk->directory_table_start); ··· 202 199 msblk->read_page = squashfs_cache_init("data", 203 200 squashfs_max_decompressors(), msblk->block_size); 204 201 if (msblk->read_page == NULL) { 205 - ERROR("Failed to allocate read_page block\n"); 202 + errorf(fc, "Failed to allocate read_page block"); 206 203 goto failed_mount; 207 204 } 208 205 ··· 210 207 if (IS_ERR(msblk->stream)) { 211 208 err = PTR_ERR(msblk->stream); 212 209 msblk->stream = NULL; 213 - goto failed_mount; 210 + goto insanity; 214 211 } 215 212 216 213 /* Handle xattrs */ ··· 225 222 msblk->xattr_id_table = squashfs_read_xattr_id_table(sb, 226 223 xattr_id_table_start, &msblk->xattr_table, &msblk->xattr_ids); 227 224 if (IS_ERR(msblk->xattr_id_table)) { 228 - ERROR("unable to read xattr id index table\n"); 225 + errorf(fc, "unable to read xattr id index table"); 229 226 err = PTR_ERR(msblk->xattr_id_table); 230 227 msblk->xattr_id_table = NULL; 231 228 if (err != -ENOTSUPP) ··· 239 236 le64_to_cpu(sblk->id_table_start), next_table, 240 237 le16_to_cpu(sblk->no_ids)); 241 238 if (IS_ERR(msblk->id_table)) { 242 - ERROR("unable to read id index table\n"); 239 + errorf(fc, "unable to read id index table"); 243 240 err = PTR_ERR(msblk->id_table); 244 241 msblk->id_table = NULL; 245 242 goto failed_mount; ··· 255 252 msblk->inode_lookup_table = squashfs_read_inode_lookup_table(sb, 256 253 lookup_table_start, next_table, msblk->inodes); 257 254 if (IS_ERR(msblk->inode_lookup_table)) { 258 - ERROR("unable to read inode lookup table\n"); 255 + errorf(fc, "unable to read inode lookup table"); 259 256 err = PTR_ERR(msblk->inode_lookup_table); 260 257 msblk->inode_lookup_table = NULL; 261 258 goto failed_mount; ··· 280 277 msblk->fragment_index = squashfs_read_fragment_index_table(sb, 281 278 le64_to_cpu(sblk->fragment_table_start), next_table, fragments); 282 279 if (IS_ERR(msblk->fragment_index)) { 283 - ERROR("unable to read fragment index table\n"); 280 + errorf(fc, "unable to read fragment index table"); 284 281 err = PTR_ERR(msblk->fragment_index); 285 282 msblk->fragment_index = NULL; 286 283 goto failed_mount; ··· 291 288 /* Sanity check directory_table */ 292 289 if (msblk->directory_table > next_table) { 293 290 err = -EINVAL; 294 - goto failed_mount; 291 + goto insanity; 295 292 } 296 293 297 294 /* Sanity check inode_table */ 298 295 if (msblk->inode_table >= msblk->directory_table) { 299 296 err = -EINVAL; 300 - goto failed_mount; 297 + goto insanity; 301 298 } 302 299 303 300 /* allocate root */ ··· 326 323 kfree(sblk); 327 324 return 0; 328 325 326 + insanity: 327 + errorf(fc, "squashfs image failed sanity check"); 329 328 failed_mount: 330 329 squashfs_cache_delete(msblk->block_cache); 331 330 squashfs_cache_delete(msblk->fragment_cache); ··· 343 338 return err; 344 339 } 345 340 341 + static int squashfs_get_tree(struct fs_context *fc) 342 + { 343 + return get_tree_bdev(fc, squashfs_fill_super); 344 + } 345 + 346 + static int squashfs_reconfigure(struct fs_context *fc) 347 + { 348 + sync_filesystem(fc->root->d_sb); 349 + fc->sb_flags |= SB_RDONLY; 350 + return 0; 351 + } 352 + 353 + static const struct fs_context_operations squashfs_context_ops = { 354 + .get_tree = squashfs_get_tree, 355 + .reconfigure = squashfs_reconfigure, 356 + }; 357 + 358 + static int squashfs_init_fs_context(struct fs_context *fc) 359 + { 360 + fc->ops = &squashfs_context_ops; 361 + return 0; 362 + } 346 363 347 364 static int squashfs_statfs(struct dentry *dentry, struct kstatfs *buf) 348 365 { ··· 387 360 } 388 361 389 362 390 - static int squashfs_remount(struct super_block *sb, int *flags, char *data) 391 - { 392 - sync_filesystem(sb); 393 - *flags |= SB_RDONLY; 394 - return 0; 395 - } 396 - 397 - 398 363 static void squashfs_put_super(struct super_block *sb) 399 364 { 400 365 if (sb->s_fs_info) { ··· 404 385 sb->s_fs_info = NULL; 405 386 } 406 387 } 407 - 408 - 409 - static struct dentry *squashfs_mount(struct file_system_type *fs_type, 410 - int flags, const char *dev_name, void *data) 411 - { 412 - return mount_bdev(fs_type, flags, dev_name, data, squashfs_fill_super); 413 - } 414 - 415 388 416 389 static struct kmem_cache *squashfs_inode_cachep; 417 390 ··· 481 470 static struct file_system_type squashfs_fs_type = { 482 471 .owner = THIS_MODULE, 483 472 .name = "squashfs", 484 - .mount = squashfs_mount, 473 + .init_fs_context = squashfs_init_fs_context, 485 474 .kill_sb = kill_block_super, 486 475 .fs_flags = FS_REQUIRES_DEV 487 476 }; ··· 492 481 .free_inode = squashfs_free_inode, 493 482 .statfs = squashfs_statfs, 494 483 .put_super = squashfs_put_super, 495 - .remount_fs = squashfs_remount 496 484 }; 497 485 498 486 module_init(init_squashfs_fs);
+28 -7
fs/super.c
··· 1164 1164 { 1165 1165 int (*test)(struct super_block *, struct fs_context *); 1166 1166 struct super_block *sb; 1167 + int err; 1167 1168 1168 1169 switch (keying) { 1169 1170 case vfs_get_single_super: 1171 + case vfs_get_single_reconf_super: 1170 1172 test = test_single_super; 1171 1173 break; 1172 1174 case vfs_get_keyed_super: ··· 1186 1184 return PTR_ERR(sb); 1187 1185 1188 1186 if (!sb->s_root) { 1189 - int err = fill_super(sb, fc); 1190 - if (err) { 1191 - deactivate_locked_super(sb); 1192 - return err; 1193 - } 1187 + err = fill_super(sb, fc); 1188 + if (err) 1189 + goto error; 1194 1190 1195 1191 sb->s_flags |= SB_ACTIVE; 1192 + fc->root = dget(sb->s_root); 1193 + } else { 1194 + fc->root = dget(sb->s_root); 1195 + if (keying == vfs_get_single_reconf_super) { 1196 + err = reconfigure_super(fc); 1197 + if (err < 0) { 1198 + dput(fc->root); 1199 + fc->root = NULL; 1200 + goto error; 1201 + } 1202 + } 1196 1203 } 1197 1204 1198 - BUG_ON(fc->root); 1199 - fc->root = dget(sb->s_root); 1200 1205 return 0; 1206 + 1207 + error: 1208 + deactivate_locked_super(sb); 1209 + return err; 1201 1210 } 1202 1211 EXPORT_SYMBOL(vfs_get_super); 1203 1212 ··· 1227 1214 return vfs_get_super(fc, vfs_get_single_super, fill_super); 1228 1215 } 1229 1216 EXPORT_SYMBOL(get_tree_single); 1217 + 1218 + int get_tree_single_reconf(struct fs_context *fc, 1219 + int (*fill_super)(struct super_block *sb, 1220 + struct fs_context *fc)) 1221 + { 1222 + return vfs_get_super(fc, vfs_get_single_reconf_super, fill_super); 1223 + } 1224 + EXPORT_SYMBOL(get_tree_single_reconf); 1230 1225 1231 1226 int get_tree_keyed(struct fs_context *fc, 1232 1227 int (*fill_super)(struct super_block *sb,
+4
include/linux/fs_context.h
··· 141 141 */ 142 142 enum vfs_get_super_keying { 143 143 vfs_get_single_super, /* Only one such superblock may exist */ 144 + vfs_get_single_reconf_super, /* As above, but reconfigure if it exists */ 144 145 vfs_get_keyed_super, /* Superblocks with different s_fs_info keys may exist */ 145 146 vfs_get_independent_super, /* Multiple independent superblocks may exist */ 146 147 }; ··· 154 153 int (*fill_super)(struct super_block *sb, 155 154 struct fs_context *fc)); 156 155 extern int get_tree_single(struct fs_context *fc, 156 + int (*fill_super)(struct super_block *sb, 157 + struct fs_context *fc)); 158 + extern int get_tree_single_reconf(struct fs_context *fc, 157 159 int (*fill_super)(struct super_block *sb, 158 160 struct fs_context *fc)); 159 161 extern int get_tree_keyed(struct fs_context *fc,
-3
include/linux/mtd/super.h
··· 17 17 extern int get_tree_mtd(struct fs_context *fc, 18 18 int (*fill_super)(struct super_block *sb, 19 19 struct fs_context *fc)); 20 - extern struct dentry *mount_mtd(struct file_system_type *fs_type, int flags, 21 - const char *dev_name, void *data, 22 - int (*fill_super)(struct super_block *, void *, int)); 23 20 extern void kill_mtd_super(struct super_block *sb); 24 21 25 22
+2 -4
include/linux/ramfs.h
··· 4 4 5 5 struct inode *ramfs_get_inode(struct super_block *sb, const struct inode *dir, 6 6 umode_t mode, dev_t dev); 7 - extern struct dentry *ramfs_mount(struct file_system_type *fs_type, 8 - int flags, const char *dev_name, void *data); 7 + extern int ramfs_init_fs_context(struct fs_context *fc); 9 8 10 9 #ifdef CONFIG_MMU 11 10 static inline int ··· 16 17 extern int ramfs_nommu_expand_for_mapping(struct inode *inode, size_t newsize); 17 18 #endif 18 19 20 + extern const struct fs_parameter_description ramfs_fs_parameters; 19 21 extern const struct file_operations ramfs_file_operations; 20 22 extern const struct vm_operations_struct generic_file_vm_ops; 21 - 22 - int ramfs_fill_super(struct super_block *sb, void *data, int silent); 23 23 24 24 #endif
+2 -1
include/linux/shmem_fs.h
··· 49 49 /* 50 50 * Functions in mm/shmem.c called directly from elsewhere: 51 51 */ 52 + extern const struct fs_parameter_description shmem_fs_parameters; 52 53 extern int shmem_init(void); 53 - extern int shmem_fill_super(struct super_block *sb, void *data, int silent); 54 + extern int shmem_init_fs_context(struct fs_context *fc); 54 55 extern struct file *shmem_file_setup(const char *name, 55 56 loff_t size, unsigned long flags); 56 57 extern struct file *shmem_kernel_file_setup(const char *name, loff_t size,
+4 -7
init/do_mounts.c
··· 627 627 } 628 628 629 629 static bool is_tmpfs; 630 - static struct dentry *rootfs_mount(struct file_system_type *fs_type, 631 - int flags, const char *dev_name, void *data) 630 + static int rootfs_init_fs_context(struct fs_context *fc) 632 631 { 633 - void *fill = ramfs_fill_super; 634 - 635 632 if (IS_ENABLED(CONFIG_TMPFS) && is_tmpfs) 636 - fill = shmem_fill_super; 633 + return shmem_init_fs_context(fc); 637 634 638 - return mount_nodev(fs_type, flags, data, fill); 635 + return ramfs_init_fs_context(fc); 639 636 } 640 637 641 638 struct file_system_type rootfs_fs_type = { 642 639 .name = "rootfs", 643 - .mount = rootfs_mount, 640 + .init_fs_context = rootfs_init_fs_context, 644 641 .kill_sb = kill_litter_super, 645 642 }; 646 643
+247 -136
mm/shmem.c
··· 37 37 #include <linux/khugepaged.h> 38 38 #include <linux/hugetlb.h> 39 39 #include <linux/frontswap.h> 40 + #include <linux/fs_parser.h> 40 41 41 42 #include <asm/tlbflush.h> /* for arch/microblaze update_mmu_cache() */ 42 43 ··· 106 105 pgoff_t next; /* the next page offset to be fallocated */ 107 106 pgoff_t nr_falloced; /* how many new pages have been fallocated */ 108 107 pgoff_t nr_unswapped; /* how often writepage refused to swap out */ 108 + }; 109 + 110 + struct shmem_options { 111 + unsigned long long blocks; 112 + unsigned long long inodes; 113 + struct mempolicy *mpol; 114 + kuid_t uid; 115 + kgid_t gid; 116 + umode_t mode; 117 + int huge; 118 + int seen; 119 + #define SHMEM_SEEN_BLOCKS 1 120 + #define SHMEM_SEEN_INODES 2 121 + #define SHMEM_SEEN_HUGE 4 109 122 }; 110 123 111 124 #ifdef CONFIG_TMPFS ··· 3364 3349 .fh_to_dentry = shmem_fh_to_dentry, 3365 3350 }; 3366 3351 3367 - static int shmem_parse_options(char *options, struct shmem_sb_info *sbinfo, 3368 - bool remount) 3352 + enum shmem_param { 3353 + Opt_gid, 3354 + Opt_huge, 3355 + Opt_mode, 3356 + Opt_mpol, 3357 + Opt_nr_blocks, 3358 + Opt_nr_inodes, 3359 + Opt_size, 3360 + Opt_uid, 3361 + }; 3362 + 3363 + static const struct fs_parameter_spec shmem_param_specs[] = { 3364 + fsparam_u32 ("gid", Opt_gid), 3365 + fsparam_enum ("huge", Opt_huge), 3366 + fsparam_u32oct("mode", Opt_mode), 3367 + fsparam_string("mpol", Opt_mpol), 3368 + fsparam_string("nr_blocks", Opt_nr_blocks), 3369 + fsparam_string("nr_inodes", Opt_nr_inodes), 3370 + fsparam_string("size", Opt_size), 3371 + fsparam_u32 ("uid", Opt_uid), 3372 + {} 3373 + }; 3374 + 3375 + static const struct fs_parameter_enum shmem_param_enums[] = { 3376 + { Opt_huge, "never", SHMEM_HUGE_NEVER }, 3377 + { Opt_huge, "always", SHMEM_HUGE_ALWAYS }, 3378 + { Opt_huge, "within_size", SHMEM_HUGE_WITHIN_SIZE }, 3379 + { Opt_huge, "advise", SHMEM_HUGE_ADVISE }, 3380 + {} 3381 + }; 3382 + 3383 + const struct fs_parameter_description shmem_fs_parameters = { 3384 + .name = "tmpfs", 3385 + .specs = shmem_param_specs, 3386 + .enums = shmem_param_enums, 3387 + }; 3388 + 3389 + static int shmem_parse_one(struct fs_context *fc, struct fs_parameter *param) 3369 3390 { 3370 - char *this_char, *value, *rest; 3371 - struct mempolicy *mpol = NULL; 3372 - uid_t uid; 3373 - gid_t gid; 3391 + struct shmem_options *ctx = fc->fs_private; 3392 + struct fs_parse_result result; 3393 + unsigned long long size; 3394 + char *rest; 3395 + int opt; 3396 + 3397 + opt = fs_parse(fc, &shmem_fs_parameters, param, &result); 3398 + if (opt < 0) 3399 + return opt; 3400 + 3401 + switch (opt) { 3402 + case Opt_size: 3403 + size = memparse(param->string, &rest); 3404 + if (*rest == '%') { 3405 + size <<= PAGE_SHIFT; 3406 + size *= totalram_pages(); 3407 + do_div(size, 100); 3408 + rest++; 3409 + } 3410 + if (*rest) 3411 + goto bad_value; 3412 + ctx->blocks = DIV_ROUND_UP(size, PAGE_SIZE); 3413 + ctx->seen |= SHMEM_SEEN_BLOCKS; 3414 + break; 3415 + case Opt_nr_blocks: 3416 + ctx->blocks = memparse(param->string, &rest); 3417 + if (*rest) 3418 + goto bad_value; 3419 + ctx->seen |= SHMEM_SEEN_BLOCKS; 3420 + break; 3421 + case Opt_nr_inodes: 3422 + ctx->inodes = memparse(param->string, &rest); 3423 + if (*rest) 3424 + goto bad_value; 3425 + ctx->seen |= SHMEM_SEEN_INODES; 3426 + break; 3427 + case Opt_mode: 3428 + ctx->mode = result.uint_32 & 07777; 3429 + break; 3430 + case Opt_uid: 3431 + ctx->uid = make_kuid(current_user_ns(), result.uint_32); 3432 + if (!uid_valid(ctx->uid)) 3433 + goto bad_value; 3434 + break; 3435 + case Opt_gid: 3436 + ctx->gid = make_kgid(current_user_ns(), result.uint_32); 3437 + if (!gid_valid(ctx->gid)) 3438 + goto bad_value; 3439 + break; 3440 + case Opt_huge: 3441 + ctx->huge = result.uint_32; 3442 + if (ctx->huge != SHMEM_HUGE_NEVER && 3443 + !(IS_ENABLED(CONFIG_TRANSPARENT_HUGE_PAGECACHE) && 3444 + has_transparent_hugepage())) 3445 + goto unsupported_parameter; 3446 + ctx->seen |= SHMEM_SEEN_HUGE; 3447 + break; 3448 + case Opt_mpol: 3449 + if (IS_ENABLED(CONFIG_NUMA)) { 3450 + mpol_put(ctx->mpol); 3451 + ctx->mpol = NULL; 3452 + if (mpol_parse_str(param->string, &ctx->mpol)) 3453 + goto bad_value; 3454 + break; 3455 + } 3456 + goto unsupported_parameter; 3457 + } 3458 + return 0; 3459 + 3460 + unsupported_parameter: 3461 + return invalf(fc, "tmpfs: Unsupported parameter '%s'", param->key); 3462 + bad_value: 3463 + return invalf(fc, "tmpfs: Bad value for '%s'", param->key); 3464 + } 3465 + 3466 + static int shmem_parse_options(struct fs_context *fc, void *data) 3467 + { 3468 + char *options = data; 3374 3469 3375 3470 while (options != NULL) { 3376 - this_char = options; 3471 + char *this_char = options; 3377 3472 for (;;) { 3378 3473 /* 3379 3474 * NUL-terminate this option: unfortunately, ··· 3499 3374 break; 3500 3375 } 3501 3376 } 3502 - if (!*this_char) 3503 - continue; 3504 - if ((value = strchr(this_char,'=')) != NULL) { 3505 - *value++ = 0; 3506 - } else { 3507 - pr_err("tmpfs: No value for mount option '%s'\n", 3508 - this_char); 3509 - goto error; 3510 - } 3377 + if (*this_char) { 3378 + char *value = strchr(this_char,'='); 3379 + size_t len = 0; 3380 + int err; 3511 3381 3512 - if (!strcmp(this_char,"size")) { 3513 - unsigned long long size; 3514 - size = memparse(value,&rest); 3515 - if (*rest == '%') { 3516 - size <<= PAGE_SHIFT; 3517 - size *= totalram_pages(); 3518 - do_div(size, 100); 3519 - rest++; 3382 + if (value) { 3383 + *value++ = '\0'; 3384 + len = strlen(value); 3520 3385 } 3521 - if (*rest) 3522 - goto bad_val; 3523 - sbinfo->max_blocks = 3524 - DIV_ROUND_UP(size, PAGE_SIZE); 3525 - } else if (!strcmp(this_char,"nr_blocks")) { 3526 - sbinfo->max_blocks = memparse(value, &rest); 3527 - if (*rest) 3528 - goto bad_val; 3529 - } else if (!strcmp(this_char,"nr_inodes")) { 3530 - sbinfo->max_inodes = memparse(value, &rest); 3531 - if (*rest) 3532 - goto bad_val; 3533 - } else if (!strcmp(this_char,"mode")) { 3534 - if (remount) 3535 - continue; 3536 - sbinfo->mode = simple_strtoul(value, &rest, 8) & 07777; 3537 - if (*rest) 3538 - goto bad_val; 3539 - } else if (!strcmp(this_char,"uid")) { 3540 - if (remount) 3541 - continue; 3542 - uid = simple_strtoul(value, &rest, 0); 3543 - if (*rest) 3544 - goto bad_val; 3545 - sbinfo->uid = make_kuid(current_user_ns(), uid); 3546 - if (!uid_valid(sbinfo->uid)) 3547 - goto bad_val; 3548 - } else if (!strcmp(this_char,"gid")) { 3549 - if (remount) 3550 - continue; 3551 - gid = simple_strtoul(value, &rest, 0); 3552 - if (*rest) 3553 - goto bad_val; 3554 - sbinfo->gid = make_kgid(current_user_ns(), gid); 3555 - if (!gid_valid(sbinfo->gid)) 3556 - goto bad_val; 3557 - #ifdef CONFIG_TRANSPARENT_HUGE_PAGECACHE 3558 - } else if (!strcmp(this_char, "huge")) { 3559 - int huge; 3560 - huge = shmem_parse_huge(value); 3561 - if (huge < 0) 3562 - goto bad_val; 3563 - if (!has_transparent_hugepage() && 3564 - huge != SHMEM_HUGE_NEVER) 3565 - goto bad_val; 3566 - sbinfo->huge = huge; 3567 - #endif 3568 - #ifdef CONFIG_NUMA 3569 - } else if (!strcmp(this_char,"mpol")) { 3570 - mpol_put(mpol); 3571 - mpol = NULL; 3572 - if (mpol_parse_str(value, &mpol)) 3573 - goto bad_val; 3574 - #endif 3575 - } else { 3576 - pr_err("tmpfs: Bad mount option %s\n", this_char); 3577 - goto error; 3386 + err = vfs_parse_fs_string(fc, this_char, value, len); 3387 + if (err < 0) 3388 + return err; 3578 3389 } 3579 3390 } 3580 - sbinfo->mpol = mpol; 3581 3391 return 0; 3582 - 3583 - bad_val: 3584 - pr_err("tmpfs: Bad value '%s' for mount option '%s'\n", 3585 - value, this_char); 3586 - error: 3587 - mpol_put(mpol); 3588 - return 1; 3589 - 3590 3392 } 3591 3393 3592 - static int shmem_remount_fs(struct super_block *sb, int *flags, char *data) 3394 + /* 3395 + * Reconfigure a shmem filesystem. 3396 + * 3397 + * Note that we disallow change from limited->unlimited blocks/inodes while any 3398 + * are in use; but we must separately disallow unlimited->limited, because in 3399 + * that case we have no record of how much is already in use. 3400 + */ 3401 + static int shmem_reconfigure(struct fs_context *fc) 3593 3402 { 3594 - struct shmem_sb_info *sbinfo = SHMEM_SB(sb); 3595 - struct shmem_sb_info config = *sbinfo; 3403 + struct shmem_options *ctx = fc->fs_private; 3404 + struct shmem_sb_info *sbinfo = SHMEM_SB(fc->root->d_sb); 3596 3405 unsigned long inodes; 3597 - int error = -EINVAL; 3598 - 3599 - config.mpol = NULL; 3600 - if (shmem_parse_options(data, &config, true)) 3601 - return error; 3406 + const char *err; 3602 3407 3603 3408 spin_lock(&sbinfo->stat_lock); 3604 3409 inodes = sbinfo->max_inodes - sbinfo->free_inodes; 3605 - if (percpu_counter_compare(&sbinfo->used_blocks, config.max_blocks) > 0) 3606 - goto out; 3607 - if (config.max_inodes < inodes) 3608 - goto out; 3609 - /* 3610 - * Those tests disallow limited->unlimited while any are in use; 3611 - * but we must separately disallow unlimited->limited, because 3612 - * in that case we have no record of how much is already in use. 3613 - */ 3614 - if (config.max_blocks && !sbinfo->max_blocks) 3615 - goto out; 3616 - if (config.max_inodes && !sbinfo->max_inodes) 3617 - goto out; 3410 + if ((ctx->seen & SHMEM_SEEN_BLOCKS) && ctx->blocks) { 3411 + if (!sbinfo->max_blocks) { 3412 + err = "Cannot retroactively limit size"; 3413 + goto out; 3414 + } 3415 + if (percpu_counter_compare(&sbinfo->used_blocks, 3416 + ctx->blocks) > 0) { 3417 + err = "Too small a size for current use"; 3418 + goto out; 3419 + } 3420 + } 3421 + if ((ctx->seen & SHMEM_SEEN_INODES) && ctx->inodes) { 3422 + if (!sbinfo->max_inodes) { 3423 + err = "Cannot retroactively limit inodes"; 3424 + goto out; 3425 + } 3426 + if (ctx->inodes < inodes) { 3427 + err = "Too few inodes for current use"; 3428 + goto out; 3429 + } 3430 + } 3618 3431 3619 - error = 0; 3620 - sbinfo->huge = config.huge; 3621 - sbinfo->max_blocks = config.max_blocks; 3622 - sbinfo->max_inodes = config.max_inodes; 3623 - sbinfo->free_inodes = config.max_inodes - inodes; 3432 + if (ctx->seen & SHMEM_SEEN_HUGE) 3433 + sbinfo->huge = ctx->huge; 3434 + if (ctx->seen & SHMEM_SEEN_BLOCKS) 3435 + sbinfo->max_blocks = ctx->blocks; 3436 + if (ctx->seen & SHMEM_SEEN_INODES) { 3437 + sbinfo->max_inodes = ctx->inodes; 3438 + sbinfo->free_inodes = ctx->inodes - inodes; 3439 + } 3624 3440 3625 3441 /* 3626 3442 * Preserve previous mempolicy unless mpol remount option was specified. 3627 3443 */ 3628 - if (config.mpol) { 3444 + if (ctx->mpol) { 3629 3445 mpol_put(sbinfo->mpol); 3630 - sbinfo->mpol = config.mpol; /* transfers initial ref */ 3446 + sbinfo->mpol = ctx->mpol; /* transfers initial ref */ 3447 + ctx->mpol = NULL; 3631 3448 } 3449 + spin_unlock(&sbinfo->stat_lock); 3450 + return 0; 3632 3451 out: 3633 3452 spin_unlock(&sbinfo->stat_lock); 3634 - return error; 3453 + return invalf(fc, "tmpfs: %s", err); 3635 3454 } 3636 3455 3637 3456 static int shmem_show_options(struct seq_file *seq, struct dentry *root) ··· 3616 3547 sb->s_fs_info = NULL; 3617 3548 } 3618 3549 3619 - int shmem_fill_super(struct super_block *sb, void *data, int silent) 3550 + static int shmem_fill_super(struct super_block *sb, struct fs_context *fc) 3620 3551 { 3552 + struct shmem_options *ctx = fc->fs_private; 3621 3553 struct inode *inode; 3622 3554 struct shmem_sb_info *sbinfo; 3623 3555 int err = -ENOMEM; ··· 3629 3559 if (!sbinfo) 3630 3560 return -ENOMEM; 3631 3561 3632 - sbinfo->mode = 0777 | S_ISVTX; 3633 - sbinfo->uid = current_fsuid(); 3634 - sbinfo->gid = current_fsgid(); 3635 3562 sb->s_fs_info = sbinfo; 3636 3563 3637 3564 #ifdef CONFIG_TMPFS ··· 3638 3571 * but the internal instance is left unlimited. 3639 3572 */ 3640 3573 if (!(sb->s_flags & SB_KERNMOUNT)) { 3641 - sbinfo->max_blocks = shmem_default_max_blocks(); 3642 - sbinfo->max_inodes = shmem_default_max_inodes(); 3643 - if (shmem_parse_options(data, sbinfo, false)) { 3644 - err = -EINVAL; 3645 - goto failed; 3646 - } 3574 + if (!(ctx->seen & SHMEM_SEEN_BLOCKS)) 3575 + ctx->blocks = shmem_default_max_blocks(); 3576 + if (!(ctx->seen & SHMEM_SEEN_INODES)) 3577 + ctx->inodes = shmem_default_max_inodes(); 3647 3578 } else { 3648 3579 sb->s_flags |= SB_NOUSER; 3649 3580 } ··· 3650 3585 #else 3651 3586 sb->s_flags |= SB_NOUSER; 3652 3587 #endif 3588 + sbinfo->max_blocks = ctx->blocks; 3589 + sbinfo->free_inodes = sbinfo->max_inodes = ctx->inodes; 3590 + sbinfo->uid = ctx->uid; 3591 + sbinfo->gid = ctx->gid; 3592 + sbinfo->mode = ctx->mode; 3593 + sbinfo->huge = ctx->huge; 3594 + sbinfo->mpol = ctx->mpol; 3595 + ctx->mpol = NULL; 3653 3596 3654 3597 spin_lock_init(&sbinfo->stat_lock); 3655 3598 if (percpu_counter_init(&sbinfo->used_blocks, 0, GFP_KERNEL)) 3656 3599 goto failed; 3657 - sbinfo->free_inodes = sbinfo->max_inodes; 3658 3600 spin_lock_init(&sbinfo->shrinklist_lock); 3659 3601 INIT_LIST_HEAD(&sbinfo->shrinklist); 3660 3602 ··· 3693 3621 shmem_put_super(sb); 3694 3622 return err; 3695 3623 } 3624 + 3625 + static int shmem_get_tree(struct fs_context *fc) 3626 + { 3627 + return get_tree_nodev(fc, shmem_fill_super); 3628 + } 3629 + 3630 + static void shmem_free_fc(struct fs_context *fc) 3631 + { 3632 + struct shmem_options *ctx = fc->fs_private; 3633 + 3634 + if (ctx) { 3635 + mpol_put(ctx->mpol); 3636 + kfree(ctx); 3637 + } 3638 + } 3639 + 3640 + static const struct fs_context_operations shmem_fs_context_ops = { 3641 + .free = shmem_free_fc, 3642 + .get_tree = shmem_get_tree, 3643 + #ifdef CONFIG_TMPFS 3644 + .parse_monolithic = shmem_parse_options, 3645 + .parse_param = shmem_parse_one, 3646 + .reconfigure = shmem_reconfigure, 3647 + #endif 3648 + }; 3696 3649 3697 3650 static struct kmem_cache *shmem_inode_cachep; 3698 3651 ··· 3835 3738 .destroy_inode = shmem_destroy_inode, 3836 3739 #ifdef CONFIG_TMPFS 3837 3740 .statfs = shmem_statfs, 3838 - .remount_fs = shmem_remount_fs, 3839 3741 .show_options = shmem_show_options, 3840 3742 #endif 3841 3743 .evict_inode = shmem_evict_inode, ··· 3855 3759 #endif 3856 3760 }; 3857 3761 3858 - static struct dentry *shmem_mount(struct file_system_type *fs_type, 3859 - int flags, const char *dev_name, void *data) 3762 + int shmem_init_fs_context(struct fs_context *fc) 3860 3763 { 3861 - return mount_nodev(fs_type, flags, data, shmem_fill_super); 3764 + struct shmem_options *ctx; 3765 + 3766 + ctx = kzalloc(sizeof(struct shmem_options), GFP_KERNEL); 3767 + if (!ctx) 3768 + return -ENOMEM; 3769 + 3770 + ctx->mode = 0777 | S_ISVTX; 3771 + ctx->uid = current_fsuid(); 3772 + ctx->gid = current_fsgid(); 3773 + 3774 + fc->fs_private = ctx; 3775 + fc->ops = &shmem_fs_context_ops; 3776 + return 0; 3862 3777 } 3863 3778 3864 3779 static struct file_system_type shmem_fs_type = { 3865 3780 .owner = THIS_MODULE, 3866 3781 .name = "tmpfs", 3867 - .mount = shmem_mount, 3782 + .init_fs_context = shmem_init_fs_context, 3783 + #ifdef CONFIG_TMPFS 3784 + .parameters = &shmem_fs_parameters, 3785 + #endif 3868 3786 .kill_sb = kill_litter_super, 3869 3787 .fs_flags = FS_USERNS_MOUNT, 3870 3788 }; ··· 4022 3912 4023 3913 static struct file_system_type shmem_fs_type = { 4024 3914 .name = "tmpfs", 4025 - .mount = ramfs_mount, 3915 + .init_fs_context = ramfs_init_fs_context, 3916 + .parameters = &ramfs_fs_parameters, 4026 3917 .kill_sb = kill_litter_super, 4027 3918 .fs_flags = FS_USERNS_MOUNT, 4028 3919 };