Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 251807
b: refs/heads/master
c: 1c06b91
h: refs/heads/master
i:
  251805: ad1dc49
  251803: c95963c
  251799: fc423d7
  251791: 3497e2e
  251775: bec92d8
v: v3
  • Loading branch information
Tristan Ye committed May 25, 2011
1 parent 71f0124 commit 036ffe8
Show file tree
Hide file tree
Showing 2 changed files with 105 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 202ee5facb2c55f36a4324a4f56d8bdf3617a579
refs/heads/master: 1c06b9126130aa4a917bba81c39579ed08a67b4e
104 changes: 104 additions & 0 deletions trunk/fs/ocfs2/move_extents.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,3 +351,107 @@ static int ocfs2_defrag_extent(struct ocfs2_move_extents_context *context,

return ret;
}

/*
* find the victim alloc group, where #blkno fits.
*/
static int ocfs2_find_victim_alloc_group(struct inode *inode,
u64 vict_blkno,
int type, int slot,
int *vict_bit,
struct buffer_head **ret_bh)
{
int ret, i, blocks_per_unit = 1;
u64 blkno;
char namebuf[40];

struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
struct buffer_head *ac_bh = NULL, *gd_bh = NULL;
struct ocfs2_chain_list *cl;
struct ocfs2_chain_rec *rec;
struct ocfs2_dinode *ac_dinode;
struct ocfs2_group_desc *bg;

ocfs2_sprintf_system_inode_name(namebuf, sizeof(namebuf), type, slot);
ret = ocfs2_lookup_ino_from_name(osb->sys_root_inode, namebuf,
strlen(namebuf), &blkno);
if (ret) {
ret = -ENOENT;
goto out;
}

ret = ocfs2_read_blocks_sync(osb, blkno, 1, &ac_bh);
if (ret) {
mlog_errno(ret);
goto out;
}

ac_dinode = (struct ocfs2_dinode *)ac_bh->b_data;
cl = &(ac_dinode->id2.i_chain);
rec = &(cl->cl_recs[0]);

if (type == GLOBAL_BITMAP_SYSTEM_INODE)
blocks_per_unit <<= (osb->s_clustersize_bits -
inode->i_sb->s_blocksize_bits);
/*
* 'vict_blkno' was out of the valid range.
*/
if ((vict_blkno < le64_to_cpu(rec->c_blkno)) ||
(vict_blkno >= (le32_to_cpu(ac_dinode->id1.bitmap1.i_total) *
blocks_per_unit))) {
ret = -EINVAL;
goto out;
}

for (i = 0; i < le16_to_cpu(cl->cl_next_free_rec); i++) {

rec = &(cl->cl_recs[i]);
if (!rec)
continue;

bg = NULL;

do {
if (!bg)
blkno = le64_to_cpu(rec->c_blkno);
else
blkno = le64_to_cpu(bg->bg_next_group);

if (gd_bh) {
brelse(gd_bh);
gd_bh = NULL;
}

ret = ocfs2_read_blocks_sync(osb, blkno, 1, &gd_bh);
if (ret) {
mlog_errno(ret);
goto out;
}

bg = (struct ocfs2_group_desc *)gd_bh->b_data;

if (vict_blkno < (le64_to_cpu(bg->bg_blkno) +
le16_to_cpu(bg->bg_bits))) {

*ret_bh = gd_bh;
*vict_bit = (vict_blkno - blkno) /
blocks_per_unit;
mlog(0, "find the victim group: #%llu, "
"total_bits: %u, vict_bit: %u\n",
blkno, le16_to_cpu(bg->bg_bits),
*vict_bit);
goto out;
}

} while (le64_to_cpu(bg->bg_next_group));
}

ret = -EINVAL;
out:
brelse(ac_bh);

/*
* caller has to release the gd_bh properly.
*/
return ret;
}

0 comments on commit 036ffe8

Please sign in to comment.