summaryrefslogtreecommitdiff
path: root/fs/ext4/extents.c
diff options
context:
space:
mode:
authorMingming Cao <cmm@us.ibm.com>2008-02-25 23:29:55 +0300
committerTheodore Ts'o <tytso@mit.edu>2008-02-25 23:29:55 +0300
commitf5ab0d1f8f7df937778c60c3da6f4ef939a54a7b (patch)
tree9a5b63d45dc805383f7789bba75f7935626767fe /fs/ext4/extents.c
parent825f1481ead4ce40671089bae7412ac3519e8caa (diff)
downloadlinux-f5ab0d1f8f7df937778c60c3da6f4ef939a54a7b.tar.xz
ext4: Fix BUG when writing to an unitialized extent
This patch fixes a bug when writing to preallocated but uninitialized blocks, which resulted in a BUG in fs/buffer.c saying that the buffer is not mapped. When writing to a file, ext4_get_block_wrap() is called with create=1 in order to request that blocks be allocated if necessary. It currently calls ext4_get_blocks() with create=0 in order to do a lookup first. If the inode contains an unitialized data block, the buffer head is left unampped, which ext4_get_blocks_wrap() returns, causing the BUG. We fix this by checking to see if the buffer head is unmapped, and if so, we make sure the the buffer head is mapped by calling ext4_ext_get_blocks with create=1. Signed-off-by: Mingming Cao <cmm@us.ibm.com> Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4/extents.c')
-rw-r--r--fs/ext4/extents.c13
1 files changed, 13 insertions, 0 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:
}
/*
+ * Block allocation/map/preallocation routine for extents based files
+ *
+ *
* Need to be called with
* down_read(&EXT4_I(inode)->i_data_sem) if not allocating file system block
* (ie, create is zero). Otherwise down_write(&EXT4_I(inode)->i_data_sem)
+ *
+ * return > 0, number of of blocks already mapped/allocated
+ * if create == 0 and these are pre-allocated blocks
+ * buffer head is unmapped
+ * otherwise blocks are mapped
+ *
+ * return = 0, if plain look up failed (blocks have not been allocated)
+ * buffer head is unmapped
+ *
+ * return < 0, error case.
*/
int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
ext4_lblk_t iblock,