diff options
author | Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> | 2008-01-28 23:58:29 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2008-01-28 23:58:29 -0500 |
commit | 4df3d265bf8f3762e1d77f554ee279c39dedb020 (patch) | |
tree | 35d455ac6592750450d9173125b1e5b9b5efe819 | |
parent | 0e855ac8b103ef579052936b59fe7c599ac422a4 (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.c | 32 |
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 | ||