summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/ABI/testing/sysfs-fs-f2fs7
-rw-r--r--Documentation/filesystems/f2fs.txt3
-rw-r--r--fs/f2fs/f2fs.h6
-rw-r--r--fs/f2fs/super.c95
-rw-r--r--fs/f2fs/sysfs.c23
-rw-r--r--include/linux/f2fs_fs.h9
6 files changed, 142 insertions, 1 deletions
diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs
index dca326e0ee3e..7ab2b1b5e255 100644
--- a/Documentation/ABI/testing/sysfs-fs-f2fs
+++ b/Documentation/ABI/testing/sysfs-fs-f2fs
@@ -251,3 +251,10 @@ Description:
251 If checkpoint=disable, it displays the number of blocks that are unusable. 251 If checkpoint=disable, it displays the number of blocks that are unusable.
252 If checkpoint=enable it displays the enumber of blocks that would be unusable 252 If checkpoint=enable it displays the enumber of blocks that would be unusable
253 if checkpoint=disable were to be set. 253 if checkpoint=disable were to be set.
254
255What: /sys/fs/f2fs/<disk>/encoding
256Date July 2019
257Contact: "Daniel Rosenberg" <drosen@google.com>
258Description:
259 Displays name and version of the encoding set for the filesystem.
260 If no encoding is set, displays (none)
diff --git a/Documentation/filesystems/f2fs.txt b/Documentation/filesystems/f2fs.txt
index 496fa28b2492..5fa38ab373ca 100644
--- a/Documentation/filesystems/f2fs.txt
+++ b/Documentation/filesystems/f2fs.txt
@@ -413,6 +413,9 @@ Files in /sys/fs/f2fs/<devname>
413 that would be unusable if checkpoint=disable were 413 that would be unusable if checkpoint=disable were
414 to be set. 414 to be set.
415 415
416encoding This shows the encoding used for casefolding.
417 If casefolding is not enabled, returns (none)
418
416================================================================================ 419================================================================================
417USAGE 420USAGE
418================================================================================ 421================================================================================
diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
index 4fa9a618b31a..dd69e1559839 100644
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -153,6 +153,7 @@ struct f2fs_mount_info {
153#define F2FS_FEATURE_LOST_FOUND 0x0200 153#define F2FS_FEATURE_LOST_FOUND 0x0200
154#define F2FS_FEATURE_VERITY 0x0400 /* reserved */ 154#define F2FS_FEATURE_VERITY 0x0400 /* reserved */
155#define F2FS_FEATURE_SB_CHKSUM 0x0800 155#define F2FS_FEATURE_SB_CHKSUM 0x0800
156#define F2FS_FEATURE_CASEFOLD 0x1000
156 157
157#define __F2FS_HAS_FEATURE(raw_super, mask) \ 158#define __F2FS_HAS_FEATURE(raw_super, mask) \
158 ((raw_super->feature & cpu_to_le32(mask)) != 0) 159 ((raw_super->feature & cpu_to_le32(mask)) != 0)
@@ -1169,6 +1170,10 @@ struct f2fs_sb_info {
1169 int valid_super_block; /* valid super block no */ 1170 int valid_super_block; /* valid super block no */
1170 unsigned long s_flag; /* flags for sbi */ 1171 unsigned long s_flag; /* flags for sbi */
1171 struct mutex writepages; /* mutex for writepages() */ 1172 struct mutex writepages; /* mutex for writepages() */
1173#ifdef CONFIG_UNICODE
1174 struct unicode_map *s_encoding;
1175 __u16 s_encoding_flags;
1176#endif
1172 1177
1173#ifdef CONFIG_BLK_DEV_ZONED 1178#ifdef CONFIG_BLK_DEV_ZONED
1174 unsigned int blocks_per_blkz; /* F2FS blocks per zone */ 1179 unsigned int blocks_per_blkz; /* F2FS blocks per zone */
@@ -3565,6 +3570,7 @@ F2FS_FEATURE_FUNCS(quota_ino, QUOTA_INO);
3565F2FS_FEATURE_FUNCS(inode_crtime, INODE_CRTIME); 3570F2FS_FEATURE_FUNCS(inode_crtime, INODE_CRTIME);
3566F2FS_FEATURE_FUNCS(lost_found, LOST_FOUND); 3571F2FS_FEATURE_FUNCS(lost_found, LOST_FOUND);
3567F2FS_FEATURE_FUNCS(sb_chksum, SB_CHKSUM); 3572F2FS_FEATURE_FUNCS(sb_chksum, SB_CHKSUM);
3573F2FS_FEATURE_FUNCS(casefold, CASEFOLD);
3568 3574
3569#ifdef CONFIG_BLK_DEV_ZONED 3575#ifdef CONFIG_BLK_DEV_ZONED
3570static inline bool f2fs_blkz_is_seq(struct f2fs_sb_info *sbi, int devi, 3576static inline bool f2fs_blkz_is_seq(struct f2fs_sb_info *sbi, int devi,
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index 9167deb0c417..8bebee8e0186 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -23,6 +23,7 @@
23#include <linux/f2fs_fs.h> 23#include <linux/f2fs_fs.h>
24#include <linux/sysfs.h> 24#include <linux/sysfs.h>
25#include <linux/quota.h> 25#include <linux/quota.h>
26#include <linux/unicode.h>
26 27
27#include "f2fs.h" 28#include "f2fs.h"
28#include "node.h" 29#include "node.h"
@@ -222,6 +223,36 @@ void f2fs_printk(struct f2fs_sb_info *sbi, const char *fmt, ...)
222 va_end(args); 223 va_end(args);
223} 224}
224 225
226#ifdef CONFIG_UNICODE
227static 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
235static 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
225static inline void limit_reserve_root(struct f2fs_sb_info *sbi) 256static inline void limit_reserve_root(struct f2fs_sb_info *sbi)
226{ 257{
227 block_t limit = min((sbi->user_block_count << 1) / 1000, 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 return -EINVAL; 829 return -EINVAL;
799 } 830 }
800#endif 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 if (F2FS_IO_SIZE_BITS(sbi) && !test_opt(sbi, LFS)) { 840 if (F2FS_IO_SIZE_BITS(sbi) && !test_opt(sbi, LFS)) {
803 f2fs_err(sbi, "Should set mode=lfs with %uKB-sized IO", 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 destroy_percpu_info(sbi); 1141 destroy_percpu_info(sbi);
1104 for (i = 0; i < NR_PAGE_TYPE; i++) 1142 for (i = 0; i < NR_PAGE_TYPE; i++)
1105 kvfree(sbi->write_io[i]); 1143 kvfree(sbi->write_io[i]);
1144#ifdef CONFIG_UNICODE
1145 utf8_unload(sbi->s_encoding);
1146#endif
1106 kvfree(sbi); 1147 kvfree(sbi);
1107} 1148}
1108 1149
@@ -3075,6 +3116,52 @@ static int f2fs_scan_devices(struct f2fs_sb_info *sbi)
3075 return 0; 3116 return 0;
3076} 3117}
3077 3118
3119static 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
3078static void f2fs_tuning_parameters(struct f2fs_sb_info *sbi) 3165static void f2fs_tuning_parameters(struct f2fs_sb_info *sbi)
3079{ 3166{
3080 struct f2fs_sm_info *sm_i = SM_I(sbi); 3167 struct f2fs_sm_info *sm_i = SM_I(sbi);
@@ -3171,6 +3258,10 @@ try_onemore:
3171 le32_to_cpu(raw_super->log_blocksize); 3258 le32_to_cpu(raw_super->log_blocksize);
3172 sb->s_max_links = F2FS_LINK_MAX; 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#ifdef CONFIG_QUOTA 3265#ifdef CONFIG_QUOTA
3175 sb->dq_op = &f2fs_quota_operations; 3266 sb->dq_op = &f2fs_quota_operations;
3176 sb->s_qcop = &f2fs_quotactl_ops; 3267 sb->s_qcop = &f2fs_quotactl_ops;
@@ -3521,6 +3612,10 @@ free_percpu:
3521free_bio_info: 3612free_bio_info:
3522 for (i = 0; i < NR_PAGE_TYPE; i++) 3613 for (i = 0; i < NR_PAGE_TYPE; i++)
3523 kvfree(sbi->write_io[i]); 3614 kvfree(sbi->write_io[i]);
3615
3616#ifdef CONFIG_UNICODE
3617 utf8_unload(sbi->s_encoding);
3618#endif
3524free_options: 3619free_options:
3525#ifdef CONFIG_QUOTA 3620#ifdef CONFIG_QUOTA
3526 for (i = 0; i < MAXQUOTAS; i++) 3621 for (i = 0; i < MAXQUOTAS; i++)
diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c
index 3aeacd0aacfd..f9fcca695db9 100644
--- a/fs/f2fs/sysfs.c
+++ b/fs/f2fs/sysfs.c
@@ -10,6 +10,7 @@
10#include <linux/proc_fs.h> 10#include <linux/proc_fs.h>
11#include <linux/f2fs_fs.h> 11#include <linux/f2fs_fs.h>
12#include <linux/seq_file.h> 12#include <linux/seq_file.h>
13#include <linux/unicode.h>
13 14
14#include "f2fs.h" 15#include "f2fs.h"
15#include "segment.h" 16#include "segment.h"
@@ -81,6 +82,19 @@ static ssize_t unusable_show(struct f2fs_attr *a,
81 (unsigned long long)unusable); 82 (unsigned long long)unusable);
82} 83}
83 84
85static ssize_t encoding_show(struct f2fs_attr *a,
86 struct f2fs_sb_info *sbi, char *buf)
87{
88#ifdef CONFIG_UNICODE
89 if (f2fs_sb_has_casefold(sbi))
90 return snprintf(buf, PAGE_SIZE, "%s (%d.%d.%d)\n",
91 sbi->s_encoding->charset,
92 (sbi->s_encoding->version >> 16) & 0xff,
93 (sbi->s_encoding->version >> 8) & 0xff,
94 sbi->s_encoding->version & 0xff);
95#endif
96 return snprintf(buf, PAGE_SIZE, "(none)");
97}
84 98
85static ssize_t lifetime_write_kbytes_show(struct f2fs_attr *a, 99static ssize_t lifetime_write_kbytes_show(struct f2fs_attr *a,
86 struct f2fs_sb_info *sbi, char *buf) 100 struct f2fs_sb_info *sbi, char *buf)
@@ -134,6 +148,9 @@ static ssize_t features_show(struct f2fs_attr *a,
134 if (f2fs_sb_has_sb_chksum(sbi)) 148 if (f2fs_sb_has_sb_chksum(sbi))
135 len += snprintf(buf + len, PAGE_SIZE - len, "%s%s", 149 len += snprintf(buf + len, PAGE_SIZE - len, "%s%s",
136 len ? ", " : "", "sb_checksum"); 150 len ? ", " : "", "sb_checksum");
151 if (f2fs_sb_has_casefold(sbi))
152 len += snprintf(buf + len, PAGE_SIZE - len, "%s%s",
153 len ? ", " : "", "casefold");
137 len += snprintf(buf + len, PAGE_SIZE - len, "\n"); 154 len += snprintf(buf + len, PAGE_SIZE - len, "\n");
138 return len; 155 return len;
139} 156}
@@ -365,6 +382,7 @@ enum feat_id {
365 FEAT_INODE_CRTIME, 382 FEAT_INODE_CRTIME,
366 FEAT_LOST_FOUND, 383 FEAT_LOST_FOUND,
367 FEAT_SB_CHECKSUM, 384 FEAT_SB_CHECKSUM,
385 FEAT_CASEFOLD,
368}; 386};
369 387
370static ssize_t f2fs_feature_show(struct f2fs_attr *a, 388static ssize_t f2fs_feature_show(struct f2fs_attr *a,
@@ -382,6 +400,7 @@ static ssize_t f2fs_feature_show(struct f2fs_attr *a,
382 case FEAT_INODE_CRTIME: 400 case FEAT_INODE_CRTIME:
383 case FEAT_LOST_FOUND: 401 case FEAT_LOST_FOUND:
384 case FEAT_SB_CHECKSUM: 402 case FEAT_SB_CHECKSUM:
403 case FEAT_CASEFOLD:
385 return snprintf(buf, PAGE_SIZE, "supported\n"); 404 return snprintf(buf, PAGE_SIZE, "supported\n");
386 } 405 }
387 return 0; 406 return 0;
@@ -455,6 +474,7 @@ F2FS_GENERAL_RO_ATTR(lifetime_write_kbytes);
455F2FS_GENERAL_RO_ATTR(features); 474F2FS_GENERAL_RO_ATTR(features);
456F2FS_GENERAL_RO_ATTR(current_reserved_blocks); 475F2FS_GENERAL_RO_ATTR(current_reserved_blocks);
457F2FS_GENERAL_RO_ATTR(unusable); 476F2FS_GENERAL_RO_ATTR(unusable);
477F2FS_GENERAL_RO_ATTR(encoding);
458 478
459#ifdef CONFIG_FS_ENCRYPTION 479#ifdef CONFIG_FS_ENCRYPTION
460F2FS_FEATURE_RO_ATTR(encryption, FEAT_CRYPTO); 480F2FS_FEATURE_RO_ATTR(encryption, FEAT_CRYPTO);
@@ -471,6 +491,7 @@ F2FS_FEATURE_RO_ATTR(quota_ino, FEAT_QUOTA_INO);
471F2FS_FEATURE_RO_ATTR(inode_crtime, FEAT_INODE_CRTIME); 491F2FS_FEATURE_RO_ATTR(inode_crtime, FEAT_INODE_CRTIME);
472F2FS_FEATURE_RO_ATTR(lost_found, FEAT_LOST_FOUND); 492F2FS_FEATURE_RO_ATTR(lost_found, FEAT_LOST_FOUND);
473F2FS_FEATURE_RO_ATTR(sb_checksum, FEAT_SB_CHECKSUM); 493F2FS_FEATURE_RO_ATTR(sb_checksum, FEAT_SB_CHECKSUM);
494F2FS_FEATURE_RO_ATTR(casefold, FEAT_CASEFOLD);
474 495
475#define ATTR_LIST(name) (&f2fs_attr_##name.attr) 496#define ATTR_LIST(name) (&f2fs_attr_##name.attr)
476static struct attribute *f2fs_attrs[] = { 497static struct attribute *f2fs_attrs[] = {
@@ -515,6 +536,7 @@ static struct attribute *f2fs_attrs[] = {
515 ATTR_LIST(features), 536 ATTR_LIST(features),
516 ATTR_LIST(reserved_blocks), 537 ATTR_LIST(reserved_blocks),
517 ATTR_LIST(current_reserved_blocks), 538 ATTR_LIST(current_reserved_blocks),
539 ATTR_LIST(encoding),
518 NULL, 540 NULL,
519}; 541};
520ATTRIBUTE_GROUPS(f2fs); 542ATTRIBUTE_GROUPS(f2fs);
@@ -535,6 +557,7 @@ static struct attribute *f2fs_feat_attrs[] = {
535 ATTR_LIST(inode_crtime), 557 ATTR_LIST(inode_crtime),
536 ATTR_LIST(lost_found), 558 ATTR_LIST(lost_found),
537 ATTR_LIST(sb_checksum), 559 ATTR_LIST(sb_checksum),
560 ATTR_LIST(casefold),
538 NULL, 561 NULL,
539}; 562};
540ATTRIBUTE_GROUPS(f2fs_feat); 563ATTRIBUTE_GROUPS(f2fs_feat);
diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h
index 52af9ac164b4..284738996028 100644
--- a/include/linux/f2fs_fs.h
+++ b/include/linux/f2fs_fs.h
@@ -36,6 +36,11 @@
36 36
37#define F2FS_MAX_QUOTAS 3 37#define F2FS_MAX_QUOTAS 3
38 38
39#define F2FS_ENC_UTF8_12_1 1
40#define F2FS_ENC_STRICT_MODE_FL (1 << 0)
41#define f2fs_has_strict_mode(sbi) \
42 (sbi->s_encoding_flags & F2FS_ENC_STRICT_MODE_FL)
43
39#define F2FS_IO_SIZE(sbi) (1 << F2FS_OPTION(sbi).write_io_size_bits) /* Blocks */ 44#define F2FS_IO_SIZE(sbi) (1 << F2FS_OPTION(sbi).write_io_size_bits) /* Blocks */
40#define F2FS_IO_SIZE_KB(sbi) (1 << (F2FS_OPTION(sbi).write_io_size_bits + 2)) /* KB */ 45#define F2FS_IO_SIZE_KB(sbi) (1 << (F2FS_OPTION(sbi).write_io_size_bits + 2)) /* KB */
41#define F2FS_IO_SIZE_BYTES(sbi) (1 << (F2FS_OPTION(sbi).write_io_size_bits + 12)) /* B */ 46#define F2FS_IO_SIZE_BYTES(sbi) (1 << (F2FS_OPTION(sbi).write_io_size_bits + 12)) /* B */
@@ -110,7 +115,9 @@ struct f2fs_super_block {
110 struct f2fs_device devs[MAX_DEVICES]; /* device list */ 115 struct f2fs_device devs[MAX_DEVICES]; /* device list */
111 __le32 qf_ino[F2FS_MAX_QUOTAS]; /* quota inode numbers */ 116 __le32 qf_ino[F2FS_MAX_QUOTAS]; /* quota inode numbers */
112 __u8 hot_ext_count; /* # of hot file extension */ 117 __u8 hot_ext_count; /* # of hot file extension */
113 __u8 reserved[310]; /* valid reserved region */ 118 __le16 s_encoding; /* Filename charset encoding */
119 __le16 s_encoding_flags; /* Filename charset encoding flags */
120 __u8 reserved[306]; /* valid reserved region */
114 __le32 crc; /* checksum of superblock */ 121 __le32 crc; /* checksum of superblock */
115} __packed; 122} __packed;
116 123