Ocfs2/move_extents: helper to probe a proper region to move in an alloc group.
authorTristan Ye <tristan.ye@oracle.com>
Fri, 18 Mar 2011 06:35:37 +0000 (14:35 +0800)
committerTristan Ye <tristan.ye@oracle.com>
Wed, 25 May 2011 07:17:11 +0000 (15:17 +0800)
Before doing the movement of extents, we'd better probe the alloc group from
'goal_blk' for searching a contiguous region to fit the wanted movement, we
even will have a best-effort try by compromising to a threshold around the
given goal.

Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
fs/ocfs2/move_extents.c

index e928a88f2db19110a945d279ef8927cd914ae7ec..ebaff625fc2837a64143b45607b0168d9a161b8b 100644 (file)
@@ -516,3 +516,42 @@ out:
 
        return ret;
 }
+
+static void ocfs2_probe_alloc_group(struct inode *inode, struct buffer_head *bh,
+                                   int *goal_bit, u32 move_len, u32 max_hop,
+                                   u32 *phys_cpos)
+{
+       int i, used, last_free_bits = 0, base_bit = *goal_bit;
+       struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data;
+       u32 base_cpos = ocfs2_blocks_to_clusters(inode->i_sb,
+                                                le64_to_cpu(gd->bg_blkno));
+
+       for (i = base_bit; i < le16_to_cpu(gd->bg_bits); i++) {
+
+               used = ocfs2_test_bit(i, (unsigned long *)gd->bg_bitmap);
+               if (used) {
+                       /*
+                        * we even tried searching the free chunk by jumping
+                        * a 'max_hop' distance, but still failed.
+                        */
+                       if ((i - base_bit) > max_hop) {
+                               *phys_cpos = 0;
+                               break;
+                       }
+
+                       if (last_free_bits)
+                               last_free_bits = 0;
+
+                       continue;
+               } else
+                       last_free_bits++;
+
+               if (last_free_bits == move_len) {
+                       *goal_bit = i;
+                       *phys_cpos = base_cpos + i;
+                       break;
+               }
+       }
+
+       mlog(0, "found phys_cpos: %u to fit the wanted moving.\n", *phys_cpos);
+}