1. 05 3月, 2010 1 次提交
    • J
      ext4: use ext4_get_block_write in buffer write · 744692dc
      Jiaying Zhang 提交于
      Allocate uninitialized extent before ext4 buffer write and
      convert the extent to initialized after io completes.
      The purpose is to make sure an extent can only be marked
      initialized after it has been written with new data so
      we can safely drop the i_mutex lock in ext4 DIO read without
      exposing stale data. This helps to improve multi-thread DIO
      read performance on high-speed disks.
      
      Skip the nobh and data=journal mount cases to make things simple for now.
      Signed-off-by: NJiaying Zhang <jiayingz@google.com>
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      744692dc
  2. 03 3月, 2010 1 次提交
  3. 24 2月, 2010 1 次提交
  4. 05 3月, 2010 1 次提交
  5. 16 2月, 2010 1 次提交
  6. 25 1月, 2010 1 次提交
    • T
      ext4: Use bitops to read/modify EXT4_I(inode)->i_state · 19f5fb7a
      Theodore Ts'o 提交于
      At several places we modify EXT4_I(inode)->i_state without holding
      i_mutex (ext4_release_file, ext4_bmap, ext4_journalled_writepage,
      ext4_do_update_inode, ...). These modifications are racy and we can
      lose updates to i_state. So convert handling of i_state to use bitops
      which are atomic.
      
      Cc: Jan Kara <jack@suse.cz>
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      19f5fb7a
  7. 05 2月, 2010 1 次提交
  8. 15 1月, 2010 1 次提交
  9. 25 1月, 2010 1 次提交
  10. 01 1月, 2010 1 次提交
    • T
      ext4: Calculate metadata requirements more accurately · 9d0be502
      Theodore Ts'o 提交于
      In the past, ext4_calc_metadata_amount(), and its sub-functions
      ext4_ext_calc_metadata_amount() and ext4_indirect_calc_metadata_amount()
      badly over-estimated the number of metadata blocks that might be
      required for delayed allocation blocks.  This didn't matter as much
      when functions which managed the reserved metadata blocks were more
      aggressive about dropping reserved metadata blocks as delayed
      allocation blocks were written, but unfortunately they were too
      aggressive.  This was fixed in commit 0637c6f4, but as a result the
      over-estimation by ext4_calc_metadata_amount() would lead to reserving
      2-3 times the number of pending delayed allocation blocks as
      potentially required metadata blocks.  So if there are 1 megabytes of
      blocks which have been not yet been allocation, up to 3 megabytes of
      space would get reserved out of the user's quota and from the file
      system free space pool until all of the inode's data blocks have been
      allocated.
      
      This commit addresses this problem by much more accurately estimating
      the number of metadata blocks that will be required.  It will still
      somewhat over-estimate the number of blocks needed, since it must make
      a worst case estimate not knowing which physical blocks will be
      needed, but it is much more accurate than before.
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      9d0be502
  11. 30 12月, 2009 1 次提交
  12. 14 12月, 2009 1 次提交
  13. 10 12月, 2009 1 次提交
    • T
      ext4: Fix potential fiemap deadlock (mmap_sem vs. i_data_sem) · fab3a549
      Theodore Ts'o 提交于
      Fix the following potential circular locking dependency between
      mm->mmap_sem and ei->i_data_sem:
      
          =======================================================
          [ INFO: possible circular locking dependency detected ]
          2.6.32-04115-gec044c5 #37
          -------------------------------------------------------
          ureadahead/1855 is trying to acquire lock:
           (&mm->mmap_sem){++++++}, at: [<ffffffff81107224>] might_fault+0x5c/0xac
      
          but task is already holding lock:
           (&ei->i_data_sem){++++..}, at: [<ffffffff811be1fd>] ext4_fiemap+0x11b/0x159
      
          which lock already depends on the new lock.
      
          the existing dependency chain (in reverse order) is:
      
          -> #1 (&ei->i_data_sem){++++..}:
                 [<ffffffff81099bfa>] __lock_acquire+0xb67/0xd0f
                 [<ffffffff81099e7e>] lock_acquire+0xdc/0x102
                 [<ffffffff81516633>] down_read+0x51/0x84
                 [<ffffffff811a2414>] ext4_get_blocks+0x50/0x2a5
                 [<ffffffff811a3453>] ext4_get_block+0xab/0xef
                 [<ffffffff81154f39>] do_mpage_readpage+0x198/0x48d
                 [<ffffffff81155360>] mpage_readpages+0xd0/0x114
                 [<ffffffff811a104b>] ext4_readpages+0x1d/0x1f
                 [<ffffffff810f8644>] __do_page_cache_readahead+0x12f/0x1bc
                 [<ffffffff810f86f2>] ra_submit+0x21/0x25
                 [<ffffffff810f0cfd>] filemap_fault+0x19f/0x32c
                 [<ffffffff81107b97>] __do_fault+0x55/0x3a2
                 [<ffffffff81109db0>] handle_mm_fault+0x327/0x734
                 [<ffffffff8151aaa9>] do_page_fault+0x292/0x2aa
                 [<ffffffff81518205>] page_fault+0x25/0x30
                 [<ffffffff812a34d8>] clear_user+0x38/0x3c
                 [<ffffffff81167e16>] padzero+0x20/0x31
                 [<ffffffff81168b47>] load_elf_binary+0x8bc/0x17ed
                 [<ffffffff81130e95>] search_binary_handler+0xc2/0x259
                 [<ffffffff81166d64>] load_script+0x1b8/0x1cc
                 [<ffffffff81130e95>] search_binary_handler+0xc2/0x259
                 [<ffffffff8113255f>] do_execve+0x1ce/0x2cf
                 [<ffffffff81027494>] sys_execve+0x43/0x5a
                 [<ffffffff8102918a>] stub_execve+0x6a/0xc0
      
          -> #0 (&mm->mmap_sem){++++++}:
                 [<ffffffff81099aa4>] __lock_acquire+0xa11/0xd0f
                 [<ffffffff81099e7e>] lock_acquire+0xdc/0x102
                 [<ffffffff81107251>] might_fault+0x89/0xac
                 [<ffffffff81139382>] fiemap_fill_next_extent+0x95/0xda
                 [<ffffffff811bcb43>] ext4_ext_fiemap_cb+0x138/0x157
                 [<ffffffff811be069>] ext4_ext_walk_space+0x178/0x1f1
                 [<ffffffff811be21e>] ext4_fiemap+0x13c/0x159
                 [<ffffffff811390e6>] do_vfs_ioctl+0x348/0x4d6
                 [<ffffffff811392ca>] sys_ioctl+0x56/0x79
                 [<ffffffff81028cb2>] system_call_fastpath+0x16/0x1b
      
          other info that might help us debug this:
      
          1 lock held by ureadahead/1855:
           #0:  (&ei->i_data_sem){++++..}, at: [<ffffffff811be1fd>] ext4_fiemap+0x11b/0x159
      
          stack backtrace:
          Pid: 1855, comm: ureadahead Not tainted 2.6.32-04115-gec044c5 #37
          Call Trace:
           [<ffffffff81098c70>] print_circular_bug+0xa8/0xb7
           [<ffffffff81099aa4>] __lock_acquire+0xa11/0xd0f
           [<ffffffff8102f229>] ? sched_clock+0x9/0xd
           [<ffffffff81099e7e>] lock_acquire+0xdc/0x102
           [<ffffffff81107224>] ? might_fault+0x5c/0xac
           [<ffffffff81107251>] might_fault+0x89/0xac
           [<ffffffff81107224>] ? might_fault+0x5c/0xac
           [<ffffffff81124b44>] ? __kmalloc+0x13b/0x18c
           [<ffffffff81139382>] fiemap_fill_next_extent+0x95/0xda
           [<ffffffff811bcb43>] ext4_ext_fiemap_cb+0x138/0x157
           [<ffffffff811bca0b>] ? ext4_ext_fiemap_cb+0x0/0x157
           [<ffffffff811be069>] ext4_ext_walk_space+0x178/0x1f1
           [<ffffffff811be21e>] ext4_fiemap+0x13c/0x159
           [<ffffffff81107224>] ? might_fault+0x5c/0xac
           [<ffffffff811390e6>] do_vfs_ioctl+0x348/0x4d6
           [<ffffffff8129f6d0>] ? __up_read+0x8d/0x95
           [<ffffffff81517fb5>] ? retint_swapgs+0x13/0x1b
           [<ffffffff811392ca>] sys_ioctl+0x56/0x79
           [<ffffffff81028cb2>] system_call_fastpath+0x16/0x1b
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      fab3a549
  14. 09 12月, 2009 2 次提交
  15. 23 11月, 2009 2 次提交
    • T
      ext4: call ext4_forget() from ext4_free_blocks() · e6362609
      Theodore Ts'o 提交于
      Add the facility for ext4_forget() to be called from
      ext4_free_blocks().  This simplifies the code in a large number of
      places, and centralizes most of the work of calling ext4_forget() into
      a single place.
      
      Also fix a bug in the extents migration code; it wasn't calling
      ext4_forget() when releasing the indirect blocks during the
      conversion.  As a result, if the system cashed during or shortly after
      the extents migration, and the released indirect blocks get reused as
      data blocks, the journal replay would corrupt the data blocks.  With
      this new patch, fixing this bug was as simple as adding the
      EXT4_FREE_BLOCKS_FORGET flags to the call to ext4_free_blocks().
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      Cc: "Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
      e6362609
    • T
      ext4: make sure directory and symlink blocks are revoked · 50689696
      Theodore Ts'o 提交于
      When an inode gets unlinked, the functions ext4_clear_blocks() and
      ext4_remove_blocks() call ext4_forget() for all the buffer heads
      corresponding to the deleted inode's data blocks.  If the inode is a
      directory or a symlink, the is_metadata parameter must be non-zero so
      ext4_forget() will revoke them via jbd2_journal_revoke().  Otherwise,
      if these blocks are reused for a data file, and the system crashes
      before a journal checkpoint, the journal replay could end up
      corrupting these data blocks.
      
      Thanks to Curt Wohlgemuth for pointing out potential problems in this
      area.
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      Cc: stable@kernel.org
      50689696
  16. 06 11月, 2009 1 次提交
    • M
      ext4: Fix return value of ext4_split_unwritten_extents() to fix direct I/O · ba230c3f
      Mingming 提交于
      To prepare for a direct I/O write, we need to split the unwritten
      extents before submitting the I/O.  When no extents needed to be
      split, ext4_split_unwritten_extents() was incorrectly returning 0
      instead of the size of uninitialized extents. This bug caused the
      wrong return value sent back to VFS code when it gets called from
      async IO path, leading to an unnecessary fall back to buffered IO.
      
      This bug also hid the fact that the check to see whether or not a
      split would be necessary was incorrect; we can only skip splitting the
      extent if the write completely covers the uninitialized extent.
      Signed-off-by: NMingming Cao <cmm@us.ibm.com>
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      ba230c3f
  17. 10 11月, 2009 2 次提交
  18. 30 9月, 2009 1 次提交
  19. 29 9月, 2009 2 次提交
    • M
      ext4: async direct IO for holes and fallocate support · 8d5d02e6
      Mingming Cao 提交于
      For async direct IO that covers holes or fallocate, the end_io
      callback function now queued the convertion work on workqueue but
      don't flush the work rightaway as it might take too long to afford.
      
      But when fsync is called after all the data is completed, user expects
      the metadata also being updated before fsync returns.
      
      Thus we need to flush the conversion work when fsync() is called.
      This patch keep track of a listed of completed async direct io that
      has a work queued on workqueue.  When fsync() is called, it will go
      through the list and do the conversion.
      Signed-off-by: NMingming Cao <cmm@us.ibm.com>
      8d5d02e6
    • M
      ext4: Split uninitialized extents for direct I/O · 0031462b
      Mingming Cao 提交于
      When writing into an unitialized extent via direct I/O, and the direct
      I/O doesn't exactly cover the unitialized extent, split the extent
      into uninitialized and initialized extents before submitting the I/O.
      This avoids needing to deal with an ENOSPC error in the end_io
      callback that gets used for direct I/O.
      
      When the IO is complete, the written extent will be marked as initialized.
      
      Singed-Off-By: Mingming Cao <cmm@us.ibm.com> 
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      0031462b
  20. 28 8月, 2009 1 次提交
    • T
      ext4: fix extent sanity checking code with AGGRESSIVE_TEST · 55ad63bf
      Theodore Ts'o 提交于
      The extents sanity-checking code depends on the ext4_ext_space_*()
      functions returning the maximum alloable size for eh_max; however,
      when the debugging #ifdef AGGRESSIVE_TEST is enabled to test the
      extent tree handling code, this prevents a normally created ext4
      filesystem from being mounted with the errors:
      
      Aug 26 15:43:50 bsd086 kernel: [   96.070277] EXT4-fs error (device sda8): ext4_ext_check_inode: bad header/extent in inode #8: too large eh_max - magic f30a, entries 1, max 4(3), depth 0(0)
      Aug 26 15:43:50 bsd086 kernel: [   96.070526] EXT4-fs (sda8): no journal found
      
      Bug reported by Akira Fujita.
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      55ad63bf
  21. 18 8月, 2009 1 次提交
    • J
      ext4: Fix possible deadlock between ext4_truncate() and ext4_get_blocks() · 487caeef
      Jan Kara 提交于
      During truncate we are sometimes forced to start a new transaction as
      the amount of blocks to be journaled is both quite large and hard to
      predict. So far we restarted a transaction while holding i_data_sem
      and that violates lock ordering because i_data_sem ranks below a
      transaction start (and it can lead to a real deadlock with
      ext4_get_blocks() mapping blocks in some page while having a
      transaction open).
      
      We fix the problem by dropping the i_data_sem before restarting the
      transaction and acquire it afterwards. It's slightly subtle that this
      works:
      
      1) By the time ext4_truncate() is called, all the page cache for the
      truncated part of the file is dropped so get_block() should not be
      called on it (we only have to invalidate extent cache after we
      reacquire i_data_sem because some extent from not-truncated part could
      extend also into the part we are going to truncate).
      
      2) Writes, migrate or defrag hold i_mutex so they are stopped for all
      the time of the truncate.
      
      This bug has been found and analyzed by Theodore Tso <tytso@mit.edu>.
      Signed-off-by: NJan Kara <jack@suse.cz>
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      487caeef
  22. 19 9月, 2009 1 次提交
  23. 01 9月, 2009 1 次提交
    • M
      ext4: Compile warning fix when EXT_DEBUG enabled · 84fe3bef
      Mingming 提交于
      When EXT_DEBUG is enabled I received the following compile warning on
      PPC64:
      
        CC [M]  fs/ext4/inode.o
        CC [M]  fs/ext4/extents.o
      fs/ext4/extents.c: In function ‘ext4_ext_rm_leaf’:
      fs/ext4/extents.c:2097: warning: format ‘%lu’ expects type ‘long unsigned int’, but argument 2 has type ‘ext4_lblk_t’
      fs/ext4/extents.c: In function ‘ext4_ext_get_blocks’:
      fs/ext4/extents.c:2789: warning: format ‘%u’ expects type ‘unsigned int’, but argument 4 has type ‘long unsigned int’
      fs/ext4/extents.c:2852: warning: format ‘%lu’ expects type ‘long unsigned int’, but argument 3 has type ‘ext4_lblk_t’
      fs/ext4/extents.c:2953: warning: format ‘%lu’ expects type ‘long unsigned int’, but argument 4 has type ‘unsigned int’
        CC [M]  fs/ext4/migrate.o
      
      The patch fixes compile warning.
      Signed-off-by: NMingming Cao <cmm@us.ibm.com>
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      
      Index: linux-2.6.31-rc4/fs/ext4/extents.c
      ===================================================================
      84fe3bef
  24. 18 6月, 2009 1 次提交
  25. 11 6月, 2009 1 次提交
  26. 09 6月, 2009 1 次提交
    • J
      ext4: Get rid of EXTEND_DISKSIZE flag of ext4_get_blocks_handle() · 03f5d8bc
      Jan Kara 提交于
      Get rid of EXTEND_DISKSIZE flag of ext4_get_blocks_handle(). This
      seems to be a relict from some old days and setting disksize in this
      function does not make much sense.  Currently it was set only by
      ext4_getblk().  Since the parameter has some effect only if create ==
      1, it is easy to check by grepping through the sources that the three
      callers which end up calling ext4_getblk() with create == 1
      (ext4_append, ext4_quota_write, ext4_mkdir) do the right thing and set
      disksize themselves.
      Signed-off-by: NJan Kara <jack@suse.cz>
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      03f5d8bc
  27. 06 7月, 2009 1 次提交
  28. 18 5月, 2009 2 次提交
  29. 15 5月, 2009 1 次提交
    • T
      ext4: Fix race in ext4_inode_info.i_cached_extent · 2ec0ae3a
      Theodore Ts'o 提交于
      If two CPU's simultaneously call ext4_ext_get_blocks() at the same
      time, there is nothing protecting the i_cached_extent structure from
      being used and updated at the same time.  This could potentially cause
      the wrong location on disk to be read or written to, including
      potentially causing the corruption of the block group descriptors
      and/or inode table.
      
      This bug has been in the ext4 code since almost the very beginning of
      ext4's development.  Fortunately once the data is stored in the page
      cache cache, ext4_get_blocks() doesn't need to be called, so trying to
      replicate this problem to the point where we could identify its root
      cause was *extremely* difficult.  Many thanks to Kevin Shanahan for
      working over several months to be able to reproduce this easily so we
      could finally nail down the cause of the corruption.
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      Reviewed-by: N"Aneesh Kumar K.V" <aneesh.kumar@linux.vnet.ibm.com>
      2ec0ae3a
  30. 14 5月, 2009 3 次提交
  31. 03 5月, 2009 1 次提交
  32. 02 5月, 2009 1 次提交
  33. 13 5月, 2009 1 次提交
    • A
      ext4: Mark the unwritten buffer_head as mapped during write_begin · 29fa89d0
      Aneesh Kumar K.V 提交于
      Setting BH_Unwritten buffer_heads as BH_Mapped avoids multiple
      (unnecessary) calls to get_block() during the call to the write(2)
      system call.  Setting BH_Unwritten buffer heads as BH_Mapped requires
      that the writepages() functions can handle BH_Unwritten buffer_heads.
      
      After this commit, things work as follows:
      
      ext4_ext_get_block() returns unmapped, unwritten, buffer head when
      called with create = 0 for prealloc space. This makes sure we handle
      the read path and non-delayed allocation case correctly.  Even though
      the buffer head is marked unmapped we have valid b_blocknr and b_bdev
      values in the buffer_head.
      
      ext4_da_get_block_prep() called for block resrevation will now return
      mapped, unwritten, new buffer_head for prealloc space. This avoids
      multiple calls to get_block() for write to same offset. By making such
      buffers as BH_New, we also assure that sub-block zeroing of buffered
      writes happens correctly.
      Signed-off-by: NAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      29fa89d0