[f2fs-dev] [PATCH] f2fs: remove unused cp_blkaddr in f2fs_sanity_check_ckpt

2018-07-30 Thread Junling Zheng
Remove unused cp_blkaddr in f2fs_sanity_check_ckpt().

Signed-off-by: Junling Zheng 
---
 fs/f2fs/super.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index d56bc6eb8760..6ee003e87f63 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -2297,7 +2297,7 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi)
unsigned int sit_bitmap_size, nat_bitmap_size;
unsigned int log_blocks_per_seg;
unsigned int segment_count_main;
-   unsigned int cp_pack_start_sum, cp_blkaddr, cp_payload;
+   unsigned int cp_pack_start_sum, cp_payload;
block_t user_block_count;
int i;
 
@@ -2359,7 +2359,6 @@ int f2fs_sanity_check_ckpt(struct f2fs_sb_info *sbi)
}
 
cp_pack_start_sum = __start_sum_addr(sbi);
-   cp_blkaddr = __start_cp_addr(sbi);
cp_payload = __cp_payload(sbi);
if (cp_pack_start_sum < cp_payload + 1 ||
cp_pack_start_sum > blocks_per_seg - 1 -
-- 
2.18.0


--
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 v14 00/74] Convert page cache to XArray

2018-07-30 Thread Matthew Wilcox
On Fri, Jul 27, 2018 at 11:20:35AM -0600, Ross Zwisler wrote:
> Okay, the next failure I'm hitting is with DAX + XFS + generic/344.  It
> doesn't happen every time, but I can usually recreate it within 10 iterations
> of the test.  Here's the failure:

Thanks.  I've made some progress with this; the WARNing is coming from
a vm_insert_* mkwrite call.  Inserting sufficient debugging code has
let me determine we still have a zero_pfn in the page table when we're
trying to insert a new PFN.

--
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] f2fs: avoid fi->i_gc_rwsem[WRITE] lock in f2fs_gc

2018-07-30 Thread Chao Yu
On 2018/7/30 17:08, Jaegeuk Kim wrote:
> On 07/30, Chao Yu wrote:
>> On 2018/7/30 12:18, Jaegeuk Kim wrote:
>>> On 07/30, Chao Yu wrote:
 On 2018/7/30 9:32, Jaegeuk Kim wrote:
