diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ext4/extents.c | 13 | ||||
-rw-r--r-- | fs/ext4/inode.c | 47 |
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 | */ |
2294 | int ext4_ext_get_blocks(handle_t *handle, struct inode *inode, | 2307 | int 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 | */ | ||
911 | int ext4_get_blocks_wrap(handle_t *handle, struct inode *inode, sector_t block, | 935 | int 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 | /* |