1. 06 Jan, 2014 7 commits
    • shifei10.ge's avatar
      f2fs: fix truncate_partial_nodes bug · a225dca3
      shifei10.ge authored
      The truncate_partial_nodes puts pages incorrectly in the following two cases.
      Note that the value for argc 'depth' can only be 2 or 3.
      Please see truncate_inode_blocks() and truncate_partial_nodes().
      
      1) An err is occurred in the first 'for' loop
        When err is occurred with depth = 2, pages[0] is invalid, so this page doesn't
        need to be put. There is no problem, however, when depth is 3, it doesn't put
        the pages correctly where pages[0] is valid and pages[1] is invalid.
        In this case, depth is set to 2 (ref to statemnt depth = i + 1), and then
        'goto fail'.
        In label 'fail', for (i = depth - 3; i >= 0; i--) cannot meet the condition
        because i = -1, so pages[0] cann't be put.
      
      2) An err happened in the second 'for' loop
        Now we've got pages[0] with depth = 2, or we've got pages[0] and pages[1]
        with depth = 3. When an err is detected, we need 'goto fail' to put such
        the pages.
        When depth is 2, in label 'fail', for (i = depth - 3; i >= 0; i--) cann't
        meet the condition because i = -1, so pages[0] cann't be put.
        When depth is 3, in label 'fail', for (i = depth - 3; i >= 0; i--) can
        only put pages[0], pages[1] also cann't be put.
      
      Note that 'depth' has been changed before first 'goto fail' (ref to statemnt
      depth = i + 1), so passing this modified 'depth' to the tracepoint,
      trace_f2fs_truncate_partial_nodes, is also incorrect.
      Signed-off-by: default avatarShifei Ge <shifei10.ge@samsung.com>
      [Jaegeuk Kim: modify the description and fix one bug]
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk.kim@samsung.com>
      a225dca3
    • Jaegeuk Kim's avatar
      f2fs: handle errors correctly during f2fs_reserve_block · a8865372
      Jaegeuk Kim authored
      The get_dnode_of_data nullifies inode and node page when error is occurred.
      
      There are two cases that passes inode page into get_dnode_of_data().
      
      1. make_empty_dir()
          -> get_new_data_page()
            -> f2fs_reserve_block(ipage)
      	-> get_dnode_of_data()
      
      2. f2fs_convert_inline_data()
          -> __f2fs_convert_inline_data()
            -> f2fs_reserve_block(ipage)
      	-> get_dnode_of_data()
      
      This patch adds correct error handling codes when get_dnode_of_data() returns
      an error.
      
      At first, f2fs_reserve_block() calls f2fs_put_dnode() whenever reserve_new_block
      returns an error.
      So, the rule of f2fs_reserve_block() is to nullify inode page when there is any
      error internally.
      
      Finally, two callers of f2fs_reserve_block() should call f2fs_put_dnode()
      appropriately if they got an error since successful f2fs_reserve_block().
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk.kim@samsung.com>
      a8865372
    • Jaegeuk Kim's avatar
      f2fs: add inline_data recovery routine · 1e1bb4ba
      Jaegeuk Kim authored
      This patch adds a inline_data recovery routine with the following policy.
      
      [prev.] [next] of inline_data flag
         o       o  -> recover inline_data
         o       x  -> remove inline_data, and then recover data blocks
         x       o  -> remove inline_data, and then recover inline_data
         x       x  -> recover data blocks
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk.kim@samsung.com>
      1e1bb4ba
    • Jaegeuk Kim's avatar
      f2fs: add the number of inline_data files to status info · 0dbdc2ae
      Jaegeuk Kim authored
      This patch adds the number of inline_data files into the status information.
      Note that the number is reset whenever the filesystem is newly mounted.
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk.kim@samsung.com>
      0dbdc2ae
    • Jaegeuk Kim's avatar
      f2fs: refactor f2fs_convert_inline_data · 9e09fc85
      Jaegeuk Kim authored
      Change log from v1:
       o handle NULL pointer of grab_cache_page_write_begin() pointed by Chao Yu.
      
      This patch refactors f2fs_convert_inline_data to check a couple of conditions
      internally for deciding whether it needs to convert inline_data or not.
      
      So, the new f2fs_convert_inline_data initially checks:
      1) f2fs_has_inline_data(), and
      2) the data size to be changed.
      
      If the inode has inline_data but the size to fill is less than MAX_INLINE_DATA,
      then we don't need to convert the inline_data with data allocation.
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk.kim@samsung.com>
      9e09fc85
    • Jaegeuk Kim's avatar
      f2fs: call f2fs_put_page at the error case · 26f466f4
      Jaegeuk Kim authored
      In f2fs_write_begin(), if f2fs_conver_inline_data() returns an error like
      -ENOSPC, f2fs should call f2fs_put_page().
      Otherwise, it is remained as a locked page, resulting in the following bug.
      
      [<ffffffff8114657e>] sleep_on_page+0xe/0x20
      [<ffffffff81146567>] __lock_page+0x67/0x70
      [<ffffffff81157d08>] truncate_inode_pages_range+0x368/0x5d0
      [<ffffffff81157ff5>] truncate_inode_pages+0x15/0x20
      [<ffffffff8115804b>] truncate_pagecache+0x4b/0x70
      [<ffffffff81158082>] truncate_setsize+0x12/0x20
      [<ffffffffa02a1842>] f2fs_setattr+0x72/0x270 [f2fs]
      [<ffffffff811cdae3>] notify_change+0x213/0x400
      [<ffffffff811ab376>] do_truncate+0x66/0xa0
      [<ffffffff811ab541>] vfs_truncate+0x191/0x1b0
      [<ffffffff811ab5bc>] do_sys_truncate+0x5c/0xa0
      [<ffffffff811ab78e>] SyS_truncate+0xe/0x10
      [<ffffffff81756052>] system_call_fastpath+0x16/0x1b
      [<ffffffffffffffff>] 0xffffffffffffffff
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk.kim@samsung.com>
      26f466f4
    • Jaegeuk Kim's avatar
      f2fs: convert inline_data for punch_hole · 8230a0a4
      Jaegeuk Kim authored
      In the punch_hole(), let's convert inline_data all the time for simplicity and
      to avoid potential deadlock conditions.
      It is pretty much not a big deal to do this.
      Reviewed-by: default avatarChao Yu <chao2.yu@samsung.com>
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk.kim@samsung.com>
      8230a0a4
  2. 27 Dec, 2013 1 commit
  3. 26 Dec, 2013 8 commits
    • Huajun Li's avatar
      f2fs: update f2fs Documentation · e4024e86
      Huajun Li authored
      This patch describes the inline_data support in f2fs document.
      Signed-off-by: default avatarHuajun Li <huajun.li@intel.com>
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk.kim@samsung.com>
      e4024e86
    • Huajun Li's avatar
      f2fs: handle inline data operations · 9ffe0fb5
      Huajun Li authored
      Hook inline data read/write, truncate, fallocate, setattr, etc.
      
      Files need meet following 2 requirement to inline:
       1) file size is not greater than MAX_INLINE_DATA;
       2) file doesn't pre-allocate data blocks by fallocate().
      
      FI_INLINE_DATA will not be set while creating a new regular inode because
      most of the files are bigger than ~3.4K. Set FI_INLINE_DATA only when
      data is submitted to block layer, ranther than set it while creating a new
      inode, this also avoids converting data from inline to normal data block
      and vice versa.
      
      While writting inline data to inode block, the first data block should be
      released if the file has a block indexed by i_addr[0].
      
      On the other hand, when a file operation is appied to a file with inline
      data, we need to test if this file can remain inline by doing this
      operation, otherwise it should be convert into normal file by reserving
      a new data block, copying inline data to this new block and clear
      FI_INLINE_DATA flag. Because reserve a new data block here will make use
      of i_addr[0], if we save inline data in i_addr[0..872], then the first
      4 bytes would be overwriten. This problem can be avoided simply by
      not using i_addr[0] for inline data.
      Signed-off-by: default avatarHuajun Li <huajun.li@intel.com>
      Signed-off-by: default avatarHaicheng Li <haicheng.li@linux.intel.com>
      Signed-off-by: default avatarWeihong Xu <weihong.xu@intel.com>
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk.kim@samsung.com>
      9ffe0fb5
    • Huajun Li's avatar
      f2fs: key functions to handle inline data · e18c65b2
      Huajun Li authored
      Functions to implement inline data read/write, and move inline data to
      normal data block when file size exceeds inline data limitation.
      Signed-off-by: default avatarHuajun Li <huajun.li@intel.com>
      Signed-off-by: default avatarHaicheng Li <haicheng.li@linux.intel.com>
      Signed-off-by: default avatarWeihong Xu <weihong.xu@intel.com>
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk.kim@samsung.com>
      e18c65b2
    • Gu Zheng's avatar
      f2fs: convert max_orphans to a field of f2fs_sb_info · 0d47c1ad
      Gu Zheng authored
      Previously, we need to calculate the max orphan num when we try to acquire an
      orphan inode, but it's a stable value since the super block was inited. So
      converting it to a field of f2fs_sb_info and use it directly when needed seems
      a better choose.
      Signed-off-by: default avatarGu Zheng <guz.fnst@cn.fujitsu.com>
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk.kim@samsung.com>
      0d47c1ad
    • Jaegeuk Kim's avatar
      f2fs: check the blocksize before calling generic_direct_IO path · 944fcfc1
      Jaegeuk Kim authored
      The f2fs supports 4KB block size. If user requests dwrite with under 4KB data,
      it allocates a new 4KB data block.
      However, f2fs doesn't add zero data into the untouched data area inside the
      newly allocated data block.
      
      This incurs an error during the xfstest #263 test as follow.
      
      263 12s ... [failed, exit status 1] - output mismatch (see 263.out.bad)
      	--- 263.out	2013-03-09 03:37:15.043967603 +0900
      	+++ 263.out.bad	2013-12-27 04:20:39.230203114 +0900
      	@@ -1,3 +1,976 @@
      	QA output created by 263
      	fsx -N 10000 -o 8192 -l 500000 -r PSIZE -t BSIZE -w BSIZE -Z
      	-fsx -N 10000 -o 128000 -l 500000 -r PSIZE -t BSIZE -w BSIZE -Z
      	+fsx -N 10000 -o 8192 -l 500000 -r PSIZE -t BSIZE -w BSIZE -Z
      	+truncating to largest ever: 0x12a00
      	+truncating to largest ever: 0x75400
      	+fallocating to largest ever: 0x79cbf
      	...
      	(Run 'diff -u 263.out 263.out.bad' to see the entire diff)
      	Ran: 263
      	Failures: 263
      	Failed 1 of 1 tests
      
      It turns out that, when the test tries to write 2KB data with dio, the new dio
      path allocates 4KB data block without filling zero data inside the remained 2KB
      area. Finally, the output file contains a garbage data for that region.
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk.kim@samsung.com>
      944fcfc1
    • Jaegeuk Kim's avatar
      f2fs: should put the dnode when NEW_ADDR is detected · 1ec79083
      Jaegeuk Kim authored
      When get_dnode_of_data() in get_data_block() returns a successful dnode, we
      should put the dnode.
      But, previously, if its data block address is equal to NEW_ADDR, we didn't do
      that, resulting in a deadlock condition.
      So, this patch splits original error conditions with this case, and then calls
      f2fs_put_dnode before finishing the function.
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk.kim@samsung.com>
      1ec79083
    • Jaegeuk Kim's avatar
      f2fs: introduce F2FS_INODE macro to get f2fs_inode · 58bfaf44
      Jaegeuk Kim authored
      This patch introduces F2FS_INODE that returns struct f2fs_inode * from the inode
      page.
      By using this macro, we can remove unnecessary casting codes like below.
      
         struct f2fs_inode *ri = &F2FS_NODE(inode_page)->i;
      -> struct f2fs_inode *ri = F2FS_INODE(inode_page);
      Reviewed-by: default avatarChao Yu <chao2.yu@samsung.com>
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk.kim@samsung.com>
      58bfaf44
    • Chao Yu's avatar
      f2fs: check filename length in recover_dentry · d96b1431
      Chao Yu authored
      In current flow, we will get Null return value of f2fs_find_entry in
      recover_dentry when name.len is bigger than F2FS_NAME_LEN, and then we
      still add this inode into its dir entry.
      To avoid this situation, we must check filename length before we use it.
      
      Another point is that we could remove the code of checking filename length
      In f2fs_find_entry, because f2fs_lookup will be called previously to ensure of
      validity of filename length.
      
      V2:
       o add WARN_ON() as Jaegeuk Kim suggested.
      Signed-off-by: default avatarChao Yu <chao2.yu@samsung.com>
      Signed-off-by: default avatarJaegeuk Kim <jaegeuk.kim@samsung.com>
      d96b1431
  4. 23 Dec, 2013 24 commits