Re: [f2fs-dev] [PATCH 1/2] f2fs: don't trigger recovery for normal umount image
Hi Jaegeuk, -Original Message- From: Jaegeuk Kim [mailto:jaeg...@kernel.org] Sent: Tuesday, February 03, 2015 7:32 AM To: Chao Yu Cc: Changman Lee; linux-f2fs-devel@lists.sourceforge.net; linux-ker...@vger.kernel.org Subject: Re: [PATCH 1/2] f2fs: don't trigger recovery for normal umount image Hi Chao, On Sat, Jan 31, 2015 at 04:59:49PM +0800, Chao Yu wrote: Our recovery option is on by default, so we will try to recover data for a normally umounted image when mounting it, but no data will be recovered. So it'd be better to skip the recovery for above condition. No. We should consider the existing UMOUNT flag written by old f2fs. You're right, compatibility should be considered, my mistaken. Please ignore this patch. Thanks, -- Dive into the World of Parallel Programming. The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net/ ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH 2/2] f2fs: don't discard next free dnode page for an umount checkpoint
Hi Jaegeuk, -Original Message- From: Jaegeuk Kim [mailto:jaeg...@kernel.org] Sent: Tuesday, February 03, 2015 7:38 AM To: Chao Yu Cc: Changman Lee; linux-f2fs-devel@lists.sourceforge.net; linux-ker...@vger.kernel.org Subject: Re: [PATCH 2/2] f2fs: don't discard next free dnode page for an umount checkpoint Hi Chao, On Sat, Jan 31, 2015 at 05:06:59PM +0800, Chao Yu wrote: Previously, discard_next_dnode is added before a checkpoint to prevent that we may meet a garbage dnode page readed from next free blkaddr in recover flow. Since f2fs will skip recovery flow for a clean umount image, this condition will never happen. So it's safe for us to leave next free dnode as it is in an umount checkpoint. Signed-off-by: Chao Yu chao2...@samsung.com --- fs/f2fs/checkpoint.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index f7cdcad..991fd0a 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -905,8 +905,12 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) /* * This avoids to conduct wrong roll-forward operations and uses * metapages, so should be called prior to sync_meta_pages below. +* But if we are in an umount checkpoint, we'd better skip this +* because we will not enter recovery flow to use the next free +* blkaddr when mounting it. */ - discard_next_dnode(sbi, NEXT_FREE_BLKADDR(sbi, curseg)); + if (cpc-reason != CP_UMOUNT) + discard_next_dnode(sbi, NEXT_FREE_BLKADDR(sbi, curseg)); The reason for discard_next_dnode is to avoid wrong execution due to old mkfs.f2fs which remains gabage data. It needs to do all the time. Maybe my previously understanding is wrong. Is this issue due to old mkfs.f2fs do not discard entire flash storage device when formating? Or another bug of mkfs? If so, can you please offer a fix commit id of mkfs? I'm curious about how this happened. :-) Thanks, Thanks, /* Flush all the NAT/SIT pages */ while (get_pages(sbi, F2FS_DIRTY_META)) { -- 2.2.1 -- Dive into the World of Parallel Programming. The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net/ ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH 6/9 v5] xfs/086, 087: remove specific testing options in output
This patch removes the mkfs and mount options specified in output files in xfs/086 and xfs/087. Signed-off-by: Jaegeuk Kim jaeg...@kernel.org --- tests/xfs/086 | 2 +- tests/xfs/086.out | 20 tests/xfs/087 | 2 +- tests/xfs/087.out | 9 - 4 files changed, 2 insertions(+), 31 deletions(-) diff --git a/tests/xfs/086 b/tests/xfs/086 index 02977aa..1f81c1b 100755 --- a/tests/xfs/086 +++ b/tests/xfs/086 @@ -80,7 +80,7 @@ for s in sync nosync ; do continue fi - echo --- mkfs=$mkfs, mnt=$mnt, sync=$s --- + echo --- mkfs=$mkfs, mnt=$mnt, sync=$s --- $seqres.full export MKFS_OPTIONS=-l $mkfs export MOUNT_OPTIONS=-o $mnt diff --git a/tests/xfs/086.out b/tests/xfs/086.out index ac56cc2..40326ee 100644 --- a/tests/xfs/086.out +++ b/tests/xfs/086.out @@ -1,6 +1,5 @@ QA output created by 086 *** init FS mkfs=version=2, mnt=logbsize=32k, sync=sync --- *** mkfs *** @@ -236,7 +235,6 @@ clean log *** filesystem is checked ok *** mkfs=version=2,su=4096, mnt=logbsize=32k, sync=sync --- *** mkfs *** @@ -472,7 +470,6 @@ clean log *** filesystem is checked ok *** mkfs=version=2,su=32768, mnt=logbsize=32k, sync=sync --- *** mkfs *** @@ -708,7 +705,6 @@ clean log *** filesystem is checked ok *** mkfs=version=2,su=32768, mnt=logbsize=64k, sync=sync --- *** mkfs *** @@ -944,7 +940,6 @@ clean log *** filesystem is checked ok *** mkfs=version=2, mnt=logbsize=64k, sync=sync --- *** mkfs *** @@ -1180,7 +1175,6 @@ clean log *** filesystem is checked ok *** mkfs=version=2,su=64k, mnt=logbsize=64k, sync=sync --- *** mkfs *** @@ -1416,7 +1410,6 @@ clean log *** filesystem is checked ok *** mkfs=version=2, mnt=logbsize=128k, sync=sync --- *** mkfs *** @@ -1652,7 +1645,6 @@ clean log *** filesystem is checked ok *** mkfs=version=2,su=128k, mnt=logbsize=128k, sync=sync --- *** mkfs *** @@ -1888,7 +1880,6 @@ clean log *** filesystem is checked ok *** mkfs=version=2, mnt=logbsize=256k, sync=sync --- *** mkfs *** @@ -2124,7 +2115,6 @@ clean log *** filesystem is checked ok *** mkfs=version=2,su=256k, mnt=logbsize=256k, sync=sync --- *** mkfs *** @@ -2360,7 +2350,6 @@ clean log *** filesystem is checked ok *** mkfs=version=2, mnt=logbsize=32k, sync=nosync --- *** mkfs *** @@ -2596,7 +2585,6 @@ clean log *** filesystem is checked ok *** mkfs=version=2,su=4096, mnt=logbsize=32k, sync=nosync --- *** mkfs *** @@ -2832,7 +2820,6 @@ clean log *** filesystem is checked ok *** mkfs=version=2,su=32768, mnt=logbsize=32k, sync=nosync --- *** mkfs *** @@ -3068,7 +3055,6 @@ clean log *** filesystem is checked ok *** mkfs=version=2,su=32768, mnt=logbsize=64k, sync=nosync --- *** mkfs *** @@ -3304,7 +3290,6 @@ clean log *** filesystem is checked ok *** mkfs=version=2, mnt=logbsize=64k, sync=nosync --- *** mkfs *** @@ -3540,7 +3525,6 @@ clean log *** filesystem is checked ok *** mkfs=version=2,su=64k, mnt=logbsize=64k, sync=nosync --- *** mkfs *** @@ -3776,7 +3760,6 @@ clean log *** filesystem is checked ok *** mkfs=version=2, mnt=logbsize=128k, sync=nosync --- *** mkfs *** @@ -4012,7 +3995,6 @@ clean log *** filesystem is checked ok *** mkfs=version=2,su=128k, mnt=logbsize=128k, sync=nosync --- *** mkfs *** @@ -4248,7 +4230,6 @@ clean log *** filesystem is checked ok *** mkfs=version=2, mnt=logbsize=256k, sync=nosync --- *** mkfs *** @@ -4484,7 +4465,6 @@ clean log *** filesystem is checked ok *** mkfs=version=2,su=256k, mnt=logbsize=256k, sync=nosync --- *** mkfs *** diff --git a/tests/xfs/087 b/tests/xfs/087 index 17a999c..8986f67 100755 --- a/tests/xfs/087 +++ b/tests/xfs/087 @@ -88,7 +88,7 @@ do continue fi -echo --- mkfs=$mkfs, mnt=$mnt --- +echo --- mkfs=$mkfs, mnt=$mnt --- $seqres.full export MKFS_OPTIONS=-l $mkfs export MOUNT_OPTIONS=-o $mnt diff --git a/tests/xfs/087.out b/tests/xfs/087.out index 9f009c0..181774e 100644 --- a/tests/xfs/087.out +++ b/tests/xfs/087.out @@ -1,6 +1,5 @@ QA output created by 087 *** init FS mkfs=version=2, mnt=logbsize=32k --- *** mkfs *** @@ -43,7 +42,6 @@ clean log *** filesystem is checked ok *** mkfs=version=2,su=4096, mnt=logbsize=32k --- *** mkfs *** @@ -86,7 +84,6 @@ clean log *** filesystem is checked ok *** mkfs=version=2,su=32768, mnt=logbsize=32k --- *** mkfs *** @@ -129,7 +126,6 @@ clean log *** filesystem is checked ok *** mkfs=version=2, mnt=logbsize=64k --- *** mkfs *** @@ -172,7 +168,6 @@ clean log *** filesystem is checked ok *** mkfs=version=2,su=64k, mnt=logbsize=64k --- *** mkfs *** @@ -215,7 +210,6 @@ clean log *** filesystem is checked ok *** mkfs=version=2, mnt=logbsize=128k --- *** mkfs *** @@
Re: [f2fs-dev] [PATCH 2/2] f2fs: don't discard next free dnode page for an umount checkpoint
Hi Chao, On Thu, Feb 05, 2015 at 04:16:04PM +0800, Chao Yu wrote: Hi Jaegeuk, -Original Message- From: Jaegeuk Kim [mailto:jaeg...@kernel.org] Sent: Tuesday, February 03, 2015 7:38 AM To: Chao Yu Cc: Changman Lee; linux-f2fs-devel@lists.sourceforge.net; linux-ker...@vger.kernel.org Subject: Re: [PATCH 2/2] f2fs: don't discard next free dnode page for an umount checkpoint Hi Chao, On Sat, Jan 31, 2015 at 05:06:59PM +0800, Chao Yu wrote: Previously, discard_next_dnode is added before a checkpoint to prevent that we may meet a garbage dnode page readed from next free blkaddr in recover flow. Since f2fs will skip recovery flow for a clean umount image, this condition will never happen. So it's safe for us to leave next free dnode as it is in an umount checkpoint. Signed-off-by: Chao Yu chao2...@samsung.com --- fs/f2fs/checkpoint.c | 6 +- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c index f7cdcad..991fd0a 100644 --- a/fs/f2fs/checkpoint.c +++ b/fs/f2fs/checkpoint.c @@ -905,8 +905,12 @@ static void do_checkpoint(struct f2fs_sb_info *sbi, struct cp_control *cpc) /* * This avoids to conduct wrong roll-forward operations and uses * metapages, so should be called prior to sync_meta_pages below. + * But if we are in an umount checkpoint, we'd better skip this + * because we will not enter recovery flow to use the next free + * blkaddr when mounting it. */ - discard_next_dnode(sbi, NEXT_FREE_BLKADDR(sbi, curseg)); + if (cpc-reason != CP_UMOUNT) + discard_next_dnode(sbi, NEXT_FREE_BLKADDR(sbi, curseg)); The reason for discard_next_dnode is to avoid wrong execution due to old mkfs.f2fs which remains gabage data. It needs to do all the time. Maybe my previously understanding is wrong. Is this issue due to old mkfs.f2fs do not discard entire flash storage device when formating? Or another bug of mkfs? If so, can you please offer a fix commit id of mkfs? commit ffbada4298c7aed059bb99a8d553d6dd555963c0 Author: Jaegeuk Kim jaegeuk@samsung.com Date: Mon Nov 11 13:29:11 2013 +0900 mkfs: remove stale node blocks If the device does not support discard, we should write zero blocks to avoid roll-forward recovery. Thanks, I'm curious about how this happened. :-) Thanks, Thanks, /* Flush all the NAT/SIT pages */ while (get_pages(sbi, F2FS_DIRTY_META)) { -- 2.2.1 -- Dive into the World of Parallel Programming. The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net/ ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH 5/5 v4] f2fs: introduce a batched trim
Hi Chao, Something like this? Change log from v3: o align to section size This patch introduces a batched trimming feature, which submits split discard commands. This is to avoid long latency due to huge trim commands. If fstrim was triggered ranging from 0 to the end of device, we should lock all the checkpoint-related mutexes, resulting in very long latency. Signed-off-by: Jaegeuk Kim jaeg...@kernel.org --- Documentation/ABI/testing/sysfs-fs-f2fs | 6 ++ Documentation/filesystems/f2fs.txt | 4 fs/f2fs/f2fs.h | 7 +++ fs/f2fs/segment.c | 17 - fs/f2fs/super.c | 2 ++ 5 files changed, 31 insertions(+), 5 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs index 6f9157f..2c4cc42 100644 --- a/Documentation/ABI/testing/sysfs-fs-f2fs +++ b/Documentation/ABI/testing/sysfs-fs-f2fs @@ -74,3 +74,9 @@ Date: March 2014 Contact: Jaegeuk Kim jaegeuk@samsung.com Description: Controls the memory footprint used by f2fs. + +What: /sys/fs/f2fs/disk/trim_sections +Date: February 2015 +Contact: Jaegeuk Kim jaeg...@kernel.org +Description: +Controls the trimming rate in batch mode. diff --git a/Documentation/filesystems/f2fs.txt b/Documentation/filesystems/f2fs.txt index 6758aa3..dac11d7 100644 --- a/Documentation/filesystems/f2fs.txt +++ b/Documentation/filesystems/f2fs.txt @@ -199,6 +199,10 @@ Files in /sys/fs/f2fs/devname checkpoint is triggered, and issued during the checkpoint. By default, it is disabled with 0. + trim_sectionsThis parameter controls the number of sections + to be trimmed out in batch mode when FITRIM + conducts. 32 sections is set by default. + ipu_policy This parameter controls the policy of in-place updates in f2fs. There are five policies: 0x01: F2FS_IPU_FORCE, 0x02: F2FS_IPU_SSR, diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index db1ff55..d82a10a 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -105,6 +105,10 @@ enum { CP_DISCARD, }; +#define DEF_BATCHED_TRIM_SECTIONS 32 +#define BATCHED_TRIM_SEGMENTS(sbi) \ + (SM_I(sbi)-trim_sections * (sbi)-segs_per_sec) + struct cp_control { int reason; __u64 trim_start; @@ -448,6 +452,9 @@ struct f2fs_sm_info { int nr_discards;/* # of discards in the list */ int max_discards; /* max. discards to be issued */ + /* for batched trimming */ + int trim_sections; /* # of sections to trim */ + struct list_head sit_entry_set; /* sit entry set list */ unsigned int ipu_policy;/* in-place-update policy */ diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 5ea57ec..9f278d1 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -1066,14 +1066,19 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range) end_segno = (end = MAX_BLKADDR(sbi)) ? MAIN_SEGS(sbi) - 1 : GET_SEGNO(sbi, end); cpc.reason = CP_DISCARD; - cpc.trim_start = start_segno; - cpc.trim_end = end_segno; cpc.trim_minlen = range-minlen sbi-log_blocksize; /* do checkpoint to issue discard commands safely */ - mutex_lock(sbi-gc_mutex); - write_checkpoint(sbi, cpc); - mutex_unlock(sbi-gc_mutex); + for (; start_segno = end_segno; start_segno = cpc.trim_end + 1) { + cpc.trim_start = start_segno; + cpc.trim_end = min_t(unsigned int, rounddown(start_segno + + BATCHED_TRIM_SEGMENTS(sbi), + sbi-segs_per_sec) - 1, end_segno); + + mutex_lock(sbi-gc_mutex); + write_checkpoint(sbi, cpc); + mutex_unlock(sbi-gc_mutex); + } out: range-len = cpc.trimmed sbi-log_blocksize; return 0; @@ -2127,6 +2132,8 @@ int build_segment_manager(struct f2fs_sb_info *sbi) sm_info-nr_discards = 0; sm_info-max_discards = 0; + sm_info-trim_sections = DEF_BATCHED_TRIM_SECTIONS; + INIT_LIST_HEAD(sm_info-sit_entry_set); if (test_opt(sbi, FLUSH_MERGE) !f2fs_readonly(sbi-sb)) { diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 1e92c2e..f2fe666 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -195,6 +195,7 @@ F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_no_gc_sleep_time, no_gc_sleep_time); F2FS_RW_ATTR(GC_THREAD, f2fs_gc_kthread, gc_idle, gc_idle); F2FS_RW_ATTR(SM_INFO, f2fs_sm_info, reclaim_segments, rec_prefree_segments); F2FS_RW_ATTR(SM_INFO, f2fs_sm_info,
[f2fs-dev] [PATCH 9/9 v5] tests/generic: relocate xfs's tests into tests/generic/
This patch moves the generic testcases defined in xfs into tests/generic/. xfs/085 - generic/052 xfs/086 - generic/054 xfs/087 - generic/055 Signed-off-by: Jaegeuk Kim jaeg...@kernel.org --- tests/{xfs/085 = generic/052} | 6 +++--- tests/{xfs/085.out = generic/052.out} | 2 +- tests/{xfs/086 = generic/054} | 17 - tests/{xfs/086.out = generic/054.out} | 2 +- tests/{xfs/087 = generic/055} | 15 +++ tests/{xfs/087.out = generic/055.out} | 2 +- tests/generic/group| 3 +++ tests/xfs/group| 3 --- 8 files changed, 24 insertions(+), 26 deletions(-) diff --git a/tests/xfs/085 b/tests/generic/052 similarity index 96% rename from tests/xfs/085 rename to tests/generic/052 index 1b6f424..3430b65 100755 --- a/tests/xfs/085 +++ b/tests/generic/052 @@ -1,5 +1,5 @@ #! /bin/bash -# FS QA Test No. 085 +# FS QA Test No. 052 # # To test log replay by shutdown of file system # This is the first simple initial test to ensure that @@ -40,7 +40,7 @@ trap rm -f $tmp.*; exit \$status 0 1 2 3 15 . ./common/log # real QA test starts here -_supported_fs xfs +_supported_fs generic _supported_os IRIX Linux rm -f $seqres.full @@ -51,7 +51,7 @@ _require_scratch_shutdown _require_logstate echo mkfs -_scratch_mkfs_xfs $seqres.full 21 \ +_scratch_mkfs $seqres.full 21 \ || _fail mkfs scratch failed echo mount diff --git a/tests/xfs/085.out b/tests/generic/052.out similarity index 94% rename from tests/xfs/085.out rename to tests/generic/052.out index d2d99a1..df7a66a 100644 --- a/tests/xfs/085.out +++ b/tests/generic/052.out @@ -1,4 +1,4 @@ -QA output created by 085 +QA output created by 052 mkfs mount touch files diff --git a/tests/xfs/086 b/tests/generic/054 similarity index 92% rename from tests/xfs/086 rename to tests/generic/054 index 0cc5008..6cb0122 100755 --- a/tests/xfs/086 +++ b/tests/generic/054 @@ -1,5 +1,5 @@ #! /bin/bash -# FS QA Test No. 086 +# FS QA Test No. 054 # # To test log replay with version 2 logs # Initially keep this simple with just creates. @@ -39,14 +39,13 @@ trap rm -f $tmp.*; exit \$status 0 1 2 3 15 . ./common/log # real QA test starts here -_supported_fs xfs +_supported_fs generic _supported_os IRIX Linux rm -f $seqres.full $tmp.* _require_scratch _require_scratch_shutdown _require_logstate -_require_v2log echo *** init FS umount $SCRATCH_DEV /dev/null 21 @@ -56,14 +55,14 @@ _get_log_configs $tmp.seq.params # Do the work for various log params which # should not effect the data content of the log # Try with and without sync'ing - sync'ing will mean that -# the log will be written out unfilled and thus the log +# the log will be written out unfilled and thus the log # stripe can have an effect. # for s in sync nosync ; do cat $tmp.seq.params \ | while read mkfs mnt restofline do - if [ $mkfs = # ]; then + if [ $mkfs = # ]; then continue fi @@ -73,8 +72,8 @@ for s in sync nosync ; do # mkfs the FS _echofull mkfs - _scratch_mkfs_xfs $seqres.full 21 - if [ $? -ne 0 ] ; then + _scratch_mkfs $seqres.full 21 + if [ $? -ne 0 ] ; then _echofull mkfs failed: $MKFS_OPTIONS continue fi @@ -89,7 +88,7 @@ for s in sync nosync ; do # create the metadata if [ $s = sync ]; then # generate some log traffic - but not too much - # add some syncs to get the log flushed to disk + # add some syncs to get the log flushed to disk for file in $SCRATCH_MNT/{0,1,2,3,4,5,6,7,8,9}{0,1,2,3,4,5,6,7,8,9}; do touch $file sync @@ -137,5 +136,5 @@ for s in sync nosync ; do done done -status=0 +status=0 exit diff --git a/tests/xfs/086.out b/tests/generic/054.out similarity index 99% rename from tests/xfs/086.out rename to tests/generic/054.out index 40326ee..4654bde 100644 --- a/tests/xfs/086.out +++ b/tests/generic/054.out @@ -1,4 +1,4 @@ -QA output created by 086 +QA output created by 054 *** init FS *** mkfs *** diff --git a/tests/xfs/087 b/tests/generic/055 similarity index 93% rename from tests/xfs/087 rename to tests/generic/055 index 2fd6f1a..068f0c3 100755 --- a/tests/xfs/087 +++ b/tests/generic/055 @@ -1,7 +1,7 @@ #! /bin/bash -# FS QA Test No. 087 +# FS QA Test No. 055 # -# * like 086 but want to create more/different kinds of metadata +# * like 054 but want to create more/different kinds of metadata # and so will use fsstress # * also can interrupt metadata with godown # @@ -54,14 +54,13 @@ _do_meta() } # real QA test starts here -_supported_fs xfs +_supported_fs generic _supported_os IRIX Linux rm -f $seqres.full $tmp.* _require_scratch _require_scratch_shutdown _require_logstate -_require_v2log QUOTA_OPTION=`_get_quota_option` @@ -73,7 +72,7 @@ _get_log_configs $tmp.seq.params cat $tmp.seq.params \ | while read
[f2fs-dev] [PATCH 3/9 v5] common/rc: add _require_norecovery
This patch adds checking code whether filesystem supports norecovery mount option or not. And let use this into the following xfs test. xfs/200 (recovery vs ro-block device) * Currently, norecovery mount option is used by xfs only. But some of log-based filesystems (e.g., f2fs) are able to support it later. Signed-off-by: Jaegeuk Kim jaeg...@kernel.org --- common/rc | 8 tests/xfs/200 | 1 + 2 files changed, 9 insertions(+) diff --git a/common/rc b/common/rc index 078d3ca..395bf6c 100644 --- a/common/rc +++ b/common/rc @@ -2332,6 +2332,14 @@ _require_scratch_shutdown() _scratch_unmount } +# Does norecovery support by this fs? +_require_norecovery() +{ + _scratch_mount -o ro,norecovery || \ + _notrun $FSTYP does not support norecovery + _scratch_unmount +} + # Does fiemap support? _require_fiemap() { diff --git a/tests/xfs/200 b/tests/xfs/200 index c62d2b8..bd6d0fd 100755 --- a/tests/xfs/200 +++ b/tests/xfs/200 @@ -46,6 +46,7 @@ _supported_os Linux _require_scratch_nocheck _require_scratch_shutdown +_require_norecovery _scratch_mkfs_xfs /dev/null 21 -- 2.1.1 -- Dive into the World of Parallel Programming. The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net/ ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH 0/9 v5] make xfs/tests generic by introducing shutdown for filesystems
Thanks to Dave. :) Change log from v4: o add mkfs in _require_scratch_shutdown o add _require_fiemap and _extent_hole_counts o add _require_logstate o modify xfs/086,087 output rules for the generic usage o add _get_log_configs to introduce consistent testing options o add _get_quota_option to define quota option for each filesystems This patch-set modifies several existing xfs's tests to be used by generic filesystems. 1. FS requirement In order to activate these testcases, filesystem should support a new feature, shutdown, triggered by the following ioctl command. #define FS_IOC_SHUTDOWN _IOR('X', 125, __u32) /* Shutdown */ This ioctl needs one of three modes passed by a flag according to the syncing policy. #define FS_GOING_DOWN_FULLSYNC 0x0 /* going down with full sync */ #define FS_GOING_DOWN_METASYNC 0x1 /* going down with metadata */ #define FS_GOING_DOWN_NOSYNC0x2 /* going down */ Whenever shutdown is requested with one of the above mode, filesystem must stop any IOs, and wait for unmount, which is very useful to test power-off- recovery. 2. Changes in xfstests In this patch set, common/rc adds macros: o _require_scratch_shutdown : check whether FS supports shutdown o _require_fiemap : check bmap tool is defined o _require_norecovery : check filesystem supports norecovery option. o _require_logstate : check logstate tools is defined o _get_log_configs : define mount options for tests o _get_quota_option : define quota options for filesystems The following tests become generic. xfs/053 - generic/042 xfs/137 - generic/043 xfs/138 - generic/044 xfs/139 - generic/045 xfs/140 - generic/046 xfs/179 - generic/047 xfs/180 - generic/048 xfs/182 - generic/049 xfs/200 - generic/050 xfs/306 - generic/051 xfs/085 - generic/052 xfs/086 - generic/054 xfs/087 - generic/055 Jaegeuk Kim (9): common/rc: add _require_scratch_shtudown common/rc: add _require_fiemap and _extent_hole_counts common/rc: add _require_norecovery tests/generic: relocate xfs's tests into tests/generic/ common/log: define _require_logstate xfs/086,087: remove specific testing options in output common/log: add _get_log_configs for testing options common/quota: give quota mount option per filesystem tests/generic: relocate xfs's tests into tests/generic/ common/config | 1 + common/log | 98 +++--- common/quota | 15 ++ common/rc | 33 tests/{xfs/053 = generic/042} | 5 +- tests/{xfs/053.out = generic/042.out} | 2 +- tests/{xfs/137 = generic/043} | 19 --- tests/generic/043.out | 1 + tests/{xfs/138 = generic/044} | 19 --- tests/generic/044.out | 1 + tests/{xfs/139 = generic/045} | 19 --- tests/generic/045.out | 1 + tests/{xfs/140 = generic/046} | 15 +++--- tests/generic/046.out | 1 + tests/{xfs/179 = generic/047} | 13 +++-- tests/generic/047.out | 1 + tests/{xfs/180 = generic/048} | 13 +++-- tests/generic/048.out | 1 + tests/{xfs/182 = generic/049} | 13 +++-- tests/generic/049.out | 1 + tests/{xfs/200 = generic/050} | 10 ++-- tests/{xfs/200.out = generic/050.out} | 2 +- tests/{xfs/306 = generic/051} | 5 +- tests/{xfs/306.out = generic/051.out} | 2 +- tests/{xfs/085 = generic/052} | 8 +-- tests/{xfs/085.out = generic/052.out} | 2 +- tests/{xfs/086 = generic/054} | 36 + tests/{xfs/086.out = generic/054.out} | 22 +--- tests/{xfs/087 = generic/055} | 40 ++ tests/{xfs/087.out = generic/055.out} | 53 ++ tests/generic/group| 13 + tests/xfs/137.out | 1 - tests/xfs/138.out | 1 - tests/xfs/139.out | 1 - tests/xfs/140.out | 1 - tests/xfs/179.out | 1 - tests/xfs/180.out | 1 - tests/xfs/182.out | 1 - tests/xfs/group| 13 - 39 files changed, 319 insertions(+), 166 deletions(-) rename tests/{xfs/053 = generic/042} (97%) rename tests/{xfs/053.out = generic/042.out} (92%) rename tests/{xfs/137 = generic/043} (87%) create mode 100644 tests/generic/043.out rename tests/{xfs/138 = generic/044} (87%) create mode 100644 tests/generic/044.out rename tests/{xfs/139 = generic/045} (87%) create mode 100644 tests/generic/045.out rename tests/{xfs/140 = generic/046} (90%) create mode 100644 tests/generic/046.out rename tests/{xfs/179 = generic/047} (90%) create mode 100644 tests/generic/047.out rename tests/{xfs/180 = generic/048} (91%) create mode 100644
[f2fs-dev] [PATCH 7/9 v5] common/log: add _get_log_configs for testing options
This patch adds _get_log_configs for xfs and f2fs to test several mount options for: xfs/086 * xfs/087 In xfs/087, one more test was added, so 10 tests will be done in total. Signed-off-by: Jaegeuk Kim jaeg...@kernel.org --- common/log| 47 +++ tests/xfs/086 | 15 +-- tests/xfs/087 | 14 +- tests/xfs/087.out | 42 ++ 4 files changed, 91 insertions(+), 27 deletions(-) diff --git a/common/log b/common/log index d8b18f8..5be5411 100644 --- a/common/log +++ b/common/log @@ -510,5 +510,52 @@ _require_logstate() esac } +_xfs_log_config() +{ +echo # mkfs-opt mount-opt +echo # -- +echo version=2logbsize=32k +echo version=2,su=4096logbsize=32k +echo version=2,su=32768 logbsize=32k +echo version=2,su=32768 logbsize=64k +echo version=2logbsize=64k +echo version=2,su=64k logbsize=64k +echo version=2logbsize=128k +echo version=2,su=128klogbsize=128k +echo version=2logbsize=256k +echo version=2,su=256klogbsize=256k +} + +_f2fs_log_config() +{ +echo # mkfs-opt mount-opt +echo # -- +echo test1 active_logs=6,background_gc=off +echo test2 active_logs=6,background_gc=off,inline_data +echo test3 active_logs=6,background_gc=off,inline_dentry +echo test4 active_logs=6,background_gc=off,inline_data,inline_dentry +echo test5 active_logs=6,background_gc=off,disable_roll_forward +echo test6 active_logs=6,background_gc=off,discard,inline_data,inline_dentry +echo test7 active_logs=6,background_gc=on +echo test8 active_logs=6,background_gc=on,inline_data +echo test9 active_logs=6,background_gc=on,inline_data,inline_dentry +echo test10 active_logs=6,background_gc=on,discard,inline_data,inline_dentry +} + +_get_log_configs() +{ +case $FSTYP in +xfs) +_xfs_log_config +;; +f2fs) +_f2fs_log_config +;; +*) +_notrun $FSTYP does not support log configs. +;; +esac +} + # make sure this script returns success /bin/true diff --git a/tests/xfs/086 b/tests/xfs/086 index 1f81c1b..0cc5008 100755 --- a/tests/xfs/086 +++ b/tests/xfs/086 @@ -51,20 +51,7 @@ _require_v2log echo *** init FS umount $SCRATCH_DEV /dev/null 21 -cat $tmp.seq.params EOF -# mkfs-opt mount-opt -# -- - version=2logbsize=32k - version=2,su=4096logbsize=32k - version=2,su=32768 logbsize=32k - version=2,su=32768 logbsize=64k - version=2logbsize=64k - version=2,su=64k logbsize=64k - version=2logbsize=128k - version=2,su=128klogbsize=128k - version=2logbsize=256k - version=2,su=256klogbsize=256k -EOF +_get_log_configs $tmp.seq.params # Do the work for various log params which # should not effect the data content of the log diff --git a/tests/xfs/087 b/tests/xfs/087 index 8986f67..8da0f9c 100755 --- a/tests/xfs/087 +++ b/tests/xfs/087 @@ -67,19 +67,7 @@ _require_xfs_quota echo *** init FS umount $SCRATCH_DEV /dev/null 21 -cat $tmp.seq.params EOF -# mkfs-opt mount-opt -# -- - version=2logbsize=32k - version=2,su=4096logbsize=32k - version=2,su=32768 logbsize=32k - version=2logbsize=64k - version=2,su=64k logbsize=64k - version=2logbsize=128k - version=2,su=128klogbsize=128k - version=2logbsize=256k - version=2,su=256klogbsize=256k -EOF +_get_log_configs $tmp.seq.params cat $tmp.seq.params \ | while read mkfs mnt restofline diff --git a/tests/xfs/087.out b/tests/xfs/087.out index 181774e..9f6f80a 100644 --- a/tests/xfs/087.out +++ b/tests/xfs/087.out @@ -378,3 +378,45 @@ clean log *** filesystem is checked ok *** + +*** mkfs *** + + +*** mount *** + + +*** calling fsstress -p 4 -z -f rmdir=10 -f link=10 -f creat=10 -f mkdir=10 -f rename=30 -f stat=30 -f unlink=30 -f truncate=20 -m8 -n 1 *** + + +*** ls -RF SCRATCH_MNT *** + + +*** godown *** + + +*** unmount *** + + +*** logprint after going down... *** + +dirty log + +*** mount with replay *** + + +*** ls -RF SCRATCH_MNT *** + + +*** diff ls before and after *** + +Files TMP.ls1 and TMP.ls2 are identical + +*** unmount *** + + +*** logprint after mount and replay... *** + +clean log + +*** filesystem is checked ok *** + -- 2.1.1 -- Dive into the World of Parallel Programming. The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to
[f2fs-dev] [PATCH 1/9 v5] common/rc: add _require_scratch_shtudown
This is to detect whether filesystem supports shutdown feature or not. And let use this into the following xfs tests. xfs/053 (data exposure) xfs/137 (data vs filesize) xfs/138 (data vs filesize vs truncate) xfs/139 (data vs filesize vs partial truncate) xfs/140 (data vs filesize vs extending truncate) xfs/179 (data vs filesize w/ fsync) xfs/180 (data vs filesize w/ sync) xfs/182 (data vs filesize w/ recovery) xfs/200 (recovery vs ro-block device) xfs/306 (fsstress vs recovery) xfs/085 xfs/086 xfs/087 Signed-off-by: Jaegeuk Kim jaeg...@kernel.org --- common/rc | 12 tests/xfs/053 | 1 + tests/xfs/085 | 1 + tests/xfs/086 | 1 + tests/xfs/087 | 1 + tests/xfs/137 | 1 + tests/xfs/138 | 1 + tests/xfs/139 | 1 + tests/xfs/140 | 1 + tests/xfs/179 | 1 + tests/xfs/180 | 1 + tests/xfs/182 | 1 + tests/xfs/200 | 1 + tests/xfs/306 | 1 + 14 files changed, 25 insertions(+) diff --git a/common/rc b/common/rc index 5377ba0..234638b 100644 --- a/common/rc +++ b/common/rc @@ -2320,6 +2320,18 @@ _require_freeze() [ $result -eq 0 ] || _notrun $FSTYP does not support freezing } +# Does shutdown work on this fs? +_require_scratch_shutdown() +{ + [ -x src/godown ] || _notrun src/godown executable not found + + _scratch_mkfs /dev/null 21 + _scratch_mount + src/godown -f $SCRATCH_MNT 21 \ + || _notrun $FSTYP does not support shutdown + _scratch_unmount +} + # arg 1 is dev to remove and is output of the below eg. # ls -l /sys/class/block/sdd | rev | cut -d / -f 3 | rev _devmgt_remove() diff --git a/tests/xfs/053 b/tests/xfs/053 index 9749345..6428d5c 100755 --- a/tests/xfs/053 +++ b/tests/xfs/053 @@ -86,6 +86,7 @@ _crashtest() _supported_fs xfs _supported_os Linux _require_scratch +_require_scratch_shutdown _require_xfs_io_command falloc _require_xfs_io_command fpunch _require_xfs_io_command fzero diff --git a/tests/xfs/085 b/tests/xfs/085 index 54c2d01..539f324 100755 --- a/tests/xfs/085 +++ b/tests/xfs/085 @@ -47,6 +47,7 @@ rm -f $seqres.full rm -f $tmp.log _require_scratch +_require_scratch_shutdown echo mkfs _scratch_mkfs_xfs $seqres.full 21 \ diff --git a/tests/xfs/086 b/tests/xfs/086 index af09c7f..08566d7 100755 --- a/tests/xfs/086 +++ b/tests/xfs/086 @@ -44,6 +44,7 @@ _supported_os IRIX Linux rm -f $seqres.full $tmp.* _require_scratch +_require_scratch_shutdown _require_v2log echo *** init FS diff --git a/tests/xfs/087 b/tests/xfs/087 index 3a3fb49..42c7d3b 100755 --- a/tests/xfs/087 +++ b/tests/xfs/087 @@ -59,6 +59,7 @@ _supported_os IRIX Linux rm -f $seqres.full $tmp.* _require_scratch +_require_scratch_shutdown _require_v2log _require_xfs_quota diff --git a/tests/xfs/137 b/tests/xfs/137 index 79b3b89..662a267 100755 --- a/tests/xfs/137 +++ b/tests/xfs/137 @@ -40,6 +40,7 @@ _supported_fs xfs _supported_os Linux IRIX _require_scratch +_require_scratch_shutdown _scratch_mkfs_xfs /dev/null 21 _scratch_mount diff --git a/tests/xfs/138 b/tests/xfs/138 index 1b11cf6..3fb182c 100755 --- a/tests/xfs/138 +++ b/tests/xfs/138 @@ -40,6 +40,7 @@ _supported_fs xfs _supported_os Linux IRIX _require_scratch +_require_scratch_shutdown _scratch_mkfs_xfs /dev/null 21 _scratch_mount diff --git a/tests/xfs/139 b/tests/xfs/139 index e5296f7..6986c17 100755 --- a/tests/xfs/139 +++ b/tests/xfs/139 @@ -40,6 +40,7 @@ _supported_fs xfs _supported_os Linux IRIX _require_scratch +_require_scratch_shutdown _scratch_mkfs_xfs /dev/null 21 _scratch_mount diff --git a/tests/xfs/140 b/tests/xfs/140 index cccf262..b82e43b 100755 --- a/tests/xfs/140 +++ b/tests/xfs/140 @@ -40,6 +40,7 @@ _supported_fs xfs _supported_os Linux IRIX _require_scratch +_require_scratch_shutdown _scratch_mkfs_xfs /dev/null 21 _scratch_mount diff --git a/tests/xfs/179 b/tests/xfs/179 index ce50d99..87fac8a 100755 --- a/tests/xfs/179 +++ b/tests/xfs/179 @@ -41,6 +41,7 @@ _supported_fs xfs _supported_os Linux IRIX _require_scratch +_require_scratch_shutdown _scratch_mkfs_xfs /dev/null 21 _scratch_mount diff --git a/tests/xfs/180 b/tests/xfs/180 index a0fb69a..b3b0fe4 100755 --- a/tests/xfs/180 +++ b/tests/xfs/180 @@ -41,6 +41,7 @@ _supported_fs xfs _supported_os Linux IRIX _require_scratch +_require_scratch_shutdown _scratch_mkfs_xfs /dev/null 21 _scratch_mount diff --git a/tests/xfs/182 b/tests/xfs/182 index b75e4fc..dac15d4 100755 --- a/tests/xfs/182 +++ b/tests/xfs/182 @@ -41,6 +41,7 @@ _supported_fs xfs _supported_os Linux IRIX _require_scratch +_require_scratch_shutdown _scratch_mkfs_xfs /dev/null 21 _scratch_mount diff --git a/tests/xfs/200 b/tests/xfs/200 index f0c4337..c62d2b8 100755 --- a/tests/xfs/200 +++ b/tests/xfs/200 @@ -45,6 +45,7 @@ _supported_fs xfs _supported_os Linux _require_scratch_nocheck +_require_scratch_shutdown _scratch_mkfs_xfs /dev/null 21 diff --git a/tests/xfs/306
Re: [f2fs-dev] [PATCH RESEND 1/2] mkfs.f2fs: support large sector size
On Thu, Feb 5, 2015 at 5:36 PM, Chao Yu chao2...@samsung.com wrote: Since f2fs support large sector size in commit 55cf9cb63f0e f2fs: support large sector size, block device with sector size of 512/1024/2048/4096 bytes can be supported. But mkfs.f2fs still use default sector size: 512 bytes as sector size, let's fix this issue in this patch. v2: o remove unneeded printed message when sector size is large than 512 bytes suggested by Kinglong. o show correct sector size in printed message. o use config.sectors_per_blk instead of DEFAULT_SECTORS_PER_BLOCK suggested by Kinglong. v3: o remove another unneeded printed message when sector size is large than 512 bytes suggested by Kinglong. Signed-off-by: Chao Yu chao2...@samsung.com Reviewed-by: Kinglong Mee kinglong...@gmail.com thanks, Kinglong Mee -- Dive into the World of Parallel Programming. The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net/ ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH v3 04/10] f2fs: introduce universal lookup/update interface for extent cache
In this patch, we do these jobs: 1. rename {check,update}_extent_cache to {lookup,update}_extent_info; 2. introduce universal lookup/update interface of extent cache: f2fs_{lookup,update}_extent_cache including above two real functions, then export them to function callers. So after above cleanup, we can add new rb-tree based extent cache into exported interfaces. v2: o remove f2fs_ for inner function {lookup,update}_extent_info suggested by Jaegeuk Kim. Signed-off-by: Chao Yu chao2...@samsung.com --- fs/f2fs/data.c | 66 +- fs/f2fs/f2fs.h | 2 +- fs/f2fs/file.c | 2 +- fs/f2fs/inline.c | 2 +- fs/f2fs/recovery.c | 2 +- 5 files changed, 44 insertions(+), 30 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index f2d8deb..c805d2a 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -263,20 +263,20 @@ static void f2fs_map_bh(struct super_block *sb, pgoff_t pgofs, bh_result-b_size = UINT_MAX; } -static int check_extent_cache(struct inode *inode, pgoff_t pgofs, - struct extent_info *ei) +static bool lookup_extent_info(struct inode *inode, pgoff_t pgofs, + struct extent_info *ei) { struct f2fs_inode_info *fi = F2FS_I(inode); pgoff_t start_fofs, end_fofs; block_t start_blkaddr; if (is_inode_flag_set(fi, FI_NO_EXTENT)) - return 0; + return false; read_lock(fi-ext_lock); if (fi-ext.len == 0) { read_unlock(fi-ext_lock); - return 0; + return false; } stat_inc_total_hit(inode-i_sb); @@ -289,29 +289,22 @@ static int check_extent_cache(struct inode *inode, pgoff_t pgofs, *ei = fi-ext; stat_inc_read_hit(inode-i_sb); read_unlock(fi-ext_lock); - return 1; + return true; } read_unlock(fi-ext_lock); - return 0; + return false; } -void update_extent_cache(struct dnode_of_data *dn) +static bool update_extent_info(struct inode *inode, pgoff_t fofs, + block_t blkaddr) { - struct f2fs_inode_info *fi = F2FS_I(dn-inode); - pgoff_t fofs, start_fofs, end_fofs; + struct f2fs_inode_info *fi = F2FS_I(inode); + pgoff_t start_fofs, end_fofs; block_t start_blkaddr, end_blkaddr; int need_update = true; - f2fs_bug_on(F2FS_I_SB(dn-inode), dn-data_blkaddr == NEW_ADDR); - - /* Update the page address in the parent node */ - __set_data_blkaddr(dn); - if (is_inode_flag_set(fi, FI_NO_EXTENT)) - return; - - fofs = start_bidx_of_node(ofs_of_node(dn-node_page), fi) + - dn-ofs_in_node; + return false; write_lock(fi-ext_lock); @@ -326,16 +319,16 @@ void update_extent_cache(struct dnode_of_data *dn) /* Initial extent */ if (fi-ext.len == 0) { - if (dn-data_blkaddr != NULL_ADDR) { + if (blkaddr != NULL_ADDR) { fi-ext.fofs = fofs; - fi-ext.blk = dn-data_blkaddr; + fi-ext.blk = blkaddr; fi-ext.len = 1; } goto end_update; } /* Front merge */ - if (fofs == start_fofs - 1 dn-data_blkaddr == start_blkaddr - 1) { + if (fofs == start_fofs - 1 blkaddr == start_blkaddr - 1) { fi-ext.fofs--; fi-ext.blk--; fi-ext.len++; @@ -343,7 +336,7 @@ void update_extent_cache(struct dnode_of_data *dn) } /* Back merge */ - if (fofs == end_fofs + 1 dn-data_blkaddr == end_blkaddr + 1) { + if (fofs == end_fofs + 1 blkaddr == end_blkaddr + 1) { fi-ext.len++; goto end_update; } @@ -370,9 +363,30 @@ void update_extent_cache(struct dnode_of_data *dn) } end_update: write_unlock(fi-ext_lock); - if (need_update) + return need_update; +} + +static bool f2fs_lookup_extent_cache(struct inode *inode, pgoff_t pgofs, + struct extent_info *ei) +{ + return lookup_extent_info(inode, pgofs, ei); +} + +void f2fs_update_extent_cache(struct dnode_of_data *dn) +{ + struct f2fs_inode_info *fi = F2FS_I(dn-inode); + pgoff_t fofs; + + f2fs_bug_on(F2FS_I_SB(dn-inode), dn-data_blkaddr == NEW_ADDR); + + /* Update the page address in the parent node */ + __set_data_blkaddr(dn); + + fofs = start_bidx_of_node(ofs_of_node(dn-node_page), fi) + + dn-ofs_in_node; + + if (update_extent_info(dn-inode, fofs, dn-data_blkaddr))
[f2fs-dev] [PATCH v3 10/10] f2fs: add trace for rb-tree extent cache ops
This patch adds trace for lookup/update/shrink/destroy ops in rb-tree extent cache. Signed-off-by: Chao Yu chao2...@samsung.com --- fs/f2fs/data.c | 16 +- include/trace/events/f2fs.h | 134 2 files changed, 148 insertions(+), 2 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 6c8119a..4ba1605 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -533,6 +533,8 @@ static bool f2fs_lookup_extent_tree(struct inode *inode, pgoff_t pgofs, if (is_inode_flag_set(F2FS_I(inode), FI_NO_EXTENT)) return false; + trace_f2fs_lookup_extent_tree_start(inode, pgofs); + down_read(sbi-extent_tree_lock); et = radix_tree_lookup(sbi-extent_tree_root, inode-i_ino); if (!et) { @@ -555,6 +557,8 @@ static bool f2fs_lookup_extent_tree(struct inode *inode, pgoff_t pgofs, stat_inc_total_hit(sbi-sb); read_unlock(et-lock); + trace_f2fs_lookup_extent_tree_end(inode, pgofs, en); + atomic_dec(et-refcount); return en ? true : false; } @@ -573,6 +577,8 @@ static void f2fs_update_extent_tree(struct inode *inode, pgoff_t fofs, if (is_inode_flag_set(F2FS_I(inode), FI_NO_EXTENT)) return; + trace_f2fs_update_extent_tree(inode, fofs, blkaddr); + down_write(sbi-extent_tree_lock); et = radix_tree_lookup(sbi-extent_tree_root, ino); if (!et) { @@ -665,6 +671,7 @@ void f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) struct radix_tree_iter iter; void **slot; unsigned int found; + unsigned int node_cnt = 0, tree_cnt = 0; if (!test_opt(sbi, EXTENT_CACHE)) return; @@ -691,7 +698,7 @@ void f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) atomic_inc(et-refcount); write_lock(et-lock); - __free_extent_tree(sbi, et, false); + node_cnt += __free_extent_tree(sbi, et, false); write_unlock(et-lock); atomic_dec(et-refcount); } @@ -707,15 +714,19 @@ void f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) radix_tree_delete(sbi-extent_tree_root, et-ino); kmem_cache_free(extent_tree_slab, et); sbi-total_ext_tree--; + tree_cnt++; } } up_write(sbi-extent_tree_lock); + + trace_f2fs_shrink_extent_tree(sbi, node_cnt, tree_cnt); } void f2fs_destroy_extent_tree(struct inode *inode) { struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct extent_tree *et; + unsigned int node_cnt = 0; if (!test_opt(sbi, EXTENT_CACHE)) return; @@ -731,7 +742,7 @@ void f2fs_destroy_extent_tree(struct inode *inode) /* free all extent info belong to this extent tree */ write_lock(et-lock); - __free_extent_tree(sbi, et, true); + node_cnt = __free_extent_tree(sbi, et, true); write_unlock(et-lock); atomic_dec(et-refcount); @@ -749,6 +760,7 @@ void f2fs_destroy_extent_tree(struct inode *inode) sbi-total_ext_tree--; up_write(sbi-extent_tree_lock); out: + trace_f2fs_destroy_extent_tree(inode, node_cnt); return; } diff --git a/include/trace/events/f2fs.h b/include/trace/events/f2fs.h index 6962982..dfb1aa4 100644 --- a/include/trace/events/f2fs.h +++ b/include/trace/events/f2fs.h @@ -1010,6 +1010,140 @@ TRACE_EVENT(f2fs_issue_flush, __entry-nobarrier ? skip (nobarrier) : issue, __entry-flush_merge ? with flush_merge : ) ); + +TRACE_EVENT(f2fs_lookup_extent_tree_start, + + TP_PROTO(struct inode *inode, unsigned int pgofs), + + TP_ARGS(inode, pgofs), + + TP_STRUCT__entry( + __field(dev_t, dev) + __field(ino_t, ino) + __field(unsigned int, pgofs) + ), + + TP_fast_assign( + __entry-dev = inode-i_sb-s_dev; + __entry-ino = inode-i_ino; + __entry-pgofs = pgofs; + ), + + TP_printk(dev = (%d,%d), ino = %lu, pgofs = %u, + show_dev_ino(__entry), + __entry-pgofs) +); + +TRACE_EVENT_CONDITION(f2fs_lookup_extent_tree_end, + + TP_PROTO(struct inode *inode, unsigned int pgofs, + struct extent_node *en), + + TP_ARGS(inode, pgofs, en), + + TP_CONDITION(en), + + TP_STRUCT__entry( + __field(dev_t, dev) + __field(ino_t, ino) + __field(unsigned int, pgofs) + __field(unsigned int, fofs) + __field(u32, blk) + __field(unsigned int, len) + ), + + TP_fast_assign( + __entry-dev = inode-i_sb-s_dev; +
[f2fs-dev] [PATCH v3 08/10] f2fs: enable rb-tree extent cache
This patch enables rb-tree based extent cache in f2fs. When we mount with -o extent_cache, f2fs will try to add recently accessed page-block mappings into rb-tree based extent cache as much as possible, instead of original one extent info cache. By this way, f2fs can support more effective cache between dnode page cache and disk. It will supply high hit ratio in the cache with fewer memory when dnode page cache are reclaimed in environment of low memory. Storage: Sandisk sd card 64g 1.append write file (offset: 0, size: 128M); 2.override write file (offset: 2M, size: 1M); 3.override write file (offset: 4M, size: 1M); ... 4.override write file (offset: 48M, size: 1M); ... 5.override write file (offset: 112M, size: 1M); 6.sync 7.echo 3 /proc/sys/vm/drop_caches 8.read file (size:128M, unit: 4k, count: 32768) (time dd if=/mnt/f2fs/128m bs=4k count=32768) Extent Hit Ratio: before patched Hit Ratio 121 / 1071 1071 / 1071 Performance: before patched real0m37.051s 0m35.556s user0m0.040s0m0.026s sys 0m2.990s0m2.251s Memory Cost: before patched Tree Count: 0 1 (size: 24 bytes) Node Count: 0 45 (size: 1440 bytes) v3: o retest and given more details of test result. Signed-off-by: Chao Yu chao2...@samsung.com --- fs/f2fs/data.c| 13 + fs/f2fs/f2fs.h| 5 + fs/f2fs/inode.c | 1 + fs/f2fs/segment.c | 3 +++ fs/f2fs/super.c | 9 - 5 files changed, 30 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 4b240fb..6c8119a 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -666,6 +666,9 @@ void f2fs_shrink_extent_tree(struct f2fs_sb_info *sbi, int nr_shrink) void **slot; unsigned int found; + if (!test_opt(sbi, EXTENT_CACHE)) + return; + if (available_free_memory(sbi, EXTENT_CACHE)) return; @@ -714,6 +717,9 @@ void f2fs_destroy_extent_tree(struct inode *inode) struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct extent_tree *et; + if (!test_opt(sbi, EXTENT_CACHE)) + return; + down_read(sbi-extent_tree_lock); et = radix_tree_lookup(sbi-extent_tree_root, inode-i_ino); if (!et) { @@ -749,6 +755,9 @@ out: static bool f2fs_lookup_extent_cache(struct inode *inode, pgoff_t pgofs, struct extent_info *ei) { + if (test_opt(F2FS_I_SB(inode), EXTENT_CACHE)) + return f2fs_lookup_extent_tree(inode, pgofs, ei); + return lookup_extent_info(inode, pgofs, ei); } @@ -765,6 +774,10 @@ void f2fs_update_extent_cache(struct dnode_of_data *dn) fofs = start_bidx_of_node(ofs_of_node(dn-node_page), fi) + dn-ofs_in_node; + if (test_opt(F2FS_I_SB(dn-inode), EXTENT_CACHE)) + return f2fs_update_extent_tree(dn-inode, fofs, + dn-data_blkaddr); + if (update_extent_info(dn-inode, fofs, dn-data_blkaddr)) sync_inode_page(dn); } diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 507e604..73ca511 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1568,12 +1568,17 @@ void f2fs_submit_page_mbio(struct f2fs_sb_info *, struct page *, struct f2fs_io_info *); int reserve_new_block(struct dnode_of_data *); int f2fs_reserve_block(struct dnode_of_data *, pgoff_t); +void f2fs_shrink_extent_tree(struct f2fs_sb_info *, int); +void f2fs_destroy_extent_tree(struct inode *); void f2fs_update_extent_cache(struct dnode_of_data *); struct page *find_data_page(struct inode *, pgoff_t, bool); struct page *get_lock_data_page(struct inode *, pgoff_t); struct page *get_new_data_page(struct inode *, struct page *, pgoff_t, bool); int do_write_data_page(struct page *, struct f2fs_io_info *); int f2fs_fiemap(struct inode *inode, struct fiemap_extent_info *, u64, u64); +void init_extent_cache_info(struct f2fs_sb_info *); +int __init create_extent_cache(void); +void destroy_extent_cache(void); /* * gc.c diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index 28dd26a..b508744 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -335,6 +335,7 @@ void f2fs_evict_inode(struct inode *inode) no_delete: stat_dec_inline_dir(inode); stat_dec_inline_inode(inode); + f2fs_destroy_extent_tree(inode); invalidate_mapping_pages(NODE_MAPPING(sbi), inode-i_ino, inode-i_ino); if (xnid) invalidate_mapping_pages(NODE_MAPPING(sbi), xnid, xnid); diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index b85bb97..f3f2d6f 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -277,6 +277,9 @@ void f2fs_balance_fs(struct f2fs_sb_info *sbi) void f2fs_balance_fs_bg(struct
[f2fs-dev] [PATCH v3 09/10] f2fs: show extent tree, node stat info in debugfs
This patch add and show stat info of total memory footprint for extent tree,node in debugfs. Signed-off-by: Chao Yu chao2...@samsung.com --- fs/f2fs/debug.c | 7 +++ fs/f2fs/f2fs.h | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/debug.c b/fs/f2fs/debug.c index ac2bd8e..205e525 100644 --- a/fs/f2fs/debug.c +++ b/fs/f2fs/debug.c @@ -35,6 +35,8 @@ static void update_general_status(struct f2fs_sb_info *sbi) /* validation check of the segment numbers */ si-hit_ext = sbi-read_hit_ext; si-total_ext = sbi-total_hit_ext; + si-ext_tree = sbi-total_ext_tree; + si-ext_node = atomic_read(sbi-total_ext_node); si-ndirty_node = get_pages(sbi, F2FS_DIRTY_NODES); si-ndirty_dent = get_pages(sbi, F2FS_DIRTY_DENTS); si-ndirty_dirs = sbi-n_dirty_dirs; @@ -184,6 +186,9 @@ get_cache: si-cache_mem += sbi-n_dirty_dirs * sizeof(struct inode_entry); for (i = 0; i = UPDATE_INO; i++) si-cache_mem += sbi-im[i].ino_num * sizeof(struct ino_entry); + si-cache_mem += sbi-total_ext_tree * sizeof(struct extent_tree); + si-cache_mem += atomic_read(sbi-total_ext_node) * + sizeof(struct extent_node); si-page_mem = 0; npages = NODE_MAPPING(sbi)-nrpages; @@ -266,6 +271,8 @@ static int stat_show(struct seq_file *s, void *v) seq_printf(s, - node blocks : %d\n, si-node_blks); seq_printf(s, \nExtent Hit Ratio: %d / %d\n, si-hit_ext, si-total_ext); + seq_printf(s, \nExtent Tree Count: %d\n, si-ext_tree); + seq_printf(s, \nExtent Node Count: %d\n, si-ext_node); seq_puts(s, \nBalancing F2FS Async:\n); seq_printf(s, - inmem: %4d, wb: %4d\n, si-inmem_pages, si-wb_pages); diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 73ca511..9572f7c 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -1604,7 +1604,7 @@ struct f2fs_stat_info { struct f2fs_sb_info *sbi; int all_area_segs, sit_area_segs, nat_area_segs, ssa_area_segs; int main_area_segs, main_area_sections, main_area_zones; - int hit_ext, total_ext; + int hit_ext, total_ext, ext_tree, ext_node; int ndirty_node, ndirty_dent, ndirty_dirs, ndirty_meta; int nats, dirty_nats, sits, dirty_sits, fnids; int total_count, utilization; -- 2.2.1 -- Dive into the World of Parallel Programming. The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net/ ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH 3/3] f2fs: use extent cache for dir
We update extent cache for all user inode of f2fs including dir inode, so this patch gives another chance to try to get physical address of page from extent cache for dir inode. Signed-off-by: Chao Yu chao2...@samsung.com --- fs/f2fs/data.c | 14 ++ 1 file changed, 14 insertions(+) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 45b97a5..f84c44a 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -806,6 +806,7 @@ struct page *find_data_page(struct inode *inode, pgoff_t index, bool sync) struct address_space *mapping = inode-i_mapping; struct dnode_of_data dn; struct page *page; + struct extent_info ei; int err; struct f2fs_io_info fio = { .type = DATA, @@ -817,6 +818,11 @@ struct page *find_data_page(struct inode *inode, pgoff_t index, bool sync) return page; f2fs_put_page(page, 0); + if (f2fs_lookup_extent_cache(inode, index, ei)) { + dn.data_blkaddr = ei.blk + index - ei.fofs; + goto got_it; + } + set_new_dnode(dn, inode, NULL, NULL, 0); err = get_dnode_of_data(dn, index, LOOKUP_NODE); if (err) @@ -830,6 +836,7 @@ struct page *find_data_page(struct inode *inode, pgoff_t index, bool sync) if (unlikely(dn.data_blkaddr == NEW_ADDR)) return ERR_PTR(-EINVAL); +got_it: page = grab_cache_page(mapping, index); if (!page) return ERR_PTR(-ENOMEM); @@ -864,6 +871,7 @@ struct page *get_lock_data_page(struct inode *inode, pgoff_t index) struct address_space *mapping = inode-i_mapping; struct dnode_of_data dn; struct page *page; + struct extent_info ei; int err; struct f2fs_io_info fio = { .type = DATA, @@ -874,6 +882,11 @@ repeat: if (!page) return ERR_PTR(-ENOMEM); + if (f2fs_lookup_extent_cache(inode, index, ei)) { + dn.data_blkaddr = ei.blk + index - ei.fofs; + goto got_it; + } + set_new_dnode(dn, inode, NULL, NULL, 0); err = get_dnode_of_data(dn, index, LOOKUP_NODE); if (err) { @@ -887,6 +900,7 @@ repeat: return ERR_PTR(-ENOENT); } +got_it: if (PageUptodate(page)) return page; -- 2.2.1 -- Dive into the World of Parallel Programming. The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net/ ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
Re: [f2fs-dev] [PATCH 5/5 v3] f2fs: introduce a batched trim
Hi Jaegeuk, Changman, -Original Message- From: Jaegeuk Kim [mailto:jaeg...@kernel.org] Sent: Wednesday, February 04, 2015 4:11 AM To: Changman Lee Cc: Chao Yu; linux-fsde...@vger.kernel.org; linux-ker...@vger.kernel.org; linux-f2fs-devel@lists.sourceforge.net Subject: Re: [f2fs-dev] [PATCH 5/5 v3] f2fs: introduce a batched trim Hi Changman, Good idea! Change log from v2: o add sysfs to change the # of sections for trimming. Good idea! Change log from v1: o add description o change the # of batched segments suggested by Chao o make consistent for # of batched segments This patch introduces a batched trimming feature, which submits split discard commands. This is to avoid long latency due to huge trim commands. If fstrim was triggered ranging from 0 to the end of device, we should lock all the checkpoint-related mutexes, resulting in very long latency. Signed-off-by: Jaegeuk Kim jaeg...@kernel.org --- Documentation/ABI/testing/sysfs-fs-f2fs | 6 ++ Documentation/filesystems/f2fs.txt | 4 fs/f2fs/f2fs.h | 7 +++ fs/f2fs/segment.c | 18 +- fs/f2fs/super.c | 2 ++ 5 files changed, 32 insertions(+), 5 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-fs-f2fs b/Documentation/ABI/testing/sysfs-fs-f2fs index 6f9157f..2c4cc42 100644 --- a/Documentation/ABI/testing/sysfs-fs-f2fs +++ b/Documentation/ABI/testing/sysfs-fs-f2fs @@ -74,3 +74,9 @@ Date: March 2014 Contact: Jaegeuk Kim jaegeuk@samsung.com Description: Controls the memory footprint used by f2fs. + +What:/sys/fs/f2fs/disk/trim_sections +Date:February 2015 +Contact: Jaegeuk Kim jaeg...@kernel.org +Description: + Controls the trimming rate in batch mode. diff --git a/Documentation/filesystems/f2fs.txt b/Documentation/filesystems/f2fs.txt index 6758aa3..dac11d7 100644 --- a/Documentation/filesystems/f2fs.txt +++ b/Documentation/filesystems/f2fs.txt @@ -199,6 +199,10 @@ Files in /sys/fs/f2fs/devname checkpoint is triggered, and issued during the checkpoint. By default, it is disabled with 0. + trim_sectionsThis parameter controls the number of sections + to be trimmed out in batch mode when FITRIM + conducts. 32 sections is set by default. + ipu_policy This parameter controls the policy of in-place updates in f2fs. There are five policies: 0x01: F2FS_IPU_FORCE, 0x02: F2FS_IPU_SSR, diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 964c240..6f57da1 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -105,6 +105,10 @@ enum { CP_DISCARD, }; +#define DEF_BATCHED_TRIM_SECTIONS32 +#define BATCHED_TRIM_SEGMENTS(sbi) \ + (SM_I(sbi)-trim_sections * (sbi)-segs_per_sec) + struct cp_control { int reason; __u64 trim_start; @@ -448,6 +452,9 @@ struct f2fs_sm_info { int nr_discards;/* # of discards in the list */ int max_discards; /* max. discards to be issued */ + /* for batched trimming */ + int trim_sections; /* # of sections to trim */ + struct list_head sit_entry_set; /* sit entry set list */ unsigned int ipu_policy;/* in-place-update policy */ diff --git a/fs/f2fs/segment.c b/fs/f2fs/segment.c index 5ea57ec..c542f63 100644 --- a/fs/f2fs/segment.c +++ b/fs/f2fs/segment.c @@ -1066,14 +1066,20 @@ int f2fs_trim_fs(struct f2fs_sb_info *sbi, struct fstrim_range *range) end_segno = (end = MAX_BLKADDR(sbi)) ? MAIN_SEGS(sbi) - 1 : GET_SEGNO(sbi, end); cpc.reason = CP_DISCARD; - cpc.trim_start = start_segno; - cpc.trim_end = end_segno; cpc.trim_minlen = range-minlen sbi-log_blocksize; /* do checkpoint to issue discard commands safely */ - mutex_lock(sbi-gc_mutex); - write_checkpoint(sbi, cpc); - mutex_unlock(sbi-gc_mutex); + for (; start_segno = end_segno; + start_segno += BATCHED_TRIM_SEGMENTS(sbi)) { + cpc.trim_start = start_segno; + cpc.trim_end = min_t(unsigned int, + start_segno + BATCHED_TRIM_SEGMENTS (sbi) - 1, Actually what I mean is that in each trim we try to align start segment to first segment of section as much as possible. How about using: cpc.trim_end = min_t(unsigned int, rounddown(start_segno + BATCHED_TRIM_SEGMENTS(sbi), (sbi)-segs_per_sec) - 1, end_segno); Thanks, +
Re: [f2fs-dev] [PATCH 1/2] mkfs.f2fs: support large sector size
Hi Kinglong, -Original Message- From: Kinglong Mee [mailto:kinglong...@gmail.com] Sent: Wednesday, February 04, 2015 9:43 PM To: Chao Yu Cc: Jaegeuk Kim; Changman Lee; linux-ker...@vger.kernel.org; linux-f2fs-devel@lists.sourceforge.net Subject: Re: [f2fs-dev] [PATCH 1/2] mkfs.f2fs: support large sector size Hi Chao, On Wed, Feb 4, 2015 at 11:30 AM, Chao Yu chao2...@samsung.com wrote: Since f2fs support large sector size in commit 55cf9cb63f0e f2fs: support large sector size, block device with sector size of 512/1024/2048/4096 bytes can be supported. But mkfs.f2fs still use default sector size: 512 bytes as sector size, let's fix this issue in this patch. v2: o remove unneeded printed message when sector size is large than 512 bytes suggested by Kinglong. o show correct sector size in printed message. o use config.sectors_per_blk instead of DEFAULT_SECTORS_PER_BLOCK suggested by Kinglong. Signed-off-by: Chao Yu chao2...@samsung.com --- lib/libf2fs.c| 10 +++--- mkfs/f2fs_format.c | 12 ++-- mkfs/f2fs_format_utils.c | 2 +- 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/lib/libf2fs.c b/lib/libf2fs.c index 8123528..d2942f0 100644 --- a/lib/libf2fs.c +++ b/lib/libf2fs.c @@ -463,10 +463,6 @@ int f2fs_get_device_info(struct f2fs_configuration *c) MSG(0, \tError: Using the default sector size\n); } else { if (c-sector_size sector_size) { - MSG(0, \tError: Cannot set the sector size to: -%d as the device does not support - \nSetting the sector size to : %d\n, - c-sector_size, sector_size); c-sector_size = sector_size; c-sectors_per_blk = PAGE_SIZE / sector_size; } @@ -495,8 +491,8 @@ int f2fs_get_device_info(struct f2fs_configuration *c) return -1; } if (wanted_total_sectors wanted_total_sectors c-total_sectors) { - MSG(0, Info: total device sectors = %PRIu64 (in 512bytes)\n, - c-total_sectors); + MSG(0, Info: total device sectors = %PRIu64 (in %u bytes)\n, + c-total_sectors, c-sector_size); c-total_sectors = wanted_total_sectors; } @@ -504,7 +500,7 @@ int f2fs_get_device_info(struct f2fs_configuration *c) MSG(0, Info: total sectors = %PRIu64 (in 512bytes)\n, This 512bytes should be modified as above too. Oh my miss, sorry about this. I will resend the patch. thanks, Yu thanks, Kinglong Mee -- Dive into the World of Parallel Programming. The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net/ ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH v3 01/10] f2fs: move ext_lock out of struct extent_info
Move ext_lock out of struct extent_info, then in the following patches we can use variables with struct extent_info type as a parameter to pass pure data. Signed-off-by: Chao Yu chao2...@samsung.com --- fs/f2fs/data.c | 12 ++-- fs/f2fs/f2fs.h | 6 +- fs/f2fs/inode.c | 7 +++ fs/f2fs/super.c | 2 +- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 27dc3fd..7cc64c8 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -258,9 +258,9 @@ static int check_extent_cache(struct inode *inode, pgoff_t pgofs, if (is_inode_flag_set(fi, FI_NO_EXTENT)) return 0; - read_lock(fi-ext.ext_lock); + read_lock(fi-ext_lock); if (fi-ext.len == 0) { - read_unlock(fi-ext.ext_lock); + read_unlock(fi-ext_lock); return 0; } @@ -284,10 +284,10 @@ static int check_extent_cache(struct inode *inode, pgoff_t pgofs, bh_result-b_size = UINT_MAX; stat_inc_read_hit(inode-i_sb); - read_unlock(fi-ext.ext_lock); + read_unlock(fi-ext_lock); return 1; } - read_unlock(fi-ext.ext_lock); + read_unlock(fi-ext_lock); return 0; } @@ -309,7 +309,7 @@ void update_extent_cache(struct dnode_of_data *dn) fofs = start_bidx_of_node(ofs_of_node(dn-node_page), fi) + dn-ofs_in_node; - write_lock(fi-ext.ext_lock); + write_lock(fi-ext_lock); start_fofs = fi-ext.fofs; end_fofs = fi-ext.fofs + fi-ext.len - 1; @@ -366,7 +366,7 @@ void update_extent_cache(struct dnode_of_data *dn) need_update = true; } end_update: - write_unlock(fi-ext.ext_lock); + write_unlock(fi-ext_lock); if (need_update) sync_inode_page(dn); return; diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 47a8857..b912576 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -275,7 +275,6 @@ enum { #define F2FS_MIN_EXTENT_LEN16 /* minimum extent length */ struct extent_info { - rwlock_t ext_lock; /* rwlock for consistency */ unsigned int fofs; /* start offset in a file */ u32 blk_addr; /* start block address of the extent */ unsigned int len; /* length of the extent */ @@ -307,6 +306,7 @@ struct f2fs_inode_info { nid_t i_xattr_nid; /* node id that contains xattrs */ unsigned long long xattr_ver; /* cp version of xattr modification */ struct extent_info ext; /* in-memory extent cache entry */ + rwlock_t ext_lock; /* rwlock for single extent cache */ struct inode_entry *dirty_dir; /* the pointer of dirty dir */ struct radix_tree_root inmem_root; /* radix tree for inmem pages */ @@ -317,21 +317,17 @@ struct f2fs_inode_info { static inline void get_extent_info(struct extent_info *ext, struct f2fs_extent i_ext) { - write_lock(ext-ext_lock); ext-fofs = le32_to_cpu(i_ext.fofs); ext-blk_addr = le32_to_cpu(i_ext.blk_addr); ext-len = le32_to_cpu(i_ext.len); - write_unlock(ext-ext_lock); } static inline void set_raw_extent(struct extent_info *ext, struct f2fs_extent *i_ext) { - read_lock(ext-ext_lock); i_ext-fofs = cpu_to_le32(ext-fofs); i_ext-blk_addr = cpu_to_le32(ext-blk_addr); i_ext-len = cpu_to_le32(ext-len); - read_unlock(ext-ext_lock); } struct f2fs_nm_info { diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c index 2d002e3..28dd26a 100644 --- a/fs/f2fs/inode.c +++ b/fs/f2fs/inode.c @@ -130,7 +130,10 @@ static int do_read_inode(struct inode *inode) fi-i_pino = le32_to_cpu(ri-i_pino); fi-i_dir_level = ri-i_dir_level; + write_lock(fi-ext_lock); get_extent_info(fi-ext, ri-i_ext); + write_unlock(fi-ext_lock); + get_inline_info(fi, ri); /* check data exist */ @@ -220,7 +223,11 @@ void update_inode(struct inode *inode, struct page *node_page) ri-i_links = cpu_to_le32(inode-i_nlink); ri-i_size = cpu_to_le64(i_size_read(inode)); ri-i_blocks = cpu_to_le64(inode-i_blocks); + + read_lock(F2FS_I(inode)-ext_lock); set_raw_extent(F2FS_I(inode)-ext, ri-i_ext); + read_unlock(F2FS_I(inode)-ext_lock); + set_raw_inline(F2FS_I(inode), ri); ri-i_atime = cpu_to_le64(inode-i_atime.tv_sec); diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c index 1e92c2e..8557582 100644 --- a/fs/f2fs/super.c +++ b/fs/f2fs/super.c @@ -390,7 +390,7 @@ static struct inode *f2fs_alloc_inode(struct super_block *sb) atomic_set(fi-dirty_pages, 0); fi-i_current_depth = 1; fi-i_advise = 0; - rwlock_init(fi-ext.ext_lock); + rwlock_init(fi-ext_lock);
[f2fs-dev] [PATCH v3 02/10] f2fs: simplfy a field name in struct f2fs_extent, extent_info
Rename a filed name from 'blk_addr' to 'blk' in struct {f2fs_extent,extent_info} as annotation of this field descripts its meaning well to us. By this way, we can avoid long statement in code of following patches. Signed-off-by: Chao Yu chao2...@samsung.com --- fs/f2fs/data.c | 13 ++--- fs/f2fs/f2fs.h | 6 +++--- include/linux/f2fs_fs.h | 2 +- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 7cc64c8..335df0d 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -268,7 +268,7 @@ static int check_extent_cache(struct inode *inode, pgoff_t pgofs, start_fofs = fi-ext.fofs; end_fofs = fi-ext.fofs + fi-ext.len - 1; - start_blkaddr = fi-ext.blk_addr; + start_blkaddr = fi-ext.blk; if (pgofs = start_fofs pgofs = end_fofs) { unsigned int blkbits = inode-i_sb-s_blocksize_bits; @@ -313,8 +313,8 @@ void update_extent_cache(struct dnode_of_data *dn) start_fofs = fi-ext.fofs; end_fofs = fi-ext.fofs + fi-ext.len - 1; - start_blkaddr = fi-ext.blk_addr; - end_blkaddr = fi-ext.blk_addr + fi-ext.len - 1; + start_blkaddr = fi-ext.blk; + end_blkaddr = fi-ext.blk + fi-ext.len - 1; /* Drop and initialize the matched extent */ if (fi-ext.len == 1 fofs == start_fofs) @@ -324,7 +324,7 @@ void update_extent_cache(struct dnode_of_data *dn) if (fi-ext.len == 0) { if (dn-data_blkaddr != NULL_ADDR) { fi-ext.fofs = fofs; - fi-ext.blk_addr = dn-data_blkaddr; + fi-ext.blk = dn-data_blkaddr; fi-ext.len = 1; } goto end_update; @@ -333,7 +333,7 @@ void update_extent_cache(struct dnode_of_data *dn) /* Front merge */ if (fofs == start_fofs - 1 dn-data_blkaddr == start_blkaddr - 1) { fi-ext.fofs--; - fi-ext.blk_addr--; + fi-ext.blk--; fi-ext.len++; goto end_update; } @@ -351,8 +351,7 @@ void update_extent_cache(struct dnode_of_data *dn) fi-ext.len = fofs - start_fofs; } else { fi-ext.fofs = fofs + 1; - fi-ext.blk_addr = start_blkaddr + - fofs - start_fofs + 1; + fi-ext.blk = start_blkaddr + fofs - start_fofs + 1; fi-ext.len -= fofs - start_fofs + 1; } } else { diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index b912576..03e30bc 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -276,7 +276,7 @@ enum { struct extent_info { unsigned int fofs; /* start offset in a file */ - u32 blk_addr; /* start block address of the extent */ + u32 blk;/* start block address of the extent */ unsigned int len; /* length of the extent */ }; @@ -318,7 +318,7 @@ static inline void get_extent_info(struct extent_info *ext, struct f2fs_extent i_ext) { ext-fofs = le32_to_cpu(i_ext.fofs); - ext-blk_addr = le32_to_cpu(i_ext.blk_addr); + ext-blk = le32_to_cpu(i_ext.blk); ext-len = le32_to_cpu(i_ext.len); } @@ -326,7 +326,7 @@ static inline void set_raw_extent(struct extent_info *ext, struct f2fs_extent *i_ext) { i_ext-fofs = cpu_to_le32(ext-fofs); - i_ext-blk_addr = cpu_to_le32(ext-blk_addr); + i_ext-blk = cpu_to_le32(ext-blk); i_ext-len = cpu_to_le32(ext-len); } diff --git a/include/linux/f2fs_fs.h b/include/linux/f2fs_fs.h index 0980572..cfe771b 100644 --- a/include/linux/f2fs_fs.h +++ b/include/linux/f2fs_fs.h @@ -149,7 +149,7 @@ struct f2fs_orphan_block { */ struct f2fs_extent { __le32 fofs;/* start file offset of the extent */ - __le32 blk_addr;/* start block address of the extent */ + __le32 blk; /* start block address of the extent */ __le32 len; /* lengh of the extent */ } __packed; -- 2.2.1 -- Dive into the World of Parallel Programming. The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net/ ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH RESEND 1/2] mkfs.f2fs: support large sector size
Since f2fs support large sector size in commit 55cf9cb63f0e f2fs: support large sector size, block device with sector size of 512/1024/2048/4096 bytes can be supported. But mkfs.f2fs still use default sector size: 512 bytes as sector size, let's fix this issue in this patch. v2: o remove unneeded printed message when sector size is large than 512 bytes suggested by Kinglong. o show correct sector size in printed message. o use config.sectors_per_blk instead of DEFAULT_SECTORS_PER_BLOCK suggested by Kinglong. v3: o remove another unneeded printed message when sector size is large than 512 bytes suggested by Kinglong. Signed-off-by: Chao Yu chao2...@samsung.com --- lib/libf2fs.c| 14 +- mkfs/f2fs_format.c | 12 ++-- mkfs/f2fs_format_utils.c | 2 +- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/lib/libf2fs.c b/lib/libf2fs.c index 8123528..9e19e9b 100644 --- a/lib/libf2fs.c +++ b/lib/libf2fs.c @@ -463,10 +463,6 @@ int f2fs_get_device_info(struct f2fs_configuration *c) MSG(0, \tError: Using the default sector size\n); } else { if (c-sector_size sector_size) { - MSG(0, \tError: Cannot set the sector size to: -%d as the device does not support - \nSetting the sector size to : %d\n, - c-sector_size, sector_size); c-sector_size = sector_size; c-sectors_per_blk = PAGE_SIZE / sector_size; } @@ -495,16 +491,16 @@ int f2fs_get_device_info(struct f2fs_configuration *c) return -1; } if (wanted_total_sectors wanted_total_sectors c-total_sectors) { - MSG(0, Info: total device sectors = %PRIu64 (in 512bytes)\n, - c-total_sectors); + MSG(0, Info: total device sectors = %PRIu64 (in %u bytes)\n, + c-total_sectors, c-sector_size); c-total_sectors = wanted_total_sectors; } MSG(0, Info: sector size = %u\n, c-sector_size); - MSG(0, Info: total sectors = %PRIu64 (in 512bytes)\n, - c-total_sectors); + MSG(0, Info: total sectors = %PRIu64 (in %u bytes)\n, + c-total_sectors, c-sector_size); if (c-total_sectors - (F2FS_MIN_VOLUME_SIZE / DEFAULT_SECTOR_SIZE)) { + (F2FS_MIN_VOLUME_SIZE / c-sector_size)) { MSG(0, Error: Min volume size supported is %d\n, F2FS_MIN_VOLUME_SIZE); return -1; diff --git a/mkfs/f2fs_format.c b/mkfs/f2fs_format.c index a8d2db6..2cce7c3 100644 --- a/mkfs/f2fs_format.c +++ b/mkfs/f2fs_format.c @@ -198,20 +198,20 @@ static int f2fs_prepare_super_block(void) set_sb(block_count, config.total_sectors log_sectors_per_block); zone_align_start_offset = - (config.start_sector * DEFAULT_SECTOR_SIZE + + (config.start_sector * config.sector_size + 2 * F2FS_BLKSIZE + zone_size_bytes - 1) / zone_size_bytes * zone_size_bytes - - config.start_sector * DEFAULT_SECTOR_SIZE; + config.start_sector * config.sector_size; - if (config.start_sector % DEFAULT_SECTORS_PER_BLOCK) { + if (config.start_sector % config.sectors_per_blk) { MSG(1, \tWARN: Align start sector number to the page unit\n); MSG(1, \ti.e., start sector: %d, ofs:%d (sects/page: %d)\n, config.start_sector, - config.start_sector % DEFAULT_SECTORS_PER_BLOCK, - DEFAULT_SECTORS_PER_BLOCK); + config.start_sector % config.sectors_per_blk, + config.sectors_per_blk); } - set_sb(segment_count, (config.total_sectors * DEFAULT_SECTOR_SIZE - + set_sb(segment_count, (config.total_sectors * config.sector_size - zone_align_start_offset) / segment_size_bytes); set_sb(segment0_blkaddr, zone_align_start_offset / blk_size_bytes); diff --git a/mkfs/f2fs_format_utils.c b/mkfs/f2fs_format_utils.c index 88b9953..a0f85f5 100644 --- a/mkfs/f2fs_format_utils.c +++ b/mkfs/f2fs_format_utils.c @@ -36,7 +36,7 @@ int f2fs_trim_device() return 0; range[0] = 0; - range[1] = config.total_sectors * DEFAULT_SECTOR_SIZE; + range[1] = config.total_sectors * config.sector_size; if (fstat(config.fd, stat_buf) 0 ) { MSG(1, \tError: Failed to get the device stat!!!\n); -- 2.2.1
[f2fs-dev] [PATCH RESEND 2/2] fsck.f2fs: support large sector size
Since f2fs support large sector size in commit 55cf9cb63f0e f2fs: support large sector size, block device with sector size of 512/1024/2048/4096 bytes can be supported. But fsck.f2fs still use default F2FS_LOG_SECTOR_SIZE/F2FS_LOG_SECTORS_PER_BLOCK to verify related data in f2fs image, it's wrong, let's fix this issue in this patch. Signed-off-by: Chao Yu chao2...@samsung.com --- fsck/mount.c | 9 ++--- include/f2fs_fs.h | 4 ++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/fsck/mount.c b/fsck/mount.c index 73eba6b..6d96db8 100644 --- a/fsck/mount.c +++ b/fsck/mount.c @@ -221,12 +221,15 @@ int sanity_check_raw_super(struct f2fs_super_block *raw_super) return -1; } - if (F2FS_LOG_SECTOR_SIZE != le32_to_cpu(raw_super-log_sectorsize)) { + if (le32_to_cpu(raw_super-log_sectorsize) F2FS_MAX_LOG_SECTOR_SIZE || + le32_to_cpu(raw_super-log_sectorsize) + F2FS_MIN_LOG_SECTOR_SIZE) { return -1; } - if (F2FS_LOG_SECTORS_PER_BLOCK != - le32_to_cpu(raw_super-log_sectors_per_block)) { + if (le32_to_cpu(raw_super-log_sectors_per_block) + + le32_to_cpu(raw_super-log_sectorsize) != + F2FS_MAX_LOG_SECTOR_SIZE) { return -1; } diff --git a/include/f2fs_fs.h b/include/f2fs_fs.h index 4dc2426..99c21eb 100644 --- a/include/f2fs_fs.h +++ b/include/f2fs_fs.h @@ -289,8 +289,8 @@ enum { * Copied from include/linux/f2fs_sb.h */ #define F2FS_SUPER_OFFSET 1024/* byte-size offset */ -#define F2FS_LOG_SECTOR_SIZE 9 /* 9 bits for 512 byte */ -#define F2FS_LOG_SECTORS_PER_BLOCK 3 /* 4KB: F2FS_BLKSIZE */ +#define F2FS_MIN_LOG_SECTOR_SIZE 9 /* 9 bits for 512 bytes */ +#define F2FS_MAX_LOG_SECTOR_SIZE 12 /* 12 bits for 4096 bytes */ #define F2FS_BLKSIZE 4096/* support only 4KB block */ #define F2FS_MAX_EXTENSION 64 /* # of extension entries */ #define F2FS_BLK_ALIGN(x) (((x) + F2FS_BLKSIZE - 1) / F2FS_BLKSIZE) -- 2.2.1 -- Dive into the World of Parallel Programming. The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net/ ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH v3 03/10] f2fs: introduce f2fs_map_bh to clean codes of check_extent_cache
This patch introduces f2fs_map_bh to clean codes of check_extent_cache. v2: o cleanup f2fs_map_bh pointed out by Jaegeuk Kim. Signed-off-by: Chao Yu chao2...@samsung.com --- fs/f2fs/data.c | 35 +-- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 335df0d..f2d8deb 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -248,8 +248,23 @@ int f2fs_reserve_block(struct dnode_of_data *dn, pgoff_t index) return err; } +static void f2fs_map_bh(struct super_block *sb, pgoff_t pgofs, + struct extent_info *ei, struct buffer_head *bh_result) +{ + unsigned int blkbits = sb-s_blocksize_bits; + size_t count; + + clear_buffer_new(bh_result); + map_bh(bh_result, sb, ei-blk + pgofs - ei-fofs); + count = ei-fofs + ei-len - pgofs; + if (count (UINT_MAX blkbits)) + bh_result-b_size = (count blkbits); + else + bh_result-b_size = UINT_MAX; +} + static int check_extent_cache(struct inode *inode, pgoff_t pgofs, - struct buffer_head *bh_result) + struct extent_info *ei) { struct f2fs_inode_info *fi = F2FS_I(inode); pgoff_t start_fofs, end_fofs; @@ -271,18 +286,7 @@ static int check_extent_cache(struct inode *inode, pgoff_t pgofs, start_blkaddr = fi-ext.blk; if (pgofs = start_fofs pgofs = end_fofs) { - unsigned int blkbits = inode-i_sb-s_blocksize_bits; - size_t count; - - clear_buffer_new(bh_result); - map_bh(bh_result, inode-i_sb, - start_blkaddr + pgofs - start_fofs); - count = end_fofs - pgofs + 1; - if (count (UINT_MAX blkbits)) - bh_result-b_size = (count blkbits); - else - bh_result-b_size = UINT_MAX; - + *ei = fi-ext; stat_inc_read_hit(inode-i_sb); read_unlock(fi-ext_lock); return 1; @@ -608,13 +612,16 @@ static int __get_data_block(struct inode *inode, sector_t iblock, int mode = create ? ALLOC_NODE : LOOKUP_NODE_RA; pgoff_t pgofs, end_offset; int err = 0, ofs = 1; + struct extent_info ei; bool allocated = false; /* Get the page offset from the block offset(iblock) */ pgofs = (pgoff_t)(iblock (PAGE_CACHE_SHIFT - blkbits)); - if (check_extent_cache(inode, pgofs, bh_result)) + if (check_extent_cache(inode, pgofs, ei)) { + f2fs_map_bh(inode-i_sb, pgofs, ei, bh_result); goto out; + } if (create) { f2fs_balance_fs(F2FS_I_SB(inode)); -- 2.2.1 -- Dive into the World of Parallel Programming. The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net/ ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH 1/3] f2fs: support fast lookup in extent cache
This patch adds a fast lookup path for rb-tree extent cache. In this patch we add a recently accessed extent node pointer 'cached_en' in extent tree. In lookup path of extent cache, we will firstly lookup the last accessed extent node which cached_en points, if we do not hit in this node, we will try to lookup extent node in rb-tree. By this way we can avoid unnecessary slow lookup in rb-tree sometimes. Note that, side-effect of this patch is that we will increase memory cost, because we will store a pointer variable in each struct extent tree additionally. Signed-off-by: Chao Yu chao2...@samsung.com --- fs/f2fs/data.c | 19 --- fs/f2fs/f2fs.h | 1 + 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index 4ba1605..112db9c 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -395,6 +395,9 @@ static void __detach_extent_node(struct f2fs_sb_info *sbi, rb_erase(en-rb_node, et-root); et-count--; atomic_dec(sbi-total_ext_node); + + if (et-cached_en == en) + et-cached_en = NULL; } static struct extent_node *__lookup_extent_tree(struct extent_tree *et, @@ -403,15 +406,24 @@ static struct extent_node *__lookup_extent_tree(struct extent_tree *et, struct rb_node *node = et-root.rb_node; struct extent_node *en; + if (et-cached_en) { + struct extent_info *cei = et-cached_en-ei; + + if (cei-fofs = fofs cei-fofs + cei-len fofs) + return et-cached_en; + } + while (node) { en = rb_entry(node, struct extent_node, rb_node); - if (fofs en-ei.fofs) + if (fofs en-ei.fofs) { node = node-rb_left; - else if (fofs = en-ei.fofs + en-ei.len) + } else if (fofs = en-ei.fofs + en-ei.len) { node = node-rb_right; - else + } else { + et-cached_en = en; return en; + } } return NULL; } @@ -587,6 +599,7 @@ static void f2fs_update_extent_tree(struct inode *inode, pgoff_t fofs, memset(et, 0, sizeof(struct extent_tree)); et-ino = ino; et-root = RB_ROOT; + et-cached_en = NULL; rwlock_init(et-lock); atomic_set(et-refcount, 0); et-count = 0; diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h index 9572f7c..47b30de 100644 --- a/fs/f2fs/f2fs.h +++ b/fs/f2fs/f2fs.h @@ -296,6 +296,7 @@ struct extent_node { struct extent_tree { nid_t ino; /* inode number */ struct rb_root root;/* root of extent info rb-tree */ + struct extent_node *cached_en; /* recently accessed extent node */ rwlock_t lock; /* protect extent info rb-tree */ atomic_t refcount; /* reference count of rb-tree */ unsigned int count; /* # of extent node in rb-tree*/ -- 2.2.1 -- Dive into the World of Parallel Programming. The Go Parallel Website, sponsored by Intel and developed in partnership with Slashdot Media, is your hub for all things parallel software development, from weekly thought leadership blogs to news, videos, case studies, tutorials and more. Take a look and join the conversation now. http://goparallel.sourceforge.net/ ___ Linux-f2fs-devel mailing list Linux-f2fs-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel
[f2fs-dev] [PATCH v3 06/10] f2fs: add core functions for rb-tree extent cache
This patch adds core functions including slab cache init function and init/lookup/update/shrink/destroy function for rb-tree based extent cache. Thank Jaegeuk Kim and Changman Lee as they gave much suggestion about detail design and implementation of extent cache. Todo: * register rb-based extent cache shrink with mm shrink interface. v2: o move set_extent_info and __is_{extent,back,front}_mergeable into f2fs.h. o introduce __{attach,detach}_extent_node for code readability. o add cond_resched() when fail to invoke kmem_cache_alloc/radix_tree_insert. o fix some coding style and typo issues. v3: o fix oops due to using an unassigned pointer. o use list_del to remove extent node in shrink list. Signed-off-by: Chao Yu chao2...@samsung.com Signed-off-by: Jaegeuk Kim jaeg...@kernel.org Signed-off-by: Changman Lee cm224@samsung.com --- fs/f2fs/data.c | 411 + fs/f2fs/f2fs.h | 27 fs/f2fs/node.c | 9 +- 3 files changed, 446 insertions(+), 1 deletion(-) diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c index c805d2a..4b240fb 100644 --- a/fs/f2fs/data.c +++ b/fs/f2fs/data.c @@ -25,6 +25,9 @@ #include trace.h #include trace/events/f2fs.h +struct kmem_cache *extent_tree_slab; +struct kmem_cache *extent_node_slab; + static void f2fs_read_end_io(struct bio *bio, int err) { struct bio_vec *bvec; @@ -366,6 +369,383 @@ end_update: return need_update; } +struct extent_node *__attach_extent_node(struct f2fs_sb_info *sbi, + struct extent_tree *et, struct extent_info *ei, + struct rb_node *parent, struct rb_node **p) +{ + struct extent_node *en; + + en = kmem_cache_alloc(extent_node_slab, GFP_ATOMIC); + if (!en) + return NULL; + + en-ei = *ei; + INIT_LIST_HEAD(en-list); + + rb_link_node(en-rb_node, parent, p); + rb_insert_color(en-rb_node, et-root); + et-count++; + atomic_inc(sbi-total_ext_node); + return en; +} + +static void __detach_extent_node(struct f2fs_sb_info *sbi, + struct extent_tree *et, struct extent_node *en) +{ + rb_erase(en-rb_node, et-root); + et-count--; + atomic_dec(sbi-total_ext_node); +} + +static struct extent_node *__lookup_extent_tree(struct extent_tree *et, + unsigned int fofs) +{ + struct rb_node *node = et-root.rb_node; + struct extent_node *en; + + while (node) { + en = rb_entry(node, struct extent_node, rb_node); + + if (fofs en-ei.fofs) + node = node-rb_left; + else if (fofs = en-ei.fofs + en-ei.len) + node = node-rb_right; + else + return en; + } + return NULL; +} + +static struct extent_node *__try_back_merge(struct f2fs_sb_info *sbi, + struct extent_tree *et, struct extent_node *en) +{ + struct extent_node *prev; + struct rb_node *node; + + node = rb_prev(en-rb_node); + if (!node) + return NULL; + + prev = rb_entry(node, struct extent_node, rb_node); + if (__is_back_mergeable(en-ei, prev-ei)) { + en-ei.fofs = prev-ei.fofs; + en-ei.blk = prev-ei.blk; + en-ei.len += prev-ei.len; + __detach_extent_node(sbi, et, prev); + return prev; + } + return NULL; +} + +static struct extent_node *__try_front_merge(struct f2fs_sb_info *sbi, + struct extent_tree *et, struct extent_node *en) +{ + struct extent_node *next; + struct rb_node *node; + + node = rb_next(en-rb_node); + if (!node) + return NULL; + + next = rb_entry(node, struct extent_node, rb_node); + if (__is_front_mergeable(en-ei, next-ei)) { + en-ei.len += next-ei.len; + __detach_extent_node(sbi, et, next); + return next; + } + return NULL; +} + +static struct extent_node *__insert_extent_tree(struct f2fs_sb_info *sbi, + struct extent_tree *et, struct extent_info *ei, + struct extent_node **den) +{ + struct rb_node **p = et-root.rb_node; + struct rb_node *parent = NULL; + struct extent_node *en; + + while (*p) { + parent = *p; + en = rb_entry(parent, struct extent_node, rb_node); + + if (ei-fofs en-ei.fofs) { + if (__is_front_mergeable(ei, en-ei)) { + f2fs_bug_on(sbi, !den); + en-ei.fofs = ei-fofs; + en-ei.blk = ei-blk; + en-ei.len += ei-len; + *den = __try_back_merge(sbi, et, en); +