Re: [f2fs-dev] [PATCH] f2fs: introduce ra_meta_pages to readahead CP/NAT/SIT pages

2014-02-07 Thread Chao Yu
Hi Kim,

 -Original Message-
 From: Jaegeuk Kim [mailto:jaegeuk@samsung.com]
 Sent: Friday, February 07, 2014 2:58 PM
 To: Chao Yu
 Cc: linux-fsde...@vger.kernel.org; linux-ker...@vger.kernel.org;
 linux-f2fs-devel@lists.sourceforge.net
 Subject: Re: [f2fs-dev] [PATCH] f2fs: introduce ra_meta_pages to readahead 
 CP/NAT/SIT pages
 
 Hi Chao,
 
 Sorry for the delay.
 When I tested this patch, a deadlock was occurred, so I couldn't afford
 to look inside in more detail.
 When I see again, there is a bug wrt blkno.
 Please see below.

You're right, and your code could fix this deadloop bug.
Thanks for the test and review. :)
I will send patch v2 later.

 
 2014-01-28 (화), 10:28 +0800, Chao Yu:
  This patch help us to cleanup the readahead code by merging 
  ra_{sit,nat}_pages
  function into ra_meta_pages.
  Additionally the new function is used to readahead cp block in
  recover_orphan_inodes.
 
  Signed-off-by: Chao Yu chao2...@samsung.com
  ---
   fs/f2fs/checkpoint.c |   78 
  ++
   fs/f2fs/f2fs.h   |   10 +++
   fs/f2fs/node.c   |   38 +---
   fs/f2fs/segment.c|   43 +---
   4 files changed, 90 insertions(+), 79 deletions(-)
 
  diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
  index 293d048..a1986c3 100644
  --- a/fs/f2fs/checkpoint.c
  +++ b/fs/f2fs/checkpoint.c
  @@ -75,6 +75,82 @@ out:
  return page;
   }
 
  +inline int get_max_meta_blks(struct f2fs_sb_info *sbi, int type)
  +{
  +   switch (type) {
  +   case META_NAT:
  +   return NM_I(sbi)-max_nid / NAT_ENTRY_PER_BLOCK;
  +   case META_SIT:
  +   return SIT_BLK_CNT(sbi);
  +   case META_CP:
  +   return 0;
  +   default:
  +   BUG();
  +   }
  +}
  +
  +/*
  + * Readahead CP/NAT/SIT pages
  + */
  +int ra_meta_pages(struct f2fs_sb_info *sbi, int start, int nrpages, int 
  type)
  +{
  +   struct address_space *mapping = sbi-meta_inode-i_mapping;
 
   We don't need to do this. Instead, we can use META_MAPPING(sbi) below.
 
  +   struct page *page;
  +   block_t blk_addr, prev_blk_addr = 0;
  +   int blkno = start;
  +   int max_blks = get_max_meta_blks(sbi, type);
 
   block_t prev_blk_addr = 0;
   struct page *page;
   int blkno = start;
   int max_blks = get_max_meta_blks(sbi, type);
 
  +   struct f2fs_io_info fio = {
  +   .type = META,
  +   .rw = READ_SYNC | REQ_META | REQ_PRIO
  +   };
  +
  +   for (blkno = start; blkno  start + nrpages; blkno++) {
 
   for (; nrpages--  0; blkno++) {
   block_t blk_addr;
 
  -- In the case of META_NAT, blkno becomes 0 if it hits max_blks.
  So, we should not use *blkno  start + nrpages*.
 
  +
  +   switch (type) {
  +   case META_NAT:
  +   /* get nat block addr */
  +   if (unlikely(blkno = max_blks))
  +   blkno = 0;
  +   blk_addr = current_nat_addr(sbi,
  +   blkno * NAT_ENTRY_PER_BLOCK);
  +   break;
  +   case META_SIT:
  +   /* get sit block addr */
  +   if (unlikely(blkno = max_blks))
  +   goto out;
  +   blk_addr = current_sit_addr(sbi,
  +   blkno * SIT_ENTRY_PER_BLOCK);
  +   if (blkno != start  prev_blk_addr + 1 != blk_addr)
  +   goto out;
  +   prev_blk_addr = blk_addr;
  +   break;
  +   case META_CP:
  +   /* get cp block addr */
  +   blk_addr = blkno;
  +   break;
  +   default:
  +   BUG();
  +   }
  +
  +   page = grab_cache_page(mapping, blk_addr);
 
   page = grab_cache_page(META_MAPPING(sbi), blk_addr);
 
  +   if (!page)
  +   continue;
  +   if (PageUptodate(page)) {
  +   mark_page_accessed(page);
  +   f2fs_put_page(page, 1);
  +   continue;
  +   }
  +
  +   f2fs_submit_page_mbio(sbi, page, blk_addr, fio);
  +   mark_page_accessed(page);
  +   f2fs_put_page(page, 0);
  +   }
  +out:
  +   f2fs_submit_merged_bio(sbi, META, READ);
  +   return blkno - start;
  +}
  +
   static int f2fs_write_meta_page(struct page *page,
  struct writeback_control *wbc)
   {
  @@ -285,6 +361,8 @@ void recover_orphan_inodes(struct f2fs_sb_info *sbi)
  start_blk = __start_cp_addr(sbi) + 1;
  orphan_blkaddr = __start_sum_addr(sbi) - 1;
 
  +   ra_meta_pages(sbi, start_blk, orphan_blkaddr, META_CP);
  +
  for (i = 0; i  orphan_blkaddr; i++) {
  struct page *page = get_meta_page(sbi, start_blk + i);
  struct f2fs_orphan_block *orphan_blk;
  diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h

Re: [f2fs-dev] [PATCH] f2fs: introduce ra_meta_pages to readahead CP/NAT/SIT pages

2014-02-06 Thread Jaegeuk Kim
Hi Chao,

Sorry for the delay.
When I tested this patch, a deadlock was occurred, so I couldn't afford
to look inside in more detail.
When I see again, there is a bug wrt blkno.
Please see below.

2014-01-28 (화), 10:28 +0800, Chao Yu:
 This patch help us to cleanup the readahead code by merging ra_{sit,nat}_pages
 function into ra_meta_pages.
 Additionally the new function is used to readahead cp block in
 recover_orphan_inodes.
 
 Signed-off-by: Chao Yu chao2...@samsung.com
 ---
  fs/f2fs/checkpoint.c |   78 
 ++
  fs/f2fs/f2fs.h   |   10 +++
  fs/f2fs/node.c   |   38 +---
  fs/f2fs/segment.c|   43 +---
  4 files changed, 90 insertions(+), 79 deletions(-)
 
 diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c
 index 293d048..a1986c3 100644
 --- a/fs/f2fs/checkpoint.c
 +++ b/fs/f2fs/checkpoint.c
 @@ -75,6 +75,82 @@ out:
   return page;
  }
  
 +inline int get_max_meta_blks(struct f2fs_sb_info *sbi, int type)
 +{
 + switch (type) {
 + case META_NAT:
 + return NM_I(sbi)-max_nid / NAT_ENTRY_PER_BLOCK;
 + case META_SIT:
 + return SIT_BLK_CNT(sbi);
 + case META_CP:
 + return 0;
 + default:
 + BUG();
 + }
 +}
 +
 +/*
 + * Readahead CP/NAT/SIT pages
 + */
 +int ra_meta_pages(struct f2fs_sb_info *sbi, int start, int nrpages, int type)
 +{
 + struct address_space *mapping = sbi-meta_inode-i_mapping;

We don't need to do this. Instead, we can use META_MAPPING(sbi) below.

 + struct page *page;
 + block_t blk_addr, prev_blk_addr = 0;
 + int blkno = start;
 + int max_blks = get_max_meta_blks(sbi, type);

block_t prev_blk_addr = 0;
struct page *page;
int blkno = start;
int max_blks = get_max_meta_blks(sbi, type);

 + struct f2fs_io_info fio = {
 + .type = META,
 + .rw = READ_SYNC | REQ_META | REQ_PRIO
 + };
 +
 + for (blkno = start; blkno  start + nrpages; blkno++) {

for (; nrpages--  0; blkno++) {
block_t blk_addr;

 -- In the case of META_NAT, blkno becomes 0 if it hits max_blks.
 So, we should not use *blkno  start + nrpages*.

 +
 + switch (type) {
 + case META_NAT:
 + /* get nat block addr */
 + if (unlikely(blkno = max_blks))
 + blkno = 0;
 + blk_addr = current_nat_addr(sbi,
 + blkno * NAT_ENTRY_PER_BLOCK);
 + break;
 + case META_SIT:
 + /* get sit block addr */
 + if (unlikely(blkno = max_blks))
 + goto out;
 + blk_addr = current_sit_addr(sbi,
 + blkno * SIT_ENTRY_PER_BLOCK);
 + if (blkno != start  prev_blk_addr + 1 != blk_addr)
 + goto out;
 + prev_blk_addr = blk_addr;
 + break;
 + case META_CP:
 + /* get cp block addr */
 + blk_addr = blkno;
 + break;
 + default:
 + BUG();
 + }
 +
 + page = grab_cache_page(mapping, blk_addr);

page = grab_cache_page(META_MAPPING(sbi), blk_addr);

 + if (!page)
 + continue;
 + if (PageUptodate(page)) {
 + mark_page_accessed(page);
 + f2fs_put_page(page, 1);
 + continue;
 + }
 +
 + f2fs_submit_page_mbio(sbi, page, blk_addr, fio);
 + mark_page_accessed(page);
 + f2fs_put_page(page, 0);
 + }
 +out:
 + f2fs_submit_merged_bio(sbi, META, READ);
 + return blkno - start;
 +}
 +
  static int f2fs_write_meta_page(struct page *page,
   struct writeback_control *wbc)
  {
 @@ -285,6 +361,8 @@ void recover_orphan_inodes(struct f2fs_sb_info *sbi)
   start_blk = __start_cp_addr(sbi) + 1;
   orphan_blkaddr = __start_sum_addr(sbi) - 1;
  
 + ra_meta_pages(sbi, start_blk, orphan_blkaddr, META_CP);
 +
   for (i = 0; i  orphan_blkaddr; i++) {
   struct page *page = get_meta_page(sbi, start_blk + i);
   struct f2fs_orphan_block *orphan_blk;
 diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h
 index af51a0b..69ffc1b 100644
 --- a/fs/f2fs/f2fs.h
 +++ b/fs/f2fs/f2fs.h
 @@ -88,6 +88,15 @@ enum {
   SIT_BITMAP
  };
  
 +/*
 + * For CP/NAT/SIT readahead
 + */
 +enum {
 + META_CP,
 + META_NAT,
 + META_SIT
 +};
 +
  /* for the list of orphan inodes */
  struct orphan_inode_entry {
   struct list_head list;  /* list head */
 @@ -1158,6 +1167,7 @@ void destroy_segment_manager_caches(void);
   */
  struct page *grab_meta_page(struct