Re: [f2fs-dev] [RFC PATCH 4/4] f2fs-tools: introduce sb checksum
On 2018/8/14 10:03, Junling Zheng wrote: > Hi, Chao > > On 2018/8/13 22:33, Chao Yu wrote: >> On 2018/8/13 21:32, Junling Zheng wrote: >>> This patch introduced crc for superblock. >>> >>> Signed-off-by: Junling Zheng >>> --- >>> fsck/mount.c | 23 +++ >>> fsck/resize.c | 12 ++-- >>> include/f2fs_fs.h | 16 +++- >>> mkfs/f2fs_format.c | 3 +++ >>> 4 files changed, 47 insertions(+), 7 deletions(-) >>> >>> diff --git a/fsck/mount.c b/fsck/mount.c >>> index e7ceb8d..af9b219 100644 >>> --- a/fsck/mount.c >>> +++ b/fsck/mount.c >>> @@ -340,6 +340,7 @@ void print_raw_sb_info(struct f2fs_super_block *sb) >>> DISP_u32(sb, node_ino); >>> DISP_u32(sb, meta_ino); >>> DISP_u32(sb, cp_payload); >>> + DISP_u32(sb, crc); >> >> if (feature is on) { >> DISP_u32(sb, checksum_offset); >> DISP_u32(sb, crc); >> } >> > > sb->checksum_offset had been printed before without any conditions. > So I think it's better to print them always :) Alright, since it's trivial. :) Thanks, > >> Thanks, >> >>> DISP("%-.256s", sb, version); >>> printf("\n"); >>> } >>> @@ -467,6 +468,9 @@ void print_sb_state(struct f2fs_super_block *sb) >>> if (f & cpu_to_le32(F2FS_FEATURE_LOST_FOUND)) { >>> MSG(0, "%s", " lost_found"); >>> } >>> + if (f & cpu_to_le32(F2FS_FEATURE_SB_CHKSUM)) { >>> + MSG(0, "%s", " sb_checksum"); >>> + } >>> MSG(0, "\n"); >>> MSG(0, "Info: superblock encrypt level = %d, salt = ", >>> sb->encryption_level); >>> @@ -555,10 +559,29 @@ static inline int sanity_check_area_boundary(struct >>> f2fs_super_block *sb, >>> return 0; >>> } >>> >>> +static int verify_sb_chksum(struct f2fs_super_block *sb) >>> +{ >>> + if (SB_CHKSUM_OFFSET != get_sb(checksum_offset)) { >>> + MSG(0, "\tInvalid SB CRC offset: %u\n", >>> + get_sb(checksum_offset)); >>> + return -1; >>> + } >>> + if (f2fs_crc_valid(get_sb(crc), sb, >>> + get_sb(checksum_offset))) { >>> + MSG(0, "\tInvalid SB CRC: 0x%x\n", get_sb(crc)); >>> + return -1; >>> + } >>> + return 0; >>> +} >>> + >>> int sanity_check_raw_super(struct f2fs_super_block *sb, enum SB_ADDR >>> sb_addr) >>> { >>> unsigned int blocksize; >>> >>> + if ((get_sb(feature) & F2FS_FEATURE_SB_CHKSUM) && >>> + verify_sb_chksum(sb)) >>> + return -1; >>> + >>> if (F2FS_SUPER_MAGIC != get_sb(magic)) >>> return -1; >>> >>> diff --git a/fsck/resize.c b/fsck/resize.c >>> index 5161a1f..3462165 100644 >>> --- a/fsck/resize.c >>> +++ b/fsck/resize.c >>> @@ -603,9 +603,6 @@ static int f2fs_resize_grow(struct f2fs_sb_info *sbi) >>> } >>> } >>> >>> - print_raw_sb_info(sb); >>> - print_raw_sb_info(new_sb); >>> - >>> old_main_blkaddr = get_sb(main_blkaddr); >>> new_main_blkaddr = get_newsb(main_blkaddr); >>> offset = new_main_blkaddr - old_main_blkaddr; >>> @@ -629,6 +626,9 @@ static int f2fs_resize_grow(struct f2fs_sb_info *sbi) >>> migrate_sit(sbi, new_sb, offset_seg); >>> rebuild_checkpoint(sbi, new_sb, offset_seg); >>> update_superblock(new_sb, SB_ALL); >>> + print_raw_sb_info(sb); >>> + print_raw_sb_info(new_sb); >>> + >>> return 0; >>> } >>> >>> @@ -658,9 +658,6 @@ static int f2fs_resize_shrink(struct f2fs_sb_info *sbi) >>> } >>> } >>> >>> - print_raw_sb_info(sb); >>> - print_raw_sb_info(new_sb); >>> - >>> old_main_blkaddr = get_sb(main_blkaddr); >>> new_main_blkaddr = get_newsb(main_blkaddr); >>> offset = old_main_blkaddr - new_main_blkaddr; >>> @@ -690,6 +687,9 @@ static int f2fs_resize_shrink(struct f2fs_sb_info *sbi) >>> /* move whole data region */ >>> //if (err) >>> // migrate_main(sbi, offset); >>> + print_raw_sb_info(sb); >>> + print_raw_sb_info(new_sb); >>> + >>> return 0; >>> } >>> >>> diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h >>> index b0d9b9b..556d526 100644 >>> --- a/include/f2fs_fs.h >>> +++ b/include/f2fs_fs.h >>> @@ -279,6 +279,7 @@ static inline uint64_t bswap_64(uint64_t val) >>> #define BITS_PER_BYTE 8 >>> #define F2FS_SUPER_MAGIC 0xF2F52010 /* F2FS Magic Number */ >>> #define CP_CHKSUM_OFFSET 4092 >>> +#define SB_CHKSUM_OFFSET 3068 >>> #define MAX_PATH_LEN 64 >>> #define MAX_DEVICES8 >>> >>> @@ -579,6 +580,7 @@ enum { >>> #define F2FS_FEATURE_INODE_CRTIME 0x0100 >>> #define F2FS_FEATURE_LOST_FOUND0x0200 >>> #define F2FS_FEATURE_VERITY0x0400 /* reserved */ >>> +#define F2FS_FEATURE_SB_CHKSUM 0x0800 >>> >>> #define MAX_VOLUME_NAME512 >>> >>> @@ -632,7 +634,8 @@ struct f2fs_super_block { >>> struct f2fs_device devs[MAX_DEVICES]; /* device list */ >>> __le32 qf_ino[F2FS_MAX_QUOTAS]; /* quota inode
Re: [f2fs-dev] [PATCH 2/2] f2fs: tune discard speed with storage usage rate
On 08/10, Chao Yu wrote: > Previously, discard speed was fixed mostly, and in high usage rate > device, we will speed up issuing discard, but it doesn't make sense > that in a non-full filesystem, we still issue discard with slow speed. Could you please elaborate the problem in more detail? The speed depends on how many candidates? Thanks, > > Anyway, it comes out undiscarded block makes FTL GC be lower efficient > and causing high lifetime overhead. > > Let's tune discard speed as below: > > a. adjust default issue interval: > originalafter > min_interval: 50ms100ms > mid_interval: 500ms 1000ms > max_interval: 6ms 1ms > > b. if last time we stop issuing discard due to IO interruption of user, > let's reset all {min,mid,max}_interval to default one. > > c. tune {min,mid,max}_interval with below calculation method: > > base_interval = default_interval / 10; > total_interval = default_interval - base_interval; > interval = base_interval + total_interval * (100 - dev_util) / 100; > > For example: > min_interval (:100ms) > dev_util (%) interval (ms) > 0 100 > 1091 > 2082 > 3073 > ... > 8028 > 9019 > 100 10 > > Signed-off-by: Chao Yu > --- > fs/f2fs/f2fs.h| 11 > fs/f2fs/segment.c | 64 +-- > fs/f2fs/segment.h | 9 +++ > fs/f2fs/super.c | 2 +- > 4 files changed, 67 insertions(+), 19 deletions(-) > > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h > index 273ffdaf4891..a1dd2e1c3cb9 100644 > --- a/fs/f2fs/f2fs.h > +++ b/fs/f2fs/f2fs.h > @@ -185,10 +185,9 @@ enum { > > #define MAX_DISCARD_BLOCKS(sbi) BLKS_PER_SEC(sbi) > #define DEF_MAX_DISCARD_REQUEST 8 /* issue 8 discards per > round */ > -#define DEF_MIN_DISCARD_ISSUE_TIME 50 /* 50 ms, if exists */ > -#define DEF_MID_DISCARD_ISSUE_TIME 500 /* 500 ms, if device busy */ > -#define DEF_MAX_DISCARD_ISSUE_TIME 6 /* 60 s, if no candidates */ > -#define DEF_DISCARD_URGENT_UTIL 80 /* do more discard over > 80% */ > +#define DEF_MIN_DISCARD_ISSUE_TIME 100 /* 100 ms, if exists */ > +#define DEF_MID_DISCARD_ISSUE_TIME 1000/* 1000 ms, if device busy */ > +#define DEF_MAX_DISCARD_ISSUE_TIME 1 /* 1 ms, if no candidates */ > #define DEF_CP_INTERVAL 60 /* 60 secs */ > #define DEF_IDLE_INTERVAL5 /* 5 secs */ > > @@ -248,7 +247,8 @@ struct discard_entry { > }; > > /* default discard granularity of inner discard thread, unit: block count */ > -#define DEFAULT_DISCARD_GRANULARITY 1 > +#define MID_DISCARD_GRANULARITY 16 > +#define MIN_DISCARD_GRANULARITY 1 > > /* max discard pend list number */ > #define MAX_PLIST_NUM512 > @@ -330,6 +330,7 @@ struct discard_cmd_control { > atomic_t discard_cmd_cnt; /* # of cached cmd count */ > struct rb_root root;/* root of discard rb-tree */ > bool rbtree_check; /* config for consistence check > */ > + bool io_interrupted;/* last state of io interrupted > */ > }; > > /* for the list of fsync inodes, used only during recovery */ > diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c > index 8b52e8dfb12f..9564aaf1f27b 100644 > --- a/fs/f2fs/segment.c > +++ b/fs/f2fs/segment.c > @@ -968,6 +968,44 @@ static void __check_sit_bitmap(struct f2fs_sb_info *sbi, > #endif > } > > +static void __adjust_discard_speed(unsigned int *interval, > + unsigned int def_interval, int dev_util) > +{ > + unsigned int base_interval, total_interval; > + > + base_interval = def_interval / 10; > + total_interval = def_interval - base_interval; > + > + /* > + * if def_interval = 100, adjusted interval should be in range of > + * [10, 100]. > + */ > + *interval = base_interval + total_interval * (100 - dev_util) / 100; > +} > + > +static void __tune_discard_policy(struct f2fs_sb_info *sbi, > + struct discard_policy *dpolicy) > +{ > + struct discard_cmd_control *dcc = SM_I(sbi)->dcc_info; > + int dev_util; > + > + if (dcc->io_interrupted) { > + dpolicy->min_interval = DEF_MIN_DISCARD_ISSUE_TIME; > + dpolicy->mid_interval = DEF_MID_DISCARD_ISSUE_TIME; > + dpolicy->max_interval = DEF_MAX_DISCARD_ISSUE_TIME; > + return; > + } > + > + dev_util = dev_utilization(sbi); > + > + __adjust_discard_speed(>min_interval, > + DEF_MIN_DISCARD_ISSUE_TIME, dev_util); > + __adjust_discard_speed(>mid_interval, > + DEF_MID_DISCARD_ISSUE_TIME, dev_util); > + __adjust_discard_speed(>max_interval, > +
Re: [f2fs-dev] [PATCH 1/2] f2fs: set 4KB discard granularity by default
On 08/10, Chao Yu wrote: > Small granularity (size < 64K) fragmentation will cause f2fs suspending > all pending discards, result in performance regression, so let's set > 4KB discard granularity by default. > > So that without fstrim, we also have the ability to avoid any performance > regression caused by non-alignment mapping between fs and flash device. This is why we added a sysfs entry. Why do we need to change the default value every time? > > Signed-off-by: Chao Yu > --- > fs/f2fs/f2fs.h | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h > index 58431b9bfd8f..273ffdaf4891 100644 > --- a/fs/f2fs/f2fs.h > +++ b/fs/f2fs/f2fs.h > @@ -248,7 +248,7 @@ struct discard_entry { > }; > > /* default discard granularity of inner discard thread, unit: block count */ > -#define DEFAULT_DISCARD_GRANULARITY 16 > +#define DEFAULT_DISCARD_GRANULARITY 1 > > /* max discard pend list number */ > #define MAX_PLIST_NUM512 > -- > 2.18.0.rc1 -- Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH v3] f2fs: fix performance issue observed with multi-thread sequential read
On 08/14, Chao Yu wrote: > On 2018/8/14 4:11, Jaegeuk Kim wrote: > > On 08/13, Chao Yu wrote: > >> Hi Jaegeuk, > >> > >> On 2018/8/11 2:56, Jaegeuk Kim wrote: > >>> This reverts the commit - "b93f771 - f2fs: remove writepages lock" > >>> to fix the drop in sequential read throughput. > >>> > >>> Test: ./tiotest -t 32 -d /data/tio_tmp -f 32 -b 524288 -k 1 -k 3 -L > >>> device: UFS > >>> > >>> Before - > >>> read throughput: 185 MB/s > >>> total read requests: 85177 (of these ~8 are 4KB size requests). > >>> total write requests: 2546 (of these ~2208 requests are written in 512KB). > >>> > >>> After - > >>> read throughput: 758 MB/s > >>> total read requests: 2417 (of these ~2042 are 512KB reads). > >>> total write requests: 2701 (of these ~2034 requests are written in 512KB). > >> > >> IMO, it only impact sequential read performance in a large file which may > >> be > >> fragmented during multi-thread writing. > >> > >> In android environment, mostly, the large file should be cold type, such > >> as apk, > >> mp3, rmvb, jpeg..., so I think we only need to serialize writepages() for > >> cold > >> data area writer. > >> > >> So how about adding a mount option to serialize writepage() for different > >> type > >> of log, e.g. in android, using serialize=4; by default, using serialize=7 > >> HOT_DATA 1 > >> WARM_DATA 2 > >> COLD_DATA 4 > > > > Well, I don't think we need to give too many mount options for this > > fragmented > > case. How about doing this for the large files only like this? > > Thread A write 512 pages Thread B write 8 pages > > - writepages() > - mutex_lock(>writepages); > - writepage(); > ... > - writepages() >- writepage() > > - writepage(); > ... > - mutex_unlock(>writepages); > > Above case will also cause fragmentation since we didn't serialize all > concurrent IO with the lock. > > Do we need to consider such case? We can simply allow 512 and 8 in the same segment, which would not a big deal, when considering starvation of Thread B. > > Thanks, > > > > >>From 4fea0b6e4da8512a72dd52afc7a51beb35966ad9 Mon Sep 17 00:00:00 2001 > > From: Jaegeuk Kim > > Date: Thu, 9 Aug 2018 17:53:34 -0700 > > Subject: [PATCH] f2fs: fix performance issue observed with multi-thread > > sequential read > > > > This reverts the commit - "b93f771 - f2fs: remove writepages lock" > > to fix the drop in sequential read throughput. > > > > Test: ./tiotest -t 32 -d /data/tio_tmp -f 32 -b 524288 -k 1 -k 3 -L > > device: UFS > > > > Before - > > read throughput: 185 MB/s > > total read requests: 85177 (of these ~8 are 4KB size requests). > > total write requests: 2546 (of these ~2208 requests are written in 512KB). > > > > After - > > read throughput: 758 MB/s > > total read requests: 2417 (of these ~2042 are 512KB reads). > > total write requests: 2701 (of these ~2034 requests are written in 512KB). > > > > Signed-off-by: Sahitya Tummala > > Signed-off-by: Jaegeuk Kim > > --- > > Documentation/ABI/testing/sysfs-fs-f2fs | 8 > > fs/f2fs/data.c | 10 ++ > > fs/f2fs/f2fs.h | 2 ++ > > fs/f2fs/segment.c | 1 + > > fs/f2fs/super.c | 1 + > > fs/f2fs/sysfs.c | 2 ++ > > 6 files changed, 24 insertions(+) > > > > diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs > > b/Documentation/ABI/testing/sysfs-fs-f2fs > > index 9b0123388f18..94a24aedcdb2 100644 > > --- a/Documentation/ABI/testing/sysfs-fs-f2fs > > +++ b/Documentation/ABI/testing/sysfs-fs-f2fs > > @@ -51,6 +51,14 @@ Description: > > Controls the dirty page count condition for the in-place-update > > policies. > > > > +What: /sys/fs/f2fs//min_seq_blocks > > +Date: August 2018 > > +Contact: "Jaegeuk Kim" > > +Description: > > +Controls the dirty page count condition for batched sequential > > +writes in ->writepages. > > + > > + > > What: /sys/fs/f2fs//min_hot_blocks > > Date: March 2017 > > Contact: "Jaegeuk Kim" > > diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c > > index 45f043ee48bd..f09231b1cc74 100644 > > --- a/fs/f2fs/data.c > > +++ b/fs/f2fs/data.c > > @@ -2132,6 +2132,7 @@ static int __f2fs_write_data_pages(struct > > address_space *mapping, > > struct f2fs_sb_info *sbi = F2FS_I_SB(inode); > > struct blk_plug plug; > > int ret; > > + bool locked = false; > > > > /* deal with chardevs and other special file */ > > if (!mapping->a_ops->writepage) > > @@ -2162,10 +2163,19 @@ static int __f2fs_write_data_pages(struct > > address_space *mapping, > > else if (atomic_read(>wb_sync_req[DATA])) > > goto skip_write; > > > > + if (!S_ISDIR(inode->i_mode) && > > +
Re: [f2fs-dev] [PATCH v3] f2fs: fix performance issue observed with multi-thread sequential read
On 2018/8/14 4:11, Jaegeuk Kim wrote: > On 08/13, Chao Yu wrote: >> Hi Jaegeuk, >> >> On 2018/8/11 2:56, Jaegeuk Kim wrote: >>> This reverts the commit - "b93f771 - f2fs: remove writepages lock" >>> to fix the drop in sequential read throughput. >>> >>> Test: ./tiotest -t 32 -d /data/tio_tmp -f 32 -b 524288 -k 1 -k 3 -L >>> device: UFS >>> >>> Before - >>> read throughput: 185 MB/s >>> total read requests: 85177 (of these ~8 are 4KB size requests). >>> total write requests: 2546 (of these ~2208 requests are written in 512KB). >>> >>> After - >>> read throughput: 758 MB/s >>> total read requests: 2417 (of these ~2042 are 512KB reads). >>> total write requests: 2701 (of these ~2034 requests are written in 512KB). >> >> IMO, it only impact sequential read performance in a large file which may be >> fragmented during multi-thread writing. >> >> In android environment, mostly, the large file should be cold type, such as >> apk, >> mp3, rmvb, jpeg..., so I think we only need to serialize writepages() for >> cold >> data area writer. >> >> So how about adding a mount option to serialize writepage() for different >> type >> of log, e.g. in android, using serialize=4; by default, using serialize=7 >> HOT_DATA 1 >> WARM_DATA2 >> COLD_DATA4 > > Well, I don't think we need to give too many mount options for this fragmented > case. How about doing this for the large files only like this? Thread A write 512 pagesThread B write 8 pages - writepages() - mutex_lock(>writepages); - writepage(); ... - writepages() - writepage() - writepage(); ... - mutex_unlock(>writepages); Above case will also cause fragmentation since we didn't serialize all concurrent IO with the lock. Do we need to consider such case? Thanks, > >>From 4fea0b6e4da8512a72dd52afc7a51beb35966ad9 Mon Sep 17 00:00:00 2001 > From: Jaegeuk Kim > Date: Thu, 9 Aug 2018 17:53:34 -0700 > Subject: [PATCH] f2fs: fix performance issue observed with multi-thread > sequential read > > This reverts the commit - "b93f771 - f2fs: remove writepages lock" > to fix the drop in sequential read throughput. > > Test: ./tiotest -t 32 -d /data/tio_tmp -f 32 -b 524288 -k 1 -k 3 -L > device: UFS > > Before - > read throughput: 185 MB/s > total read requests: 85177 (of these ~8 are 4KB size requests). > total write requests: 2546 (of these ~2208 requests are written in 512KB). > > After - > read throughput: 758 MB/s > total read requests: 2417 (of these ~2042 are 512KB reads). > total write requests: 2701 (of these ~2034 requests are written in 512KB). > > Signed-off-by: Sahitya Tummala > Signed-off-by: Jaegeuk Kim > --- > Documentation/ABI/testing/sysfs-fs-f2fs | 8 > fs/f2fs/data.c | 10 ++ > fs/f2fs/f2fs.h | 2 ++ > fs/f2fs/segment.c | 1 + > fs/f2fs/super.c | 1 + > fs/f2fs/sysfs.c | 2 ++ > 6 files changed, 24 insertions(+) > > diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs > b/Documentation/ABI/testing/sysfs-fs-f2fs > index 9b0123388f18..94a24aedcdb2 100644 > --- a/Documentation/ABI/testing/sysfs-fs-f2fs > +++ b/Documentation/ABI/testing/sysfs-fs-f2fs > @@ -51,6 +51,14 @@ Description: >Controls the dirty page count condition for the in-place-update >policies. > > +What:/sys/fs/f2fs//min_seq_blocks > +Date:August 2018 > +Contact: "Jaegeuk Kim" > +Description: > + Controls the dirty page count condition for batched sequential > + writes in ->writepages. > + > + > What:/sys/fs/f2fs//min_hot_blocks > Date:March 2017 > Contact: "Jaegeuk Kim" > diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c > index 45f043ee48bd..f09231b1cc74 100644 > --- a/fs/f2fs/data.c > +++ b/fs/f2fs/data.c > @@ -2132,6 +2132,7 @@ static int __f2fs_write_data_pages(struct address_space > *mapping, > struct f2fs_sb_info *sbi = F2FS_I_SB(inode); > struct blk_plug plug; > int ret; > + bool locked = false; > > /* deal with chardevs and other special file */ > if (!mapping->a_ops->writepage) > @@ -2162,10 +2163,19 @@ static int __f2fs_write_data_pages(struct > address_space *mapping, > else if (atomic_read(>wb_sync_req[DATA])) > goto skip_write; > > + if (!S_ISDIR(inode->i_mode) && > + get_dirty_pages(inode) <= SM_I(sbi)->min_seq_blocks) { > + mutex_lock(>writepages); > + locked = true; > + } > + > blk_start_plug(); > ret = f2fs_write_cache_pages(mapping, wbc, io_type); > blk_finish_plug(); > > + if (locked) > + mutex_unlock(>writepages); > + > if (wbc->sync_mode ==
Re: [f2fs-dev] [RFC PATCH 3/4] f2fs-tools: unify the writeback of superblock
On 2018/8/13 22:25, Chao Yu wrote: > On 2018/8/13 21:32, Junling Zheng wrote: >> Introduce __write_superblock() to support updating specified one >> superblock or both, thus we can wrapper it in update_superblock() and >> f2fs_write_super_block to unify all places where sb needs to be updated. >> >> Signed-off-by: Junling Zheng >> --- >> fsck/fsck.h| 2 +- >> fsck/mount.c | 74 +++--- >> fsck/resize.c | 20 ++--- >> include/f2fs_fs.h | 31 +++ >> mkfs/f2fs_format.c | 19 +--- >> 5 files changed, 52 insertions(+), 94 deletions(-) >> >> diff --git a/fsck/fsck.h b/fsck/fsck.h >> index 6042e68..e3490e6 100644 >> --- a/fsck/fsck.h >> +++ b/fsck/fsck.h >> @@ -178,7 +178,7 @@ extern void move_curseg_info(struct f2fs_sb_info *, u64, >> int); >> extern void write_curseg_info(struct f2fs_sb_info *); >> extern int find_next_free_block(struct f2fs_sb_info *, u64 *, int, int); >> extern void write_checkpoint(struct f2fs_sb_info *); >> -extern void write_superblock(struct f2fs_super_block *); >> +extern void update_superblock(struct f2fs_super_block *, int); >> extern void update_data_blkaddr(struct f2fs_sb_info *, nid_t, u16, block_t); >> extern void update_nat_blkaddr(struct f2fs_sb_info *, nid_t, nid_t, >> block_t); >> >> diff --git a/fsck/mount.c b/fsck/mount.c >> index 58ef3e6..e7ceb8d 100644 >> --- a/fsck/mount.c >> +++ b/fsck/mount.c >> @@ -476,7 +476,7 @@ void print_sb_state(struct f2fs_super_block *sb) >> } >> >> static inline int sanity_check_area_boundary(struct f2fs_super_block *sb, >> -u64 offset) >> +enum SB_ADDR sb_addr) >> { >> u32 segment0_blkaddr = get_sb(segment0_blkaddr); >> u32 cp_blkaddr = get_sb(cp_blkaddr); >> @@ -542,14 +542,11 @@ static inline int sanity_check_area_boundary(struct >> f2fs_super_block *sb, >> segment_count_main << log_blocks_per_seg); >> return -1; >> } else if (main_end_blkaddr < seg_end_blkaddr) { >> -int err; >> - >> set_sb(segment_count, (main_end_blkaddr - >> segment0_blkaddr) >> log_blocks_per_seg); >> >> -err = dev_write(sb, offset, sizeof(struct f2fs_super_block)); >> -MSG(0, "Info: Fix alignment: %s, start(%u) end(%u) block(%u)\n", >> -err ? "failed": "done", >> +update_superblock(sb, 1 << sb_addr); >> +MSG(0, "Info: Fix alignment: start(%u) end(%u) block(%u)\n", >> main_blkaddr, >> segment0_blkaddr + >> (segment_count << log_blocks_per_seg), >> @@ -558,7 +555,7 @@ static inline int sanity_check_area_boundary(struct >> f2fs_super_block *sb, >> return 0; >> } >> >> -int sanity_check_raw_super(struct f2fs_super_block *sb, u64 offset) >> +int sanity_check_raw_super(struct f2fs_super_block *sb, enum SB_ADDR >> sb_addr) >> { >> unsigned int blocksize; >> >> @@ -600,30 +597,24 @@ int sanity_check_raw_super(struct f2fs_super_block >> *sb, u64 offset) >> if (get_sb(segment_count) > F2FS_MAX_SEGMENT) >> return -1; >> >> -if (sanity_check_area_boundary(sb, offset)) >> +if (sanity_check_area_boundary(sb, sb_addr)) >> return -1; >> return 0; >> } >> >> -int validate_super_block(struct f2fs_sb_info *sbi, int block) >> +int validate_super_block(struct f2fs_sb_info *sbi, enum SB_ADDR sb_addr) >> { >> -u64 offset; >> char buf[F2FS_BLKSIZE]; >> >> sbi->raw_super = malloc(sizeof(struct f2fs_super_block)); >> >> -if (block == 0) >> -offset = F2FS_SUPER_OFFSET; >> -else >> -offset = F2FS_BLKSIZE + F2FS_SUPER_OFFSET; >> - >> -if (dev_read_block(buf, block)) >> +if (dev_read_block(buf, sb_addr)) >> return -1; >> >> memcpy(sbi->raw_super, buf + F2FS_SUPER_OFFSET, >> sizeof(struct f2fs_super_block)); >> >> -if (!sanity_check_raw_super(sbi->raw_super, offset)) { >> +if (!sanity_check_raw_super(sbi->raw_super, sb_addr)) { >> /* get kernel version */ >> if (c.kd >= 0) { >> dev_read_version(c.version, 0, VERSION_LEN); >> @@ -642,13 +633,9 @@ int validate_super_block(struct f2fs_sb_info *sbi, int >> block) >> MSG(0, "Info: FSCK version\n from \"%s\"\nto \"%s\"\n", >> c.sb_version, c.version); >> if (memcmp(c.sb_version, c.version, VERSION_LEN)) { >> -int ret; >> - >> memcpy(sbi->raw_super->version, >> c.version, VERSION_LEN); >> -ret = dev_write(sbi->raw_super, offset, >> -sizeof(struct
Re: [f2fs-dev] [RFC PATCH 4/4] f2fs-tools: introduce sb checksum
Hi, Chao On 2018/8/13 22:33, Chao Yu wrote: > On 2018/8/13 21:32, Junling Zheng wrote: >> This patch introduced crc for superblock. >> >> Signed-off-by: Junling Zheng >> --- >> fsck/mount.c | 23 +++ >> fsck/resize.c | 12 ++-- >> include/f2fs_fs.h | 16 +++- >> mkfs/f2fs_format.c | 3 +++ >> 4 files changed, 47 insertions(+), 7 deletions(-) >> >> diff --git a/fsck/mount.c b/fsck/mount.c >> index e7ceb8d..af9b219 100644 >> --- a/fsck/mount.c >> +++ b/fsck/mount.c >> @@ -340,6 +340,7 @@ void print_raw_sb_info(struct f2fs_super_block *sb) >> DISP_u32(sb, node_ino); >> DISP_u32(sb, meta_ino); >> DISP_u32(sb, cp_payload); >> +DISP_u32(sb, crc); > > if (feature is on) { > DISP_u32(sb, checksum_offset); > DISP_u32(sb, crc); > } > sb->checksum_offset had been printed before without any conditions. So I think it's better to print them always :) > Thanks, > >> DISP("%-.256s", sb, version); >> printf("\n"); >> } >> @@ -467,6 +468,9 @@ void print_sb_state(struct f2fs_super_block *sb) >> if (f & cpu_to_le32(F2FS_FEATURE_LOST_FOUND)) { >> MSG(0, "%s", " lost_found"); >> } >> +if (f & cpu_to_le32(F2FS_FEATURE_SB_CHKSUM)) { >> +MSG(0, "%s", " sb_checksum"); >> +} >> MSG(0, "\n"); >> MSG(0, "Info: superblock encrypt level = %d, salt = ", >> sb->encryption_level); >> @@ -555,10 +559,29 @@ static inline int sanity_check_area_boundary(struct >> f2fs_super_block *sb, >> return 0; >> } >> >> +static int verify_sb_chksum(struct f2fs_super_block *sb) >> +{ >> +if (SB_CHKSUM_OFFSET != get_sb(checksum_offset)) { >> +MSG(0, "\tInvalid SB CRC offset: %u\n", >> +get_sb(checksum_offset)); >> +return -1; >> +} >> +if (f2fs_crc_valid(get_sb(crc), sb, >> +get_sb(checksum_offset))) { >> +MSG(0, "\tInvalid SB CRC: 0x%x\n", get_sb(crc)); >> +return -1; >> +} >> +return 0; >> +} >> + >> int sanity_check_raw_super(struct f2fs_super_block *sb, enum SB_ADDR >> sb_addr) >> { >> unsigned int blocksize; >> >> +if ((get_sb(feature) & F2FS_FEATURE_SB_CHKSUM) && >> +verify_sb_chksum(sb)) >> +return -1; >> + >> if (F2FS_SUPER_MAGIC != get_sb(magic)) >> return -1; >> >> diff --git a/fsck/resize.c b/fsck/resize.c >> index 5161a1f..3462165 100644 >> --- a/fsck/resize.c >> +++ b/fsck/resize.c >> @@ -603,9 +603,6 @@ static int f2fs_resize_grow(struct f2fs_sb_info *sbi) >> } >> } >> >> -print_raw_sb_info(sb); >> -print_raw_sb_info(new_sb); >> - >> old_main_blkaddr = get_sb(main_blkaddr); >> new_main_blkaddr = get_newsb(main_blkaddr); >> offset = new_main_blkaddr - old_main_blkaddr; >> @@ -629,6 +626,9 @@ static int f2fs_resize_grow(struct f2fs_sb_info *sbi) >> migrate_sit(sbi, new_sb, offset_seg); >> rebuild_checkpoint(sbi, new_sb, offset_seg); >> update_superblock(new_sb, SB_ALL); >> +print_raw_sb_info(sb); >> +print_raw_sb_info(new_sb); >> + >> return 0; >> } >> >> @@ -658,9 +658,6 @@ static int f2fs_resize_shrink(struct f2fs_sb_info *sbi) >> } >> } >> >> -print_raw_sb_info(sb); >> -print_raw_sb_info(new_sb); >> - >> old_main_blkaddr = get_sb(main_blkaddr); >> new_main_blkaddr = get_newsb(main_blkaddr); >> offset = old_main_blkaddr - new_main_blkaddr; >> @@ -690,6 +687,9 @@ static int f2fs_resize_shrink(struct f2fs_sb_info *sbi) >> /* move whole data region */ >> //if (err) >> // migrate_main(sbi, offset); >> +print_raw_sb_info(sb); >> +print_raw_sb_info(new_sb); >> + >> return 0; >> } >> >> diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h >> index b0d9b9b..556d526 100644 >> --- a/include/f2fs_fs.h >> +++ b/include/f2fs_fs.h >> @@ -279,6 +279,7 @@ static inline uint64_t bswap_64(uint64_t val) >> #define BITS_PER_BYTE 8 >> #define F2FS_SUPER_MAGIC0xF2F52010 /* F2FS Magic Number */ >> #define CP_CHKSUM_OFFSET4092 >> +#define SB_CHKSUM_OFFSET3068 >> #define MAX_PATH_LEN64 >> #define MAX_DEVICES 8 >> >> @@ -579,6 +580,7 @@ enum { >> #define F2FS_FEATURE_INODE_CRTIME 0x0100 >> #define F2FS_FEATURE_LOST_FOUND 0x0200 >> #define F2FS_FEATURE_VERITY 0x0400 /* reserved */ >> +#define F2FS_FEATURE_SB_CHKSUM 0x0800 >> >> #define MAX_VOLUME_NAME 512 >> >> @@ -632,7 +634,8 @@ struct f2fs_super_block { >> struct f2fs_device devs[MAX_DEVICES]; /* device list */ >> __le32 qf_ino[F2FS_MAX_QUOTAS]; /* quota inode numbers */ >> __u8 hot_ext_count; /* # of hot file extension */ >> -__u8 reserved[314]; /* valid reserved region */ >> +__u8 reserved[310];
[f2fs-dev] [PATCH] f2fs: rework fault injection handling to avoid a warning
When CONFIG_F2FS_FAULT_INJECTION is disabled, we get a warning about an unused label: fs/f2fs/segment.c: In function '__submit_discard_cmd': fs/f2fs/segment.c:1059:1: error: label 'submit' defined but not used [-Werror=unused-label] This could be fixed by adding another #ifdef around it, but the more reliable way of doing this seems to be to remove the other #ifdefs where that is easily possible. By defining time_to_inject() as a trivial stub, most of the checks for CONFIG_F2FS_FAULT_INJECTION can go away. This also leads to nicer formatting of the code. Signed-off-by: Arnd Bergmann --- fs/f2fs/checkpoint.c | 3 +-- fs/f2fs/data.c | 2 -- fs/f2fs/dir.c| 3 +-- fs/f2fs/f2fs.h | 50 ++-- fs/f2fs/file.c | 3 +-- fs/f2fs/gc.c | 2 -- fs/f2fs/inode.c | 3 +-- fs/f2fs/node.c | 3 +-- fs/f2fs/recovery.c | 5 ++--- fs/f2fs/segment.c| 4 10 files changed, 32 insertions(+), 46 deletions(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index 3ab7a00c0641..e8b6b89bddb8 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -555,13 +555,12 @@ int f2fs_acquire_orphan_inode(struct f2fs_sb_info *sbi) spin_lock(>ino_lock); -#ifdef CONFIG_F2FS_FAULT_INJECTION if (time_to_inject(sbi, FAULT_ORPHAN)) { spin_unlock(>ino_lock); f2fs_show_injection_info(FAULT_ORPHAN); return -ENOSPC; } -#endif + if (unlikely(im->ino_num >= sbi->max_orphans)) err = -ENOSPC; else diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 67dc5fd8d4d5..773f82bbb618 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -126,12 +126,10 @@ static bool f2fs_bio_post_read_required(struct bio *bio) static void f2fs_read_end_io(struct bio *bio) { -#ifdef CONFIG_F2FS_FAULT_INJECTION if (time_to_inject(F2FS_P_SB(bio_first_page_all(bio)), FAULT_IO)) { f2fs_show_injection_info(FAULT_IO); bio->bi_status = BLK_STS_IOERR; } -#endif if (f2fs_bio_post_read_required(bio)) { struct bio_post_read_ctx *ctx = bio->bi_private; diff --git a/fs/f2fs/dir.c b/fs/f2fs/dir.c index 9c2a23242f64..01006085904a 100644 --- a/fs/f2fs/dir.c +++ b/fs/f2fs/dir.c @@ -517,12 +517,11 @@ int f2fs_add_regular_entry(struct inode *dir, const struct qstr *new_name, } start: -#ifdef CONFIG_F2FS_FAULT_INJECTION if (time_to_inject(F2FS_I_SB(dir), FAULT_DIR_DEPTH)) { f2fs_show_injection_info(FAULT_DIR_DEPTH); return -ENOSPC; } -#endif + if (unlikely(current_depth == MAX_DIR_HASH_DEPTH)) return -ENOSPC; diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index a8ae1c73d3b3..8d2086e2571b 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -41,7 +41,6 @@ } while (0) #endif -#ifdef CONFIG_F2FS_FAULT_INJECTION enum { FAULT_KMALLOC, FAULT_KVMALLOC, @@ -60,6 +59,7 @@ enum { FAULT_MAX, }; +#ifdef CONFIG_F2FS_FAULT_INJECTION #define F2FS_ALL_FAULT_TYPE((1 << FAULT_MAX) - 1) struct f2fs_fault_info { @@ -1326,6 +1326,12 @@ static inline bool time_to_inject(struct f2fs_sb_info *sbi, int type) } return false; } +#else +#define f2fs_show_injection_info(type) do { } while (0) +static inline bool time_to_inject(struct f2fs_sb_info *sbi, int type) +{ + return false; +} #endif /* For write statistics. Suppose sector size is 512 bytes, @@ -1678,13 +1684,12 @@ static inline int inc_valid_block_count(struct f2fs_sb_info *sbi, if (ret) return ret; -#ifdef CONFIG_F2FS_FAULT_INJECTION if (time_to_inject(sbi, FAULT_BLOCK)) { f2fs_show_injection_info(FAULT_BLOCK); release = *count; goto enospc; } -#endif + /* * let's increase this in prior to actual block count change in order * for f2fs_sync_file to avoid data races when deciding checkpoint. @@ -1893,12 +1898,10 @@ static inline int inc_valid_node_count(struct f2fs_sb_info *sbi, return ret; } -#ifdef CONFIG_F2FS_FAULT_INJECTION if (time_to_inject(sbi, FAULT_BLOCK)) { f2fs_show_injection_info(FAULT_BLOCK); goto enospc; } -#endif spin_lock(>stat_lock); @@ -1983,22 +1986,23 @@ static inline s64 valid_inode_count(struct f2fs_sb_info *sbi) static inline struct page *f2fs_grab_cache_page(struct address_space *mapping, pgoff_t index, bool for_write) { -#ifdef CONFIG_F2FS_FAULT_INJECTION struct page *page; - if (!for_write) - page = find_get_page_flags(mapping, index, - FGP_LOCK | FGP_ACCESSED); - else - page = find_lock_page(mapping, index); - if (page) -
Re: [f2fs-dev] [PATCH] f2fs: avoid fi->i_gc_rwsem[WRITE] lock in f2fs_gc
On 08/12, Chao Yu wrote: > On 2018/8/4 10:31, Chao Yu wrote: > > How about keep lock order as: > > > > - inode_lock > > - i_mmap_sem > > - lock_all() > > - unlock_all() > > - i_gc_rwsem[WRITE] > >- lock_op() > > I got below warning when testing last dev-test: > > - f2fs_direct_IO current lock dependency > - i_gc_rwsem[WRITE] > - i_mmap_sem > - do_blockdev_direct_IO >- i_mmap_sem >- i_gc_rwsem[WRITE] > Yeah, it seems it's true. How about this? --- fs/f2fs/data.c | 4 ++-- fs/f2fs/file.c | 43 +++ 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index f09231b1cc74..021923dc666b 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -2208,14 +2208,14 @@ static void f2fs_write_failed(struct address_space *mapping, loff_t to) loff_t i_size = i_size_read(inode); if (to > i_size) { - down_write(_I(inode)->i_mmap_sem); down_write(_I(inode)->i_gc_rwsem[WRITE]); + down_write(_I(inode)->i_mmap_sem); truncate_pagecache(inode, i_size); f2fs_truncate_blocks(inode, i_size, true); - up_write(_I(inode)->i_gc_rwsem[WRITE]); up_write(_I(inode)->i_mmap_sem); + up_write(_I(inode)->i_gc_rwsem[WRITE]); } } diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c index 560751adba01..8b13afb23734 100644 --- a/fs/f2fs/file.c +++ b/fs/f2fs/file.c @@ -798,8 +798,8 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr) if (attr->ia_valid & ATTR_SIZE) { bool to_smaller = (attr->ia_size <= i_size_read(inode)); - down_write(_I(inode)->i_mmap_sem); down_write(_I(inode)->i_gc_rwsem[WRITE]); + down_write(_I(inode)->i_mmap_sem); truncate_setsize(inode, attr->ia_size); @@ -809,8 +809,8 @@ int f2fs_setattr(struct dentry *dentry, struct iattr *attr) * do not trim all blocks after i_size if target size is * larger than i_size. */ - up_write(_I(inode)->i_gc_rwsem[WRITE]); up_write(_I(inode)->i_mmap_sem); + up_write(_I(inode)->i_gc_rwsem[WRITE]); if (err) return err; @@ -963,8 +963,8 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len) blk_start = (loff_t)pg_start << PAGE_SHIFT; blk_end = (loff_t)pg_end << PAGE_SHIFT; - down_write(_I(inode)->i_mmap_sem); down_write(_I(inode)->i_gc_rwsem[WRITE]); + down_write(_I(inode)->i_mmap_sem); truncate_inode_pages_range(mapping, blk_start, blk_end - 1); @@ -973,8 +973,8 @@ static int punch_hole(struct inode *inode, loff_t offset, loff_t len) ret = f2fs_truncate_hole(inode, pg_start, pg_end); f2fs_unlock_op(sbi); - up_write(_I(inode)->i_gc_rwsem[WRITE]); up_write(_I(inode)->i_mmap_sem); + up_write(_I(inode)->i_gc_rwsem[WRITE]); } } @@ -1201,6 +1201,7 @@ static int f2fs_do_collapse(struct inode *inode, loff_t offset, loff_t len) /* avoid gc operation during block exchange */ down_write(_I(inode)->i_gc_rwsem[WRITE]); + down_write(_I(inode)->i_mmap_sem); f2fs_lock_op(sbi); f2fs_drop_extent_tree(inode); @@ -1208,6 +1209,7 @@ static int f2fs_do_collapse(struct inode *inode, loff_t offset, loff_t len) ret = __exchange_data_block(inode, inode, end, start, nrpages - end, true); f2fs_unlock_op(sbi); + up_write(_I(inode)->i_mmap_sem); up_write(_I(inode)->i_gc_rwsem[WRITE]); return ret; } @@ -1228,17 +1230,17 @@ static int f2fs_collapse_range(struct inode *inode, loff_t offset, loff_t len) if (ret) return ret; - down_write(_I(inode)->i_mmap_sem); /* write out all dirty pages from offset */ ret = filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX); if (ret) - goto out_unlock; + return ret; ret = f2fs_do_collapse(inode, offset, len); if (ret) - goto out_unlock; + return ret; /* write out all moved pages, if possible */ + down_write(_I(inode)->i_mmap_sem); filemap_write_and_wait_range(inode->i_mapping, offset, LLONG_MAX); truncate_pagecache(inode, offset); @@ -1246,10 +1248,9 @@ static int f2fs_collapse_range(struct inode *inode, loff_t offset, loff_t len) truncate_pagecache(inode, new_size); ret = f2fs_truncate_blocks(inode,
Re: [f2fs-dev] [PATCH v3] f2fs: fix performance issue observed with multi-thread sequential read
On 08/13, Chao Yu wrote: > Hi Jaegeuk, > > On 2018/8/11 2:56, Jaegeuk Kim wrote: > > This reverts the commit - "b93f771 - f2fs: remove writepages lock" > > to fix the drop in sequential read throughput. > > > > Test: ./tiotest -t 32 -d /data/tio_tmp -f 32 -b 524288 -k 1 -k 3 -L > > device: UFS > > > > Before - > > read throughput: 185 MB/s > > total read requests: 85177 (of these ~8 are 4KB size requests). > > total write requests: 2546 (of these ~2208 requests are written in 512KB). > > > > After - > > read throughput: 758 MB/s > > total read requests: 2417 (of these ~2042 are 512KB reads). > > total write requests: 2701 (of these ~2034 requests are written in 512KB). > > IMO, it only impact sequential read performance in a large file which may be > fragmented during multi-thread writing. > > In android environment, mostly, the large file should be cold type, such as > apk, > mp3, rmvb, jpeg..., so I think we only need to serialize writepages() for cold > data area writer. > > So how about adding a mount option to serialize writepage() for different type > of log, e.g. in android, using serialize=4; by default, using serialize=7 > HOT_DATA 1 > WARM_DATA 2 > COLD_DATA 4 Well, I don't think we need to give too many mount options for this fragmented case. How about doing this for the large files only like this? >From 4fea0b6e4da8512a72dd52afc7a51beb35966ad9 Mon Sep 17 00:00:00 2001 From: Jaegeuk Kim Date: Thu, 9 Aug 2018 17:53:34 -0700 Subject: [PATCH] f2fs: fix performance issue observed with multi-thread sequential read This reverts the commit - "b93f771 - f2fs: remove writepages lock" to fix the drop in sequential read throughput. Test: ./tiotest -t 32 -d /data/tio_tmp -f 32 -b 524288 -k 1 -k 3 -L device: UFS Before - read throughput: 185 MB/s total read requests: 85177 (of these ~8 are 4KB size requests). total write requests: 2546 (of these ~2208 requests are written in 512KB). After - read throughput: 758 MB/s total read requests: 2417 (of these ~2042 are 512KB reads). total write requests: 2701 (of these ~2034 requests are written in 512KB). Signed-off-by: Sahitya Tummala Signed-off-by: Jaegeuk Kim --- Documentation/ABI/testing/sysfs-fs-f2fs | 8 fs/f2fs/data.c | 10 ++ fs/f2fs/f2fs.h | 2 ++ fs/f2fs/segment.c | 1 + fs/f2fs/super.c | 1 + fs/f2fs/sysfs.c | 2 ++ 6 files changed, 24 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs index 9b0123388f18..94a24aedcdb2 100644 --- a/Documentation/ABI/testing/sysfs-fs-f2fs +++ b/Documentation/ABI/testing/sysfs-fs-f2fs @@ -51,6 +51,14 @@ Description: Controls the dirty page count condition for the in-place-update policies. +What: /sys/fs/f2fs//min_seq_blocks +Date: August 2018 +Contact: "Jaegeuk Kim" +Description: +Controls the dirty page count condition for batched sequential +writes in ->writepages. + + What: /sys/fs/f2fs//min_hot_blocks Date: March 2017 Contact: "Jaegeuk Kim" diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 45f043ee48bd..f09231b1cc74 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -2132,6 +2132,7 @@ static int __f2fs_write_data_pages(struct address_space *mapping, struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct blk_plug plug; int ret; + bool locked = false; /* deal with chardevs and other special file */ if (!mapping->a_ops->writepage) @@ -2162,10 +2163,19 @@ static int __f2fs_write_data_pages(struct address_space *mapping, else if (atomic_read(>wb_sync_req[DATA])) goto skip_write; + if (!S_ISDIR(inode->i_mode) && + get_dirty_pages(inode) <= SM_I(sbi)->min_seq_blocks) { + mutex_lock(>writepages); + locked = true; + } + blk_start_plug(); ret = f2fs_write_cache_pages(mapping, wbc, io_type); blk_finish_plug(); + if (locked) + mutex_unlock(>writepages); + if (wbc->sync_mode == WB_SYNC_ALL) atomic_dec(>wb_sync_req[DATA]); /* diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 375aa9f30cfa..098bdedc28bf 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -913,6 +913,7 @@ struct f2fs_sm_info { unsigned int ipu_policy;/* in-place-update policy */ unsigned int min_ipu_util; /* in-place-update threshold */ unsigned int min_fsync_blocks; /* threshold for fsync */ + unsigned int min_seq_blocks;/* threshold for sequential blocks */ unsigned int min_hot_blocks;/* threshold for hot block allocation */ unsigned int min_ssr_sections; /* threshold to trigger SSR allocation */ @@ -1133,6 +1134,7 @@ struct
Re: [f2fs-dev] [RFC PATCH 4/4] f2fs-tools: introduce sb checksum
On 2018/8/13 21:32, Junling Zheng wrote: > This patch introduced crc for superblock. > > Signed-off-by: Junling Zheng > --- > fsck/mount.c | 23 +++ > fsck/resize.c | 12 ++-- > include/f2fs_fs.h | 16 +++- > mkfs/f2fs_format.c | 3 +++ > 4 files changed, 47 insertions(+), 7 deletions(-) > > diff --git a/fsck/mount.c b/fsck/mount.c > index e7ceb8d..af9b219 100644 > --- a/fsck/mount.c > +++ b/fsck/mount.c > @@ -340,6 +340,7 @@ void print_raw_sb_info(struct f2fs_super_block *sb) > DISP_u32(sb, node_ino); > DISP_u32(sb, meta_ino); > DISP_u32(sb, cp_payload); > + DISP_u32(sb, crc); if (feature is on) { DISP_u32(sb, checksum_offset); DISP_u32(sb, crc); } Thanks, > DISP("%-.256s", sb, version); > printf("\n"); > } > @@ -467,6 +468,9 @@ void print_sb_state(struct f2fs_super_block *sb) > if (f & cpu_to_le32(F2FS_FEATURE_LOST_FOUND)) { > MSG(0, "%s", " lost_found"); > } > + if (f & cpu_to_le32(F2FS_FEATURE_SB_CHKSUM)) { > + MSG(0, "%s", " sb_checksum"); > + } > MSG(0, "\n"); > MSG(0, "Info: superblock encrypt level = %d, salt = ", > sb->encryption_level); > @@ -555,10 +559,29 @@ static inline int sanity_check_area_boundary(struct > f2fs_super_block *sb, > return 0; > } > > +static int verify_sb_chksum(struct f2fs_super_block *sb) > +{ > + if (SB_CHKSUM_OFFSET != get_sb(checksum_offset)) { > + MSG(0, "\tInvalid SB CRC offset: %u\n", > + get_sb(checksum_offset)); > + return -1; > + } > + if (f2fs_crc_valid(get_sb(crc), sb, > + get_sb(checksum_offset))) { > + MSG(0, "\tInvalid SB CRC: 0x%x\n", get_sb(crc)); > + return -1; > + } > + return 0; > +} > + > int sanity_check_raw_super(struct f2fs_super_block *sb, enum SB_ADDR sb_addr) > { > unsigned int blocksize; > > + if ((get_sb(feature) & F2FS_FEATURE_SB_CHKSUM) && > + verify_sb_chksum(sb)) > + return -1; > + > if (F2FS_SUPER_MAGIC != get_sb(magic)) > return -1; > > diff --git a/fsck/resize.c b/fsck/resize.c > index 5161a1f..3462165 100644 > --- a/fsck/resize.c > +++ b/fsck/resize.c > @@ -603,9 +603,6 @@ static int f2fs_resize_grow(struct f2fs_sb_info *sbi) > } > } > > - print_raw_sb_info(sb); > - print_raw_sb_info(new_sb); > - > old_main_blkaddr = get_sb(main_blkaddr); > new_main_blkaddr = get_newsb(main_blkaddr); > offset = new_main_blkaddr - old_main_blkaddr; > @@ -629,6 +626,9 @@ static int f2fs_resize_grow(struct f2fs_sb_info *sbi) > migrate_sit(sbi, new_sb, offset_seg); > rebuild_checkpoint(sbi, new_sb, offset_seg); > update_superblock(new_sb, SB_ALL); > + print_raw_sb_info(sb); > + print_raw_sb_info(new_sb); > + > return 0; > } > > @@ -658,9 +658,6 @@ static int f2fs_resize_shrink(struct f2fs_sb_info *sbi) > } > } > > - print_raw_sb_info(sb); > - print_raw_sb_info(new_sb); > - > old_main_blkaddr = get_sb(main_blkaddr); > new_main_blkaddr = get_newsb(main_blkaddr); > offset = old_main_blkaddr - new_main_blkaddr; > @@ -690,6 +687,9 @@ static int f2fs_resize_shrink(struct f2fs_sb_info *sbi) > /* move whole data region */ > //if (err) > // migrate_main(sbi, offset); > + print_raw_sb_info(sb); > + print_raw_sb_info(new_sb); > + > return 0; > } > > diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h > index b0d9b9b..556d526 100644 > --- a/include/f2fs_fs.h > +++ b/include/f2fs_fs.h > @@ -279,6 +279,7 @@ static inline uint64_t bswap_64(uint64_t val) > #define BITS_PER_BYTE8 > #define F2FS_SUPER_MAGIC 0xF2F52010 /* F2FS Magic Number */ > #define CP_CHKSUM_OFFSET 4092 > +#define SB_CHKSUM_OFFSET 3068 > #define MAX_PATH_LEN 64 > #define MAX_DEVICES 8 > > @@ -579,6 +580,7 @@ enum { > #define F2FS_FEATURE_INODE_CRTIME0x0100 > #define F2FS_FEATURE_LOST_FOUND 0x0200 > #define F2FS_FEATURE_VERITY 0x0400 /* reserved */ > +#define F2FS_FEATURE_SB_CHKSUM 0x0800 > > #define MAX_VOLUME_NAME 512 > > @@ -632,7 +634,8 @@ struct f2fs_super_block { > struct f2fs_device devs[MAX_DEVICES]; /* device list */ > __le32 qf_ino[F2FS_MAX_QUOTAS]; /* quota inode numbers */ > __u8 hot_ext_count; /* # of hot file extension */ > - __u8 reserved[314]; /* valid reserved region */ > + __u8 reserved[310]; /* valid reserved region */ > + __le32 crc; /* checksum of superblock */ > } __attribute__((packed)); > > /* > @@ -1337,6 +1340,7 @@ struct feature feature_table[] = { > \
[f2fs-dev] [RFC PATCH 3/4] f2fs-tools: unify the writeback of superblock
Introduce __write_superblock() to support updating specified one superblock or both, thus we can wrapper it in update_superblock() and f2fs_write_super_block to unify all places where sb needs to be updated. Signed-off-by: Junling Zheng --- fsck/fsck.h| 2 +- fsck/mount.c | 74 +++--- fsck/resize.c | 20 ++--- include/f2fs_fs.h | 31 +++ mkfs/f2fs_format.c | 19 +--- 5 files changed, 52 insertions(+), 94 deletions(-) diff --git a/fsck/fsck.h b/fsck/fsck.h index 6042e68..e3490e6 100644 --- a/fsck/fsck.h +++ b/fsck/fsck.h @@ -178,7 +178,7 @@ extern void move_curseg_info(struct f2fs_sb_info *, u64, int); extern void write_curseg_info(struct f2fs_sb_info *); extern int find_next_free_block(struct f2fs_sb_info *, u64 *, int, int); extern void write_checkpoint(struct f2fs_sb_info *); -extern void write_superblock(struct f2fs_super_block *); +extern void update_superblock(struct f2fs_super_block *, int); extern void update_data_blkaddr(struct f2fs_sb_info *, nid_t, u16, block_t); extern void update_nat_blkaddr(struct f2fs_sb_info *, nid_t, nid_t, block_t); diff --git a/fsck/mount.c b/fsck/mount.c index 58ef3e6..e7ceb8d 100644 --- a/fsck/mount.c +++ b/fsck/mount.c @@ -476,7 +476,7 @@ void print_sb_state(struct f2fs_super_block *sb) } static inline int sanity_check_area_boundary(struct f2fs_super_block *sb, - u64 offset) + enum SB_ADDR sb_addr) { u32 segment0_blkaddr = get_sb(segment0_blkaddr); u32 cp_blkaddr = get_sb(cp_blkaddr); @@ -542,14 +542,11 @@ static inline int sanity_check_area_boundary(struct f2fs_super_block *sb, segment_count_main << log_blocks_per_seg); return -1; } else if (main_end_blkaddr < seg_end_blkaddr) { - int err; - set_sb(segment_count, (main_end_blkaddr - segment0_blkaddr) >> log_blocks_per_seg); - err = dev_write(sb, offset, sizeof(struct f2fs_super_block)); - MSG(0, "Info: Fix alignment: %s, start(%u) end(%u) block(%u)\n", - err ? "failed": "done", + update_superblock(sb, 1 << sb_addr); + MSG(0, "Info: Fix alignment: start(%u) end(%u) block(%u)\n", main_blkaddr, segment0_blkaddr + (segment_count << log_blocks_per_seg), @@ -558,7 +555,7 @@ static inline int sanity_check_area_boundary(struct f2fs_super_block *sb, return 0; } -int sanity_check_raw_super(struct f2fs_super_block *sb, u64 offset) +int sanity_check_raw_super(struct f2fs_super_block *sb, enum SB_ADDR sb_addr) { unsigned int blocksize; @@ -600,30 +597,24 @@ int sanity_check_raw_super(struct f2fs_super_block *sb, u64 offset) if (get_sb(segment_count) > F2FS_MAX_SEGMENT) return -1; - if (sanity_check_area_boundary(sb, offset)) + if (sanity_check_area_boundary(sb, sb_addr)) return -1; return 0; } -int validate_super_block(struct f2fs_sb_info *sbi, int block) +int validate_super_block(struct f2fs_sb_info *sbi, enum SB_ADDR sb_addr) { - u64 offset; char buf[F2FS_BLKSIZE]; sbi->raw_super = malloc(sizeof(struct f2fs_super_block)); - if (block == 0) - offset = F2FS_SUPER_OFFSET; - else - offset = F2FS_BLKSIZE + F2FS_SUPER_OFFSET; - - if (dev_read_block(buf, block)) + if (dev_read_block(buf, sb_addr)) return -1; memcpy(sbi->raw_super, buf + F2FS_SUPER_OFFSET, sizeof(struct f2fs_super_block)); - if (!sanity_check_raw_super(sbi->raw_super, offset)) { + if (!sanity_check_raw_super(sbi->raw_super, sb_addr)) { /* get kernel version */ if (c.kd >= 0) { dev_read_version(c.version, 0, VERSION_LEN); @@ -642,13 +633,9 @@ int validate_super_block(struct f2fs_sb_info *sbi, int block) MSG(0, "Info: FSCK version\n from \"%s\"\nto \"%s\"\n", c.sb_version, c.version); if (memcmp(c.sb_version, c.version, VERSION_LEN)) { - int ret; - memcpy(sbi->raw_super->version, c.version, VERSION_LEN); - ret = dev_write(sbi->raw_super, offset, - sizeof(struct f2fs_super_block)); - ASSERT(ret >= 0); + update_superblock(sbi->raw_super, 1 << sb_addr); c.auto_fix = 0; c.fix_on = 1; @@ -659,7 +646,7 @@ int validate_super_block(struct f2fs_sb_info *sbi, int
[f2fs-dev] [RFC PATCH RESEND 2/4] f2fs-tools: rename CHECKSUM_OFFSET to CP_CHKSUM_OFFSET
This patch renamed CHECKSUM_OFFSET to CP_CHKSUM_OFFSET. Reviewed-by: Chao Yu Signed-off-by: Junling Zheng --- fsck/fsck.c| 4 ++-- fsck/mount.c | 4 ++-- fsck/resize.c | 8 include/f2fs_fs.h | 6 +++--- mkfs/f2fs_format.c | 14 +++--- 5 files changed, 18 insertions(+), 18 deletions(-) diff --git a/fsck/fsck.c b/fsck/fsck.c index d550403..f080d3c 100644 --- a/fsck/fsck.c +++ b/fsck/fsck.c @@ -2010,8 +2010,8 @@ static void fix_checkpoint(struct f2fs_sb_info *sbi) set_cp(valid_node_count, fsck->chk.valid_node_cnt); set_cp(valid_inode_count, fsck->chk.valid_inode_cnt); - crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, cp, CHECKSUM_OFFSET); - *((__le32 *)((unsigned char *)cp + CHECKSUM_OFFSET)) = cpu_to_le32(crc); + crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, cp, CP_CHKSUM_OFFSET); + *((__le32 *)((unsigned char *)cp + CP_CHKSUM_OFFSET)) = cpu_to_le32(crc); cp_blk_no = get_sb(cp_blkaddr); if (sbi->cur_cp == 2) diff --git a/fsck/mount.c b/fsck/mount.c index 8fb4d59..58ef3e6 100644 --- a/fsck/mount.c +++ b/fsck/mount.c @@ -2187,8 +2187,8 @@ void write_checkpoint(struct f2fs_sb_info *sbi) flags = update_nat_bits_flags(sb, cp, flags); set_cp(ckpt_flags, flags); - crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, cp, CHECKSUM_OFFSET); - *((__le32 *)((unsigned char *)cp + CHECKSUM_OFFSET)) = cpu_to_le32(crc); + crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, cp, CP_CHKSUM_OFFSET); + *((__le32 *)((unsigned char *)cp + CP_CHKSUM_OFFSET)) = cpu_to_le32(crc); cp_blk_no = get_sb(cp_blkaddr); if (sbi->cur_cp == 2) diff --git a/fsck/resize.c b/fsck/resize.c index fe8a61a..e9612b3 100644 --- a/fsck/resize.c +++ b/fsck/resize.c @@ -90,10 +90,10 @@ static int get_new_sb(struct f2fs_super_block *sb) * It requires more pages for cp. */ if (max_sit_bitmap_size > MAX_SIT_BITMAP_SIZE_IN_CKPT) { - max_nat_bitmap_size = CHECKSUM_OFFSET - sizeof(struct f2fs_checkpoint) + 1; + max_nat_bitmap_size = CP_CHKSUM_OFFSET - sizeof(struct f2fs_checkpoint) + 1; set_sb(cp_payload, F2FS_BLK_ALIGN(max_sit_bitmap_size)); } else { - max_nat_bitmap_size = CHECKSUM_OFFSET - sizeof(struct f2fs_checkpoint) + 1 + max_nat_bitmap_size = CP_CHKSUM_OFFSET - sizeof(struct f2fs_checkpoint) + 1 - max_sit_bitmap_size; set_sb(cp_payload, 0); } @@ -520,8 +520,8 @@ static void rebuild_checkpoint(struct f2fs_sb_info *sbi, (unsigned char *)cp); new_cp->checkpoint_ver = cpu_to_le64(cp_ver + 1); - crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, new_cp, CHECKSUM_OFFSET); - *((__le32 *)((unsigned char *)new_cp + CHECKSUM_OFFSET)) = + crc = f2fs_cal_crc32(F2FS_SUPER_MAGIC, new_cp, CP_CHKSUM_OFFSET); + *((__le32 *)((unsigned char *)new_cp + CP_CHKSUM_OFFSET)) = cpu_to_le32(crc); /* Write a new checkpoint in the other set */ diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h index 53fa002..e279b9f 100644 --- a/include/f2fs_fs.h +++ b/include/f2fs_fs.h @@ -278,7 +278,7 @@ static inline uint64_t bswap_64(uint64_t val) #define PAGE_CACHE_SIZE4096 #define BITS_PER_BYTE 8 #define F2FS_SUPER_MAGIC 0xF2F52010 /* F2FS Magic Number */ -#define CHECKSUM_OFFSET4092 +#define CP_CHKSUM_OFFSET 4092 #define MAX_PATH_LEN 64 #define MAX_DEVICES8 @@ -682,9 +682,9 @@ struct f2fs_checkpoint { } __attribute__((packed)); #define MAX_SIT_BITMAP_SIZE_IN_CKPT\ - (CHECKSUM_OFFSET - sizeof(struct f2fs_checkpoint) + 1 - 64) + (CP_CHKSUM_OFFSET - sizeof(struct f2fs_checkpoint) + 1 - 64) #define MAX_BITMAP_SIZE_IN_CKPT\ - (CHECKSUM_OFFSET - sizeof(struct f2fs_checkpoint) + 1) + (CP_CHKSUM_OFFSET - sizeof(struct f2fs_checkpoint) + 1) /* * For orphan inode management diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c index 4b88d93..621126c 100644 --- a/mkfs/f2fs_format.c +++ b/mkfs/f2fs_format.c @@ -342,12 +342,12 @@ static int f2fs_prepare_super_block(void) * It requires more pages for cp. */ if (max_sit_bitmap_size > MAX_SIT_BITMAP_SIZE_IN_CKPT) { - max_nat_bitmap_size = CHECKSUM_OFFSET - + max_nat_bitmap_size = CP_CHKSUM_OFFSET - sizeof(struct f2fs_checkpoint) + 1; set_sb(cp_payload, F2FS_BLK_ALIGN(max_sit_bitmap_size)); } else { max_nat_bitmap_size = - CHECKSUM_OFFSET - sizeof(struct f2fs_checkpoint) + 1 +
[f2fs-dev] [RFC PATCH 4/4] f2fs-tools: introduce sb checksum
This patch introduced crc for superblock. Signed-off-by: Junling Zheng --- fsck/mount.c | 23 +++ fsck/resize.c | 12 ++-- include/f2fs_fs.h | 16 +++- mkfs/f2fs_format.c | 3 +++ 4 files changed, 47 insertions(+), 7 deletions(-) diff --git a/fsck/mount.c b/fsck/mount.c index e7ceb8d..af9b219 100644 --- a/fsck/mount.c +++ b/fsck/mount.c @@ -340,6 +340,7 @@ void print_raw_sb_info(struct f2fs_super_block *sb) DISP_u32(sb, node_ino); DISP_u32(sb, meta_ino); DISP_u32(sb, cp_payload); + DISP_u32(sb, crc); DISP("%-.256s", sb, version); printf("\n"); } @@ -467,6 +468,9 @@ void print_sb_state(struct f2fs_super_block *sb) if (f & cpu_to_le32(F2FS_FEATURE_LOST_FOUND)) { MSG(0, "%s", " lost_found"); } + if (f & cpu_to_le32(F2FS_FEATURE_SB_CHKSUM)) { + MSG(0, "%s", " sb_checksum"); + } MSG(0, "\n"); MSG(0, "Info: superblock encrypt level = %d, salt = ", sb->encryption_level); @@ -555,10 +559,29 @@ static inline int sanity_check_area_boundary(struct f2fs_super_block *sb, return 0; } +static int verify_sb_chksum(struct f2fs_super_block *sb) +{ + if (SB_CHKSUM_OFFSET != get_sb(checksum_offset)) { + MSG(0, "\tInvalid SB CRC offset: %u\n", + get_sb(checksum_offset)); + return -1; + } + if (f2fs_crc_valid(get_sb(crc), sb, + get_sb(checksum_offset))) { + MSG(0, "\tInvalid SB CRC: 0x%x\n", get_sb(crc)); + return -1; + } + return 0; +} + int sanity_check_raw_super(struct f2fs_super_block *sb, enum SB_ADDR sb_addr) { unsigned int blocksize; + if ((get_sb(feature) & F2FS_FEATURE_SB_CHKSUM) && + verify_sb_chksum(sb)) + return -1; + if (F2FS_SUPER_MAGIC != get_sb(magic)) return -1; diff --git a/fsck/resize.c b/fsck/resize.c index 5161a1f..3462165 100644 --- a/fsck/resize.c +++ b/fsck/resize.c @@ -603,9 +603,6 @@ static int f2fs_resize_grow(struct f2fs_sb_info *sbi) } } - print_raw_sb_info(sb); - print_raw_sb_info(new_sb); - old_main_blkaddr = get_sb(main_blkaddr); new_main_blkaddr = get_newsb(main_blkaddr); offset = new_main_blkaddr - old_main_blkaddr; @@ -629,6 +626,9 @@ static int f2fs_resize_grow(struct f2fs_sb_info *sbi) migrate_sit(sbi, new_sb, offset_seg); rebuild_checkpoint(sbi, new_sb, offset_seg); update_superblock(new_sb, SB_ALL); + print_raw_sb_info(sb); + print_raw_sb_info(new_sb); + return 0; } @@ -658,9 +658,6 @@ static int f2fs_resize_shrink(struct f2fs_sb_info *sbi) } } - print_raw_sb_info(sb); - print_raw_sb_info(new_sb); - old_main_blkaddr = get_sb(main_blkaddr); new_main_blkaddr = get_newsb(main_blkaddr); offset = old_main_blkaddr - new_main_blkaddr; @@ -690,6 +687,9 @@ static int f2fs_resize_shrink(struct f2fs_sb_info *sbi) /* move whole data region */ //if (err) // migrate_main(sbi, offset); + print_raw_sb_info(sb); + print_raw_sb_info(new_sb); + return 0; } diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h index b0d9b9b..556d526 100644 --- a/include/f2fs_fs.h +++ b/include/f2fs_fs.h @@ -279,6 +279,7 @@ static inline uint64_t bswap_64(uint64_t val) #define BITS_PER_BYTE 8 #define F2FS_SUPER_MAGIC 0xF2F52010 /* F2FS Magic Number */ #define CP_CHKSUM_OFFSET 4092 +#define SB_CHKSUM_OFFSET 3068 #define MAX_PATH_LEN 64 #define MAX_DEVICES8 @@ -579,6 +580,7 @@ enum { #define F2FS_FEATURE_INODE_CRTIME 0x0100 #define F2FS_FEATURE_LOST_FOUND0x0200 #define F2FS_FEATURE_VERITY0x0400 /* reserved */ +#define F2FS_FEATURE_SB_CHKSUM 0x0800 #define MAX_VOLUME_NAME512 @@ -632,7 +634,8 @@ struct f2fs_super_block { struct f2fs_device devs[MAX_DEVICES]; /* device list */ __le32 qf_ino[F2FS_MAX_QUOTAS]; /* quota inode numbers */ __u8 hot_ext_count; /* # of hot file extension */ - __u8 reserved[314]; /* valid reserved region */ + __u8 reserved[310]; /* valid reserved region */ + __le32 crc; /* checksum of superblock */ } __attribute__((packed)); /* @@ -1337,6 +1340,7 @@ struct feature feature_table[] = { \ { "inode_crtime", F2FS_FEATURE_INODE_CRTIME },\ { "lost_found", F2FS_FEATURE_LOST_FOUND }, \ { "verity", F2FS_FEATURE_VERITY }, /* reserved */ \ + { "sb_checksum",
[f2fs-dev] [RFC PATCH RESEND 1/4] f2fs: support superblock checksum
Now we support crc32 checksum for superblock. Reviewed-by: Chao Yu Signed-off-by: Junling Zheng --- fs/f2fs/f2fs.h | 2 ++ fs/f2fs/super.c | 29 + fs/f2fs/sysfs.c | 7 +++ include/linux/f2fs_fs.h | 3 ++- 4 files changed, 40 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 4525f4f82af0..d50d6efda96b 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -147,6 +147,7 @@ struct f2fs_mount_info { #define F2FS_FEATURE_INODE_CRTIME 0x0100 #define F2FS_FEATURE_LOST_FOUND0x0200 #define F2FS_FEATURE_VERITY0x0400 /* reserved */ +#define F2FS_FEATURE_SB_CHKSUM 0x0800 #define F2FS_HAS_FEATURE(sb, mask) \ ((F2FS_SB(sb)->raw_super->feature & cpu_to_le32(mask)) != 0) @@ -3376,6 +3377,7 @@ F2FS_FEATURE_FUNCS(flexible_inline_xattr, FLEXIBLE_INLINE_XATTR); F2FS_FEATURE_FUNCS(quota_ino, QUOTA_INO); F2FS_FEATURE_FUNCS(inode_crtime, INODE_CRTIME); F2FS_FEATURE_FUNCS(lost_found, LOST_FOUND); +F2FS_FEATURE_FUNCS(sb_chksum, SB_CHKSUM); #ifdef CONFIG_BLK_DEV_ZONED static inline int get_blkz_type(struct f2fs_sb_info *sbi, diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index bd57be470e23..3ffc336caea8 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -2149,6 +2149,26 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi, (bh->b_data + F2FS_SUPER_OFFSET); struct super_block *sb = sbi->sb; unsigned int blocksize; + size_t crc_offset = 0; + __u32 crc = 0; + + /* Check checksum_offset and crc in superblock */ + if (le32_to_cpu(raw_super->feature) & F2FS_FEATURE_SB_CHKSUM) { + crc_offset = le32_to_cpu(raw_super->checksum_offset); + if (crc_offset != + offsetof(struct f2fs_super_block, crc)) { + f2fs_msg(sb, KERN_INFO, + "Invalid SB checksum offset: %zu", + crc_offset); + return 1; + } + crc = le32_to_cpu(raw_super->crc); + if (!f2fs_crc_valid(sbi, crc, raw_super, crc_offset)) { + f2fs_msg(sb, KERN_INFO, + "Invalid SB checksum value: %u", crc); + return 1; + } + } if (F2FS_SUPER_MAGIC != le32_to_cpu(raw_super->magic)) { f2fs_msg(sb, KERN_INFO, @@ -2568,6 +2588,7 @@ static int read_raw_super_block(struct f2fs_sb_info *sbi, int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover) { struct buffer_head *bh; + __u32 crc = 0; int err; if ((recover && f2fs_readonly(sbi->sb)) || @@ -2576,6 +2597,13 @@ int f2fs_commit_super(struct f2fs_sb_info *sbi, bool recover) return -EROFS; } + /* we should update superblock crc here */ + if (!recover && f2fs_sb_has_sb_chksum(sbi->sb)) { + crc = f2fs_crc32(sbi, F2FS_RAW_SUPER(sbi), + offsetof(struct f2fs_super_block, crc)); + F2FS_RAW_SUPER(sbi)->crc = cpu_to_le32(crc); + } + /* write back-up superblock first */ bh = sb_bread(sbi->sb, sbi->valid_super_block ? 0 : 1); if (!bh) diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c index cd2e030e47b8..c86d91be6c48 100644 --- a/fs/f2fs/sysfs.c +++ b/fs/f2fs/sysfs.c @@ -120,6 +120,9 @@ static ssize_t features_show(struct f2fs_attr *a, if (f2fs_sb_has_lost_found(sb)) len += snprintf(buf + len, PAGE_SIZE - len, "%s%s", len ? ", " : "", "lost_found"); + if (f2fs_sb_has_sb_chksum(sb)) + len += snprintf(buf + len, PAGE_SIZE - len, "%s%s", + len ? ", " : "", "sb_checksum"); len += snprintf(buf + len, PAGE_SIZE - len, "\n"); return len; } @@ -337,6 +340,7 @@ enum feat_id { FEAT_QUOTA_INO, FEAT_INODE_CRTIME, FEAT_LOST_FOUND, + FEAT_SB_CHECKSUM, }; static ssize_t f2fs_feature_show(struct f2fs_attr *a, @@ -353,6 +357,7 @@ static ssize_t f2fs_feature_show(struct f2fs_attr *a, case FEAT_QUOTA_INO: case FEAT_INODE_CRTIME: case FEAT_LOST_FOUND: + case FEAT_SB_CHECKSUM: return snprintf(buf, PAGE_SIZE, "supported\n"); } return 0; @@ -433,6 +438,7 @@ F2FS_FEATURE_RO_ATTR(flexible_inline_xattr, FEAT_FLEXIBLE_INLINE_XATTR); F2FS_FEATURE_RO_ATTR(quota_ino, FEAT_QUOTA_INO); F2FS_FEATURE_RO_ATTR(inode_crtime, FEAT_INODE_CRTIME); F2FS_FEATURE_RO_ATTR(lost_found, FEAT_LOST_FOUND); +F2FS_FEATURE_RO_ATTR(sb_checksum, FEAT_SB_CHECKSUM); #define ATTR_LIST(name) (_attr_##name.attr) static struct attribute *f2fs_attrs[] = { @@ -489,6 +495,7 @@ static struct attribute *f2fs_feat_attrs[] = { ATTR_LIST(quota_ino),
Re: [f2fs-dev] [PATCH] Revert "f2fs: use printk_ratelimited for f2fs_msg"
On Mon, 2018-08-13 at 14:28 +0800, Chao Yu wrote: > Don't limit printing log, so that we will not miss any key messages. > > This reverts commit a36c106dffb616250117efb1cab271c19a8f94ff. [] > diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c [] > @@ -209,7 +209,7 @@ void f2fs_msg(struct super_block *sb, const char *level, > const char *fmt, ...) > va_start(args, fmt); > vaf.fmt = fmt; > vaf.va = > - printk_ratelimited("%sF2FS-fs (%s): %pV\n", level, sb->s_id, ); > + printk("%sF2FS-fs (%s): %pV\n", level, sb->s_id, ); > va_end(args); > } If there was value in ratelimiting these messages at all, perhaps there is value in using a specific ratelimit_state other than static DEFINE_RATELIMIT_STATE(_rs, \ DEFAULT_RATELIMIT_INTERVAL, \ DEFAULT_RATELIMIT_BURST); \ -- Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH v2] f2fs: fix return value of f2fs_set_qf_name and parse_options
On 2018/8/13 13:41, Tiezhu Yang wrote: > match_strdup() returns NULL when kmalloc failed, so the caller > function f2fs_set_qf_name() should return -ENOMEM in this case; > match_int() returns -ENOMEM, -EINVAL, or -ERANGE on failure, > so the caller function parse_options() should not always return > -EINVAL in this case. > > Signed-off-by: Tiezhu Yang Reviewed-by: Chao Yu Thanks, -- Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH] Revert "f2fs: use printk_ratelimited for f2fs_msg"
Don't limit printing log, so that we will not miss any key messages. This reverts commit a36c106dffb616250117efb1cab271c19a8f94ff. Signed-off-by: Chao Yu --- fs/f2fs/super.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index bf4c919fe418..3d89d94191e7 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -209,7 +209,7 @@ void f2fs_msg(struct super_block *sb, const char *level, const char *fmt, ...) va_start(args, fmt); vaf.fmt = fmt; vaf.va = - printk_ratelimited("%sF2FS-fs (%s): %pV\n", level, sb->s_id, ); + printk("%sF2FS-fs (%s): %pV\n", level, sb->s_id, ); va_end(args); } -- 2.18.0.rc1 -- Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel