1. 07 Sep, 2011 2 commits
    • Allison Henderson's avatar
      ext4: fix partial page writes · 02fac129
      Allison Henderson authored
      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: default avatarAllison Henderson <achender@linux.vnet.ibm.com>
      Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
      02fac129
    • Allison Henderson's avatar
      ext4: fix fsx truncate failure · 189e868f
      Allison Henderson authored
      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: default avatarAllison Henderson <achender@linux.vnet.ibm.com>
      Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
      189e868f
  2. 06 Sep, 2011 1 commit
    • Theodore Ts'o's avatar
      ext4: only call ext4_jbd2_file_inode when an inode has been extended · decbd919
      Theodore Ts'o authored
      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: default avatar"Theodore Ts'o" <tytso@mit.edu>
      Cc: Allison Henderson <achender@linux.vnet.ibm.com>
      Cc: Jan Kara <jack@suse.cz>
      decbd919
  3. 04 Sep, 2011 2 commits
    • Dan Carpenter's avatar
      jbd2: use gfp_t instead of int · d2159fb7
      Dan Carpenter authored
      This silences some Sparse warnings:
      fs/jbd2/transaction.c:135:69: warning: incorrect type in argument 2 (different base types)
      fs/jbd2/transaction.c:135:69:    expected restricted gfp_t [usertype] flags
      fs/jbd2/transaction.c:135:69:    got int [signed] gfp_mask
      Signed-off-by: default avatarDan Carpenter <error27@gmail.com>
      Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
      d2159fb7
    • Theodore Ts'o's avatar
      jbd2: add debugging information to jbd2_journal_dirty_metadata() · 9ea7a0df
      Theodore Ts'o authored
      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: default avatar"Theodore Ts'o" <tytso@mit.edu>
      9ea7a0df
  4. 03 Sep, 2011 4 commits
    • Theodore Ts'o's avatar
      ext4: improve handling of conflicting mount options · 56889787
      Theodore Ts'o authored
      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: default avatar"Theodore Ts'o" <tytso@mit.edu>
      56889787
    • Allison Henderson's avatar
      ext4: fix 2nd xfstests 127 punch hole failure · 2be4751b
      Allison Henderson authored
      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: default avatarAllison Henderson <achender@linux.vnet.ibm.com>
      2be4751b
    • Allison Henderson's avatar
      ext4: fix xfstests 75, 112, 127 punch hole failure · ba06208a
      Allison Henderson authored
      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: default avatarAllison Henderson <achender@linux.vnet.ibm.com>
      ba06208a
    • Allison Henderson's avatar
      ext4: Add new ext4_discard_partial_page_buffers routines · 4e96b2db
      Allison Henderson authored
      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: default avatarAllison Henderson <achender@linux.vnet.ibm.com>
      Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
      4e96b2db
  5. 31 Aug, 2011 6 commits
    • Theodore Ts'o's avatar
      ext4: call ext4_handle_dirty_metadata with correct inode in ext4_dx_add_entry · 5930ea64
      Theodore Ts'o authored
      ext4_dx_add_entry manipulates bh2 and frames[0].bh, which are two buffer_heads
      that point to directory blocks assigned to the directory inode.  However, the
      function calls ext4_handle_dirty_metadata with the inode of the file that's
      being added to the directory, not the directory inode itself.  Therefore,
      correct the code to dirty the directory buffers with the directory inode, not
      the file inode.
      Signed-off-by: default avatarDarrick J. Wong <djwong@us.ibm.com>
      Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
      Cc: stable@kernel.org
      5930ea64
    • Darrick J. Wong's avatar
      ext4: ext4_mkdir should dirty dir_block with newly created directory inode · f9287c1f
      Darrick J. Wong authored
      ext4_mkdir calls ext4_handle_dirty_metadata with dir_block and the inode "dir".
      Unfortunately, dir_block belongs to the newly created directory (which is
      "inode"), not the parent directory (which is "dir").  Fix the incorrect
      association.
      Signed-off-by: default avatarDarrick J. Wong <djwong@us.ibm.com>
      Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
      Cc: stable@kernel.org
      f9287c1f
    • Darrick J. Wong's avatar
      ext4: ext4_rename should dirty dir_bh with the correct directory · bcaa9929
      Darrick J. Wong authored
      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: default avatarDarrick J. Wong <djwong@us.ibm.com>
      Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
      Cc: stable@kernel.org
      bcaa9929
    • Theodore Ts'o's avatar
      ext4: fake direct I/O mode for data=journal · 84ebd795
      Theodore Ts'o authored
      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: default avatar"Theodore Ts'o" <tytso@mit.edu>
      84ebd795
    • Theodore Ts'o's avatar
      ext2,ext3,ext4: don't inherit APPEND_FL or IMMUTABLE_FL for new inodes · 1cd9f097
      Theodore Ts'o authored
      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: default avatar"Theodore Ts'o" <tytso@mit.edu>
      Cc:stable@kernel.org
      1cd9f097
    • Jiaying Zhang's avatar
      ext4: remove i_mutex lock in ext4_evict_inode to fix lockdep complaining · 8c0bec21
      Jiaying Zhang authored
      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: default avatarJiaying Zhang <jiayingz@google.com>
      Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
      8c0bec21
  6. 22 Aug, 2011 6 commits
  7. 21 Aug, 2011 4 commits
  8. 20 Aug, 2011 4 commits
  9. 19 Aug, 2011 11 commits