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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'vfs-6.15-rc1.mount.api' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull vfs mount API updates from Christian Brauner:
"This converts the remaining pseudo filesystems to the new mount api.

The sysv conversion is a bit gratuitous because we remove sysv in
another pull request. But if we have to revert the removal we at least
will have it converted to the new mount api already"

* tag 'vfs-6.15-rc1.mount.api' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
sysv: convert sysv to use the new mount api
vfs: remove some unused old mount api code
devtmpfs: replace ->mount with ->get_tree in public instance
vfs: Convert devpts to use the new mount API
pstore: convert to the new mount API

+285 -269
+64 -17
drivers/base/devtmpfs.c
··· 63 63 64 64 static struct vfsmount *mnt; 65 65 66 - static struct dentry *public_dev_mount(struct file_system_type *fs_type, int flags, 67 - const char *dev_name, void *data) 68 - { 69 - struct super_block *s = mnt->mnt_sb; 70 - int err; 71 - 72 - atomic_inc(&s->s_active); 73 - down_write(&s->s_umount); 74 - err = reconfigure_single(s, flags, data); 75 - if (err < 0) { 76 - deactivate_locked_super(s); 77 - return ERR_PTR(err); 78 - } 79 - return dget(s->s_root); 80 - } 81 - 82 66 static struct file_system_type internal_fs_type = { 83 67 .name = "devtmpfs", 84 68 #ifdef CONFIG_TMPFS ··· 73 89 .kill_sb = kill_litter_super, 74 90 }; 75 91 92 + /* Simply take a ref on the existing mount */ 93 + static int devtmpfs_get_tree(struct fs_context *fc) 94 + { 95 + struct super_block *sb = mnt->mnt_sb; 96 + 97 + atomic_inc(&sb->s_active); 98 + down_write(&sb->s_umount); 99 + fc->root = dget(sb->s_root); 100 + return 0; 101 + } 102 + 103 + /* Ops are filled in during init depending on underlying shmem or ramfs type */ 104 + struct fs_context_operations devtmpfs_context_ops = {}; 105 + 106 + /* Call the underlying initialization and set to our ops */ 107 + static int devtmpfs_init_fs_context(struct fs_context *fc) 108 + { 109 + int ret; 110 + #ifdef CONFIG_TMPFS 111 + ret = shmem_init_fs_context(fc); 112 + #else 113 + ret = ramfs_init_fs_context(fc); 114 + #endif 115 + if (ret < 0) 116 + return ret; 117 + 118 + fc->ops = &devtmpfs_context_ops; 119 + 120 + return 0; 121 + } 122 + 76 123 static struct file_system_type dev_fs_type = { 77 124 .name = "devtmpfs", 78 - .mount = public_dev_mount, 125 + .init_fs_context = devtmpfs_init_fs_context, 79 126 }; 80 127 81 128 static int devtmpfs_submit_req(struct req *req, const char *tmp) ··· 458 443 } 459 444 460 445 /* 446 + * Get the underlying (shmem/ramfs) context ops to build ours 447 + */ 448 + static int devtmpfs_configure_context(void) 449 + { 450 + struct fs_context *fc; 451 + 452 + fc = fs_context_for_reconfigure(mnt->mnt_root, mnt->mnt_sb->s_flags, 453 + MS_RMT_MASK); 454 + if (IS_ERR(fc)) 455 + return PTR_ERR(fc); 456 + 457 + /* Set up devtmpfs_context_ops based on underlying type */ 458 + devtmpfs_context_ops.free = fc->ops->free; 459 + devtmpfs_context_ops.dup = fc->ops->dup; 460 + devtmpfs_context_ops.parse_param = fc->ops->parse_param; 461 + devtmpfs_context_ops.parse_monolithic = fc->ops->parse_monolithic; 462 + devtmpfs_context_ops.get_tree = &devtmpfs_get_tree; 463 + devtmpfs_context_ops.reconfigure = fc->ops->reconfigure; 464 + 465 + put_fs_context(fc); 466 + 467 + return 0; 468 + } 469 + 470 + /* 461 471 * Create devtmpfs instance, driver-core devices will add their device 462 472 * nodes here. 463 473 */ ··· 496 456 pr_err("unable to create devtmpfs %ld\n", PTR_ERR(mnt)); 497 457 return PTR_ERR(mnt); 498 458 } 459 + 460 + err = devtmpfs_configure_context(); 461 + if (err) { 462 + pr_err("unable to configure devtmpfs type %d\n", err); 463 + return err; 464 + } 465 + 499 466 err = register_filesystem(&dev_fs_type); 500 467 if (err) { 501 468 pr_err("unable to register devtmpfs type %d\n", err);
+108 -139
fs/devpts/inode.c
··· 12 12 #include <linux/module.h> 13 13 #include <linux/init.h> 14 14 #include <linux/fs.h> 15 + #include <linux/fs_context.h> 16 + #include <linux/fs_parser.h> 15 17 #include <linux/sched.h> 16 18 #include <linux/namei.h> 17 19 #include <linux/slab.h> ··· 23 21 #include <linux/magic.h> 24 22 #include <linux/idr.h> 25 23 #include <linux/devpts_fs.h> 26 - #include <linux/parser.h> 27 24 #include <linux/fsnotify.h> 28 25 #include <linux/seq_file.h> 29 26 ··· 88 87 Opt_err 89 88 }; 90 89 91 - static const match_table_t tokens = { 92 - {Opt_uid, "uid=%u"}, 93 - {Opt_gid, "gid=%u"}, 94 - {Opt_mode, "mode=%o"}, 95 - {Opt_ptmxmode, "ptmxmode=%o"}, 96 - {Opt_newinstance, "newinstance"}, 97 - {Opt_max, "max=%d"}, 98 - {Opt_err, NULL} 90 + static const struct fs_parameter_spec devpts_param_specs[] = { 91 + fsparam_u32 ("gid", Opt_gid), 92 + fsparam_s32 ("max", Opt_max), 93 + fsparam_u32oct ("mode", Opt_mode), 94 + fsparam_flag ("newinstance", Opt_newinstance), 95 + fsparam_u32oct ("ptmxmode", Opt_ptmxmode), 96 + fsparam_u32 ("uid", Opt_uid), 97 + {} 99 98 }; 100 99 101 100 struct pts_fs_info { ··· 215 214 deactivate_super(fsi->sb); 216 215 } 217 216 218 - #define PARSE_MOUNT 0 219 - #define PARSE_REMOUNT 1 220 - 221 217 /* 222 - * parse_mount_options(): 223 - * Set @opts to mount options specified in @data. If an option is not 224 - * specified in @data, set it to its default value. 225 - * 226 - * Note: @data may be NULL (in which case all options are set to default). 218 + * devpts_parse_param - Parse mount parameters 227 219 */ 228 - static int parse_mount_options(char *data, int op, struct pts_mount_opts *opts) 220 + static int devpts_parse_param(struct fs_context *fc, struct fs_parameter *param) 229 221 { 230 - char *p; 231 - kuid_t uid; 232 - kgid_t gid; 222 + struct pts_fs_info *fsi = fc->s_fs_info; 223 + struct pts_mount_opts *opts = &fsi->mount_opts; 224 + struct fs_parse_result result; 225 + int opt; 233 226 234 - opts->setuid = 0; 235 - opts->setgid = 0; 236 - opts->uid = GLOBAL_ROOT_UID; 237 - opts->gid = GLOBAL_ROOT_GID; 238 - opts->mode = DEVPTS_DEFAULT_MODE; 239 - opts->ptmxmode = DEVPTS_DEFAULT_PTMX_MODE; 240 - opts->max = NR_UNIX98_PTY_MAX; 227 + opt = fs_parse(fc, devpts_param_specs, param, &result); 228 + if (opt < 0) 229 + return opt; 241 230 242 - /* Only allow instances mounted from the initial mount 243 - * namespace to tap the reserve pool of ptys. 244 - */ 245 - if (op == PARSE_MOUNT) 246 - opts->reserve = 247 - (current->nsproxy->mnt_ns == init_task.nsproxy->mnt_ns); 248 - 249 - while ((p = strsep(&data, ",")) != NULL) { 250 - substring_t args[MAX_OPT_ARGS]; 251 - int token; 252 - int option; 253 - 254 - if (!*p) 255 - continue; 256 - 257 - token = match_token(p, tokens, args); 258 - switch (token) { 259 - case Opt_uid: 260 - if (match_int(&args[0], &option)) 261 - return -EINVAL; 262 - uid = make_kuid(current_user_ns(), option); 263 - if (!uid_valid(uid)) 264 - return -EINVAL; 265 - opts->uid = uid; 266 - opts->setuid = 1; 267 - break; 268 - case Opt_gid: 269 - if (match_int(&args[0], &option)) 270 - return -EINVAL; 271 - gid = make_kgid(current_user_ns(), option); 272 - if (!gid_valid(gid)) 273 - return -EINVAL; 274 - opts->gid = gid; 275 - opts->setgid = 1; 276 - break; 277 - case Opt_mode: 278 - if (match_octal(&args[0], &option)) 279 - return -EINVAL; 280 - opts->mode = option & S_IALLUGO; 281 - break; 282 - case Opt_ptmxmode: 283 - if (match_octal(&args[0], &option)) 284 - return -EINVAL; 285 - opts->ptmxmode = option & S_IALLUGO; 286 - break; 287 - case Opt_newinstance: 288 - break; 289 - case Opt_max: 290 - if (match_int(&args[0], &option) || 291 - option < 0 || option > NR_UNIX98_PTY_MAX) 292 - return -EINVAL; 293 - opts->max = option; 294 - break; 295 - default: 296 - pr_err("called with bogus options\n"); 297 - return -EINVAL; 298 - } 231 + switch (opt) { 232 + case Opt_uid: 233 + opts->uid = result.uid; 234 + opts->setuid = 1; 235 + break; 236 + case Opt_gid: 237 + opts->gid = result.gid; 238 + opts->setgid = 1; 239 + break; 240 + case Opt_mode: 241 + opts->mode = result.uint_32 & S_IALLUGO; 242 + break; 243 + case Opt_ptmxmode: 244 + opts->ptmxmode = result.uint_32 & S_IALLUGO; 245 + break; 246 + case Opt_newinstance: 247 + break; 248 + case Opt_max: 249 + if (result.uint_32 > NR_UNIX98_PTY_MAX) 250 + return invalf(fc, "max out of range"); 251 + opts->max = result.uint_32; 252 + break; 299 253 } 300 254 301 255 return 0; 302 256 } 303 257 304 - static int mknod_ptmx(struct super_block *sb) 258 + static int mknod_ptmx(struct super_block *sb, struct fs_context *fc) 305 259 { 306 260 int mode; 307 261 int rc = -ENOMEM; ··· 318 362 } 319 363 } 320 364 321 - static int devpts_remount(struct super_block *sb, int *flags, char *data) 365 + static int devpts_reconfigure(struct fs_context *fc) 322 366 { 323 - int err; 324 - struct pts_fs_info *fsi = DEVPTS_SB(sb); 325 - struct pts_mount_opts *opts = &fsi->mount_opts; 367 + struct pts_fs_info *fsi = DEVPTS_SB(fc->root->d_sb); 368 + struct pts_fs_info *new = fc->s_fs_info; 326 369 327 - err = parse_mount_options(data, PARSE_REMOUNT, opts); 370 + /* Apply the revised options. We don't want to change ->reserve. 371 + * Ideally, we'd update each option conditionally on it having been 372 + * explicitly changed, but the default is to reset everything so that 373 + * would break UAPI... 374 + */ 375 + fsi->mount_opts.setuid = new->mount_opts.setuid; 376 + fsi->mount_opts.setgid = new->mount_opts.setgid; 377 + fsi->mount_opts.uid = new->mount_opts.uid; 378 + fsi->mount_opts.gid = new->mount_opts.gid; 379 + fsi->mount_opts.mode = new->mount_opts.mode; 380 + fsi->mount_opts.ptmxmode = new->mount_opts.ptmxmode; 381 + fsi->mount_opts.max = new->mount_opts.max; 328 382 329 383 /* 330 384 * parse_mount_options() restores options to default values ··· 344 378 */ 345 379 update_ptmx_mode(fsi); 346 380 347 - return err; 381 + return 0; 348 382 } 349 383 350 384 static int devpts_show_options(struct seq_file *seq, struct dentry *root) ··· 368 402 369 403 static const struct super_operations devpts_sops = { 370 404 .statfs = simple_statfs, 371 - .remount_fs = devpts_remount, 372 405 .show_options = devpts_show_options, 373 406 }; 374 407 375 - static void *new_pts_fs_info(struct super_block *sb) 408 + static int devpts_fill_super(struct super_block *s, struct fs_context *fc) 376 409 { 377 - struct pts_fs_info *fsi; 378 - 379 - fsi = kzalloc(sizeof(struct pts_fs_info), GFP_KERNEL); 380 - if (!fsi) 381 - return NULL; 382 - 383 - ida_init(&fsi->allocated_ptys); 384 - fsi->mount_opts.mode = DEVPTS_DEFAULT_MODE; 385 - fsi->mount_opts.ptmxmode = DEVPTS_DEFAULT_PTMX_MODE; 386 - fsi->sb = sb; 387 - 388 - return fsi; 389 - } 390 - 391 - static int 392 - devpts_fill_super(struct super_block *s, void *data, int silent) 393 - { 410 + struct pts_fs_info *fsi = DEVPTS_SB(s); 394 411 struct inode *inode; 395 - int error; 396 412 397 413 s->s_iflags &= ~SB_I_NODEV; 398 414 s->s_blocksize = 1024; ··· 383 435 s->s_op = &devpts_sops; 384 436 s->s_d_op = &simple_dentry_operations; 385 437 s->s_time_gran = 1; 438 + fsi->sb = s; 386 439 387 - error = -ENOMEM; 388 - s->s_fs_info = new_pts_fs_info(s); 389 - if (!s->s_fs_info) 390 - goto fail; 391 - 392 - error = parse_mount_options(data, PARSE_MOUNT, &DEVPTS_SB(s)->mount_opts); 393 - if (error) 394 - goto fail; 395 - 396 - error = -ENOMEM; 397 440 inode = new_inode(s); 398 441 if (!inode) 399 - goto fail; 442 + return -ENOMEM; 400 443 inode->i_ino = 1; 401 444 simple_inode_init_ts(inode); 402 445 inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR; ··· 398 459 s->s_root = d_make_root(inode); 399 460 if (!s->s_root) { 400 461 pr_err("get root dentry failed\n"); 401 - goto fail; 462 + return -ENOMEM; 402 463 } 403 464 404 - error = mknod_ptmx(s); 405 - if (error) 406 - goto fail_dput; 407 - 408 - return 0; 409 - fail_dput: 410 - dput(s->s_root); 411 - s->s_root = NULL; 412 - fail: 413 - return error; 465 + return mknod_ptmx(s, fc); 414 466 } 415 467 416 468 /* 417 - * devpts_mount() 469 + * devpts_get_tree() 418 470 * 419 471 * Mount a new (private) instance of devpts. PTYs created in this 420 472 * instance are independent of the PTYs in other devpts instances. 421 473 */ 422 - static struct dentry *devpts_mount(struct file_system_type *fs_type, 423 - int flags, const char *dev_name, void *data) 474 + static int devpts_get_tree(struct fs_context *fc) 424 475 { 425 - return mount_nodev(fs_type, flags, data, devpts_fill_super); 476 + return get_tree_nodev(fc, devpts_fill_super); 477 + } 478 + 479 + static void devpts_free_fc(struct fs_context *fc) 480 + { 481 + kfree(fc->s_fs_info); 482 + } 483 + 484 + static const struct fs_context_operations devpts_context_ops = { 485 + .free = devpts_free_fc, 486 + .parse_param = devpts_parse_param, 487 + .get_tree = devpts_get_tree, 488 + .reconfigure = devpts_reconfigure, 489 + }; 490 + 491 + /* 492 + * Set up the filesystem mount context. 493 + */ 494 + static int devpts_init_fs_context(struct fs_context *fc) 495 + { 496 + struct pts_fs_info *fsi; 497 + 498 + fsi = kzalloc(sizeof(struct pts_fs_info), GFP_KERNEL); 499 + if (!fsi) 500 + return -ENOMEM; 501 + 502 + ida_init(&fsi->allocated_ptys); 503 + fsi->mount_opts.uid = GLOBAL_ROOT_UID; 504 + fsi->mount_opts.gid = GLOBAL_ROOT_GID; 505 + fsi->mount_opts.mode = DEVPTS_DEFAULT_MODE; 506 + fsi->mount_opts.ptmxmode = DEVPTS_DEFAULT_PTMX_MODE; 507 + fsi->mount_opts.max = NR_UNIX98_PTY_MAX; 508 + 509 + if (fc->purpose == FS_CONTEXT_FOR_MOUNT && 510 + current->nsproxy->mnt_ns == init_task.nsproxy->mnt_ns) 511 + fsi->mount_opts.reserve = true; 512 + 513 + fc->s_fs_info = fsi; 514 + fc->ops = &devpts_context_ops; 515 + return 0; 426 516 } 427 517 428 518 static void devpts_kill_sb(struct super_block *sb) ··· 466 498 467 499 static struct file_system_type devpts_fs_type = { 468 500 .name = "devpts", 469 - .mount = devpts_mount, 501 + .init_fs_context = devpts_init_fs_context, 502 + .parameters = devpts_param_specs, 470 503 .kill_sb = devpts_kill_sb, 471 504 .fs_flags = FS_USERNS_MOUNT, 472 505 };
+74 -35
fs/pstore/inode.c
··· 14 14 #include <linux/init.h> 15 15 #include <linux/list.h> 16 16 #include <linux/string.h> 17 - #include <linux/mount.h> 18 17 #include <linux/seq_file.h> 19 18 #include <linux/ramfs.h> 20 - #include <linux/parser.h> 19 + #include <linux/fs_parser.h> 20 + #include <linux/fs_context.h> 21 21 #include <linux/sched.h> 22 22 #include <linux/magic.h> 23 23 #include <linux/pstore.h> ··· 226 226 } 227 227 228 228 enum { 229 - Opt_kmsg_bytes, Opt_err 229 + Opt_kmsg_bytes 230 230 }; 231 231 232 - static const match_table_t tokens = { 233 - {Opt_kmsg_bytes, "kmsg_bytes=%u"}, 234 - {Opt_err, NULL} 232 + static const struct fs_parameter_spec pstore_param_spec[] = { 233 + fsparam_u32 ("kmsg_bytes", Opt_kmsg_bytes), 234 + {} 235 235 }; 236 236 237 - static void parse_options(char *options) 237 + struct pstore_context { 238 + unsigned int kmsg_bytes; 239 + }; 240 + 241 + static int pstore_parse_param(struct fs_context *fc, struct fs_parameter *param) 238 242 { 239 - char *p; 240 - substring_t args[MAX_OPT_ARGS]; 241 - int option; 243 + struct pstore_context *ctx = fc->fs_private; 244 + struct fs_parse_result result; 245 + int opt; 242 246 243 - if (!options) 244 - return; 247 + opt = fs_parse(fc, pstore_param_spec, param, &result); 248 + /* pstore has historically ignored invalid kmsg_bytes param */ 249 + if (opt < 0) 250 + return 0; 245 251 246 - while ((p = strsep(&options, ",")) != NULL) { 247 - int token; 248 - 249 - if (!*p) 250 - continue; 251 - 252 - token = match_token(p, tokens, args); 253 - switch (token) { 254 - case Opt_kmsg_bytes: 255 - if (!match_int(&args[0], &option)) 256 - pstore_set_kmsg_bytes(option); 257 - break; 258 - } 252 + switch (opt) { 253 + case Opt_kmsg_bytes: 254 + ctx->kmsg_bytes = result.uint_32; 255 + break; 256 + default: 257 + return -EINVAL; 259 258 } 259 + 260 + return 0; 260 261 } 261 262 262 263 /* ··· 270 269 return 0; 271 270 } 272 271 273 - static int pstore_remount(struct super_block *sb, int *flags, char *data) 272 + static int pstore_reconfigure(struct fs_context *fc) 274 273 { 275 - sync_filesystem(sb); 276 - parse_options(data); 274 + struct pstore_context *ctx = fc->fs_private; 275 + 276 + sync_filesystem(fc->root->d_sb); 277 + pstore_set_kmsg_bytes(ctx->kmsg_bytes); 277 278 278 279 return 0; 279 280 } ··· 284 281 .statfs = simple_statfs, 285 282 .drop_inode = generic_delete_inode, 286 283 .evict_inode = pstore_evict_inode, 287 - .remount_fs = pstore_remount, 288 284 .show_options = pstore_show_options, 289 285 }; 290 286 ··· 408 406 inode_unlock(d_inode(root)); 409 407 } 410 408 411 - static int pstore_fill_super(struct super_block *sb, void *data, int silent) 409 + static int pstore_fill_super(struct super_block *sb, struct fs_context *fc) 412 410 { 411 + struct pstore_context *ctx = fc->fs_private; 413 412 struct inode *inode; 414 413 415 414 sb->s_maxbytes = MAX_LFS_FILESIZE; ··· 420 417 sb->s_op = &pstore_ops; 421 418 sb->s_time_gran = 1; 422 419 423 - parse_options(data); 420 + pstore_set_kmsg_bytes(ctx->kmsg_bytes); 424 421 425 422 inode = pstore_get_inode(sb); 426 423 if (inode) { ··· 441 438 return 0; 442 439 } 443 440 444 - static struct dentry *pstore_mount(struct file_system_type *fs_type, 445 - int flags, const char *dev_name, void *data) 441 + static int pstore_get_tree(struct fs_context *fc) 446 442 { 447 - return mount_single(fs_type, flags, data, pstore_fill_super); 443 + if (fc->root) 444 + return pstore_reconfigure(fc); 445 + 446 + return get_tree_single(fc, pstore_fill_super); 448 447 } 448 + 449 + static void pstore_free_fc(struct fs_context *fc) 450 + { 451 + kfree(fc->fs_private); 452 + } 453 + 454 + static const struct fs_context_operations pstore_context_ops = { 455 + .parse_param = pstore_parse_param, 456 + .get_tree = pstore_get_tree, 457 + .reconfigure = pstore_reconfigure, 458 + .free = pstore_free_fc, 459 + }; 449 460 450 461 static void pstore_kill_sb(struct super_block *sb) 451 462 { ··· 473 456 INIT_LIST_HEAD(&records_list); 474 457 } 475 458 459 + static int pstore_init_fs_context(struct fs_context *fc) 460 + { 461 + struct pstore_context *ctx; 462 + 463 + ctx = kzalloc(sizeof(struct pstore_context), GFP_KERNEL); 464 + if (!ctx) 465 + return -ENOMEM; 466 + 467 + /* 468 + * Global kmsg_bytes is initialized to default, and updated 469 + * every time we (re)mount the single-sb filesystem with the 470 + * option specified. 471 + */ 472 + ctx->kmsg_bytes = kmsg_bytes; 473 + 474 + fc->fs_private = ctx; 475 + fc->ops = &pstore_context_ops; 476 + 477 + return 0; 478 + } 479 + 476 480 static struct file_system_type pstore_fs_type = { 477 481 .owner = THIS_MODULE, 478 482 .name = "pstore", 479 - .mount = pstore_mount, 480 483 .kill_sb = pstore_kill_sb, 484 + .init_fs_context = pstore_init_fs_context, 485 + .parameters = pstore_param_spec, 481 486 }; 482 487 483 488 int __init pstore_init_fs(void)
-55
fs/super.c
··· 1737 1737 } 1738 1738 EXPORT_SYMBOL(mount_nodev); 1739 1739 1740 - int reconfigure_single(struct super_block *s, 1741 - int flags, void *data) 1742 - { 1743 - struct fs_context *fc; 1744 - int ret; 1745 - 1746 - /* The caller really need to be passing fc down into mount_single(), 1747 - * then a chunk of this can be removed. [Bollocks -- AV] 1748 - * Better yet, reconfiguration shouldn't happen, but rather the second 1749 - * mount should be rejected if the parameters are not compatible. 1750 - */ 1751 - fc = fs_context_for_reconfigure(s->s_root, flags, MS_RMT_MASK); 1752 - if (IS_ERR(fc)) 1753 - return PTR_ERR(fc); 1754 - 1755 - ret = parse_monolithic_mount_data(fc, data); 1756 - if (ret < 0) 1757 - goto out; 1758 - 1759 - ret = reconfigure_super(fc); 1760 - out: 1761 - put_fs_context(fc); 1762 - return ret; 1763 - } 1764 - 1765 - static int compare_single(struct super_block *s, void *p) 1766 - { 1767 - return 1; 1768 - } 1769 - 1770 - struct dentry *mount_single(struct file_system_type *fs_type, 1771 - int flags, void *data, 1772 - int (*fill_super)(struct super_block *, void *, int)) 1773 - { 1774 - struct super_block *s; 1775 - int error; 1776 - 1777 - s = sget(fs_type, compare_single, set_anon_super, flags, NULL); 1778 - if (IS_ERR(s)) 1779 - return ERR_CAST(s); 1780 - if (!s->s_root) { 1781 - error = fill_super(s, data, flags & SB_SILENT ? 1 : 0); 1782 - if (!error) 1783 - s->s_flags |= SB_ACTIVE; 1784 - } else { 1785 - error = reconfigure_single(s, flags, data); 1786 - } 1787 - if (unlikely(error)) { 1788 - deactivate_locked_super(s); 1789 - return ERR_PTR(error); 1790 - } 1791 - return dget(s->s_root); 1792 - } 1793 - EXPORT_SYMBOL(mount_single); 1794 - 1795 1740 /** 1796 1741 * vfs_get_tree - Get the mountable root 1797 1742 * @fc: The superblock configuration context.
+39 -18
fs/sysv/super.c
··· 25 25 #include <linux/init.h> 26 26 #include <linux/slab.h> 27 27 #include <linux/buffer_head.h> 28 + #include <linux/fs_context.h> 28 29 #include "sysv.h" 29 30 30 31 /* ··· 350 349 return 1; 351 350 } 352 351 353 - static int sysv_fill_super(struct super_block *sb, void *data, int silent) 352 + static int sysv_fill_super(struct super_block *sb, struct fs_context *fc) 354 353 { 355 354 struct buffer_head *bh1, *bh = NULL; 356 355 struct sysv_sb_info *sbi; 357 356 unsigned long blocknr; 358 357 int size = 0, i; 358 + int silent = fc->sb_flags & SB_SILENT; 359 359 360 360 BUILD_BUG_ON(1024 != sizeof (struct xenix_super_block)); 361 361 BUILD_BUG_ON(512 != sizeof (struct sysv4_super_block)); ··· 473 471 return 1; 474 472 } 475 473 476 - static int v7_fill_super(struct super_block *sb, void *data, int silent) 474 + static int v7_fill_super(struct super_block *sb, struct fs_context *fc) 477 475 { 478 476 struct sysv_sb_info *sbi; 479 477 struct buffer_head *bh; 478 + int silent = fc->sb_flags & SB_SILENT; 480 479 481 480 BUILD_BUG_ON(sizeof(struct v7_super_block) != 440); 482 481 BUILD_BUG_ON(sizeof(struct sysv_inode) != 64); ··· 531 528 532 529 /* Every kernel module contains stuff like this. */ 533 530 534 - static struct dentry *sysv_mount(struct file_system_type *fs_type, 535 - int flags, const char *dev_name, void *data) 531 + static int sysv_get_tree(struct fs_context *fc) 536 532 { 537 - return mount_bdev(fs_type, flags, dev_name, data, sysv_fill_super); 533 + return get_tree_bdev(fc, sysv_fill_super); 538 534 } 539 535 540 - static struct dentry *v7_mount(struct file_system_type *fs_type, 541 - int flags, const char *dev_name, void *data) 536 + static int v7_get_tree(struct fs_context *fc) 542 537 { 543 - return mount_bdev(fs_type, flags, dev_name, data, v7_fill_super); 538 + return get_tree_bdev(fc, v7_fill_super); 539 + } 540 + 541 + static const struct fs_context_operations sysv_context_ops = { 542 + .get_tree = sysv_get_tree, 543 + }; 544 + 545 + static const struct fs_context_operations v7_context_ops = { 546 + .get_tree = v7_get_tree, 547 + }; 548 + 549 + static int sysv_init_fs_context(struct fs_context *fc) 550 + { 551 + fc->ops = &sysv_context_ops; 552 + return 0; 553 + } 554 + 555 + static int v7_init_fs_context(struct fs_context *fc) 556 + { 557 + fc->ops = &v7_context_ops; 558 + return 0; 544 559 } 545 560 546 561 static struct file_system_type sysv_fs_type = { 547 - .owner = THIS_MODULE, 548 - .name = "sysv", 549 - .mount = sysv_mount, 550 - .kill_sb = kill_block_super, 551 - .fs_flags = FS_REQUIRES_DEV, 562 + .owner = THIS_MODULE, 563 + .name = "sysv", 564 + .kill_sb = kill_block_super, 565 + .fs_flags = FS_REQUIRES_DEV, 566 + .init_fs_context = sysv_init_fs_context, 552 567 }; 553 568 MODULE_ALIAS_FS("sysv"); 554 569 555 570 static struct file_system_type v7_fs_type = { 556 - .owner = THIS_MODULE, 557 - .name = "v7", 558 - .mount = v7_mount, 559 - .kill_sb = kill_block_super, 560 - .fs_flags = FS_REQUIRES_DEV, 571 + .owner = THIS_MODULE, 572 + .name = "v7", 573 + .kill_sb = kill_block_super, 574 + .fs_flags = FS_REQUIRES_DEV, 575 + .init_fs_context = v7_init_fs_context, 561 576 }; 562 577 MODULE_ALIAS_FS("v7"); 563 578 MODULE_ALIAS("v7");
-3
include/linux/fs.h
··· 2653 2653 extern struct dentry *mount_bdev(struct file_system_type *fs_type, 2654 2654 int flags, const char *dev_name, void *data, 2655 2655 int (*fill_super)(struct super_block *, void *, int)); 2656 - extern struct dentry *mount_single(struct file_system_type *fs_type, 2657 - int flags, void *data, 2658 - int (*fill_super)(struct super_block *, void *, int)); 2659 2656 extern struct dentry *mount_nodev(struct file_system_type *fs_type, 2660 2657 int flags, void *data, 2661 2658 int (*fill_super)(struct super_block *, void *, int));
-2
include/linux/fs_context.h
··· 144 144 extern int vfs_parse_fs_param_source(struct fs_context *fc, 145 145 struct fs_parameter *param); 146 146 extern void fc_drop_locked(struct fs_context *fc); 147 - int reconfigure_single(struct super_block *s, 148 - int flags, void *data); 149 147 150 148 extern int get_tree_nodev(struct fs_context *fc, 151 149 int (*fill_super)(struct super_block *sb,