1. 23 Nov, 2009 5 commits
    • Akira Fujita's avatar
      ext4: fix possible recursive locking warning in EXT4_IOC_MOVE_EXT · 49bd22bc
      Akira Fujita authored
      If CONFIG_PROVE_LOCKING is enabled, the double_down_write_data_sem()
      will trigger a false-positive warning of a recursive lock.  Since we
      take i_data_sem for the two inodes ordered by their inode numbers,
      this isn't a problem.  Use of down_write_nested() will notify the lock
      dependency checker machinery that there is no problem here.
      
      This problem was reported by Brian Rogers:
      
      	http://marc.info/?l=linux-ext4&m=125115356928011&w=1Reported-by: default avatarBrian Rogers <brian@xyzw.org>
      Signed-off-by: default avatarAkira Fujita <a-fujita@rs.jp.nec.com>
      Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
      49bd22bc
    • Akira Fujita's avatar
      ext4: fix lock order problem in ext4_move_extents() · fc04cb49
      Akira Fujita authored
      ext4_move_extents() checks the logical block contiguousness
      of original file with ext4_find_extent() and mext_next_extent().
      Therefore the extent which ext4_ext_path structure indicates
      must not be changed between above functions.
      
      But in current implementation, there is no i_data_sem protection
      between ext4_ext_find_extent() and mext_next_extent().  So the extent
      which ext4_ext_path structure indicates may be overwritten by
      delalloc.  As a result, ext4_move_extents() will exchange wrong blocks
      between original and donor files.  I change the place where
      acquire/release i_data_sem to solve this problem.
      
      Moreover, I changed move_extent_per_page() to start transaction first,
      and then acquire i_data_sem.  Without this change, there is a
      possibility of the deadlock between mmap() and ext4_move_extents():
      
      * NOTE: "A", "B" and "C" mean different processes
      
      A-1: ext4_ext_move_extents() acquires i_data_sem of two inodes.
      
      B:   do_page_fault() starts the transaction (T),
           and then tries to acquire i_data_sem.
           But process "A" is already holding it, so it is kept waiting.
      
      C:   While "A" and "B" running, kjournald2 tries to commit transaction (T)
           but it is under updating, so kjournald2 waits for it.
      
      A-2: Call ext4_journal_start with holding i_data_sem,
           but transaction (T) is locked.
      Signed-off-by: default avatarAkira Fujita <a-fujita@rs.jp.nec.com>
      Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
      fc04cb49
    • Akira Fujita's avatar
      ext4: fix the returned block count if EXT4_IOC_MOVE_EXT fails · f868a48d
      Akira Fujita authored
      If the EXT4_IOC_MOVE_EXT ioctl fails, the number of blocks that were
      exchanged before the failure should be returned to the userspace
      caller.  Unfortunately, currently if the block size is not the same as
      the page size, the returned block count that is returned is the
      page-aligned block count instead of the actual block count.  This
      commit addresses this bug.
      Signed-off-by: default avatarAkira Fujita <a-fujita@rs.jp.nec.com>
      Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
      f868a48d
    • Theodore Ts'o's avatar
      ext4: avoid divide by zero when trying to mount a corrupted file system · 503358ae
      Theodore Ts'o authored
      If s_log_groups_per_flex is greater than 31, then groups_per_flex will
      will overflow and cause a divide by zero error.  This can cause kernel
      BUG if such a file system is mounted.
      
      Thanks to Nageswara R Sastry for analyzing the failure and providing
      an initial patch.
      
      http://bugzilla.kernel.org/show_bug.cgi?id=14287Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
      Cc: stable@kernel.org
      503358ae
    • Theodore Ts'o's avatar
      ext4: fix potential buffer head leak when add_dirent_to_buf() returns ENOSPC · 2de770a4
      Theodore Ts'o authored
      Previously add_dirent_to_buf() did not free its passed-in buffer head
      in the case of ENOSPC, since in some cases the caller still needed it.
      However, this led to potential buffer head leaks since not all callers
      dealt with this correctly.  Fix this by making simplifying the freeing
      convention; now add_dirent_to_buf() *never* frees the passed-in buffer
      head, and leaves that to the responsibility of its caller.  This makes
      things cleaner and easier to prove that the code is neither leaking
      buffer heads or calling brelse() one time too many.
      Signed-off-by: default avatar"Theodore Ts'o" <tytso@mit.edu>
      Cc: Curt Wohlgemuth <curtw@google.com>
      Cc: stable@kernel.org
      2de770a4
  2. 13 Nov, 2009 1 commit
  3. 12 Nov, 2009 34 commits