diff options
author | Tristan Ye <tristan.ye@oracle.com> | 2011-03-18 02:35:36 -0400 |
---|---|---|
committer | Tristan Ye <tristan.ye@oracle.com> | 2011-05-25 03:17:10 -0400 |
commit | 99e4c750419e0bb24a1bbf094b1e6a5a4eedbc36 (patch) | |
tree | 2d9fdf13b965f6b786b1831182df02d9d5d694da /fs/ocfs2 | |
parent | 1c06b9126130aa4a917bba81c39579ed08a67b4e (diff) |
Ocfs2/move_extents: helper to validate and adjust moving goal.
First best-effort attempt to validate and adjust the goal (physical address in
block), while it can't guarantee later operation can succeed all the time since
global_bitmap may change a bit over time.
Signed-off-by: Tristan Ye <tristan.ye@oracle.com>
Diffstat (limited to 'fs/ocfs2')
-rw-r--r-- | fs/ocfs2/move_extents.c | 61 |
1 files changed, 61 insertions, 0 deletions
diff --git a/fs/ocfs2/move_extents.c b/fs/ocfs2/move_extents.c index 68e00b47332b..e928a88f2db1 100644 --- a/fs/ocfs2/move_extents.c +++ b/fs/ocfs2/move_extents.c | |||
@@ -455,3 +455,64 @@ out: | |||
455 | */ | 455 | */ |
456 | return ret; | 456 | return ret; |
457 | } | 457 | } |
458 | |||
459 | /* | ||
460 | * XXX: helper to validate and adjust moving goal. | ||
461 | */ | ||
462 | static int ocfs2_validate_and_adjust_move_goal(struct inode *inode, | ||
463 | struct ocfs2_move_extents *range) | ||
464 | { | ||
465 | int ret, goal_bit = 0; | ||
466 | |||
467 | struct buffer_head *gd_bh = NULL; | ||
468 | struct ocfs2_group_desc *bg; | ||
469 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
470 | int c_to_b = 1 << (osb->s_clustersize_bits - | ||
471 | inode->i_sb->s_blocksize_bits); | ||
472 | |||
473 | /* | ||
474 | * validate goal sits within global_bitmap, and return the victim | ||
475 | * group desc | ||
476 | */ | ||
477 | ret = ocfs2_find_victim_alloc_group(inode, range->me_goal, | ||
478 | GLOBAL_BITMAP_SYSTEM_INODE, | ||
479 | OCFS2_INVALID_SLOT, | ||
480 | &goal_bit, &gd_bh); | ||
481 | if (ret) | ||
482 | goto out; | ||
483 | |||
484 | bg = (struct ocfs2_group_desc *)gd_bh->b_data; | ||
485 | |||
486 | /* | ||
487 | * make goal become cluster aligned. | ||
488 | */ | ||
489 | if (range->me_goal % c_to_b) | ||
490 | range->me_goal = range->me_goal / c_to_b * c_to_b; | ||
491 | |||
492 | /* | ||
493 | * moving goal is not allowd to start with a group desc blok(#0 blk) | ||
494 | * let's compromise to the latter cluster. | ||
495 | */ | ||
496 | if (range->me_goal == le64_to_cpu(bg->bg_blkno)) | ||
497 | range->me_goal += c_to_b; | ||
498 | |||
499 | /* | ||
500 | * movement is not gonna cross two groups. | ||
501 | */ | ||
502 | if ((le16_to_cpu(bg->bg_bits) - goal_bit) * osb->s_clustersize < | ||
503 | range->me_len) { | ||
504 | ret = -EINVAL; | ||
505 | goto out; | ||
506 | } | ||
507 | /* | ||
508 | * more exact validations/adjustments will be performed later during | ||
509 | * moving operation for each extent range. | ||
510 | */ | ||
511 | mlog(0, "extents get ready to be moved to #%llu block\n", | ||
512 | range->me_goal); | ||
513 | |||
514 | out: | ||
515 | brelse(gd_bh); | ||
516 | |||
517 | return ret; | ||
518 | } | ||