> The f2fs_gc() called by f2fs_balance_fs() requires to be called outside of
> fi->i_gc_rwsem[WRITE], since f2fs_gc() can try to grab it in a loop.
>
> If it hits the miximum retrials in GC, let's give a chance to release
> gc_mutex for a short time in order not to go into live lock in the worst
> case.
>
> Signed-off-by: Jaegeuk Kim 
> ---
>  fs/f2fs/f2fs.h|  1 +
>  fs/f2fs/file.c| 62 ++-
>  fs/f2fs/gc.c  | 22 -
>  fs/f2fs/segment.c |  5 +++-
>  fs/f2fs/segment.h |  2 +-
>  5 files changed, 51 insertions(+), 41 deletions(-)
>
> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> index a9447c7d6570..50349780001b 100644
> --- a/fs/f2fs/f2fs.h
> +++ b/fs/f2fs/f2fs.h
> @@ -1223,6 +1223,7 @@ struct f2fs_sb_info {
>   unsigned int gc_mode;   /* current GC state */
>   /* for skip statistic */
>   unsigned long long skipped_atomic_files[2]; /* FG_GC and BG_GC */
> + unsigned long long skipped_gc_rwsem;/* FG_GC only */
>  
>   /* threshold for gc trials on pinned files */
>   u64 gc_pin_file_threshold;
> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> index 78c1bd6b8497..2b7d26ebb294 100644
> --- a/fs/f2fs/file.c
> +++ b/fs/f2fs/file.c
> @@ -1179,10 +1179,12 @@ static int __exchange_data_block(struct inode 
> *src_inode,
>   return ret;
>  }
>  
> -static int f2fs_do_collapse(struct inode *inode, pgoff_t start, pgoff_t 
> end)
> +static int f2fs_do_collapse(struct inode *inode, loff_t offset, loff_t 
> len)
>  {
>   struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
>   pgoff_t nrpages = (i_size_read(inode) + PAGE_SIZE - 1) / PAGE_SIZE;
> + pgoff_t start = offset >> PAGE_SHIFT;
> + pgoff_t end = (offset + len) >> PAGE_SHIFT;
>   int ret;
>  
>   f2fs_balance_fs(sbi, true);
> @@ -1190,14 +1192,18 @@ static int f2fs_do_collapse(struct inode *inode, 
> pgoff_t start, pgoff_t end)
>  
>   f2fs_drop_extent_tree(inode);
>  
> + /* avoid gc operation during block exchange */
> + down_write(_I(inode)->i_gc_rwsem[WRITE]);
> + truncate_pagecache(inode, offset);
>   ret = __exchange_data_block(inode, inode, end, start, nrpages - end, 
> true);
> + up_write(_I(inode)->i_gc_rwsem[WRITE]);
> +
>   f2fs_unlock_op(sbi);
>   return ret;
>  }
>  
>  static int f2fs_collapse_range(struct inode *inode, loff_t offset, 
> loff_t len)
>  {
> - pgoff_t pg_start, pg_end;
>   loff_t new_size;
>   int ret;
>  
> @@ -1212,21 +1218,13 @@ static int f2fs_collapse_range(struct inode 
> *inode, loff_t offset, loff_t len)
>   if (ret)
>   return ret;
>  
> - pg_start = offset >> PAGE_SHIFT;
> - pg_end = (offset + len) >> PAGE_SHIFT;
> -
> - /* avoid gc operation during block exchange */
> - down_write(_I(inode)->i_gc_rwsem[WRITE]);
> -
>   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;
>  
> - truncate_pagecache(inode, offset);
> -
> - ret = f2fs_do_collapse(inode, pg_start, pg_end);
> + ret = f2fs_do_collapse(inode, offset, len);
>   if (ret)
>   goto out_unlock;
>  
> @@ -1242,7 +1240,6 @@ static int f2fs_collapse_range(struct inode *inode, 
> loff_t offset, loff_t len)
>   f2fs_i_size_write(inode, new_size);
>  out_unlock:
>   up_write(_I(inode)->i_mmap_sem);
> - up_write(_I(inode)->i_gc_rwsem[WRITE]);
>   return ret;
>  }
>  
> @@ -1417,9 +1414,6 @@ static int f2fs_insert_range(struct inode *inode, 
> loff_t offset, loff_t len)
>  
>   f2fs_balance_fs(sbi, true);
>  
> - /* avoid gc operation during block exchange */
> - down_write(_I(inode)->i_gc_rwsem[WRITE]);
> -
>   down_write(_I(inode)->i_mmap_sem);
>   ret = f2fs_truncate_blocks(inode, i_size_read(inode), true);
>   if (ret)
> @@ -1430,13 +1424,15 @@ static int f2fs_insert_range(struct inode *inode, 
> loff_t offset, loff_t len)
>   if (ret)
>   goto out;
>  
> - truncate_pagecache(inode, offset);
> -
>   pg_start = offset >> PAGE_SHIFT;
>   pg_end = (offset + len) >> PAGE_SHIFT;
>   delta = pg_end - pg_start;
>   idx = (i_size_read(inode) + PAGE_SIZE - 1) / PAGE_SIZE;
>  
> + /* avoid gc operation during block exchange */
> + down_write(_I(inode)->i_gc_rwsem[WRITE]);
> + truncate_pagecache(inode, offset);
> +
>  

Re: [f2fs-dev] [PATCH] f2fs: avoid fi->i_gc_rwsem[WRITE] lock in f2fs_gc

2018-07-30 Thread Jaegeuk Kim
On 07/30, Chao Yu wrote:
> On 2018/7/30 12:18, Jaegeuk Kim wrote:
> > On 07/30, Chao Yu wrote:
> >> On 2018/7/30 9:32, Jaegeuk Kim wrote:
> >>> The f2fs_gc() called by f2fs_balance_fs() requires to be called outside of
> >>> fi->i_gc_rwsem[WRITE], since f2fs_gc() can try to grab it in a loop.
> >>>
> >>> If it hits the miximum retrials in GC, let's give a chance to release
> >>> gc_mutex for a short time in order not to go into live lock in the worst
> >>> case.
> >>>
> >>> Signed-off-by: Jaegeuk Kim 
> >>> ---
> >>>  fs/f2fs/f2fs.h|  1 +
> >>>  fs/f2fs/file.c| 62 ++-
> >>>  fs/f2fs/gc.c  | 22 -
> >>>  fs/f2fs/segment.c |  5 +++-
> >>>  fs/f2fs/segment.h |  2 +-
> >>>  5 files changed, 51 insertions(+), 41 deletions(-)
> >>>
> >>> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
> >>> index a9447c7d6570..50349780001b 100644
> >>> --- a/fs/f2fs/f2fs.h
> >>> +++ b/fs/f2fs/f2fs.h
> >>> @@ -1223,6 +1223,7 @@ struct f2fs_sb_info {
> >>>   unsigned int gc_mode;   /* current GC state */
> >>>   /* for skip statistic */
> >>>   unsigned long long skipped_atomic_files[2]; /* FG_GC and BG_GC */
> >>> + unsigned long long skipped_gc_rwsem;/* FG_GC only */
> >>>  
> >>>   /* threshold for gc trials on pinned files */
> >>>   u64 gc_pin_file_threshold;
> >>> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
> >>> index 78c1bd6b8497..2b7d26ebb294 100644
> >>> --- a/fs/f2fs/file.c
> >>> +++ b/fs/f2fs/file.c
> >>> @@ -1179,10 +1179,12 @@ static int __exchange_data_block(struct inode 
> >>> *src_inode,
> >>>   return ret;
> >>>  }
> >>>  
> >>> -static int f2fs_do_collapse(struct inode *inode, pgoff_t start, pgoff_t 
> >>> end)
> >>> +static int f2fs_do_collapse(struct inode *inode, loff_t offset, loff_t 
> >>> len)
> >>>  {
> >>>   struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
> >>>   pgoff_t nrpages = (i_size_read(inode) + PAGE_SIZE - 1) / PAGE_SIZE;
> >>> + pgoff_t start = offset >> PAGE_SHIFT;
> >>> + pgoff_t end = (offset + len) >> PAGE_SHIFT;
> >>>   int ret;
> >>>  
> >>>   f2fs_balance_fs(sbi, true);
> >>> @@ -1190,14 +1192,18 @@ static int f2fs_do_collapse(struct inode *inode, 
> >>> pgoff_t start, pgoff_t end)
> >>>  
> >>>   f2fs_drop_extent_tree(inode);
> >>>  
> >>> + /* avoid gc operation during block exchange */
> >>> + down_write(_I(inode)->i_gc_rwsem[WRITE]);
> >>> + truncate_pagecache(inode, offset);
> >>>   ret = __exchange_data_block(inode, inode, end, start, nrpages - end, 
> >>> true);
> >>> + up_write(_I(inode)->i_gc_rwsem[WRITE]);
> >>> +
> >>>   f2fs_unlock_op(sbi);
> >>>   return ret;
> >>>  }
> >>>  
> >>>  static int f2fs_collapse_range(struct inode *inode, loff_t offset, 
> >>> loff_t len)
> >>>  {
> >>> - pgoff_t pg_start, pg_end;
> >>>   loff_t new_size;
> >>>   int ret;
> >>>  
> >>> @@ -1212,21 +1218,13 @@ static int f2fs_collapse_range(struct inode 
> >>> *inode, loff_t offset, loff_t len)
> >>>   if (ret)
> >>>   return ret;
> >>>  
> >>> - pg_start = offset >> PAGE_SHIFT;
> >>> - pg_end = (offset + len) >> PAGE_SHIFT;
> >>> -
> >>> - /* avoid gc operation during block exchange */
> >>> - down_write(_I(inode)->i_gc_rwsem[WRITE]);
> >>> -
> >>>   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;
> >>>  
> >>> - truncate_pagecache(inode, offset);
> >>> -
> >>> - ret = f2fs_do_collapse(inode, pg_start, pg_end);
> >>> + ret = f2fs_do_collapse(inode, offset, len);
> >>>   if (ret)
> >>>   goto out_unlock;
> >>>  
> >>> @@ -1242,7 +1240,6 @@ static int f2fs_collapse_range(struct inode *inode, 
> >>> loff_t offset, loff_t len)
> >>>   f2fs_i_size_write(inode, new_size);
> >>>  out_unlock:
> >>>   up_write(_I(inode)->i_mmap_sem);
> >>> - up_write(_I(inode)->i_gc_rwsem[WRITE]);
> >>>   return ret;
> >>>  }
> >>>  
> >>> @@ -1417,9 +1414,6 @@ static int f2fs_insert_range(struct inode *inode, 
> >>> loff_t offset, loff_t len)
> >>>  
> >>>   f2fs_balance_fs(sbi, true);
> >>>  
> >>> - /* avoid gc operation during block exchange */
> >>> - down_write(_I(inode)->i_gc_rwsem[WRITE]);
> >>> -
> >>>   down_write(_I(inode)->i_mmap_sem);
> >>>   ret = f2fs_truncate_blocks(inode, i_size_read(inode), true);
> >>>   if (ret)
> >>> @@ -1430,13 +1424,15 @@ static int f2fs_insert_range(struct inode *inode, 
> >>> loff_t offset, loff_t len)
> >>>   if (ret)
> >>>   goto out;
> >>>  
> >>> - truncate_pagecache(inode, offset);
> >>> -
> >>>   pg_start = offset >> PAGE_SHIFT;
> >>>   pg_end = (offset + len) >> PAGE_SHIFT;
> >>>   delta = pg_end - pg_start;
> >>>   idx = (i_size_read(inode) + PAGE_SIZE - 1) / PAGE_SIZE;
> >>>  
> >>> + /* avoid gc operation during block exchange */
> >>> + down_write(_I(inode)->i_gc_rwsem[WRITE]);
> >>> + truncate_pagecache(inode, offset);
> >>> +
> >>>   while (!ret && idx > pg_start) {
> >>>   

Re: [f2fs-dev] [PATCH v3] fsck.f2fs: write checkpoint out of place first

2018-07-30 Thread guoweichao



On 2018/7/30 14:41, Chao Yu wrote:
> Hi Weichao,
> 
> On 2018/7/30 18:46, Weichao Guo wrote:
> 
> Could you check and adjust your server's date, it looks like we are receiving
> patch from future. ;)
> 
Oh, I didn't notice that. It will not happen any more.

Thanks,

>> We may encounter both checkpoints invalid in such a case:
>> 1. write checkpoint A, B, C;
>> 2. sudden power-cut during write checkpoint D;
>> 3. fsck changes the total block count of checkpoint C;
>> 4. sudden power-cut during fsck write checkpoint C in place
>>
>>  -   -
>> |  ver C  | |  ver D  |
>> |   ...   | |   ...   |
>> | content | | content |
>> |   ...   | |   ...   |
>> |  ver C  | | |
>> |  ver A  | |  ver B  |
>>  -   -
>>
>> As the total # of checkpoint C is changed, an old cp block
>> like ver A or an invalid cp block may be referenced.
>> To avoid both checkpoints invalid, and considering fsck should
>> not update the checkpoint version, fsck could write checkpoint
>> out of place first and then write checkpoint in place. This
>> makes sure the file system is fixed by fsck and at least one
>> of the two checkpoints is valid.
>>
>> Signed-off-by: Weichao Guo 
> 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


Re: [f2fs-dev] [PATCH v3] fsck.f2fs: write checkpoint out of place first

2018-07-30 Thread Chao Yu
Hi Weichao,

On 2018/7/30 18:46, Weichao Guo wrote:

Could you check and adjust your server's date, it looks like we are receiving
patch from future. ;)

> We may encounter both checkpoints invalid in such a case:
> 1. write checkpoint A, B, C;
> 2. sudden power-cut during write checkpoint D;
> 3. fsck changes the total block count of checkpoint C;
> 4. sudden power-cut during fsck write checkpoint C in place
> 
>  -   -
> |  ver C  | |  ver D  |
> |   ...   | |   ...   |
> | content | | content |
> |   ...   | |   ...   |
> |  ver C  | | |
> |  ver A  | |  ver B  |
>  -   -
> 
> As the total # of checkpoint C is changed, an old cp block
> like ver A or an invalid cp block may be referenced.
> To avoid both checkpoints invalid, and considering fsck should
> not update the checkpoint version, fsck could write checkpoint
> out of place first and then write checkpoint in place. This
> makes sure the file system is fixed by fsck and at least one
> of the two checkpoints is valid.
> 
> Signed-off-by: Weichao Guo 
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


Re: [f2fs-dev] [PATCH] f2fs: avoid fi->i_gc_rwsem[WRITE] lock in f2fs_gc

2018-07-30 Thread Chao Yu
On 2018/7/30 12:18, Jaegeuk Kim wrote:
> On 07/30, Chao Yu wrote:
>> On 2018/7/30 9:32, Jaegeuk Kim wrote:
>>> The f2fs_gc() called by f2fs_balance_fs() requires to be called outside of
>>> fi->i_gc_rwsem[WRITE], since f2fs_gc() can try to grab it in a loop.
>>>
>>> If it hits the miximum retrials in GC, let's give a chance to release
>>> gc_mutex for a short time in order not to go into live lock in the worst
>>> case.
>>>
>>> Signed-off-by: Jaegeuk Kim 
>>> ---
>>>  fs/f2fs/f2fs.h|  1 +
>>>  fs/f2fs/file.c| 62 ++-
>>>  fs/f2fs/gc.c  | 22 -
>>>  fs/f2fs/segment.c |  5 +++-
>>>  fs/f2fs/segment.h |  2 +-
>>>  5 files changed, 51 insertions(+), 41 deletions(-)
>>>
>>> diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
>>> index a9447c7d6570..50349780001b 100644
>>> --- a/fs/f2fs/f2fs.h
>>> +++ b/fs/f2fs/f2fs.h
>>> @@ -1223,6 +1223,7 @@ struct f2fs_sb_info {
>>> unsigned int gc_mode;   /* current GC state */
>>> /* for skip statistic */
>>> unsigned long long skipped_atomic_files[2]; /* FG_GC and BG_GC */
>>> +   unsigned long long skipped_gc_rwsem;/* FG_GC only */
>>>  
>>> /* threshold for gc trials on pinned files */
>>> u64 gc_pin_file_threshold;
>>> diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c
>>> index 78c1bd6b8497..2b7d26ebb294 100644
>>> --- a/fs/f2fs/file.c
>>> +++ b/fs/f2fs/file.c
>>> @@ -1179,10 +1179,12 @@ static int __exchange_data_block(struct inode 
>>> *src_inode,
>>> return ret;
>>>  }
>>>  
>>> -static int f2fs_do_collapse(struct inode *inode, pgoff_t start, pgoff_t 
>>> end)
>>> +static int f2fs_do_collapse(struct inode *inode, loff_t offset, loff_t len)
>>>  {
>>> struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
>>> pgoff_t nrpages = (i_size_read(inode) + PAGE_SIZE - 1) / PAGE_SIZE;
>>> +   pgoff_t start = offset >> PAGE_SHIFT;
>>> +   pgoff_t end = (offset + len) >> PAGE_SHIFT;
>>> int ret;
>>>  
>>> f2fs_balance_fs(sbi, true);
>>> @@ -1190,14 +1192,18 @@ static int f2fs_do_collapse(struct inode *inode, 
>>> pgoff_t start, pgoff_t end)
>>>  
>>> f2fs_drop_extent_tree(inode);
>>>  
>>> +   /* avoid gc operation during block exchange */
>>> +   down_write(_I(inode)->i_gc_rwsem[WRITE]);
>>> +   truncate_pagecache(inode, offset);
>>> ret = __exchange_data_block(inode, inode, end, start, nrpages - end, 
>>> true);
>>> +   up_write(_I(inode)->i_gc_rwsem[WRITE]);
>>> +
>>> f2fs_unlock_op(sbi);
>>> return ret;
>>>  }
>>>  
>>>  static int f2fs_collapse_range(struct inode *inode, loff_t offset, loff_t 
>>> len)
>>>  {
>>> -   pgoff_t pg_start, pg_end;
>>> loff_t new_size;
>>> int ret;
>>>  
>>> @@ -1212,21 +1218,13 @@ static int f2fs_collapse_range(struct inode *inode, 
>>> loff_t offset, loff_t len)
>>> if (ret)
>>> return ret;
>>>  
>>> -   pg_start = offset >> PAGE_SHIFT;
>>> -   pg_end = (offset + len) >> PAGE_SHIFT;
>>> -
>>> -   /* avoid gc operation during block exchange */
>>> -   down_write(_I(inode)->i_gc_rwsem[WRITE]);
>>> -
>>> 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;
>>>  
>>> -   truncate_pagecache(inode, offset);
>>> -
>>> -   ret = f2fs_do_collapse(inode, pg_start, pg_end);
>>> +   ret = f2fs_do_collapse(inode, offset, len);
>>> if (ret)
>>> goto out_unlock;
>>>  
>>> @@ -1242,7 +1240,6 @@ static int f2fs_collapse_range(struct inode *inode, 
>>> loff_t offset, loff_t len)
>>> f2fs_i_size_write(inode, new_size);
>>>  out_unlock:
>>> up_write(_I(inode)->i_mmap_sem);
>>> -   up_write(_I(inode)->i_gc_rwsem[WRITE]);
>>> return ret;
>>>  }
>>>  
>>> @@ -1417,9 +1414,6 @@ static int f2fs_insert_range(struct inode *inode, 
>>> loff_t offset, loff_t len)
>>>  
>>> f2fs_balance_fs(sbi, true);
>>>  
>>> -   /* avoid gc operation during block exchange */
>>> -   down_write(_I(inode)->i_gc_rwsem[WRITE]);
>>> -
>>> down_write(_I(inode)->i_mmap_sem);
>>> ret = f2fs_truncate_blocks(inode, i_size_read(inode), true);
>>> if (ret)
>>> @@ -1430,13 +1424,15 @@ static int f2fs_insert_range(struct inode *inode, 
>>> loff_t offset, loff_t len)
>>> if (ret)
>>> goto out;
>>>  
>>> -   truncate_pagecache(inode, offset);
>>> -
>>> pg_start = offset >> PAGE_SHIFT;
>>> pg_end = (offset + len) >> PAGE_SHIFT;
>>> delta = pg_end - pg_start;
>>> idx = (i_size_read(inode) + PAGE_SIZE - 1) / PAGE_SIZE;
>>>  
>>> +   /* avoid gc operation during block exchange */
>>> +   down_write(_I(inode)->i_gc_rwsem[WRITE]);
>>> +   truncate_pagecache(inode, offset);
>>> +
>>> while (!ret && idx > pg_start) {
>>> nr = idx - pg_start;
>>> if (nr > delta)
>>> @@ -1450,6 +1446,7 @@ static int f2fs_insert_range(struct inode *inode, 
>>> loff_t offset, loff_t len)
>>>