Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 146923
b: refs/heads/master
c: 60a0b8f
h: refs/heads/master
i:
  146921: f61e22f
  146919: d183ae3
v: v3
  • Loading branch information
Steven Whitehouse committed May 21, 2009
1 parent c01b557 commit b206d0b
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 31 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: 09010978345e8883003bf411bb99753710eb5a3a
refs/heads/master: 60a0b8f93664621a07b93273fc8ebc29590c62f5
3 changes: 3 additions & 0 deletions trunk/fs/gfs2/incore.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,12 @@ struct gfs2_log_element {
const struct gfs2_log_operations *le_ops;
};

#define GBF_FULL 1

struct gfs2_bitmap {
struct buffer_head *bi_bh;
char *bi_clone;
unsigned long bi_flags;
u32 bi_offset;
u32 bi_start;
u32 bi_len;
Expand Down
77 changes: 47 additions & 30 deletions trunk/fs/gfs2/rgrp.c
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,7 @@ static int compute_bitstructs(struct gfs2_rgrpd *rgd)
for (x = 0; x < length; x++) {
bi = rgd->rd_bits + x;

bi->bi_flags = 0;
/* small rgrp; bitmap stored completely in header block */
if (length == 1) {
bytes = bytes_left;
Expand Down Expand Up @@ -769,6 +770,8 @@ int gfs2_rgrp_bh_get(struct gfs2_rgrpd *rgd)
}

if (!(rgd->rd_flags & GFS2_RDF_UPTODATE)) {
for (x = 0; x < length; x++)
clear_bit(GBF_FULL, &rgd->rd_bits[x].bi_flags);
gfs2_rgrp_in(rgd, (rgd->rd_bits[0].bi_bh)->b_data);
rgd->rd_flags |= GFS2_RDF_UPTODATE;
}
Expand Down Expand Up @@ -897,6 +900,7 @@ void gfs2_rgrp_repolish_clones(struct gfs2_rgrpd *rgd)
continue;
if (sdp->sd_args.ar_discard)
gfs2_rgrp_send_discards(sdp, rgd->rd_data0, bi);
clear_bit(GBF_FULL, &bi->bi_flags);
memcpy(bi->bi_clone + bi->bi_offset,
bi->bi_bh->b_data + bi->bi_offset, bi->bi_len);
}
Expand Down Expand Up @@ -1309,30 +1313,37 @@ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal,
{
struct gfs2_bitmap *bi = NULL;
const u32 length = rgd->rd_length;
u32 blk = 0;
u32 blk = BFITNOENT;
unsigned int buf, x;
const unsigned int elen = *n;
const u8 *buffer;
const u8 *buffer = NULL;

*n = 0;
/* Find bitmap block that contains bits for goal block */
for (buf = 0; buf < length; buf++) {
bi = rgd->rd_bits + buf;
if (goal < (bi->bi_start + bi->bi_len) * GFS2_NBBY)
break;
/* Convert scope of "goal" from rgrp-wide to within found bit block */
if (goal < (bi->bi_start + bi->bi_len) * GFS2_NBBY) {
goal -= bi->bi_start * GFS2_NBBY;
goto do_search;
}
}
buf = 0;
goal = 0;

gfs2_assert(rgd->rd_sbd, buf < length);

/* Convert scope of "goal" from rgrp-wide to within found bit block */
goal -= bi->bi_start * GFS2_NBBY;

do_search:
/* Search (up to entire) bitmap in this rgrp for allocatable block.
"x <= length", instead of "x < length", because we typically start
the search in the middle of a bit block, but if we can't find an
allocatable block anywhere else, we want to be able wrap around and
search in the first part of our first-searched bit block. */
for (x = 0; x <= length; x++) {
bi = rgd->rd_bits + buf;

if (test_bit(GBF_FULL, &bi->bi_flags) &&
(old_state == GFS2_BLKST_FREE))
goto skip;

/* The GFS2_BLKST_UNLINKED state doesn't apply to the clone
bitmaps, so we must search the originals for that. */
buffer = bi->bi_bh->b_data + bi->bi_offset;
Expand All @@ -1343,33 +1354,39 @@ static u32 rgblk_search(struct gfs2_rgrpd *rgd, u32 goal,
if (blk != BFITNOENT)
break;

if ((goal == 0) && (old_state == GFS2_BLKST_FREE))
set_bit(GBF_FULL, &bi->bi_flags);

/* Try next bitmap block (wrap back to rgrp header if at end) */
buf = (buf + 1) % length;
bi = rgd->rd_bits + buf;
skip:
buf++;
buf %= length;
goal = 0;
}

if (blk != BFITNOENT && old_state != new_state) {
*n = 1;
gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1);
if (blk == BFITNOENT)
return blk;
*n = 1;
if (old_state == new_state)
goto out;

gfs2_trans_add_bh(rgd->rd_gl, bi->bi_bh, 1);
gfs2_setbit(rgd, bi->bi_bh->b_data, bi->bi_clone, bi->bi_offset,
bi->bi_len, blk, new_state);
goal = blk;
while (*n < elen) {
goal++;
if (goal >= (bi->bi_len * GFS2_NBBY))
break;
if (gfs2_testbit(rgd, buffer, bi->bi_len, goal) !=
GFS2_BLKST_FREE)
break;
gfs2_setbit(rgd, bi->bi_bh->b_data, bi->bi_clone, bi->bi_offset,
bi->bi_len, blk, new_state);
goal = blk;
while (*n < elen) {
goal++;
if (goal >= (bi->bi_len * GFS2_NBBY))
break;
if (gfs2_testbit(rgd, buffer, bi->bi_len, goal) !=
GFS2_BLKST_FREE)
break;
gfs2_setbit(rgd, bi->bi_bh->b_data, bi->bi_clone,
bi->bi_offset, bi->bi_len, goal,
new_state);
(*n)++;
}
bi->bi_len, goal, new_state);
(*n)++;
}

return (blk == BFITNOENT) ? blk : (bi->bi_start * GFS2_NBBY) + blk;
out:
return (bi->bi_start * GFS2_NBBY) + blk;
}

/**
Expand Down

0 comments on commit b206d0b

Please sign in to comment.