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

orangefs: Convert to use the new mount API

Convert the orangefs filesystem to the new internal mount API as the old
one will be obsoleted and removed. This allows greater flexibility in
communication of mount parameters between userspace, the VFS and the
filesystem.

See Documentation/filesystems/mount_api.txt for more information.

[sandeen: forward-port older patch, fix SB_POSIXACL handling]

Signed-off-by: David Howells <dhowells@redhat.com>
Co-developed-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
cc: Mike Marshall <hubcap@omnibond.com>
cc: Martin Brandenburg <martin@omnibond.com>
cc: devel@lists.orangefs.org
Signed-off-by: Mike Marshall <hubcap@omnibond.com>

authored by

Eric Sandeen and committed by
Mike Marshall
4dc784e9 82f2b0b9

+100 -96
+4 -4
fs/orangefs/orangefs-kernel.h
··· 32 32 #include <linux/slab.h> 33 33 #include <linux/types.h> 34 34 #include <linux/fs.h> 35 + #include <linux/fs_context.h> 36 + #include <linux/fs_parser.h> 35 37 #include <linux/vmalloc.h> 36 38 37 39 #include <linux/aio.h> ··· 330 328 * defined in super.c 331 329 */ 332 330 extern uint64_t orangefs_features; 331 + extern const struct fs_parameter_spec orangefs_fs_param_spec[]; 333 332 334 - struct dentry *orangefs_mount(struct file_system_type *fst, 335 - int flags, 336 - const char *devname, 337 - void *data); 333 + int orangefs_init_fs_context(struct fs_context *fc); 338 334 339 335 void orangefs_kill_sb(struct super_block *sb); 340 336 int orangefs_remount(struct orangefs_sb_info_s *);
+2 -1
fs/orangefs/orangefs-mod.c
··· 46 46 47 47 static struct file_system_type orangefs_fs_type = { 48 48 .name = "pvfs2", 49 - .mount = orangefs_mount, 49 + .init_fs_context = orangefs_init_fs_context, 50 + .parameters = orangefs_fs_param_spec, 50 51 .kill_sb = orangefs_kill_sb, 51 52 .owner = THIS_MODULE, 52 53 };
+94 -91
fs/orangefs/super.c
··· 9 9 #include "orangefs-kernel.h" 10 10 #include "orangefs-bufmap.h" 11 11 12 - #include <linux/parser.h> 13 12 #include <linux/hashtable.h> 14 13 #include <linux/seq_file.h> 15 14 ··· 21 22 DEFINE_SPINLOCK(orangefs_superblocks_lock); 22 23 23 24 enum { 24 - Opt_intr, 25 25 Opt_acl, 26 + Opt_intr, 26 27 Opt_local_lock, 27 - 28 - Opt_err 29 28 }; 30 29 31 - static const match_table_t tokens = { 32 - { Opt_acl, "acl" }, 33 - { Opt_intr, "intr" }, 34 - { Opt_local_lock, "local_lock" }, 35 - { Opt_err, NULL } 30 + const struct fs_parameter_spec orangefs_fs_param_spec[] = { 31 + fsparam_flag ("acl", Opt_acl), 32 + fsparam_flag ("intr", Opt_intr), 33 + fsparam_flag ("local_lock", Opt_local_lock), 34 + {} 36 35 }; 37 36 38 37 uint64_t orangefs_features; ··· 48 51 return 0; 49 52 } 50 53 51 - static int parse_mount_options(struct super_block *sb, char *options, 52 - int silent) 54 + static int orangefs_parse_param(struct fs_context *fc, 55 + struct fs_parameter *param) 53 56 { 54 - struct orangefs_sb_info_s *orangefs_sb = ORANGEFS_SB(sb); 55 - substring_t args[MAX_OPT_ARGS]; 56 - char *p; 57 + struct orangefs_sb_info_s *orangefs_sb = fc->s_fs_info; 58 + struct fs_parse_result result; 59 + int opt; 57 60 58 - /* 59 - * Force any potential flags that might be set from the mount 60 - * to zero, ie, initialize to unset. 61 - */ 62 - sb->s_flags &= ~SB_POSIXACL; 63 - orangefs_sb->flags &= ~ORANGEFS_OPT_INTR; 64 - orangefs_sb->flags &= ~ORANGEFS_OPT_LOCAL_LOCK; 61 + opt = fs_parse(fc, orangefs_fs_param_spec, param, &result); 62 + if (opt < 0) 63 + return opt; 65 64 66 - while ((p = strsep(&options, ",")) != NULL) { 67 - int token; 68 - 69 - if (!*p) 70 - continue; 71 - 72 - token = match_token(p, tokens, args); 73 - switch (token) { 74 - case Opt_acl: 75 - sb->s_flags |= SB_POSIXACL; 76 - break; 77 - case Opt_intr: 78 - orangefs_sb->flags |= ORANGEFS_OPT_INTR; 79 - break; 80 - case Opt_local_lock: 81 - orangefs_sb->flags |= ORANGEFS_OPT_LOCAL_LOCK; 82 - break; 83 - default: 84 - goto fail; 85 - } 65 + switch (opt) { 66 + case Opt_acl: 67 + fc->sb_flags |= SB_POSIXACL; 68 + break; 69 + case Opt_intr: 70 + orangefs_sb->flags |= ORANGEFS_OPT_INTR; 71 + break; 72 + case Opt_local_lock: 73 + orangefs_sb->flags |= ORANGEFS_OPT_LOCAL_LOCK; 74 + break; 86 75 } 87 76 88 77 return 0; 89 - fail: 90 - if (!silent) 91 - gossip_err("Error: mount option [%s] is not supported.\n", p); 92 - return -EINVAL; 93 78 } 94 79 95 80 static void orangefs_inode_cache_ctor(void *req) ··· 202 223 * Remount as initiated by VFS layer. We just need to reparse the mount 203 224 * options, no need to signal pvfs2-client-core about it. 204 225 */ 205 - static int orangefs_remount_fs(struct super_block *sb, int *flags, char *data) 226 + static int orangefs_reconfigure(struct fs_context *fc) 206 227 { 207 - gossip_debug(GOSSIP_SUPER_DEBUG, "orangefs_remount_fs: called\n"); 208 - return parse_mount_options(sb, data, 1); 228 + struct super_block *sb = fc->root->d_sb; 229 + struct orangefs_sb_info_s *orangefs_sb = ORANGEFS_SB(sb); 230 + struct orangefs_sb_info_s *revised = fc->s_fs_info; 231 + unsigned int flags; 232 + 233 + flags = orangefs_sb->flags; 234 + flags &= ~(ORANGEFS_OPT_INTR | ORANGEFS_OPT_LOCAL_LOCK); 235 + flags |= revised->flags; 236 + WRITE_ONCE(orangefs_sb->flags, flags); 237 + 238 + gossip_debug(GOSSIP_SUPER_DEBUG, "orangefs_reconfigure: called\n"); 239 + return 0; 209 240 } 210 241 211 242 /* ··· 308 319 .write_inode = orangefs_write_inode, 309 320 .drop_inode = generic_delete_inode, 310 321 .statfs = orangefs_statfs, 311 - .remount_fs = orangefs_remount_fs, 312 322 .show_options = orangefs_show_options, 313 323 }; 314 324 ··· 398 410 } 399 411 400 412 static int orangefs_fill_sb(struct super_block *sb, 401 - struct orangefs_fs_mount_response *fs_mount, 402 - void *data, int silent) 413 + struct fs_context *fc, 414 + struct orangefs_fs_mount_response *fs_mount) 403 415 { 404 416 int ret; 405 417 struct inode *root; ··· 411 423 ORANGEFS_SB(sb)->root_khandle = fs_mount->root_khandle; 412 424 ORANGEFS_SB(sb)->fs_id = fs_mount->fs_id; 413 425 ORANGEFS_SB(sb)->id = fs_mount->id; 414 - 415 - if (data) { 416 - ret = parse_mount_options(sb, data, silent); 417 - if (ret) 418 - return ret; 419 - } 420 426 421 427 /* Hang the xattr handlers off the superblock */ 422 428 sb->s_xattr = orangefs_xattr_handlers; ··· 452 470 return 0; 453 471 } 454 472 455 - struct dentry *orangefs_mount(struct file_system_type *fst, 456 - int flags, 457 - const char *devname, 458 - void *data) 473 + static int orangefs_get_tree(struct fs_context *fc) 459 474 { 460 475 int ret; 461 476 struct super_block *sb = ERR_PTR(-EINVAL); 462 477 struct orangefs_kernel_op_s *new_op; 463 - struct dentry *d = ERR_PTR(-EINVAL); 478 + 479 + if (!fc->source) 480 + return invalf(fc, "Device name not specified.\n"); 464 481 465 482 gossip_debug(GOSSIP_SUPER_DEBUG, 466 483 "orangefs_mount: called with devname %s\n", 467 - devname); 468 - 469 - if (!devname) { 470 - gossip_err("ERROR: device name not specified.\n"); 471 - return ERR_PTR(-EINVAL); 472 - } 484 + fc->source); 473 485 474 486 new_op = op_alloc(ORANGEFS_VFS_OP_FS_MOUNT); 475 487 if (!new_op) 476 - return ERR_PTR(-ENOMEM); 488 + return -ENOMEM; 477 489 478 - strscpy(new_op->upcall.req.fs_mount.orangefs_config_server, devname); 490 + strscpy(new_op->upcall.req.fs_mount.orangefs_config_server, fc->source); 479 491 480 492 gossip_debug(GOSSIP_SUPER_DEBUG, 481 493 "Attempting ORANGEFS Mount via host %s\n", ··· 487 511 goto free_op; 488 512 } 489 513 490 - sb = sget(fst, NULL, set_anon_super, flags, NULL); 514 + sb = sget_fc(fc, NULL, set_anon_super_fc); 491 515 492 516 if (IS_ERR(sb)) { 493 - d = ERR_CAST(sb); 517 + ret = PTR_ERR(sb); 494 518 orangefs_unmount(new_op->downcall.resp.fs_mount.id, 495 - new_op->downcall.resp.fs_mount.fs_id, devname); 519 + new_op->downcall.resp.fs_mount.fs_id, 520 + fc->source); 496 521 goto free_op; 497 522 } 498 523 499 - /* alloc and init our private orangefs sb info */ 500 - sb->s_fs_info = kzalloc(sizeof(struct orangefs_sb_info_s), GFP_KERNEL); 501 - if (!ORANGEFS_SB(sb)) { 502 - d = ERR_PTR(-ENOMEM); 503 - goto free_op; 504 - } 524 + /* init our private orangefs sb info */ 525 + ret = orangefs_fill_sb(sb, fc, &new_op->downcall.resp.fs_mount); 505 526 506 - ret = orangefs_fill_sb(sb, 507 - &new_op->downcall.resp.fs_mount, data, 508 - flags & SB_SILENT ? 1 : 0); 509 - 510 - if (ret) { 511 - d = ERR_PTR(ret); 527 + if (ret) 512 528 goto free_sb_and_op; 513 - } 514 529 515 530 /* 516 531 * on successful mount, store the devname and data 517 532 * used 518 533 */ 519 - strscpy(ORANGEFS_SB(sb)->devname, devname); 520 - 534 + strscpy(ORANGEFS_SB(sb)->devname, fc->source); 521 535 522 536 /* mount_pending must be cleared */ 523 537 ORANGEFS_SB(sb)->mount_pending = 0; ··· 530 564 if (orangefs_userspace_version >= 20906) { 531 565 new_op = op_alloc(ORANGEFS_VFS_OP_FEATURES); 532 566 if (!new_op) 533 - return ERR_PTR(-ENOMEM); 567 + return -ENOMEM; 534 568 new_op->upcall.req.features.features = 0; 535 569 ret = service_operation(new_op, "orangefs_features", 0); 536 570 orangefs_features = new_op->downcall.resp.features.features; ··· 539 573 orangefs_features = 0; 540 574 } 541 575 542 - return dget(sb->s_root); 576 + fc->root = dget(sb->s_root); 577 + return 0; 543 578 544 579 free_sb_and_op: 545 580 /* Will call orangefs_kill_sb with sb not in list. */ ··· 556 589 557 590 op_release(new_op); 558 591 559 - return d; 592 + return ret; 593 + } 594 + 595 + static void orangefs_free_fc(struct fs_context *fc) 596 + { 597 + kfree(fc->s_fs_info); 598 + } 599 + 600 + static const struct fs_context_operations orangefs_context_ops = { 601 + .free = orangefs_free_fc, 602 + .parse_param = orangefs_parse_param, 603 + .get_tree = orangefs_get_tree, 604 + .reconfigure = orangefs_reconfigure, 605 + }; 606 + 607 + /* 608 + * Set up the filesystem mount context. 609 + */ 610 + int orangefs_init_fs_context(struct fs_context *fc) 611 + { 612 + struct orangefs_sb_info_s *osi; 613 + 614 + osi = kzalloc(sizeof(struct orangefs_sb_info_s), GFP_KERNEL); 615 + if (!osi) 616 + return -ENOMEM; 617 + 618 + /* 619 + * Force any potential flags that might be set from the mount 620 + * to zero, ie, initialize to unset. 621 + */ 622 + fc->sb_flags_mask &= ~SB_POSIXACL; 623 + osi->flags &= ~ORANGEFS_OPT_INTR; 624 + osi->flags &= ~ORANGEFS_OPT_LOCAL_LOCK; 625 + 626 + fc->s_fs_info = osi; 627 + fc->ops = &orangefs_context_ops; 628 + return 0; 560 629 } 561 630 562 631 void orangefs_kill_sb(struct super_block *sb)