From: Steven Whitehouse <swhiteho@redhat.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] [PATCH 12/24] GFS2: Add a rgrp bitmap full flag
Date: Wed, 10 Jun 2009 09:30:53 +0100 [thread overview]
Message-ID: <1244622665-7470-13-git-send-email-swhiteho@redhat.com> (raw)
In-Reply-To: <1244622665-7470-12-git-send-email-swhiteho@redhat.com>
During block allocation, it is useful to know if sections of disk
are full on a finer grained basis than a single resource group.
This can make a performance difference when resource groups have
larger numbers of bitmap blocks, since we no longer have to search
them all block by block in each individual bitmap.
The full flag is set on a per-bitmap basis when it has been
searched and found to have no free space. It is then skipped in
subsequent searches until the flag is reset. The resetting
occurs if we have to drop the glock on the resource group for any
reason, or if we deallocate some blocks within that resource
group and thus free up some space.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
diff --git a/fs/gfs2/incore.h b/fs/gfs2/incore.h
index de50d86..dd87379 100644
--- a/fs/gfs2/incore.h
+++ b/fs/gfs2/incore.h
@@ -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;
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c
index fbacf09..23637b9 100644
--- a/fs/gfs2/rgrp.c
+++ b/fs/gfs2/rgrp.c
@@ -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;
@@ -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;
}
@@ -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);
}
@@ -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;
@@ -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;
}
/**
--
1.6.0.6
next prev parent reply other threads:[~2009-06-10 8:30 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-06-10 8:30 [Cluster-devel] GFS2: Pre-pull patch posting Steven Whitehouse
2009-06-10 8:30 ` [Cluster-devel] [PATCH 01/24] GFS2: Update the rw flags Steven Whitehouse
2009-06-10 8:30 ` [Cluster-devel] [PATCH 02/24] GFS2: Optimise writepage for metadata Steven Whitehouse
2009-06-10 8:30 ` [Cluster-devel] [PATCH 03/24] GFS2: Something nonlinear this way comes! Steven Whitehouse
2009-06-10 8:30 ` [Cluster-devel] [PATCH 04/24] GFS2: Fix timestamps on write Steven Whitehouse
2009-06-10 8:30 ` [Cluster-devel] [PATCH 05/24] GFS2: Move journal live test at transaction start Steven Whitehouse
2009-06-10 8:30 ` [Cluster-devel] [PATCH 06/24] GFS2: Add commit= mount option Steven Whitehouse
2009-06-10 8:30 ` [Cluster-devel] [PATCH 07/24] GFS2: Remove a couple of unused sysfs entries Steven Whitehouse
2009-06-10 8:30 ` [Cluster-devel] [PATCH 08/24] GFS2: Umount recovery race fix Steven Whitehouse
2009-06-10 8:30 ` [Cluster-devel] [PATCH 09/24] GFS2: Update docs Steven Whitehouse
2009-06-10 8:30 ` [Cluster-devel] [PATCH 10/24] GFS2: Don't warn when delete inode fails on ro filesystem Steven Whitehouse
2009-06-10 8:30 ` [Cluster-devel] [PATCH 11/24] GFS2: Improve resource group error handling Steven Whitehouse
2009-06-10 8:30 ` Steven Whitehouse [this message]
2009-06-10 8:30 ` [Cluster-devel] [PATCH 13/24] GFS2: Be more aggressive in reclaiming unlinked inodes Steven Whitehouse
2009-06-10 8:30 ` [Cluster-devel] [PATCH 14/24] GFS2: Clean up some file names Steven Whitehouse
2009-06-10 8:30 ` [Cluster-devel] [PATCH 15/24] GFS2: Merge mount.c and ops_super.c into super.c Steven Whitehouse
2009-06-10 8:30 ` [Cluster-devel] [PATCH 16/24] GFS2: Move gfs2_rmdiri into ops_inode.c Steven Whitehouse
2009-06-10 8:30 ` [Cluster-devel] [PATCH 17/24] GFS2: Move gfs2_readlinki " Steven Whitehouse
2009-06-10 8:30 ` [Cluster-devel] [PATCH 18/24] GFS2: Move gfs2_unlink_ok " Steven Whitehouse
2009-06-10 8:31 ` [Cluster-devel] [PATCH 19/24] GFS2: Remove lockstruct subdir from gfs2 sysfs files Steven Whitehouse
2009-06-10 8:31 ` [Cluster-devel] [PATCH 20/24] GFS2: Remove args " Steven Whitehouse
2009-06-10 8:31 ` [Cluster-devel] [PATCH 21/24] GFS2: smbd proccess hangs with flock() call Steven Whitehouse
2009-06-10 8:31 ` [Cluster-devel] [PATCH 22/24] GFS2: Remove unused variable Steven Whitehouse
2009-06-10 8:31 ` [Cluster-devel] [PATCH 23/24] GFS2: Fix locking issue mounting gfs2meta fs Steven Whitehouse
2009-06-10 8:31 ` [Cluster-devel] [PATCH 24/24] GFS2: Fix cache coherency between truncate and O_DIRECT read Steven Whitehouse
2009-06-10 9:53 ` [Cluster-devel] Re: [PATCH 23/24] GFS2: Fix locking issue mounting gfs2meta fs Christoph Hellwig
2009-06-10 10:06 ` Steven Whitehouse
2009-06-10 10:43 ` [Cluster-devel] GFS2: Merge gfs2_get_sb into gfs2_get_sb_meta Steven Whitehouse
2009-06-10 9:49 ` [Cluster-devel] Re: [PATCH 10/24] GFS2: Don't warn when delete inode fails on ro filesystem Christoph Hellwig
2009-06-10 10:03 ` Steven Whitehouse
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1244622665-7470-13-git-send-email-swhiteho@redhat.com \
--to=swhiteho@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).