Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 33365
b: refs/heads/master
c: 883d4ca
h: refs/heads/master
i:
  33363: bba27a3
v: v3
  • Loading branch information
Mark Fasheh committed Aug 7, 2006
1 parent 13a64c0 commit fcb5d1c
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 14 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7bf72edee614e10b8d470c40a326f47bfdd69992
refs/heads/master: 883d4cae4a2b01a05193cf2665c77b7489a8b6a0
8 changes: 8 additions & 0 deletions trunk/fs/ocfs2/localalloc.c
Original file line number Diff line number Diff line change
Expand Up @@ -840,6 +840,12 @@ static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb,

mlog(0, "Allocating %u clusters for a new window.\n",
ocfs2_local_alloc_window_bits(osb));

/* Instruct the allocation code to try the most recently used
* cluster group. We'll re-record the group used this pass
* below. */
ac->ac_last_group = osb->la_last_gd;

/* we used the generic suballoc reserve function, but we set
* everything up nicely, so there's no reason why we can't use
* the more specific cluster api to claim bits. */
Expand All @@ -852,6 +858,8 @@ static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb,
goto bail;
}

osb->la_last_gd = ac->ac_last_group;

la->la_bm_off = cpu_to_le32(cluster_off);
alloc->id1.bitmap1.i_total = cpu_to_le32(cluster_count);
/* just in case... In the future when we find space ourselves,
Expand Down
1 change: 1 addition & 0 deletions trunk/fs/ocfs2/ocfs2.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ struct ocfs2_super

enum ocfs2_local_alloc_state local_alloc_state;
struct buffer_head *local_alloc_bh;
u64 la_last_gd;

/* Next two fields are for local node slot recovery during
* mount. */
Expand Down
147 changes: 134 additions & 13 deletions trunk/fs/ocfs2/suballoc.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,6 @@ static int ocfs2_block_group_search(struct inode *inode,
struct buffer_head *group_bh,
u32 bits_wanted, u32 min_bits,
u16 *bit_off, u16 *bits_found);
static int ocfs2_search_chain(struct ocfs2_alloc_context *ac,
u32 bits_wanted,
u32 min_bits,
u16 *bit_off,
unsigned int *num_bits,
u64 *bg_blkno);
static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb,
struct ocfs2_alloc_context *ac,
u32 bits_wanted,
Expand Down Expand Up @@ -1030,12 +1024,103 @@ static int ocfs2_block_group_search(struct inode *inode,
return ret;
}

static int ocfs2_alloc_dinode_update_counts(struct inode *inode,
struct ocfs2_journal_handle *handle,
struct buffer_head *di_bh,
u32 num_bits,
u16 chain)
{
int ret;
u32 tmp_used;
struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data;
struct ocfs2_chain_list *cl = (struct ocfs2_chain_list *) &di->id2.i_chain;

ret = ocfs2_journal_access(handle, inode, di_bh,
OCFS2_JOURNAL_ACCESS_WRITE);
if (ret < 0) {
mlog_errno(ret);
goto out;
}

tmp_used = le32_to_cpu(di->id1.bitmap1.i_used);
di->id1.bitmap1.i_used = cpu_to_le32(num_bits + tmp_used);
le32_add_cpu(&cl->cl_recs[chain].c_free, -num_bits);

ret = ocfs2_journal_dirty(handle, di_bh);
if (ret < 0)
mlog_errno(ret);

out:
return ret;
}

static int ocfs2_search_one_group(struct ocfs2_alloc_context *ac,
u32 bits_wanted,
u32 min_bits,
u16 *bit_off,
unsigned int *num_bits,
u64 gd_blkno,
u16 *bits_left)
{
int ret;
u16 found;
struct buffer_head *group_bh = NULL;
struct ocfs2_group_desc *gd;
struct inode *alloc_inode = ac->ac_inode;
struct ocfs2_journal_handle *handle = ac->ac_handle;

ret = ocfs2_read_block(OCFS2_SB(alloc_inode->i_sb), gd_blkno,
&group_bh, OCFS2_BH_CACHED, alloc_inode);
if (ret < 0) {
mlog_errno(ret);
return ret;
}

gd = (struct ocfs2_group_desc *) group_bh->b_data;
if (!OCFS2_IS_VALID_GROUP_DESC(gd)) {
OCFS2_RO_ON_INVALID_GROUP_DESC(alloc_inode->i_sb, gd);
ret = -EIO;
goto out;
}

ret = ac->ac_group_search(alloc_inode, group_bh, bits_wanted, min_bits,
bit_off, &found);
if (ret < 0) {
if (ret != -ENOSPC)
mlog_errno(ret);
goto out;
}

*num_bits = found;

ret = ocfs2_alloc_dinode_update_counts(alloc_inode, handle, ac->ac_bh,
*num_bits,
le16_to_cpu(gd->bg_chain));
if (ret < 0) {
mlog_errno(ret);
goto out;
}

ret = ocfs2_block_group_set_bits(handle, alloc_inode, gd, group_bh,
*bit_off, *num_bits);
if (ret < 0)
mlog_errno(ret);

*bits_left = le16_to_cpu(gd->bg_free_bits_count);

out:
brelse(group_bh);

return ret;
}

