Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=4df3d265bf8f3762e1d77f554ee279c39dedb020
Commit:     4df3d265bf8f3762e1d77f554ee279c39dedb020
Parent:     0e855ac8b103ef579052936b59fe7c599ac422a4
Author:     Aneesh Kumar K.V <[EMAIL PROTECTED]>
AuthorDate: Mon Jan 28 23:58:29 2008 -0500
Committer:  Theodore Ts'o <[EMAIL PROTECTED]>
CommitDate: Mon Jan 28 23:58:29 2008 -0500

    ext4: Take read lock during overwrite case.
    
    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 a7eb8bb..89cd353 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -901,11 +901,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);
@@ -913,11 +933,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;
 }
 
-
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