summaryrefslogtreecommitdiffstats
path: root/fs/ext4/super.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4/super.c')
-rw-r--r--fs/ext4/super.c85
1 files changed, 85 insertions, 0 deletions
diff --git a/fs/ext4/super.c b/fs/ext4/super.c
index 184944d4d8d1..c1b02c3a5a68 100644
--- a/fs/ext4/super.c
+++ b/fs/ext4/super.c
@@ -42,6 +42,7 @@
42#include <linux/cleancache.h> 42#include <linux/cleancache.h>
43#include <linux/uaccess.h> 43#include <linux/uaccess.h>
44#include <linux/iversion.h> 44#include <linux/iversion.h>
45#include <linux/unicode.h>
45 46
46#include <linux/kthread.h> 47#include <linux/kthread.h>
47#include <linux/freezer.h> 48#include <linux/freezer.h>
@@ -1054,6 +1055,9 @@ static void ext4_put_super(struct super_block *sb)
1054 crypto_free_shash(sbi->s_chksum_driver); 1055 crypto_free_shash(sbi->s_chksum_driver);
1055 kfree(sbi->s_blockgroup_lock); 1056 kfree(sbi->s_blockgroup_lock);
1056 fs_put_dax(sbi->s_daxdev); 1057 fs_put_dax(sbi->s_daxdev);
1058#ifdef CONFIG_UNICODE
1059 utf8_unload(sbi->s_encoding);
1060#endif
1057 kfree(sbi); 1061 kfree(sbi);
1058} 1062}
1059 1063
@@ -1750,6 +1754,36 @@ static const struct mount_opts {
1750 {Opt_err, 0, 0} 1754 {Opt_err, 0, 0}
1751}; 1755};
1752 1756
1757#ifdef CONFIG_UNICODE
1758static const struct ext4_sb_encodings {
1759 __u16 magic;
1760 char *name;
1761 char *version;
1762} ext4_sb_encoding_map[] = {
1763 {EXT4_ENC_UTF8_12_1, "utf8", "12.1.0"},
1764};
1765
1766static int ext4_sb_read_encoding(const struct ext4_super_block *es,
1767 const struct ext4_sb_encodings **encoding,
1768 __u16 *flags)
1769{
1770 __u16 magic = le16_to_cpu(es->s_encoding);
1771 int i;
1772
1773 for (i = 0; i < ARRAY_SIZE(ext4_sb_encoding_map); i++)
1774 if (magic == ext4_sb_encoding_map[i].magic)
1775 break;
1776
1777 if (i >= ARRAY_SIZE(ext4_sb_encoding_map))
1778 return -EINVAL;
1779
1780 *encoding = &ext4_sb_encoding_map[i];
1781 *flags = le16_to_cpu(es->s_encoding_flags);
1782
1783 return 0;
1784}
1785#endif
1786
1753static int handle_mount_opt(struct super_block *sb, char *opt, int token, 1787static int handle_mount_opt(struct super_block *sb, char *opt, int token,
1754 substring_t *args, unsigned long *journal_devnum, 1788 substring_t *args, unsigned long *journal_devnum,
1755 unsigned int *journal_ioprio, int is_remount) 1789 unsigned int *journal_ioprio, int is_remount)
@@ -2880,6 +2914,15 @@ static int ext4_feature_set_ok(struct super_block *sb, int readonly)
2880 return 0; 2914 return 0;
2881 } 2915 }
2882 2916
2917#ifndef CONFIG_UNICODE
2918 if (ext4_has_feature_casefold(sb)) {
2919 ext4_msg(sb, KERN_ERR,
2920 "Filesystem with casefold feature cannot be "
2921 "mounted without CONFIG_UNICODE");
2922 return 0;
2923 }
2924#endif
2925
2883 if (readonly) 2926 if (readonly)
2884 return 1; 2927 return 1;
2885 2928
@@ -3770,6 +3813,43 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
3770 &journal_ioprio, 0)) 3813 &journal_ioprio, 0))
3771 goto failed_mount; 3814 goto failed_mount;
3772 3815
3816#ifdef CONFIG_UNICODE
3817 if (ext4_has_feature_casefold(sb) && !sbi->s_encoding) {
3818 const struct ext4_sb_encodings *encoding_info;
3819 struct unicode_map *encoding;
3820 __u16 encoding_flags;
3821
3822 if (ext4_has_feature_encrypt(sb)) {
3823 ext4_msg(sb, KERN_ERR,
3824 "Can't mount with encoding and encryption");
3825 goto failed_mount;
3826 }
3827
3828 if (ext4_sb_read_encoding(es, &encoding_info,
3829 &encoding_flags)) {
3830 ext4_msg(sb, KERN_ERR,
3831 "Encoding requested by superblock is unknown");
3832 goto failed_mount;
3833 }
3834
3835 encoding = utf8_load(encoding_info->version);
3836 if (IS_ERR(encoding)) {
3837 ext4_msg(sb, KERN_ERR,
3838 "can't mount with superblock charset: %s-%s "
3839 "not supported by the kernel. flags: 0x%x.",
3840 encoding_info->name, encoding_info->version,
3841 encoding_flags);
3842 goto failed_mount;
3843 }
3844 ext4_msg(sb, KERN_INFO,"Using encoding defined by superblock: "
3845 "%s-%s with flags 0x%hx", encoding_info->name,
3846 encoding_info->version?:"\b", encoding_flags);
3847
3848 sbi->s_encoding = encoding;
3849 sbi->s_encoding_flags = encoding_flags;
3850 }
3851#endif
3852
3773 if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) { 3853 if (test_opt(sb, DATA_FLAGS) == EXT4_MOUNT_JOURNAL_DATA) {
3774 printk_once(KERN_WARNING "EXT4-fs: Warning: mounting " 3854 printk_once(KERN_WARNING "EXT4-fs: Warning: mounting "
3775 "with data=journal disables delayed " 3855 "with data=journal disables delayed "
@@ -4586,6 +4666,11 @@ failed_mount2:
4586failed_mount: 4666failed_mount:
4587 if (sbi->s_chksum_driver) 4667 if (sbi->s_chksum_driver)
4588 crypto_free_shash(sbi->s_chksum_driver); 4668 crypto_free_shash(sbi->s_chksum_driver);
4669
4670#ifdef CONFIG_UNICODE
4671 utf8_unload(sbi->s_encoding);
4672#endif
4673
4589#ifdef CONFIG_QUOTA 4674#ifdef CONFIG_QUOTA
4590 for (i = 0; i < EXT4_MAXQUOTAS; i++) 4675 for (i = 0; i < EXT4_MAXQUOTAS; i++)
4591 kfree(sbi->s_qf_names[i]); 4676 kfree(sbi->s_qf_names[i]);