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 /fs/ecryptfs | |
parent | decabd6650915a9534dad09e967115513be12b24 (diff) |
Clean ecryptfs ->get_sb() up
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/ecryptfs')
-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 | ||