Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=55bd725aa3a83b3935988f37275b5a80e10d4169
Commit:     55bd725aa3a83b3935988f37275b5a80e10d4169
Parent:     642be6ec218b956fbae88304449720f76ba0d578
Author:     Aneesh Kumar K.V <[EMAIL PROTECTED]>
AuthorDate: Fri Feb 15 12:47:21 2008 -0500
Committer:  Theodore Ts'o <[EMAIL PROTECTED]>
CommitDate: Fri Feb 15 12:47:21 2008 -0500

    ext4: Fix locking hierarchy violation in ext4_fallocate()
    
    ext4_fallocate() was trying to acquire i_data_sem outside of
    jbd2_start_transaction/jbd2_journal_stop, which violates ext4's locking
    hierarchy.  So we take i_mutex to prevent writes and truncates during
    the complete fallocate operation, and use ext4_get_block_wrap() which
    acquires and releases i_data_sem for each block allocation.
    
    Signed-off-by: Aneesh Kumar K.V <[EMAIL PROTECTED]>
    Signed-off-by: Mingming Cao <[EMAIL PROTECTED]>
    Signed-off-by: "Theodore Ts'o" <[EMAIL PROTECTED]>
---
 fs/ext4/extents.c |   10 +++-------
 1 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index bc7081f..e856f66 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -2623,7 +2623,7 @@ long ext4_fallocate(struct inode *inode, int mode, loff_t 
offset, loff_t len)
         * modify 1 super block, 1 block bitmap and 1 group descriptor.
         */
        credits = EXT4_DATA_TRANS_BLOCKS(inode->i_sb) + 3;
-       down_write((&EXT4_I(inode)->i_data_sem));
+       mutex_lock(&inode->i_mutex);
 retry:
        while (ret >= 0 && ret < max_blocks) {
                block = block + ret;
@@ -2634,7 +2634,7 @@ retry:
                        break;
                }
 
-               ret = ext4_ext_get_blocks(handle, inode, block,
+               ret = ext4_get_blocks_wrap(handle, inode, block,
                                          max_blocks, &map_bh,
                                          EXT4_CREATE_UNINITIALIZED_EXT, 0);
                WARN_ON(ret <= 0);
@@ -2680,7 +2680,6 @@ retry:
        if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
                goto retry;
 
-       up_write((&EXT4_I(inode)->i_data_sem));
        /*
         * Time to update the file size.
         * Update only when preallocation was requested beyond the file size.
@@ -2692,21 +2691,18 @@ retry:
                         * if no error, we assume preallocation succeeded
                         * completely
                         */
-                       mutex_lock(&inode->i_mutex);
                        i_size_write(inode, offset + len);
                        EXT4_I(inode)->i_disksize = i_size_read(inode);
-                       mutex_unlock(&inode->i_mutex);
                } else if (ret < 0 && nblocks) {
                        /* Handle partial allocation scenario */
                        loff_t newsize;
 
-                       mutex_lock(&inode->i_mutex);
                        newsize  = (nblocks << blkbits) + i_size_read(inode);
                        i_size_write(inode, EXT4_BLOCK_ALIGN(newsize, blkbits));
                        EXT4_I(inode)->i_disksize = i_size_read(inode);
-                       mutex_unlock(&inode->i_mutex);
                }
        }
 
+       mutex_unlock(&inode->i_mutex);
        return ret > 0 ? ret2 : ret;
 }
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to