diff options
Diffstat (limited to 'fs/ecryptfs/main.c')
-rw-r--r-- | fs/ecryptfs/main.c | 166 |
1 files changed, 81 insertions, 85 deletions
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 760983d0f25e..cbd4e18adb20 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; |
@@ -483,68 +483,7 @@ out: | |||
483 | } | 483 | } |
484 | 484 | ||
485 | struct kmem_cache *ecryptfs_sb_info_cache; | 485 | struct kmem_cache *ecryptfs_sb_info_cache; |
486 | 486 | static struct file_system_type ecryptfs_fs_type; | |
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 | 487 | ||
549 | /** | 488 | /** |
550 | * ecryptfs_read_super | 489 | * ecryptfs_read_super |
@@ -565,6 +504,13 @@ static int ecryptfs_read_super(struct super_block *sb, const char *dev_name) | |||
565 | ecryptfs_printk(KERN_WARNING, "path_lookup() failed\n"); | 504 | ecryptfs_printk(KERN_WARNING, "path_lookup() failed\n"); |
566 | goto out; | 505 | goto out; |
567 | } | 506 | } |
507 | if (path.dentry->d_sb->s_type == &ecryptfs_fs_type) { | ||
508 | rc = -EINVAL; | ||
509 | printk(KERN_ERR "Mount on filesystem of type " | ||
510 | "eCryptfs explicitly disallowed due to " | ||
511 | "known incompatibilities\n"); | ||
512 | goto out_free; | ||
513 | } | ||
568 | ecryptfs_set_superblock_lower(sb, path.dentry->d_sb); | 514 | ecryptfs_set_superblock_lower(sb, path.dentry->d_sb); |
569 | sb->s_maxbytes = path.dentry->d_sb->s_maxbytes; | 515 | sb->s_maxbytes = path.dentry->d_sb->s_maxbytes; |
570 | sb->s_blocksize = path.dentry->d_sb->s_blocksize; | 516 | sb->s_blocksize = path.dentry->d_sb->s_blocksize; |
@@ -588,11 +534,8 @@ out: | |||
588 | * @dev_name: The path to mount over | 534 | * @dev_name: The path to mount over |
589 | * @raw_data: The options passed into the kernel | 535 | * @raw_data: The options passed into the kernel |
590 | * | 536 | * |
591 | * The whole ecryptfs_get_sb process is broken into 4 functions: | 537 | * The whole ecryptfs_get_sb process is broken into 3 functions: |
592 | * ecryptfs_parse_options(): handle options passed to ecryptfs, if any | 538 | * 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 | 539 | * ecryptfs_read_super(): this accesses the lower filesystem and uses |
597 | * ecryptfs_interpose to perform most of the linking | 540 | * ecryptfs_interpose to perform most of the linking |
598 | * ecryptfs_interpose(): links the lower filesystem into ecryptfs (inode.c) | 541 | * ecryptfs_interpose(): links the lower filesystem into ecryptfs (inode.c) |
@@ -601,30 +544,78 @@ static int ecryptfs_get_sb(struct file_system_type *fs_type, int flags, | |||
601 | const char *dev_name, void *raw_data, | 544 | const char *dev_name, void *raw_data, |
602 | struct vfsmount *mnt) | 545 | struct vfsmount *mnt) |
603 | { | 546 | { |
547 | struct super_block *s; | ||
548 | struct ecryptfs_sb_info *sbi; | ||
549 | struct ecryptfs_dentry_info *root_info; | ||
550 | const char *err = "Getting sb failed"; | ||
604 | int rc; | 551 | int rc; |
605 | struct super_block *sb; | ||
606 | 552 | ||
607 | rc = get_sb_nodev(fs_type, flags, raw_data, ecryptfs_fill_super, mnt); | 553 | sbi = kmem_cache_zalloc(ecryptfs_sb_info_cache, GFP_KERNEL); |
608 | if (rc < 0) { | 554 | if (!sbi) { |
609 | printk(KERN_ERR "Getting sb failed; rc = [%d]\n", rc); | 555 | rc = -ENOMEM; |
610 | goto out; | 556 | goto out; |
611 | } | 557 | } |
612 | sb = mnt->mnt_sb; | 558 | |
613 | rc = ecryptfs_parse_options(sb, raw_data); | 559 | rc = ecryptfs_parse_options(sbi, raw_data); |
614 | if (rc) { | 560 | if (rc) { |
615 | printk(KERN_ERR "Error parsing options; rc = [%d]\n", rc); | 561 | err = "Error parsing options"; |
616 | goto out_abort; | 562 | goto out; |
563 | } | ||
564 | |||
565 | s = sget(fs_type, NULL, set_anon_super, NULL); | ||
566 | if (IS_ERR(s)) { | ||
567 | rc = PTR_ERR(s); | ||
568 | goto out; | ||
617 | } | 569 | } |
618 | rc = ecryptfs_read_super(sb, dev_name); | 570 | |
571 | s->s_flags = flags; | ||
572 | rc = bdi_setup_and_register(&sbi->bdi, "ecryptfs", BDI_CAP_MAP_COPY); | ||
619 | if (rc) { | 573 | if (rc) { |
620 | printk(KERN_ERR "Reading sb failed; rc = [%d]\n", rc); | 574 | deactivate_locked_super(s); |
621 | goto out_abort; | 575 | goto out; |
622 | } | 576 | } |
623 | goto out; | 577 | |
624 | out_abort: | 578 | ecryptfs_set_superblock_private(s, sbi); |
625 | dput(sb->s_root); /* aka mnt->mnt_root, as set by get_sb_nodev() */ | 579 | s->s_bdi = &sbi->bdi; |
626 | deactivate_locked_super(sb); | 580 | |
581 | /* ->kill_sb() will take care of sbi after that point */ | ||
582 | sbi = NULL; | ||
583 | s->s_op = &ecryptfs_sops; | ||
584 | |||
585 | rc = -ENOMEM; | ||
586 | s->s_root = d_alloc(NULL, &(const struct qstr) { | ||
587 | .hash = 0,.name = "/",.len = 1}); | ||
588 | if (!s->s_root) { | ||
589 | deactivate_locked_super(s); | ||
590 | goto out; | ||
591 | } | ||
592 | s->s_root->d_op = &ecryptfs_dops; | ||
593 | s->s_root->d_sb = s; | ||
594 | s->s_root->d_parent = s->s_root; | ||
595 | |||
596 | root_info = kmem_cache_zalloc(ecryptfs_dentry_info_cache, GFP_KERNEL); | ||
597 | if (!root_info) { | ||
598 | deactivate_locked_super(s); | ||
599 | goto out; | ||
600 | } | ||
601 | /* ->kill_sb() will take care of root_info */ | ||
602 | ecryptfs_set_dentry_private(s->s_root, root_info); | ||
603 | s->s_flags |= MS_ACTIVE; | ||
604 | rc = ecryptfs_read_super(s, dev_name); | ||
605 | if (rc) { | ||
606 | deactivate_locked_super(s); | ||
607 | err = "Reading sb failed"; | ||
608 | goto out; | ||
609 | } | ||
610 | simple_set_mnt(mnt, s); | ||
611 | return 0; | ||
612 | |||
627 | out: | 613 | out: |
614 | if (sbi) { | ||
615 | ecryptfs_destroy_mount_crypt_stat(&sbi->mount_crypt_stat); | ||
616 | kmem_cache_free(ecryptfs_sb_info_cache, sbi); | ||
617 | } | ||
618 | printk(KERN_ERR "%s; rc = [%d]\n", err, rc); | ||
628 | return rc; | 619 | return rc; |
629 | } | 620 | } |
630 | 621 | ||
@@ -633,11 +624,16 @@ out: | |||
633 | * @sb: The ecryptfs super block | 624 | * @sb: The ecryptfs super block |
634 | * | 625 | * |
635 | * Used to bring the superblock down and free the private data. | 626 | * Used to bring the superblock down and free the private data. |
636 | * Private data is free'd in ecryptfs_put_super() | ||
637 | */ | 627 | */ |
638 | static void ecryptfs_kill_block_super(struct super_block *sb) | 628 | static void ecryptfs_kill_block_super(struct super_block *sb) |
639 | { | 629 | { |
640 | generic_shutdown_super(sb); | 630 | struct ecryptfs_sb_info *sb_info = ecryptfs_superblock_to_private(sb); |
631 | kill_anon_super(sb); | ||
632 | if (!sb_info) | ||
633 | return; | ||
634 | ecryptfs_destroy_mount_crypt_stat(&sb_info->mount_crypt_stat); | ||
635 | bdi_destroy(&sb_info->bdi); | ||
636 | kmem_cache_free(ecryptfs_sb_info_cache, sb_info); | ||
641 | } | 637 | } |
642 | 638 | ||
643 | static struct file_system_type ecryptfs_fs_type = { | 639 | static struct file_system_type ecryptfs_fs_type = { |