1. 10 9月, 2011 8 次提交
  2. 07 9月, 2011 2 次提交
    • A
      ext4: fix partial page writes · 02fac129
      Allison Henderson 提交于
      While running extended fsx tests to verify the preceeding patches,
      a similar bug was also found in the write operation
      
      When ever a write operation begins or ends in a hole,
      or extends EOF, the partial page contained in the hole
      or beyond EOF needs to be zeroed out.
      
      To correct this the new ext4_discard_partial_page_buffers_no_lock
      routine is used to zero out the partial page, but only for buffer
      heads that are already unmapped.
      Signed-off-by: NAllison Henderson <achender@linux.vnet.ibm.com>
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      02fac129
    • A
      ext4: fix fsx truncate failure · 189e868f
      Allison Henderson 提交于
      While running extended fsx tests to verify the first
      two patches, a similar bug was also found in the
      truncate operation.
      
      This bug happens because the truncate routine only zeros
      the unblock aligned portion of the last page.  This means
      that the block aligned portions of the page appearing after
      i_size are left unzeroed, and the buffer heads still mapped.
      
      This bug is corrected by using ext4_discard_partial_page_buffers
      in the truncate routine to zero the partial page and unmap
      the buffer headers.
      Signed-off-by: NAllison Henderson <achender@linux.vnet.ibm.com>
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      189e868f
  3. 06 9月, 2011 1 次提交
    • T
      ext4: only call ext4_jbd2_file_inode when an inode has been extended · decbd919
      Theodore Ts'o 提交于
      In delayed allocation mode, it's important to only call
      ext4_jbd2_file_inode when the file has been extended.  This is
      necessary to avoid a race which first got introduced in commit
      678aaf48, but which was made much more common with the introduction
      of the "punch hole" functionality.  (Especially when dioread_nolock
      was enabled; when I could reliably reproduce this problem with
      xfstests #74.)
      
      The race is this: If while trying to writeback a delayed allocation
      inode, there is a need to map delalloc blocks, and we run out of space
      in the journal, *and* at the same time the inode is already on the
      committing transaction's t_inode_list (because for example while doing
      the punch hole operation, ext4_jbd2_file_inode() is called), then the
      commit operation will wait for the inode to finish all of its pending
      writebacks by calling filemap_fdatawait(), but since that inode has
      one or more pages with the PageWriteback flag set, the commit
      operation will wait forever, and the so the writeback of the inode can
      never take place, and the kjournald thread and the writeback thread
      end up waiting for each other --- forever.
      
      It's important at this point to recall why an inode is placed on the
      t_inode_list; it is to provide the data=ordered guarantees that we
      don't end up exposing stale data.  In the case where we are truncating
      or punching a hole in the inode, there is no possibility that stale
      data could be exposed in the first place, so we don't need to put the
      inode on the t_inode_list!
      
      The right long-term fix is to get rid of data=ordered mode altogether,
      and only update the extent tree or indirect blocks after the data has
      been written.  Until then, this change will also avoid some
      unnecessary waiting in the commit operation.
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      Cc: Allison Henderson <achender@linux.vnet.ibm.com>
      Cc: Jan Kara <jack@suse.cz>
      decbd919
  4. 04 9月, 2011 2 次提交
    • T
      jbd2: add debugging information to jbd2_journal_dirty_metadata() · 9ea7a0df
      Theodore Ts'o 提交于
      Add debugging information in case jbd2_journal_dirty_metadata() is
      called with a buffer_head which didn't have
      jbd2_journal_get_write_access() called on it, or if the journal_head
      has the wrong transaction in it.  In addition, return an error code.
      This won't change anything for ocfs2, which will BUG_ON() the non-zero
      exit code.
      
      For ext4, the caller of this function is ext4_handle_dirty_metadata(),
      and on seeing a non-zero return code, will call __ext4_journal_stop(),
      which will print the function and line number of the (buggy) calling
      function and abort the journal.  This will allow us to recover instead
      of bug halting, which is better from a robustness and reliability
      point of view.
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      9ea7a0df
    • T
      ext4: improve handling of conflicting mount options · 56889787
      Theodore Ts'o 提交于
      If the user explicitly specifies conflicting mount options for
      delalloc or dioread_nolock and data=journal, fail the mount, instead
      of printing a warning and continuing (since many user's won't look at
      dmesg and notice the warning).
      
      Also, print a single warning that data=journal implies that delayed
      allocation is not on by default (since it's not supported), and
      furthermore that O_DIRECT is not supported.  Improve the text in
      Documentation/filesystems/ext4.txt so this is clear there as well.
      
      Similarly, if the dioread_nolock mount option is specified when the
      file system block size != PAGE_SIZE, fail the mount instead of
      printing a warning message and ignoring the mount option.
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      56889787
  5. 03 9月, 2011 3 次提交
    • A
      ext4: fix 2nd xfstests 127 punch hole failure · 2be4751b
      Allison Henderson 提交于
      This patch fixes a second punch hole bug found by xfstests 127.
      
      This bug happens because punch hole needs to flush the pages
      of the hole to avoid race conditions.  But if the end of the
      hole is in the same page as i_size, the buffer heads beyond
      i_size need to be unmapped and the page needs to be zeroed
      after it is flushed.
      
      To correct this, the new ext4_discard_partial_page_buffers
      routine is used to zero and unmap the partial page
      beyond i_size if the end of the hole appears in the same
      page as i_size.
      
      The code has also been optimized to set the end of the hole
      to the page after i_size if the specified hole exceeds i_size,
      and the code that flushes the pages has been simplified.
      Signed-off-by: NAllison Henderson <achender@linux.vnet.ibm.com>
      2be4751b
    • A
      ext4: fix xfstests 75, 112, 127 punch hole failure · ba06208a
      Allison Henderson 提交于
      This patch addresses a bug found by xfstests 75, 112, 127
      when blocksize = 1k
      
      This bug happens because the punch hole code only zeros
      out non block aligned regions of the page.  This means that if the
      blocks are smaller than a page, then the block aligned regions of
      the page inside the hole are left un-zeroed, and their buffer heads
      are still mapped.  This bug is corrected by using
      ext4_discard_partial_page_buffers to properly zero the partial page
      at the head and tail of the hole, and unmap the corresponding buffer
      heads
      
      This patch also addresses a bug reported by Lukas while working on a
      new patch to add discard support for loop devices using punch hole.
      The bug happened because of the first and last block number
      needed to be cast to a larger data type before calculating the
      byte offset, but since now we only need the byte offsets of the
      pages, we no longer even need to be calculating the byte offsets
      of the blocks.  The code to do the block offset calculations is
      removed in this patch.
      Signed-off-by: NAllison Henderson <achender@linux.vnet.ibm.com>
      ba06208a
    • A
      ext4: Add new ext4_discard_partial_page_buffers routines · 4e96b2db
      Allison Henderson 提交于
      This patch adds two new routines: ext4_discard_partial_page_buffers
      and ext4_discard_partial_page_buffers_no_lock.
      
      The ext4_discard_partial_page_buffers routine is a wrapper
      function to ext4_discard_partial_page_buffers_no_lock.
      The wrapper function locks the page and passes it to
      ext4_discard_partial_page_buffers_no_lock.
      Calling functions that already have the page locked can call
      ext4_discard_partial_page_buffers_no_lock directly.
      
      The ext4_discard_partial_page_buffers_no_lock function
      zeros a specified range in a page, and unmaps the
      corresponding buffer heads.  Only block aligned regions of the
      page will have their buffer heads unmapped.  Unblock aligned regions
      will be mapped if needed so that they can be updated with the
      partial zero out.  This function is meant to
      be used to update a page and its buffer heads to be zeroed
      and unmapped when the corresponding blocks have been released
      or will be released.
      
      This routine is used in the following scenarios:
      * A hole is punched and the non page aligned regions
        of the head and tail of the hole need to be discarded
      
      * The file is truncated and the partial page beyond EOF needs
        to be discarded
      
      * The end of a hole is in the same page as EOF.  After the
        page is flushed, the partial page beyond EOF needs to be
        discarded.
      
      * A write operation begins or ends inside a hole and the partial
        page appearing before or after the write needs to be discarded
      
      * A write operation extends EOF and the partial page beyond EOF
        needs to be discarded
      
      This function takes a flag EXT4_DISCARD_PARTIAL_PG_ZERO_UNMAPPED
      which is used when a write operation begins or ends in a hole.
      When the EXT4_DISCARD_PARTIAL_PG_ZERO_UNMAPPED flag is used, only
      buffer heads that are already unmapped will have the corresponding
      regions of the page zeroed.
      Signed-off-by: NAllison Henderson <achender@linux.vnet.ibm.com>
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      4e96b2db
  6. 01 9月, 2011 2 次提交
  7. 31 8月, 2011 4 次提交
    • D
      ext4: ext4_rename should dirty dir_bh with the correct directory · bcaa9929
      Darrick J. Wong 提交于
      When ext4_rename performs a directory rename (move), dir_bh is a
      buffer that is modified to update the '..' link in the directory being
      moved (old_inode).  However, ext4_handle_dirty_metadata is called with
      the old parent directory inode (old_dir) and dir_bh, which is
      incorrect because dir_bh does not belong to the parent inode.  Fix
      this error.
      Signed-off-by: NDarrick J. Wong <djwong@us.ibm.com>
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      Cc: stable@kernel.org
      bcaa9929
    • T
      ext4: fake direct I/O mode for data=journal · 84ebd795
      Theodore Ts'o 提交于
      Currently attempts to open a file with O_DIRECT in data=journal mode
      causes the open to fail with -EINVAL.  This makes it very hard to test
      data=journal mode.  So we will let the open succeed, but then always
      fall back to O_DSYNC buffered writes.
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      84ebd795
    • T
      ext2,ext3,ext4: don't inherit APPEND_FL or IMMUTABLE_FL for new inodes · 1cd9f097
      Theodore Ts'o 提交于
      This doesn't make much sense, and it exposes a bug in the kernel where
      attempts to create a new file in an append-only directory using
      O_CREAT will fail (but still leave a zero-length file).  This was
      discovered when xfstests #79 was generalized so it could run on all
      file systems.
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      Cc:stable@kernel.org
      1cd9f097
    • J
      ext4: remove i_mutex lock in ext4_evict_inode to fix lockdep complaining · 8c0bec21
      Jiaying Zhang 提交于
      The i_mutex lock and flush_completed_IO() added by commit 2581fdc8
      in ext4_evict_inode() causes lockdep complaining about potential
      deadlock in several places.  In most/all of these LOCKDEP complaints
      it looks like it's a false positive, since many of the potential
      circular locking cases can't take place by the time the
      ext4_evict_inode() is called; but since at the very least it may mask
      real problems, we need to address this.
      
      This change removes the flush_completed_IO() and i_mutex lock in
      ext4_evict_inode().  Instead, we take a different approach to resolve
      the software lockup that commit 2581fdc8 intends to fix.  Rather
      than having ext4-dio-unwritten thread wait for grabing the i_mutex
      lock of an inode, we use mutex_trylock() instead, and simply requeue
      the work item if we fail to grab the inode's i_mutex lock.
      
      This should speed up work queue processing in general and also
      prevents the following deadlock scenario: During page fault,
      shrink_icache_memory is called that in turn evicts another inode B.
      Inode B has some pending io_end work so it calls ext4_ioend_wait()
      that waits for inode B's i_ioend_count to become zero.  However, inode
      B's ioend work was queued behind some of inode A's ioend work on the
      same cpu's ext4-dio-unwritten workqueue.  As the ext4-dio-unwritten
      thread on that cpu is processing inode A's ioend work, it tries to
      grab inode A's i_mutex lock.  Since the i_mutex lock of inode A is
      still hold before the page fault happened, we enter a deadlock.
      Signed-off-by: NJiaying Zhang <jiayingz@google.com>
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      8c0bec21
  8. 20 8月, 2011 1 次提交
    • J
      ext4: flush any pending end_io requests before DIO reads w/dioread_nolock · dccaf33f
      Jiaying Zhang 提交于
      There is a race between ext4 buffer write and direct_IO read with
      dioread_nolock mount option enabled. The problem is that we clear
      PageWriteback flag during end_io time but will do
      uninitialized-to-initialized extent conversion later with dioread_nolock.
      If an O_direct read request comes in during this period, ext4 will return
      zero instead of the recently written data.
      
      This patch checks whether there are any pending uninitialized-to-initialized
      extent conversion requests before doing O_direct read to close the race.
      Note that this is just a bandaid fix. The fundamental issue is that we
      clear PageWriteback flag before we really complete an IO, which is
      problem-prone. To fix the fundamental issue, we may need to implement an
      extent tree cache that we can use to look up pending to-be-converted extents.
      Signed-off-by: NJiaying Zhang <jiayingz@google.com>
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      Cc: stable@kernel.org
      dccaf33f
  9. 14 8月, 2011 3 次提交
    • T
      ext4: fix nomblk_io_submit option so it correctly converts uninit blocks · 9dd75f1f
      Theodore Ts'o 提交于
      Bug discovered by Jan Kara:
      
      Finally, commit 1449032b returned back
      the old IO submission code but apparently it forgot to return the old
      handling of uninitialized buffers so we unconditionnaly call
      block_write_full_page() without specifying end_io function. So AFAICS
      we never convert unwritten extents to written in some cases. For
      example when I mount the fs as: mount -t ext4 -o
      nomblk_io_submit,dioread_nolock /dev/ubdb /mnt and do
              int fd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC, 0600);
              char buf[1024];
              memset(buf, 'a', sizeof(buf));
              fallocate(fd, 0, 0, 16384);
              write(fd, buf, sizeof(buf));
      
      I get a file full of zeros (after remounting the filesystem so that
      pagecache is dropped) instead of seeing the first KB contain 'a's.
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      Cc: stable@kernel.org
      9dd75f1f
    • T
      ext4: Resolve the hang of direct i/o read in handling EXT4_IO_END_UNWRITTEN. · 32c80b32
      Tao Ma 提交于
      EXT4_IO_END_UNWRITTEN flag set and the increase of i_aiodio_unwritten
      should be done simultaneously since ext4_end_io_nolock always clear
      the flag and decrease the counter in the same time.
      
      We don't increase i_aiodio_unwritten when setting
      EXT4_IO_END_UNWRITTEN so it will go nagative and causes some process
      to wait forever.
      
      Part of the patch came from Eric in his e-mail, but it doesn't fix the
      problem met by Michael actually.
      
      http://marc.info/?l=linux-ext4&m=131316851417460&w=2
      
      Reported-and-Tested-by: Michael Tokarev<mjt@tls.msk.ru>
      Signed-off-by: NEric Sandeen <sandeen@redhat.com>
      Signed-off-by: NTao Ma <boyu.mt@taobao.com>
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      Cc: stable@kernel.org
      32c80b32
    • J
      ext4: call ext4_ioend_wait and ext4_flush_completed_IO in ext4_evict_inode · 2581fdc8
      Jiaying Zhang 提交于
      Flush inode's i_completed_io_list before calling ext4_io_wait to
      prevent the following deadlock scenario: A page fault happens while
      some process is writing inode A. During page fault,
      shrink_icache_memory is called that in turn evicts another inode
      B. Inode B has some pending io_end work so it calls ext4_ioend_wait()
      that waits for inode B's i_ioend_count to become zero. However, inode
      B's ioend work was queued behind some of inode A's ioend work on the
      same cpu's ext4-dio-unwritten workqueue. As the ext4-dio-unwritten
      thread on that cpu is processing inode A's ioend work, it tries to
      grab inode A's i_mutex lock. Since the i_mutex lock of inode A is
      still hold before the page fault happened, we enter a deadlock.
      
      Also moves ext4_flush_completed_IO and ext4_ioend_wait from
      ext4_destroy_inode() to ext4_evict_inode(). During inode deleteion,
      ext4_evict_inode() is called before ext4_destroy_inode() and in
      ext4_evict_inode(), we may call ext4_truncate() without holding
      i_mutex lock. As a result, there is a race between flush_completed_IO
      that is called from ext4_ext_truncate() and ext4_end_io_work, which
      may cause corruption on an io_end structure. This change moves
      ext4_flush_completed_IO and ext4_ioend_wait from ext4_destroy_inode()
      to ext4_evict_inode() to resolve the race between ext4_truncate() and
      ext4_end_io_work during inode deletion.
      Signed-off-by: NJiaying Zhang <jiayingz@google.com>
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      Cc: stable@kernel.org
      2581fdc8
  10. 13 8月, 2011 1 次提交
    • C
      ext4: Fix ext4_should_writeback_data() for no-journal mode · 441c8508
      Curt Wohlgemuth 提交于
      ext4_should_writeback_data() had an incorrect sequence of
      tests to determine if it should return 0 or 1: in
      particular, even in no-journal mode, 0 was being returned
      for a non-regular-file inode.
      
      This meant that, in non-journal mode, we would use
      ext4_journalled_aops for directories, symlinks, and other
      non-regular files.  However, calling journalled aop
      callbacks when there is no valid handle, can cause problems.
      
      This would cause a kernel crash with Jan Kara's commit
      2d859db3 ("ext4: fix data corruption in inodes with
      journalled data"), because we now dereference 'handle' in
      ext4_journalled_write_end().
      
      I also added BUG_ONs to check for a valid handle in the
      obviously journal-only aops callbacks.
      
      I tested this running xfstests with a scratch device in
      these modes:
      
         - no-journal
         - data=ordered
         - data=writeback
         - data=journal
      
      All work fine; the data=journal run has many failures and a
      crash in xfstests 074, but this is no different from a
      vanilla kernel.
      Signed-off-by: NCurt Wohlgemuth <curtw@google.com>
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      Cc: stable@kernel.org
      441c8508
  11. 12 8月, 2011 1 次提交
  12. 04 8月, 2011 1 次提交
  13. 02 8月, 2011 3 次提交
  14. 01 8月, 2011 5 次提交
  15. 31 7月, 2011 2 次提交
    • D
      ext4: add missing kfree() on error return path in add_new_gdb() · c49bafa3
      Dan Carpenter 提交于
      We added some more error handling in b4097142 "ext4: add error
      checking to calls to ext4_handle_dirty_metadata()".  But we need to
      call kfree() as well to avoid a memory leak.
      Signed-off-by: NDan Carpenter <error27@gmail.com>
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      c49bafa3
    • T
      ext4: fix races in ext4_sync_parent() · d59729f4
      Theodore Ts'o 提交于
      Fix problems if fsync() races against a rename of a parent directory
      as pointed out by Al Viro in his own inimitable way:
      
      >While we are at it, could somebody please explain what the hell is ext4
      >doing in
      >static int ext4_sync_parent(struct inode *inode)
      >{
      >        struct writeback_control wbc;
      >        struct dentry *dentry = NULL;
      >        int ret = 0;
      >
      >        while (inode && ext4_test_inode_state(inode, EXT4_STATE_NEWENTRY)) {
      >                ext4_clear_inode_state(inode, EXT4_STATE_NEWENTRY);
      >                dentry = list_entry(inode->i_dentry.next,
      >                                    struct dentry, d_alias);
      >                if (!dentry || !dentry->d_parent || !dentry->d_parent->d_inode)
      >                        break;
      >                inode = dentry->d_parent->d_inode;
      >                ret = sync_mapping_buffers(inode->i_mapping);
      >                ...
      >Note that dentry obviously can't be NULL there.  dentry->d_parent is never
      >NULL.  And dentry->d_parent would better not be negative, for crying out
      >loud!  What's worse, there's no guarantees that dentry->d_parent will
      >remain our parent over that sync_mapping_buffers() *and* that inode won't
      >just be freed under us (after rename() and memory pressure leading to
      >eviction of what used to be our dentry->d_parent)......
      Reported-by: NAl Viro <viro@ZenIV.linux.org.uk>
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      d59729f4
  16. 28 7月, 2011 1 次提交
    • U
      ext4: Fix overflow caused by missing cast in ext4_fallocate() · 29ae07b7
      Utako Kusaka 提交于
      The logical block number in map.l_blk is a __u32, and so before we
      shift it left, by the block size, we neeed cast it to a 64-bit size.
      
      Otherwise i_size can be corrupted on an ENOSPC.
      
      # df -T /mnt/mp1
      Filesystem    Type   1K-blocks      Used Available Use% Mounted on
      /dev/sda6     ext4     9843276    153056   9190200   2% /mnt/mp1
      # fallocate -o 0 -l 2199023251456 /mnt/mp1/testfile
      fallocate: /mnt/mp1/testfile: fallocate failed: No space left on device
      # stat /mnt/mp1/testfile
        File: `/mnt/mp1/testfile'
        Size: 4293656576	Blocks: 19380440   IO Block: 4096   regular file
      Device: 806h/2054d	Inode: 12          Links: 1
      Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
      Access: 2011-07-25 13:01:31.414490496 +0900
      Modify: 2011-07-25 13:01:31.414490496 +0900
      Change: 2011-07-25 13:01:31.454490495 +0900
      Signed-off-by: NUtako Kusaka <u-kusaka@wm.jp.nec.com>
      Signed-off-by: N"Theodore Ts'o" <tytso@mit.edu>
      --
       fs/ext4/extents.c |    2 +-
       1 files changed, 1 insertions(+), 1 deletions(-)
      29ae07b7