diff options
Diffstat (limited to 'fs/ext4/inode.c')
| -rw-r--r-- | fs/ext4/inode.c | 47 |
1 files changed, 44 insertions, 3 deletions
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 | /* |
