aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ext4/extents.c13
-rw-r--r--fs/ext4/inode.c47
2 files changed, 57 insertions, 3 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
index 8a59f7ba30e6..bcf5d040e328 100644
--- a/fs/ext4/extents.c
+++ b/fs/ext4/extents.c
@@ -2287,9 +2287,22 @@ out:
2287} 2287}
2288 2288
2289/* 2289/*
2290 * Block allocation/map/preallocation routine for extents based files
2291 *
2292 *
2290 * Need to be called with 2293 * Need to be called with
2291 * down_read(&EXT4_I(inode)->i_data_sem) if not allocating file system block 2294 * down_read(&EXT4_I(inode)->i_data_sem) if not allocating file system block
2292 * (ie, create is zero). Otherwise down_write(&EXT4_I(inode)->i_data_sem) 2295 * (ie, create is zero). Otherwise down_write(&EXT4_I(inode)->i_data_sem)
2296 *
2297 * return > 0, number of of blocks already mapped/allocated
2298 * if create == 0 and these are pre-allocated blocks
2299 * buffer head is unmapped
2300 * otherwise blocks are mapped
2301 *
2302 * return = 0, if plain look up failed (blocks have not been allocated)
2303 * buffer head is unmapped
2304 *
2305 * return < 0, error case.
2293 */ 2306 */
2294int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, 2307int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
2295 ext4_lblk_t iblock, 2308 ext4_lblk_t iblock,
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 34f3eb615fd5..945cbf6cb1fc 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -908,11 +908,38 @@ out:
908 */ 908 */
909#define DIO_CREDITS 25 909#define DIO_CREDITS 25
910 910
911
912/*
913 *
914 *
915 * ext4_ext4 get_block() wrapper function
916 * It will do a look up first, and returns if the blocks already mapped.
917 * Otherwise it takes the write lock of the i_data_sem and allocate blocks
918 * and store the allocated blocks in the result buffer head and mark it
919 * mapped.
920 *
921 * If file type is extents based, it will call ext4_ext_get_blocks(),
922 * Otherwise, call with ext4_get_blocks_handle() to handle indirect mapping
923 * based files
924 *
925 * On success, it returns the number of blocks being mapped or allocate.
926 * if create==0 and the blocks are pre-allocated and uninitialized block,
927 * the result buffer head is unmapped. If the create ==1, it will make sure
928 * the buffer head is mapped.
929 *
930 * It returns 0 if plain look up failed (blocks have not been allocated), in
931 * that casem, buffer head is unmapped
932 *
933 * It returns the error in case of allocation failure.
934 */
911int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, 935int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block,
912 unsigned long max_blocks, struct buffer_head *bh, 936 unsigned long max_blocks, struct buffer_head *bh,
913 int create, int extend_disksize) 937 int create, int extend_disksize)
914{ 938{
915 int retval; 939 int retval;
940
941 clear_buffer_mapped(bh);
942
916 /* 943 /*
917 * Try to see if we can get the block without requesting 944 * Try to see if we can get the block without requesting
918 * for new file system block. 945 * for new file system block.
@@ -926,12 +953,26 @@ int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block,
926 inode, block, max_blocks, bh, 0, 0); 953 inode, block, max_blocks, bh, 0, 0);
927 } 954 }
928 up_read((&EXT4_I(inode)->i_data_sem)); 955 up_read((&EXT4_I(inode)->i_data_sem));
929 if (!create || (retval > 0)) 956
957 /* If it is only a block(s) look up */
958 if (!create)
959 return retval;
960
961 /*
962 * Returns if the blocks have already allocated
963 *
964 * Note that if blocks have been preallocated
965 * ext4_ext_get_block() returns th create = 0
966 * with buffer head unmapped.
967 */
968 if (retval > 0 && buffer_mapped(bh))
930 return retval; 969 return retval;
931 970
932 /* 971 /*
933 * We need to allocate new blocks which will result 972 * New blocks allocate and/or writing to uninitialized extent
934 * in i_data update 973 * will possibly result in updating i_data, so we take
974 * the write lock of i_data_sem, and call get_blocks()
975 * with create == 1 flag.
935 */ 976 */
936 down_write((&EXT4_I(inode)->i_data_sem)); 977 down_write((&EXT4_I(inode)->i_data_sem));
937 /* 978 /*