diff options
Diffstat (limited to 'fs/ecryptfs/main.c')
-rw-r--r-- | fs/ecryptfs/main.c | 135 |
1 files changed, 24 insertions, 111 deletions
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index b83a512b7e08..0249aa4ae181 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -138,11 +138,14 @@ int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry) | |||
138 | inode_info->lower_file = dentry_open(lower_dentry, | 138 | inode_info->lower_file = dentry_open(lower_dentry, |
139 | lower_mnt, | 139 | lower_mnt, |
140 | (O_RDWR | O_LARGEFILE)); | 140 | (O_RDWR | O_LARGEFILE)); |
141 | if (IS_ERR(inode_info->lower_file)) | 141 | if (IS_ERR(inode_info->lower_file)) { |
142 | dget(lower_dentry); | ||
143 | mntget(lower_mnt); | ||
142 | inode_info->lower_file = dentry_open(lower_dentry, | 144 | inode_info->lower_file = dentry_open(lower_dentry, |
143 | lower_mnt, | 145 | lower_mnt, |
144 | (O_RDONLY | 146 | (O_RDONLY |
145 | | O_LARGEFILE)); | 147 | | O_LARGEFILE)); |
148 | } | ||
146 | if (IS_ERR(inode_info->lower_file)) { | 149 | if (IS_ERR(inode_info->lower_file)) { |
147 | printk(KERN_ERR "Error opening lower persistent file " | 150 | printk(KERN_ERR "Error opening lower persistent file " |
148 | "for lower_dentry [0x%p] and lower_mnt [0x%p]\n", | 151 | "for lower_dentry [0x%p] and lower_mnt [0x%p]\n", |
@@ -523,6 +526,7 @@ static int ecryptfs_read_super(struct super_block *sb, const char *dev_name) | |||
523 | lower_mnt = nd.mnt; | 526 | lower_mnt = nd.mnt; |
524 | ecryptfs_set_superblock_lower(sb, lower_root->d_sb); | 527 | ecryptfs_set_superblock_lower(sb, lower_root->d_sb); |
525 | sb->s_maxbytes = lower_root->d_sb->s_maxbytes; | 528 | sb->s_maxbytes = lower_root->d_sb->s_maxbytes; |
529 | sb->s_blocksize = lower_root->d_sb->s_blocksize; | ||
526 | ecryptfs_set_dentry_lower(sb->s_root, lower_root); | 530 | ecryptfs_set_dentry_lower(sb->s_root, lower_root); |
527 | ecryptfs_set_dentry_lower_mnt(sb->s_root, lower_mnt); | 531 | ecryptfs_set_dentry_lower_mnt(sb->s_root, lower_mnt); |
528 | rc = ecryptfs_interpose(lower_root, sb->s_root, sb, 0); | 532 | rc = ecryptfs_interpose(lower_root, sb->s_root, sb, 0); |
@@ -730,127 +734,40 @@ static int ecryptfs_init_kmem_caches(void) | |||
730 | return 0; | 734 | return 0; |
731 | } | 735 | } |
732 | 736 | ||
733 | struct ecryptfs_obj { | 737 | static struct kobject *ecryptfs_kobj; |
734 | char *name; | ||
735 | struct list_head slot_list; | ||
736 | struct kobject kobj; | ||
737 | }; | ||
738 | |||
739 | struct ecryptfs_attribute { | ||
740 | struct attribute attr; | ||
741 | ssize_t(*show) (struct ecryptfs_obj *, char *); | ||
742 | ssize_t(*store) (struct ecryptfs_obj *, const char *, size_t); | ||
743 | }; | ||
744 | |||
745 | static ssize_t | ||
746 | ecryptfs_attr_store(struct kobject *kobj, | ||
747 | struct attribute *attr, const char *buf, size_t len) | ||
748 | { | ||
749 | struct ecryptfs_obj *obj = container_of(kobj, struct ecryptfs_obj, | ||
750 | kobj); | ||
751 | struct ecryptfs_attribute *attribute = | ||
752 | container_of(attr, struct ecryptfs_attribute, attr); | ||
753 | |||
754 | return (attribute->store ? attribute->store(obj, buf, len) : 0); | ||
755 | } | ||
756 | 738 | ||
757 | static ssize_t | 739 | static ssize_t version_show(struct kobject *kobj, |
758 | ecryptfs_attr_show(struct kobject *kobj, struct attribute *attr, char *buf) | 740 | struct kobj_attribute *attr, char *buff) |
759 | { | 741 | { |
760 | struct ecryptfs_obj *obj = container_of(kobj, struct ecryptfs_obj, | 742 | return snprintf(buff, PAGE_SIZE, "%d\n", ECRYPTFS_VERSIONING_MASK); |
761 | kobj); | ||
762 | struct ecryptfs_attribute *attribute = | ||
763 | container_of(attr, struct ecryptfs_attribute, attr); | ||
764 | |||
765 | return (attribute->show ? attribute->show(obj, buf) : 0); | ||
766 | } | 743 | } |
767 | 744 | ||
768 | static struct sysfs_ops ecryptfs_sysfs_ops = { | 745 | static struct kobj_attribute version_attr = __ATTR_RO(version); |
769 | .show = ecryptfs_attr_show, | ||
770 | .store = ecryptfs_attr_store | ||
771 | }; | ||
772 | 746 | ||
773 | static struct kobj_type ecryptfs_ktype = { | 747 | static struct attribute *attributes[] = { |
774 | .sysfs_ops = &ecryptfs_sysfs_ops | 748 | &version_attr.attr, |
749 | NULL, | ||
775 | }; | 750 | }; |
776 | 751 | ||
777 | static decl_subsys(ecryptfs, &ecryptfs_ktype, NULL); | 752 | static struct attribute_group attr_group = { |
778 | 753 | .attrs = attributes, | |
779 | static ssize_t version_show(struct ecryptfs_obj *obj, char *buff) | ||
780 | { | ||
781 | return snprintf(buff, PAGE_SIZE, "%d\n", ECRYPTFS_VERSIONING_MASK); | ||
782 | } | ||
783 | |||
784 | static struct ecryptfs_attribute sysfs_attr_version = __ATTR_RO(version); | ||
785 | |||
786 | static struct ecryptfs_version_str_map_elem { | ||
787 | u32 flag; | ||
788 | char *str; | ||
789 | } ecryptfs_version_str_map[] = { | ||
790 | {ECRYPTFS_VERSIONING_PASSPHRASE, "passphrase"}, | ||
791 | {ECRYPTFS_VERSIONING_PUBKEY, "pubkey"}, | ||
792 | {ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH, "plaintext passthrough"}, | ||
793 | {ECRYPTFS_VERSIONING_POLICY, "policy"}, | ||
794 | {ECRYPTFS_VERSIONING_XATTR, "metadata in extended attribute"}, | ||
795 | {ECRYPTFS_VERSIONING_MULTKEY, "multiple keys per file"} | ||
796 | }; | 754 | }; |
797 | 755 | ||
798 | static ssize_t version_str_show(struct ecryptfs_obj *obj, char *buff) | ||
799 | { | ||
800 | int i; | ||
801 | int remaining = PAGE_SIZE; | ||
802 | int total_written = 0; | ||
803 | |||
804 | buff[0] = '\0'; | ||
805 | for (i = 0; i < ARRAY_SIZE(ecryptfs_version_str_map); i++) { | ||
806 | int entry_size; | ||
807 | |||
808 | if (!(ECRYPTFS_VERSIONING_MASK | ||
809 | & ecryptfs_version_str_map[i].flag)) | ||
810 | continue; | ||
811 | entry_size = strlen(ecryptfs_version_str_map[i].str); | ||
812 | if ((entry_size + 2) > remaining) | ||
813 | goto out; | ||
814 | memcpy(buff, ecryptfs_version_str_map[i].str, entry_size); | ||
815 | buff[entry_size++] = '\n'; | ||
816 | buff[entry_size] = '\0'; | ||
817 | buff += entry_size; | ||
818 | total_written += entry_size; | ||
819 | remaining -= entry_size; | ||
820 | } | ||
821 | out: | ||
822 | return total_written; | ||
823 | } | ||
824 | |||
825 | static struct ecryptfs_attribute sysfs_attr_version_str = __ATTR_RO(version_str); | ||
826 | |||
827 | static int do_sysfs_registration(void) | 756 | static int do_sysfs_registration(void) |
828 | { | 757 | { |
829 | int rc; | 758 | int rc; |
830 | 759 | ||
831 | rc = subsystem_register(&ecryptfs_subsys); | 760 | ecryptfs_kobj = kobject_create_and_add("ecryptfs", fs_kobj); |
832 | if (rc) { | 761 | if (!ecryptfs_kobj) { |
833 | printk(KERN_ERR | 762 | printk(KERN_ERR "Unable to create ecryptfs kset\n"); |
834 | "Unable to register ecryptfs sysfs subsystem\n"); | 763 | rc = -ENOMEM; |
835 | goto out; | ||
836 | } | ||
837 | rc = sysfs_create_file(&ecryptfs_subsys.kobj, | ||
838 | &sysfs_attr_version.attr); | ||
839 | if (rc) { | ||
840 | printk(KERN_ERR | ||
841 | "Unable to create ecryptfs version attribute\n"); | ||
842 | subsystem_unregister(&ecryptfs_subsys); | ||
843 | goto out; | 764 | goto out; |
844 | } | 765 | } |
845 | rc = sysfs_create_file(&ecryptfs_subsys.kobj, | 766 | rc = sysfs_create_group(ecryptfs_kobj, &attr_group); |
846 | &sysfs_attr_version_str.attr); | ||
847 | if (rc) { | 767 | if (rc) { |
848 | printk(KERN_ERR | 768 | printk(KERN_ERR |
849 | "Unable to create ecryptfs version_str attribute\n"); | 769 | "Unable to create ecryptfs version attributes\n"); |
850 | sysfs_remove_file(&ecryptfs_subsys.kobj, | 770 | kobject_put(ecryptfs_kobj); |
851 | &sysfs_attr_version.attr); | ||
852 | subsystem_unregister(&ecryptfs_subsys); | ||
853 | goto out; | ||
854 | } | 771 | } |
855 | out: | 772 | out: |
856 | return rc; | 773 | return rc; |
@@ -858,11 +775,8 @@ out: | |||
858 | 775 | ||
859 | static void do_sysfs_unregistration(void) | 776 | static void do_sysfs_unregistration(void) |
860 | { | 777 | { |
861 | sysfs_remove_file(&ecryptfs_subsys.kobj, | 778 | sysfs_remove_group(ecryptfs_kobj, &attr_group); |
862 | &sysfs_attr_version.attr); | 779 | kobject_put(ecryptfs_kobj); |
863 | sysfs_remove_file(&ecryptfs_subsys.kobj, | ||
864 | &sysfs_attr_version_str.attr); | ||
865 | subsystem_unregister(&ecryptfs_subsys); | ||
866 | } | 780 | } |
867 | 781 | ||
868 | static int __init ecryptfs_init(void) | 782 | static int __init ecryptfs_init(void) |
@@ -890,7 +804,6 @@ static int __init ecryptfs_init(void) | |||
890 | printk(KERN_ERR "Failed to register filesystem\n"); | 804 | printk(KERN_ERR "Failed to register filesystem\n"); |
891 | goto out_free_kmem_caches; | 805 | goto out_free_kmem_caches; |
892 | } | 806 | } |
893 | kobj_set_kset_s(&ecryptfs_subsys, fs_subsys); | ||
894 | rc = do_sysfs_registration(); | 807 | rc = do_sysfs_registration(); |
895 | if (rc) { | 808 | if (rc) { |
896 | printk(KERN_ERR "sysfs registration failed\n"); | 809 | printk(KERN_ERR "sysfs registration failed\n"); |