Btrfs: use flag EXTENT_DEFRAG for snapshot-aware defrag
authorLiu Bo <bo.li.liu@oracle.com>
Thu, 6 Sep 2012 01:10:51 +0000 (19:10 -0600)
committerChris Mason <chris.mason@fusionio.com>
Mon, 1 Oct 2012 19:19:15 +0000 (15:19 -0400)
We're going to use this flag EXTENT_DEFRAG to indicate which range
belongs to defragment so that we can implement snapshow-aware defrag:

We set the EXTENT_DEFRAG flag when dirtying the extents that need
defragmented, so later on writeback thread can differentiate between
normal writeback and writeback started by defragmentation.

Original-Signed-off-by: Li Zefan <lizf@cn.fujitsu.com>
Signed-off-by: Liu Bo <bo.li.liu@oracle.com>
fs/btrfs/extent_io.c
fs/btrfs/extent_io.h
fs/btrfs/file.c
fs/btrfs/inode.c
fs/btrfs/ioctl.c

index 19319f5a91a85506d566015f9eda00e52ce74f71..4a41b17295dcc73f89895a13ef8f00e0d1f7c589 100644 (file)
@@ -1144,6 +1144,14 @@ int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end,
                              NULL, cached_state, mask);
 }
 
+int set_extent_defrag(struct extent_io_tree *tree, u64 start, u64 end,
+                     struct extent_state **cached_state, gfp_t mask)
+{
+       return set_extent_bit(tree, start, end,
+                             EXTENT_DELALLOC | EXTENT_UPTODATE | EXTENT_DEFRAG,
+                             NULL, cached_state, mask);
+}
+
 int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end,
                       gfp_t mask)
 {
index 25900af5b15d43e6bdfe0cef7c865ac2aa81bd36..512f8da041f195ed18c8aa1b7981209ef0e80096 100644 (file)
@@ -235,6 +235,8 @@ int convert_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
                       int bits, int clear_bits, gfp_t mask);
 int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end,
                        struct extent_state **cached_state, gfp_t mask);
+int set_extent_defrag(struct extent_io_tree *tree, u64 start, u64 end,
+                     struct extent_state **cached_state, gfp_t mask);
 int find_first_extent_bit(struct extent_io_tree *tree, u64 start,
                          u64 *start_ret, u64 *end_ret, int bits);
 struct extent_state *find_first_extent_bit_state(struct extent_io_tree *tree,
index 00279c9a7f35b8cfe605e32e48be5299794deb11..0a4b03d8fcd6eed47e5c0eb28417b64cfce9dabe 100644 (file)
@@ -1203,8 +1203,8 @@ again:
 
                clear_extent_bit(&BTRFS_I(inode)->io_tree, start_pos,
                                  last_pos - 1, EXTENT_DIRTY | EXTENT_DELALLOC |
-                                 EXTENT_DO_ACCOUNTING, 0, 0, &cached_state,
-                                 GFP_NOFS);
+                                 EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
+                                 0, 0, &cached_state, GFP_NOFS);
                unlock_extent_cached(&BTRFS_I(inode)->io_tree,
                                     start_pos, last_pos - 1, &cached_state,
                                     GFP_NOFS);
index d34eb329720db6c70fb9676dce4a64290db2c8d2..9b21cf97cdd55e0bb1ab7a288df6e671f02925da 100644 (file)
@@ -3549,7 +3549,8 @@ again:
        }
 
        clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start, page_end,
-                         EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING,
+                         EXTENT_DIRTY | EXTENT_DELALLOC |
+                         EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
                          0, 0, &cached_state, GFP_NOFS);
 
        ret = btrfs_set_extent_delalloc(inode, page_start, page_end,
@@ -6061,7 +6062,8 @@ unlock:
        if (lockstart < lockend) {
                if (create && len < lockend - lockstart) {
                        clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart,
-                                        lockstart + len - 1, unlock_bits, 1, 0,
+                                        lockstart + len - 1,
+                                        unlock_bits | EXTENT_DEFRAG, 1, 0,
                                         &cached_state, GFP_NOFS);
                        /*
                         * Beside unlock, we also need to cleanup reserved space
@@ -6069,8 +6071,8 @@ unlock:
                         */
                        clear_extent_bit(&BTRFS_I(inode)->io_tree,
                                         lockstart + len, lockend,
-                                        unlock_bits | EXTENT_DO_ACCOUNTING,
-                                        1, 0, NULL, GFP_NOFS);
+                                        unlock_bits | EXTENT_DO_ACCOUNTING |
+                                        EXTENT_DEFRAG, 1, 0, NULL, GFP_NOFS);
                } else {
                        clear_extent_bit(&BTRFS_I(inode)->io_tree, lockstart,
                                         lockend, unlock_bits, 1, 0,
@@ -6635,8 +6637,8 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset)
                 */
                clear_extent_bit(tree, page_start, page_end,
                                 EXTENT_DIRTY | EXTENT_DELALLOC |
-                                EXTENT_LOCKED | EXTENT_DO_ACCOUNTING, 1, 0,
-                                &cached_state, GFP_NOFS);
+                                EXTENT_LOCKED | EXTENT_DO_ACCOUNTING |
+                                EXTENT_DEFRAG, 1, 0, &cached_state, GFP_NOFS);
                /*
                 * whoever cleared the private bit is responsible
                 * for the finish_ordered_io
@@ -6652,7 +6654,8 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset)
        }
        clear_extent_bit(tree, page_start, page_end,
                 EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC |
-                EXTENT_DO_ACCOUNTING, 1, 1, &cached_state, GFP_NOFS);
+                EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, 1, 1,
+                &cached_state, GFP_NOFS);
        __btrfs_releasepage(page, GFP_NOFS);
 
        ClearPageChecked(page);
@@ -6749,7 +6752,8 @@ again:
         * prepare_pages in the normal write path.
         */
        clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start, page_end,
-                         EXTENT_DIRTY | EXTENT_DELALLOC | EXTENT_DO_ACCOUNTING,
+                         EXTENT_DIRTY | EXTENT_DELALLOC |
+                         EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG,
                          0, 0, &cached_state, GFP_NOFS);
 
        ret = btrfs_set_extent_delalloc(inode, page_start, page_end,
index c56daa368768a2a1ac90efc48c6839d714c6ddac..de886ac7ba0fc3958913a141430e1219c275d47a 100644 (file)
@@ -1023,8 +1023,8 @@ again:
                         page_start, page_end - 1, 0, &cached_state);
        clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start,
                          page_end - 1, EXTENT_DIRTY | EXTENT_DELALLOC |
-                         EXTENT_DO_ACCOUNTING, 0, 0, &cached_state,
-                         GFP_NOFS);
+                         EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, 0, 0,
+                         &cached_state, GFP_NOFS);
 
        if (i_done != page_cnt) {
                spin_lock(&BTRFS_I(inode)->lock);
@@ -1035,8 +1035,8 @@ again:
        }
 
 
-       btrfs_set_extent_delalloc(inode, page_start, page_end - 1,
-                                 &cached_state);
+       set_extent_defrag(&BTRFS_I(inode)->io_tree, page_start, page_end - 1,
+                         &cached_state, GFP_NOFS);
 
        unlock_extent_cached(&BTRFS_I(inode)->io_tree,
                             page_start, page_end - 1, &cached_state,