ext3: add support for extent_map library
authorJens Axboe <jens.axboe@oracle.com>
Tue, 3 Mar 2009 11:16:14 +0000 (12:16 +0100)
committerJens Axboe <jens.axboe@oracle.com>
Tue, 3 Mar 2009 11:16:14 +0000 (12:16 +0100)
Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
fs/ext3/ialloc.c
fs/ext3/inode.c
fs/ext3/super.c
include/linux/ext3_fs_i.h

index 8de6c720e510910b0278c5c806e836494d783fd2..6812929252311896de3071a5e698dacf6b130c94 100644 (file)
@@ -23,6 +23,7 @@
 #include <linux/buffer_head.h>
 #include <linux/random.h>
 #include <linux/bitops.h>
+#include <linux/extent_map.h>
 
 #include <asm/byteorder.h>
 
@@ -571,6 +572,7 @@ got:
        ei->i_dtime = 0;
        ei->i_block_alloc_info = NULL;
        ei->i_block_group = group;
+       extent_map_tree_init(&ei->extent_tree);
 
        ext3_set_inode_flags(inode);
        if (IS_DIRSYNC(inode))
index 5fa453b49a649dd63e681c042742320b6f54a0bf..68e6255583fd919b59c4e542d529b7c78619a75c 100644 (file)
@@ -34,6 +34,7 @@
 #include <linux/buffer_head.h>
 #include <linux/writeback.h>
 #include <linux/mpage.h>
+#include <linux/extent_map.h>
 #include <linux/uio.h>
 #include <linux/bio.h>
 #include <linux/fiemap.h>
@@ -229,9 +230,11 @@ void ext3_delete_inode (struct inode * inode)
                clear_inode(inode);
        else
                ext3_free_inode(handle, inode);
+       remove_extent_mappings(&EXT3_I(inode)->extent_tree, 0, (u64) -1);
        ext3_journal_stop(handle);
        return;
 no_delete:
+       remove_extent_mappings(&EXT3_I(inode)->extent_tree, 0, (u64) -1);
        clear_inode(inode);     /* We must guarantee clearing of inode... */
 }
 
@@ -990,6 +993,29 @@ int ext3_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
                                    ext3_get_block);
 }
 
+static struct extent_map *ext3_map_extent(struct address_space *mapping,
+                                         struct page *page, size_t page_offset,
+                                         loff_t start, u64 len, int create,
+                                         gfp_t gfp_mask)
+{
+       struct extent_map_tree *tree = &EXT3_I(mapping->host)->extent_tree;
+       handle_t *handle = NULL;
+       struct extent_map *ret;
+
+       if (create) {
+               handle = ext3_journal_start(mapping->host, len >> 9);
+               if (IS_ERR(handle))
+                       return (struct extent_map *) handle;
+       }
+
+       ret = map_extent_get_block(tree, mapping, start, len, create, gfp_mask,
+                                       ext3_get_block);
+       if (handle)
+               ext3_journal_stop(handle);
+
+       return ret;
+}
+
 /*
  * `handle' can be NULL if create is zero
  */
@@ -1795,6 +1821,7 @@ static const struct address_space_operations ext3_ordered_aops = {
        .direct_IO              = ext3_direct_IO,
        .migratepage            = buffer_migrate_page,
        .is_partially_uptodate  = block_is_partially_uptodate,
+       .map_extent             = ext3_map_extent,
 };
 
 static const struct address_space_operations ext3_writeback_aops = {
@@ -1810,6 +1837,7 @@ static const struct address_space_operations ext3_writeback_aops = {
        .direct_IO              = ext3_direct_IO,
        .migratepage            = buffer_migrate_page,
        .is_partially_uptodate  = block_is_partially_uptodate,
+       .map_extent             = ext3_map_extent,
 };
 
 static const struct address_space_operations ext3_journalled_aops = {
@@ -1824,6 +1852,7 @@ static const struct address_space_operations ext3_journalled_aops = {
        .invalidatepage         = ext3_invalidatepage,
        .releasepage            = ext3_releasepage,
        .is_partially_uptodate  = block_is_partially_uptodate,
+       .map_extent             = ext3_map_extent,
 };
 
 void ext3_set_aops(struct inode *inode)
@@ -2835,6 +2864,7 @@ struct inode *ext3_iget(struct super_block *sb, unsigned long ino)
                        init_special_inode(inode, inode->i_mode,
                           new_decode_dev(le32_to_cpu(raw_inode->i_block[1])));
        }
+       extent_map_tree_init(&ei->extent_tree);
        brelse (iloc.bh);
        ext3_set_inode_flags(inode);
        unlock_new_inode(inode);
index 4a970411a458f4534c9c4a09f0c02026a9bbc61e..6e4dac04e4b2a6a4885ca6767107bcdc7191ef88 100644 (file)
@@ -475,6 +475,7 @@ static void ext3_destroy_inode(struct inode *inode)
                                false);
                dump_stack();
        }
+       remove_extent_mappings(&EXT3_I(inode)->extent_tree, 0, (u64) -1);
        kmem_cache_free(ext3_inode_cachep, EXT3_I(inode));
 }
 
@@ -487,6 +488,7 @@ static void init_once(void *foo)
        init_rwsem(&ei->xattr_sem);
 #endif
        mutex_init(&ei->truncate_mutex);
+       extent_map_tree_init(&ei->extent_tree);
        inode_init_once(&ei->vfs_inode);
 }
 
index 7894dd0f3b77544a8006ff1d4471554f460be093..db7bab2b20ef2dd6c5500d9c0537a90fc145b5ca 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/rbtree.h>
 #include <linux/seqlock.h>
 #include <linux/mutex.h>
+#include <linux/extent_map.h>
 
 /* data type for block offset of block group */
 typedef int ext3_grpblk_t;
@@ -142,6 +143,8 @@ struct ext3_inode_info {
         */
        struct mutex truncate_mutex;
        struct inode vfs_inode;
+
+       struct extent_map_tree extent_tree;
 };
 
 #endif /* _LINUX_EXT3_FS_I */