summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/ext4.h21
-rw-r--r--fs/ext4/super.c85
2 files changed, 105 insertions, 1 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
index 2a2e6ed9aab4..c1504c471fef 100644
--- a/fs/ext4/ext4.h
+++ b/fs/ext4/ext4.h
@@ -1313,7 +1313,9 @@ struct ext4_super_block {
1313 __u8 s_first_error_time_hi; 1313 __u8 s_first_error_time_hi;
1314 __u8 s_last_error_time_hi; 1314 __u8 s_last_error_time_hi;
1315 __u8 s_pad[2]; 1315 __u8 s_pad[2];
1316 __le32 s_reserved[96]; /* Padding to the end of the block */ 1316 __le16 s_encoding; /* Filename charset encoding */
1317 __le16 s_encoding_flags; /* Filename charset encoding flags */
1318 __le32 s_reserved[95]; /* Padding to the end of the block */
1317 __le32 s_checksum; /* crc32c(superblock) */ 1319 __le32 s_checksum; /* crc32c(superblock) */
1318}; 1320};
1319 1321
@@ -1338,6 +1340,16 @@ struct ext4_super_block {
1338/* Number of quota types we support */ 1340/* Number of quota types we support */
1339#define EXT4_MAXQUOTAS 3 1341#define EXT4_MAXQUOTAS 3
1340 1342
1343#define EXT4_ENC_UTF8_12_1 1
1344
1345/*
1346 * Flags for ext4_sb_info.s_encoding_flags.
1347 */
1348#define EXT4_ENC_STRICT_MODE_FL (1 << 0)
1349
1350#define ext4_has_strict_mode(sbi) \
1351 (sbi->s_encoding_flags & EXT4_ENC_STRICT_MODE_FL)
1352
1341/* 1353/*
1342 * fourth extended-fs super-block data in memory 1354 * fourth extended-fs super-block data in memory
1343 */ 1355 */
@@ -1387,6 +1399,10 @@ struct ext4_sb_info {
1387 struct kobject s_kobj; 1399 struct kobject s_kobj;
1388 struct completion s_kobj_unregister; 1400 struct completion s_kobj_unregister;
1389 struct super_block *s_sb; 1401 struct super_block *s_sb;
1402#ifdef CONFIG_UNICODE
1403 struct unicode_map *s_encoding;
1404 __u16 s_encoding_flags;
1405#endif
1390 1406
1391 /* Journaling */ 1407 /* Journaling */
1392 struct journal_s *s_journal; 1408 struct journal_s *s_journal;
@@ -1660,6 +1676,7 @@ static inline void ext4_clear_state_flags(struct ext4_inode_info *ei)
1660#define EXT4_FEATURE_INCOMPAT_LARGEDIR 0x4000 /* >2GB or 3-lvl htree */ 1676#define EXT4_FEATURE_INCOMPAT_LARGEDIR 0x4000 /* >2GB or 3-lvl htree */
1661#define EXT4_FEATURE_INCOMPAT_INLINE_DATA 0x8000 /* data in inode */ 1677#define EXT4_FEATURE_INCOMPAT_INLINE_DATA 0x8000 /* data in inode */
1662#define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000 1678#define EXT4_FEATURE_INCOMPAT_ENCRYPT 0x10000
1679#define EXT4_FEATURE_INCOMPAT_CASEFOLD 0x20000
1663 1680
1664extern void ext4_update_dynamic_rev(struct super_block *sb); 1681extern void ext4_update_dynamic_rev(struct super_block *sb);
1665 1682
@@ -1753,6 +1770,7 @@ EXT4_FEATURE_INCOMPAT_FUNCS(csum_seed, CSUM_SEED)
1753EXT4_FEATURE_INCOMPAT_FUNCS(largedir, LARGEDIR) 1770EXT4_FEATURE_INCOMPAT_FUNCS(largedir, LARGEDIR)
1754EXT4_FEATURE_INCOMPAT_FUNCS(inline_data, INLINE_DATA) 1771EXT4_FEATURE_INCOMPAT_FUNCS(inline_data, INLINE_DATA)
1755EXT4_FEATURE_INCOMPAT_FUNCS(encrypt, ENCRYPT) 1772EXT4_FEATURE_INCOMPAT_FUNCS(encrypt, ENCRYPT)
1773EXT4_FEATURE_INCOMPAT_FUNCS(casefold, CASEFOLD)
1756 1774
1757#define EXT2_FEATURE_COMPAT_SUPP EXT4_FEATURE_COMPAT_EXT_ATTR 1775#define EXT2_FEATURE_COMPAT_SUPP EXT4_FEATURE_COMPAT_EXT_ATTR
1758#define EXT2_FEATURE_INCOMPAT_SUPP (EXT4_FEATURE_INCOMPAT_FILETYPE| \ 1776#define EXT2_FEATURE_INCOMPAT_SUPP (EXT4_FEATURE_INCOMPAT_FILETYPE| \
@@ -1780,6 +1798,7 @@ EXT4_FEATURE_INCOMPAT_FUNCS(encrypt, ENCRYPT)
1780 EXT4_FEATURE_INCOMPAT_MMP | \ 1798 EXT4_FEATURE_INCOMPAT_MMP | \
1781 EXT4_FEATURE_INCOMPAT_INLINE_DATA | \ 1799 EXT4_FEATURE_INCOMPAT_INLINE_DATA | \
1782 EXT4_FEATURE_INCOMPAT_ENCRYPT | \ 1800 EXT4_FEATURE_INCOMPAT_ENCRYPT | \
1801 EXT4_FEATURE_INCOMPAT_CASEFOLD | \
1783 EXT4_FEATURE_INCOMPAT_CSUM_SEED | \ 1802 EXT4_FEATURE_INCOMPAT_CSUM_SEED | \
1784 EXT4_FEATURE_INCOMPAT_LARGEDIR) 1803 EXT4_FEATURE_INCOMPAT_LARGEDIR)
1785#define EXT4_FEATURE_RO_COMPAT_SUPP (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \ 1804#define EXT4_FEATURE_RO_COMPAT_SUPP (EXT4_FEATURE_RO_COMPAT_SPARSE_SUPER| \
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]);