aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>2008-01-28 23:58:29 -0500
committerTheodore Ts'o <tytso@mit.edu>2008-01-28 23:58:29 -0500
commit4df3d265bf8f3762e1d77f554ee279c39dedb020 (patch)
tree35d455ac6592750450d9173125b1e5b9b5efe819
parent0e855ac8b103ef579052936b59fe7c599ac422a4 (diff)
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 <aneesh.kumar@linux.vnet.ibm.com>
-rw-r--r--fs/ext4/inode.c32
1 files changed, 24 insertions, 8 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index a7eb8bb4bdd4..89cd35386ff5 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,
901 int create, int extend_disksize) 901 int create, int extend_disksize)
902{ 902{
903 int retval; 903 int retval;
904 if (create) { 904 /*
905 down_write((&EXT4_I(inode)->i_data_sem)); 905 * Try to see if we can get the block without requesting
906 * for new file system block.
907 */
908 down_read((&EXT4_I(inode)->i_data_sem));
909 if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) {
910 retval = ext4_ext_get_blocks(handle, inode, block, max_blocks,
911 bh, 0, 0);
906 } else { 912 } else {
907 down_read((&EXT4_I(inode)->i_data_sem)); 913 retval = ext4_get_blocks_handle(handle,
914 inode, block, max_blocks, bh, 0, 0);
908 } 915 }
916 up_read((&EXT4_I(inode)->i_data_sem));
917 if (!create || (retval > 0))
918 return retval;
919
920 /*
921 * We need to allocate new blocks which will result
922 * in i_data update
923 */
924 down_write((&EXT4_I(inode)->i_data_sem));
925 /*
926 * We need to check for EXT4 here because migrate
927 * could have changed the inode type in between
928 */
909 if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) { 929 if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) {
910 retval = ext4_ext_get_blocks(handle, inode, block, max_blocks, 930 retval = ext4_ext_get_blocks(handle, inode, block, max_blocks,
911 bh, create, extend_disksize); 931 bh, create, extend_disksize);
@@ -913,11 +933,7 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block,
913 retval = ext4_get_blocks_handle(handle, inode, block, 933 retval = ext4_get_blocks_handle(handle, inode, block,
914 max_blocks, bh, create, extend_disksize); 934 max_blocks, bh, create, extend_disksize);
915 } 935 }
916 if (create) { 936 up_write((&EXT4_I(inode)->i_data_sem));
917 up_write((&EXT4_I(inode)->i_data_sem));
918 } else {
919 up_read((&EXT4_I(inode)->i_data_sem));
920 }
921 return retval; 937 return retval;
922} 938}
923 939