When we are overwriting a file and not actually allocating new file system
blocks we need to take only the read lock on i_data_sem.

Signed-off-by: Aneesh Kumar K.V <[EMAIL PROTECTED]>
---
 fs/ext4/inode.c |   32 ++++++++++++++++++++++++--------
 1 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 8aa8855..4489bfd 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -894,11 +894,31 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode 
*inode, sector_t block,
                        int create, int extend_disksize)
 {
        int retval;
-       if (create) {
-               down_write((&EXT4_I(inode)->i_data_sem));
+       /*
+        * Try to see if we can get  the block without requesting
+        * for new file system block.
+        */
+       down_read((&EXT4_I(inode)->i_data_sem));
+       if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) {
+               retval =  ext4_ext_get_blocks(handle, inode, block, max_blocks,
+                               bh, 0, 0);
        } else {
-               down_read((&EXT4_I(inode)->i_data_sem));
+               retval =  ext4_get_blocks_handle(handle, inode, block, 
max_blocks,
+                               bh, 0, 0);
        }
+       up_read((&EXT4_I(inode)->i_data_sem));
+       if (!create || (retval > 0))
+               return retval;
+
+       /*
+        * We need to allocate new blocks which will result
+        * in i_data update
+        */
+       down_write((&EXT4_I(inode)->i_data_sem));
+       /*
+        * We need to check for EXT4 here because migrate
+        * could have changed the inode type in between
+        */
        if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) {
                retval =  ext4_ext_get_blocks(handle, inode, block, max_blocks,
                                bh, create, extend_disksize);
@@ -906,11 +926,7 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode 
*inode, sector_t block,
                retval =  ext4_get_blocks_handle(handle, inode, block, 
max_blocks,
                                bh, create, extend_disksize);
        }
-       if (create) {
-               up_write((&EXT4_I(inode)->i_data_sem));
-       } else {
-               up_read((&EXT4_I(inode)->i_data_sem));
-       }
+       up_write((&EXT4_I(inode)->i_data_sem));
        return retval;
 }
 static int ext4_get_block(struct inode *inode, sector_t iblock,
-- 
1.5.3.6.985.g65c6a4-dirty

-
To unsubscribe from this list: send the line "unsubscribe linux-ext4" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to