diff options
author | Tristan Ye <tristan.ye@oracle.com> | 2011-03-18 02:35:37 -0400 |
---|---|---|
committer | Tristan Ye <tristan.ye@oracle.com> | 2011-05-25 03:17:11 -0400 |
commit | e6b5859cccfa0fec02f3c5b1069481efc7186f47 (patch) | |
tree | bd0308fa3455645a5fc91e9bd50912441eb07dbf /fs/ocfs2 | |
parent | 99e4c750419e0bb24a1bbf094b1e6a5a4eedbc36 (diff) |
Ocfs2/move_extents: helper to probe a proper region to move in an alloc group.
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>
Diffstat (limited to 'fs/ocfs2')
-rw-r--r-- | fs/ocfs2/move_extents.c | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c index e928a88f2db1..ebaff625fc28 100644 --- a/fs/ocfs2/move_extents.c +++ b/fs/ocfs2/move_extents.c | |||
@@ -516,3 +516,42 @@ out: | |||
516 | 516 | ||
517 | return ret; | 517 | return ret; |
518 | } | 518 | } |
519 | |||
520 | static void ocfs2_probe_alloc_group(struct inode *inode, struct buffer_head *bh, | ||
521 | int *goal_bit, u32 move_len, u32 max_hop, | ||
522 | u32 *phys_cpos) | ||
523 | { | ||
524 | int i, used, last_free_bits = 0, base_bit = *goal_bit; | ||
525 | struct ocfs2_group_desc *gd = (struct ocfs2_group_desc *)bh->b_data; | ||
526 | u32 base_cpos = ocfs2_blocks_to_clusters(inode->i_sb, | ||
527 | le64_to_cpu(gd->bg_blkno)); | ||
528 | |||
529 | for (i = base_bit; i < le16_to_cpu(gd->bg_bits); i++) { | ||
530 | |||
531 | used = ocfs2_test_bit(i, (unsigned long *)gd->bg_bitmap); | ||
532 | if (used) { | ||
533 | /* | ||
534 | * we even tried searching the free chunk by jumping | ||
535 | * a 'max_hop' distance, but still failed. | ||
536 | */ | ||
537 | if ((i - base_bit) > max_hop) { | ||
538 | *phys_cpos = 0; | ||
539 | break; | ||
540 | } | ||
541 | |||
542 | if (last_free_bits) | ||
543 | last_free_bits = 0; | ||
544 | |||
545 | continue; | ||
546 | } else | ||
547 | last_free_bits++; | ||
548 | |||
549 | if (last_free_bits == move_len) { | ||
550 | *goal_bit = i; | ||
551 | *phys_cpos = base_cpos + i; | ||
552 | break; | ||
553 | } | ||
554 | } | ||
555 | |||
556 | mlog(0, "found phys_cpos: %u to fit the wanted moving.\n", *phys_cpos); | ||
557 | } | ||