|
23 | 23 | #include <linux/f2fs_fs.h> |
24 | 24 | #include <linux/sysfs.h> |
25 | 25 | #include <linux/quota.h> |
| 26 | +#include <linux/unicode.h> |
26 | 27 |
|
27 | 28 | #include "f2fs.h" |
28 | 29 | #include "node.h" |
@@ -222,6 +223,36 @@ void f2fs_printk(struct f2fs_sb_info *sbi, const char *fmt, ...) |
222 | 223 | va_end(args); |
223 | 224 | } |
224 | 225 |
|
| 226 | +#ifdef CONFIG_UNICODE |
| 227 | +static const struct f2fs_sb_encodings { |
| 228 | + __u16 magic; |
| 229 | + char *name; |
| 230 | + char *version; |
| 231 | +} f2fs_sb_encoding_map[] = { |
| 232 | + {F2FS_ENC_UTF8_12_1, "utf8", "12.1.0"}, |
| 233 | +}; |
| 234 | + |
| 235 | +static int f2fs_sb_read_encoding(const struct f2fs_super_block *sb, |
| 236 | + const struct f2fs_sb_encodings **encoding, |
| 237 | + __u16 *flags) |
| 238 | +{ |
| 239 | + __u16 magic = le16_to_cpu(sb->s_encoding); |
| 240 | + int i; |
| 241 | + |
| 242 | + for (i = 0; i < ARRAY_SIZE(f2fs_sb_encoding_map); i++) |
| 243 | + if (magic == f2fs_sb_encoding_map[i].magic) |
| 244 | + break; |
| 245 | + |
| 246 | + if (i >= ARRAY_SIZE(f2fs_sb_encoding_map)) |
| 247 | + return -EINVAL; |
| 248 | + |
| 249 | + *encoding = &f2fs_sb_encoding_map[i]; |
| 250 | + *flags = le16_to_cpu(sb->s_encoding_flags); |
| 251 | + |
| 252 | + return 0; |
| 253 | +} |
| 254 | +#endif |
| 255 | + |
225 | 256 | static inline void limit_reserve_root(struct f2fs_sb_info *sbi) |
226 | 257 | { |
227 | 258 | block_t limit = min((sbi->user_block_count << 1) / 1000, |
@@ -798,6 +829,13 @@ static int parse_options(struct super_block *sb, char *options) |
798 | 829 | return -EINVAL; |
799 | 830 | } |
800 | 831 | #endif |
| 832 | +#ifndef CONFIG_UNICODE |
| 833 | + if (f2fs_sb_has_casefold(sbi)) { |
| 834 | + f2fs_err(sbi, |
| 835 | + "Filesystem with casefold feature cannot be mounted without CONFIG_UNICODE"); |
| 836 | + return -EINVAL; |
| 837 | + } |
| 838 | +#endif |
801 | 839 |
|
802 | 840 | if (F2FS_IO_SIZE_BITS(sbi) && !test_opt(sbi, LFS)) { |
803 | 841 | f2fs_err(sbi, "Should set mode=lfs with %uKB-sized IO", |
@@ -1103,6 +1141,9 @@ static void f2fs_put_super(struct super_block *sb) |
1103 | 1141 | destroy_percpu_info(sbi); |
1104 | 1142 | for (i = 0; i < NR_PAGE_TYPE; i++) |
1105 | 1143 | kvfree(sbi->write_io[i]); |
| 1144 | +#ifdef CONFIG_UNICODE |
| 1145 | + utf8_unload(sbi->s_encoding); |
| 1146 | +#endif |
1106 | 1147 | kvfree(sbi); |
1107 | 1148 | } |
1108 | 1149 |
|
@@ -3075,6 +3116,52 @@ static int f2fs_scan_devices(struct f2fs_sb_info *sbi) |
3075 | 3116 | return 0; |
3076 | 3117 | } |
3077 | 3118 |
|
| 3119 | +static int f2fs_setup_casefold(struct f2fs_sb_info *sbi) |
| 3120 | +{ |
| 3121 | +#ifdef CONFIG_UNICODE |
| 3122 | + if (f2fs_sb_has_casefold(sbi) && !sbi->s_encoding) { |
| 3123 | + const struct f2fs_sb_encodings *encoding_info; |
| 3124 | + struct unicode_map *encoding; |
| 3125 | + __u16 encoding_flags; |
| 3126 | + |
| 3127 | + if (f2fs_sb_has_encrypt(sbi)) { |
| 3128 | + f2fs_err(sbi, |
| 3129 | + "Can't mount with encoding and encryption"); |
| 3130 | + return -EINVAL; |
| 3131 | + } |
| 3132 | + |
| 3133 | + if (f2fs_sb_read_encoding(sbi->raw_super, &encoding_info, |
| 3134 | + &encoding_flags)) { |
| 3135 | + f2fs_err(sbi, |
| 3136 | + "Encoding requested by superblock is unknown"); |
| 3137 | + return -EINVAL; |
| 3138 | + } |
| 3139 | + |
| 3140 | + encoding = utf8_load(encoding_info->version); |
| 3141 | + if (IS_ERR(encoding)) { |
| 3142 | + f2fs_err(sbi, |
| 3143 | + "can't mount with superblock charset: %s-%s " |
| 3144 | + "not supported by the kernel. flags: 0x%x.", |
| 3145 | + encoding_info->name, encoding_info->version, |
| 3146 | + encoding_flags); |
| 3147 | + return PTR_ERR(encoding); |
| 3148 | + } |
| 3149 | + f2fs_info(sbi, "Using encoding defined by superblock: " |
| 3150 | + "%s-%s with flags 0x%hx", encoding_info->name, |
| 3151 | + encoding_info->version?:"\b", encoding_flags); |
| 3152 | + |
| 3153 | + sbi->s_encoding = encoding; |
| 3154 | + sbi->s_encoding_flags = encoding_flags; |
| 3155 | + } |
| 3156 | +#else |
| 3157 | + if (f2fs_sb_has_casefold(sbi)) { |
| 3158 | + f2fs_err(sbi, "Filesystem with casefold feature cannot be mounted without CONFIG_UNICODE"); |
| 3159 | + return -EINVAL; |
| 3160 | + } |
| 3161 | +#endif |
| 3162 | + return 0; |
| 3163 | +} |
| 3164 | + |
3078 | 3165 | static void f2fs_tuning_parameters(struct f2fs_sb_info *sbi) |
3079 | 3166 | { |
3080 | 3167 | struct f2fs_sm_info *sm_i = SM_I(sbi); |
@@ -3171,6 +3258,10 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) |
3171 | 3258 | le32_to_cpu(raw_super->log_blocksize); |
3172 | 3259 | sb->s_max_links = F2FS_LINK_MAX; |
3173 | 3260 |
|
| 3261 | + err = f2fs_setup_casefold(sbi); |
| 3262 | + if (err) |
| 3263 | + goto free_options; |
| 3264 | + |
3174 | 3265 | #ifdef CONFIG_QUOTA |
3175 | 3266 | sb->dq_op = &f2fs_quota_operations; |
3176 | 3267 | sb->s_qcop = &f2fs_quotactl_ops; |
@@ -3521,6 +3612,10 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent) |
3521 | 3612 | free_bio_info: |
3522 | 3613 | for (i = 0; i < NR_PAGE_TYPE; i++) |
3523 | 3614 | kvfree(sbi->write_io[i]); |
| 3615 | + |
| 3616 | +#ifdef CONFIG_UNICODE |
| 3617 | + utf8_unload(sbi->s_encoding); |
| 3618 | +#endif |
3524 | 3619 | free_options: |
3525 | 3620 | #ifdef CONFIG_QUOTA |
3526 | 3621 | for (i = 0; i < MAXQUOTAS; i++) |
|
0 commit comments