[PATCH] ext3: add extent map support

On disk extents format:
/*
* this is extent on-disk structure
* it's used at the bottom of the tree
*/
struct ext3_extent {
__le32  ee_block;       /* first logical block extent covers */
__le16  ee_len;         /* number of blocks covered by extent */
__le16  ee_start_hi;    /* high 16 bits of physical block */
__le32  ee_start;       /* low 32 bigs of physical block */
};

Signed-off-by: Alex Tomas <alex@clusterfs.com>
Signed-off-by: Dave Kleikamp <shaggy@austin.ibm.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index 0d96c7d..2b81b13 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -40,8 +40,6 @@
 #include "xattr.h"
 #include "acl.h"
 
-static int ext4_writepage_trans_blocks(struct inode *inode);
-
 /*
  * Test whether an inode is a fast symlink.
  */
@@ -804,6 +802,7 @@
 	ext4_fsblk_t first_block = 0;
 
 
+	J_ASSERT(!(EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL));
 	J_ASSERT(handle != NULL || create == 0);
 	depth = ext4_block_to_path(inode,iblock,offsets,&blocks_to_boundary);
 
@@ -984,7 +983,7 @@
 
 get_block:
 	if (ret == 0) {
-		ret = ext4_get_blocks_handle(handle, inode, iblock,
+		ret = ext4_get_blocks_wrap(handle, inode, iblock,
 					max_blocks, bh_result, create, 0);
 		if (ret > 0) {
 			bh_result->b_size = (ret << inode->i_blkbits);
@@ -1008,7 +1007,7 @@
 	dummy.b_state = 0;
 	dummy.b_blocknr = -1000;
 	buffer_trace_init(&dummy.b_history);
-	err = ext4_get_blocks_handle(handle, inode, block, 1,
+	err = ext4_get_blocks_wrap(handle, inode, block, 1,
 					&dummy, create, 1);
 	/*
 	 * ext4_get_blocks_handle() returns number of blocks
@@ -1759,7 +1758,7 @@
  * This required during truncate. We need to physically zero the tail end
  * of that block so it doesn't yield old data if the file is later grown.
  */
-static int ext4_block_truncate_page(handle_t *handle, struct page *page,
+int ext4_block_truncate_page(handle_t *handle, struct page *page,
 		struct address_space *mapping, loff_t from)
 {
 	ext4_fsblk_t index = from >> PAGE_CACHE_SHIFT;
@@ -2263,6 +2262,9 @@
 			return;
 	}
 
+	if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)
+		return ext4_ext_truncate(inode, page);
+
 	handle = start_transaction(inode);
 	if (IS_ERR(handle)) {
 		if (page) {
@@ -3003,12 +3005,15 @@
  * block and work out the exact number of indirects which are touched.  Pah.
  */
 
-static int ext4_writepage_trans_blocks(struct inode *inode)
+int ext4_writepage_trans_blocks(struct inode *inode)
 {
 	int bpp = ext4_journal_blocks_per_page(inode);
 	int indirects = (EXT4_NDIR_BLOCKS % bpp) ? 5 : 3;
 	int ret;
 
+	if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)
+		return ext4_ext_writepage_trans_blocks(inode, bpp);
+
 	if (ext4_should_journal_data(inode))
 		ret = 3 * (bpp + indirects) + 2;
 	else