static int ocfs2_search_chain(struct ocfs2_alloc_context *ac,
u32 bits_wanted,
u32 min_bits,
u16 *bit_off,
unsigned int *num_bits,
u64 *bg_blkno)
u64 *bg_blkno,
u16 *bits_left)
{
int status;
u16 chain, tmp_bits;
Expand Down Expand Up @@ -1173,6 +1258,7 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac,
(unsigned long long)fe->i_blkno);

*bg_blkno = le64_to_cpu(bg->bg_blkno);
*bits_left = le16_to_cpu(bg->bg_free_bits_count);
bail:
if (group_bh)
brelse(group_bh);
Expand All @@ -1194,6 +1280,8 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb,
{
int status;
u16 victim, i;
u16 bits_left = 0;
u64 hint_blkno = ac->ac_last_group;
struct ocfs2_chain_list *cl;
struct ocfs2_dinode *fe;

Expand All @@ -1220,16 +1308,38 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb,
goto bail;
}

if (hint_blkno) {
/* Attempt to short-circuit the usual search mechanism
* by jumping straight to the most recently used
* allocation group. This helps us mantain some
* contiguousness across allocations. */
status = ocfs2_search_one_group(ac, bits_wanted, min_bits,
bit_off, num_bits,
hint_blkno, &bits_left);
if (!status) {
/* Be careful to update *bg_blkno here as the
* caller is expecting it to be filled in, and
* ocfs2_search_one_group() won't do that for
* us. */
*bg_blkno = hint_blkno;
goto set_hint;
}
if (status < 0 && status != -ENOSPC) {
mlog_errno(status);
goto bail;
}
}

cl = (struct ocfs2_chain_list *) &fe->id2.i_chain;

victim = ocfs2_find_victim_chain(cl);
ac->ac_chain = victim;
ac->ac_allow_chain_relink = 1;

status = ocfs2_search_chain(ac, bits_wanted, min_bits, bit_off,
num_bits, bg_blkno);
num_bits, bg_blkno, &bits_left);
if (!status)
goto bail;
goto set_hint;
if (status < 0 && status != -ENOSPC) {
mlog_errno(status);
goto bail;
Expand All @@ -1251,17 +1361,28 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb,

ac->ac_chain = i;
status = ocfs2_search_chain(ac, bits_wanted, min_bits,
bit_off, num_bits,
bg_blkno);
bit_off, num_bits, bg_blkno,
&bits_left);
if (!status)
break;
if (status < 0 && status != -ENOSPC) {
mlog_errno(status);
goto bail;
}
}
bail:

set_hint:
if (status != -ENOSPC) {
/* If the next search of this group is not likely to
* yield a suitable extent, then we reset the last
* group hint so as to not waste a disk read */
if (bits_left < min_bits)
ac->ac_last_group = 0;
else
ac->ac_last_group = *bg_blkno;
}

bail:
mlog_exit(status);
return status;
}
Expand Down Expand Up @@ -1415,7 +1536,7 @@ int ocfs2_claim_clusters(struct ocfs2_super *osb,
{
int status;
unsigned int bits_wanted = ac->ac_bits_wanted - ac->ac_bits_given;
u64 bg_blkno;
u64 bg_blkno = 0;
u16 bg_bit_off;

mlog_entry_void();
Expand Down
2 changes: 2 additions & 0 deletions trunk/fs/ocfs2/suballoc.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ struct ocfs2_alloc_context {
u16 ac_chain;
int ac_allow_chain_relink;
group_search_t *ac_group_search;

u64 ac_last_group;
};

void ocfs2_free_alloc_context(struct ocfs2_alloc_context *ac);
Expand Down

0 comments on commit fcb5d1c

Please sign in to comment.