diff options
| author | Al Viro <viro@zeniv.linux.org.uk> | 2010-03-21 12:24:29 -0400 |
|---|---|---|
| committer | Al Viro <viro@zeniv.linux.org.uk> | 2010-05-21 18:31:13 -0400 |
| commit | 2ccde7c631f992bf79da8007b5fc8b6425eb0d6d (patch) | |
| tree | d99cbae607223c76916fd373d7a827515ed022c0 | |
| parent | decabd6650915a9534dad09e967115513be12b24 (diff) | |
Clean ecryptfs ->get_sb() up
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
| -rw-r--r-- | fs/ecryptfs/main.c | 149 |
1 files changed, 66 insertions, 83 deletions
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 36268db29ea1..7d3ed6bfcfa5 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
| @@ -281,7 +281,7 @@ static void ecryptfs_init_mount_crypt_stat( | |||
| 281 | * | 281 | * |
| 282 | * Returns zero on success; non-zero on error | 282 | * Returns zero on success; non-zero on error |
| 283 | */ | 283 | */ |
| 284 | static int ecryptfs_parse_options(struct super_block *sb, char *options) | 284 | static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options) |
| 285 | { | 285 | { |
| 286 | char *p; | 286 | char *p; |
| 287 | int rc = 0; | 287 | int rc = 0; |
| @@ -293,7 +293,7 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options) | |||
| 293 | int fn_cipher_key_bytes; | 293 | int fn_cipher_key_bytes; |
| 294 | int fn_cipher_key_bytes_set = 0; | 294 | int fn_cipher_key_bytes_set = 0; |
| 295 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = | 295 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat = |
| 296 | &ecryptfs_superblock_to_private(sb)->mount_crypt_stat; | 296 | &sbi->mount_crypt_stat; |
| 297 | substring_t args[MAX_OPT_ARGS]; | 297 | substring_t args[MAX_OPT_ARGS]; |
| 298 | int token; | 298 | int token; |
| 299 | char *sig_src; | 299 | char *sig_src; |
| @@ -485,68 +485,6 @@ out: | |||
| 485 | struct kmem_cache *ecryptfs_sb_info_cache; | 485 | struct kmem_cache *ecryptfs_sb_info_cache; |
| 486 | 486 | ||
| 487 | /** | 487 | /** |
| 488 | * ecryptfs_fill_super | ||
| 489 | * @sb: The ecryptfs super block | ||
| 490 | * @raw_data: The options passed to mount | ||
| 491 | * @silent: Not used but required by function prototype | ||
| 492 | * | ||
| 493 | * Sets up what we can of the sb, rest is done in ecryptfs_read_super | ||
| 494 | * | ||
| 495 | * Returns zero on success; non-zero otherwise | ||
| 496 | */ | ||
| 497 | static int | ||
| 498 | ecryptfs_fill_super(struct super_block *sb, void *raw_data, int silent) | ||
| 499 | { | ||
| 500 | struct ecryptfs_sb_info *esi; | ||
| 501 | int rc = 0; | ||
| 502 | |||
| 503 | /* Released in ecryptfs_put_super() */ | ||
| 504 | ecryptfs_set_superblock_private(sb, | ||
| 505 | kmem_cache_zalloc(ecryptfs_sb_info_cache, | ||
| 506 | GFP_KERNEL)); | ||
| 507 | esi = ecryptfs_superblock_to_private(sb); | ||
| 508 | if (!esi) { | ||
| 509 | ecryptfs_printk(KERN_WARNING, "Out of memory\n"); | ||
| 510 | rc = -ENOMEM; | ||
| 511 | goto out; | ||
| 512 | } | ||
| 513 | |||
| 514 | rc = bdi_setup_and_register(&esi->bdi, "ecryptfs", BDI_CAP_MAP_COPY); | ||
| 515 | if (rc) | ||
| 516 | goto out; | ||
| 517 | |||
| 518 | sb->s_bdi = &esi->bdi; | ||
| 519 | sb->s_op = &ecryptfs_sops; | ||
| 520 | /* Released through deactivate_super(sb) from get_sb_nodev */ | ||
| 521 | sb->s_root = d_alloc(NULL, &(const struct qstr) { | ||
| 522 | .hash = 0,.name = "/",.len = 1}); | ||
| 523 | if (!sb->s_root) { | ||
| 524 | ecryptfs_printk(KERN_ERR, "d_alloc failed\n"); | ||
| 525 | rc = -ENOMEM; | ||
| 526 | goto out; | ||
| 527 | } | ||
| 528 | sb->s_root->d_op = &ecryptfs_dops; | ||
| 529 | sb->s_root->d_sb = sb; | ||
| 530 | sb->s_root->d_parent = sb->s_root; | ||
| 531 | /* Released in d_release when dput(sb->s_root) is called */ | ||
| 532 | /* through deactivate_super(sb) from get_sb_nodev() */ | ||
| 533 | ecryptfs_set_dentry_private(sb->s_root, | ||
| 534 | kmem_cache_zalloc(ecryptfs_dentry_info_cache, | ||
| 535 | GFP_KERNEL)); | ||
| 536 | if (!ecryptfs_dentry_to_private(sb->s_root)) { | ||
| 537 | ecryptfs_printk(KERN_ERR, | ||
| 538 | "dentry_info_cache alloc failed\n"); | ||
| 539 | rc = -ENOMEM; | ||
| 540 | goto out; | ||
| 541 | } | ||
| 542 | rc = 0; | ||
| 543 | out: | ||
| 544 | /* Should be able to rely on deactivate_super called from | ||
| 545 | * get_sb_nodev */ | ||
| 546 | return rc; | ||
| 547 | } | ||
| 548 | |||
| 549 | /** | ||
| 550 | * ecryptfs_read_super | 488 | * ecryptfs_read_super |
| 551 | * @sb: The ecryptfs super block | 489 | * @sb: The ecryptfs super block |
| 552 | * @dev_name: The path to mount over | 490 | * @dev_name: The path to mount over |
| @@ -588,11 +526,8 @@ out: | |||
| 588 | * @dev_name: The path to mount over | 526 | * @dev_name: The path to mount over |
| 589 | * @raw_data: The options passed into the kernel | 527 | * @raw_data: The options passed into the kernel |
| 590 | * | 528 | * |
| 591 | * The whole ecryptfs_get_sb process is broken into 4 functions: | 529 | * The whole ecryptfs_get_sb process is broken into 3 functions: |
| 592 | * ecryptfs_parse_options(): handle options passed to ecryptfs, if any | 530 | * ecryptfs_parse_options(): handle options passed to ecryptfs, if any |
| 593 | * ecryptfs_fill_super(): used by get_sb_nodev, fills out the super_block | ||
| 594 | * with as much information as it can before needing | ||
| 595 | * the lower filesystem. | ||
| 596 | * ecryptfs_read_super(): this accesses the lower filesystem and uses | 531 | * ecryptfs_read_super(): this accesses the lower filesystem and uses |
| 597 | * ecryptfs_interpose to perform most of the linking | 532 | * ecryptfs_interpose to perform most of the linking |
| 598 | * ecryptfs_interpose(): links the lower filesystem into ecryptfs (inode.c) | 533 | * ecryptfs_interpose(): links the lower filesystem into ecryptfs (inode.c) |
| @@ -601,30 +536,78 @@ static int ecryptfs_get_sb(struct file_system_type *fs_type, int flags, | |||
| 601 | const char *dev_name, void *raw_data, | 536 | const char *dev_name, void *raw_data, |
| 602 | struct vfsmount *mnt) | 537 | struct vfsmount *mnt) |
| 603 | { | 538 | { |
| 539 | struct super_block *s; | ||
| 540 | struct ecryptfs_sb_info *sbi; | ||
| 541 | struct ecryptfs_dentry_info *root_info; | ||
| 542 | const char *err = "Getting sb failed"; | ||
| 604 | int rc; | 543 | int rc; |
| 605 | struct super_block *sb; | ||
| 606 | 544 | ||
| 607 | rc = get_sb_nodev(fs_type, flags, raw_data, ecryptfs_fill_super, mnt); | 545 | sbi = kmem_cache_zalloc(ecryptfs_sb_info_cache, GFP_KERNEL); |
| 608 | if (rc < 0) { | 546 | if (!sbi) { |
| 609 | printk(KERN_ERR "Getting sb failed; rc = [%d]\n", rc); | 547 | rc = -ENOMEM; |
| 610 | goto out; | 548 | goto out; |
| 611 | } | 549 | } |
| 612 | sb = mnt->mnt_sb; | 550 | |
| 613 | rc = ecryptfs_parse_options(sb, raw_data); | 551 | rc = ecryptfs_parse_options(sbi, raw_data); |
| 614 | if (rc) { | 552 | if (rc) { |
| 615 | printk(KERN_ERR "Error parsing options; rc = [%d]\n", rc); | 553 | err = "Error parsing options"; |
| 616 | goto out_abort; | 554 | goto out; |
| 617 | } | 555 | } |
| 618 | rc = ecryptfs_read_super(sb, dev_name); | 556 | |
| 557 | s = sget(fs_type, NULL, set_anon_super, NULL); | ||
| 558 | if (IS_ERR(s)) { | ||
| 559 | rc = PTR_ERR(s); | ||
| 560 | goto out; | ||
| 561 | } | ||
| 562 | |||
| 563 | s->s_flags = flags; | ||
| 564 | rc = bdi_setup_and_register(&sbi->bdi, "ecryptfs", BDI_CAP_MAP_COPY); | ||
| 619 | if (rc) { | 565 | if (rc) { |
| 620 | printk(KERN_ERR "Reading sb failed; rc = [%d]\n", rc); | 566 | deactivate_locked_super(s); |
| 621 | goto out_abort; | 567 | goto out; |
| 622 | } | 568 | } |
| 623 | goto out; | 569 | |
| 624 | out_abort: | 570 | ecryptfs_set_superblock_private(s, sbi); |
| 625 | dput(sb->s_root); /* aka mnt->mnt_root, as set by get_sb_nodev() */ | 571 | s->s_bdi = &sbi->bdi; |
| 626 | deactivate_locked_super(sb); | 572 | |
| 573 | /* ->kill_sb() will take care of sbi after that point */ | ||
| 574 | sbi = NULL; | ||
| 575 | s->s_op = &ecryptfs_sops; | ||
| 576 | |||
| 577 | rc = -ENOMEM; | ||
| 578 | s->s_root = d_alloc(NULL, &(const struct qstr) { | ||
| 579 | .hash = 0,.name = "/",.len = 1}); | ||
| 580 | if (!s->s_root) { | ||
| 581 | deactivate_locked_super(s); | ||
| 582 | goto out; | ||
| 583 | } | ||
| 584 | s->s_root->d_op = &ecryptfs_dops; | ||
| 585 | s->s_root->d_sb = s; | ||
| 586 | s->s_root->d_parent = s->s_root; | ||
| 587 | |||
| 588 | root_info = kmem_cache_zalloc(ecryptfs_dentry_info_cache, GFP_KERNEL); | ||
| 589 | if (!root_info) { | ||
| 590 | deactivate_locked_super(s); | ||
| 591 | goto out; | ||
| 592 | } | ||
| 593 | /* ->kill_sb() will take care of root_info */ | ||
| 594 | ecryptfs_set_dentry_private(s->s_root, root_info); | ||
| 595 | s->s_flags |= MS_ACTIVE; | ||
| 596 | rc = ecryptfs_read_super(s, dev_name); | ||
| 597 | if (rc) { | ||
| 598 | deactivate_locked_super(s); | ||
| 599 | err = "Reading sb failed"; | ||
| 600 | goto out; | ||
| 601 | } | ||
| 602 | simple_set_mnt(mnt, s); | ||
| 603 | return 0; | ||
| 604 | |||
| 627 | out: | 605 | out: |
| 606 | if (sbi) { | ||
| 607 | ecryptfs_destroy_mount_crypt_stat(&sbi->mount_crypt_stat); | ||
| 608 | kmem_cache_free(ecryptfs_sb_info_cache, sbi); | ||
| 609 | } | ||
| 610 | printk(KERN_ERR "%s; rc = [%d]\n", err, rc); | ||
| 628 | return rc; | 611 | return rc; |
| 629 | } | 612 | } |
| 630 | 613 | ||
