From: swhiteho@redhat.com <swhiteho@redhat.com>
To: cluster-devel.redhat.com
Subject: [Cluster-devel] [PATCH 1/4] [GFS2] Add a function to interate over an extent
Date: Tue, 12 Feb 2008 15:33:58 +0000 [thread overview]
Message-ID: <12028304492208-git-send-email-swhiteho@redhat.com> (raw)
In-Reply-To: <12028304412239-git-send-email-swhiteho@redhat.com>
From: Steven Whitehouse <swhiteho@redhat.com>
This adds a function (currently the only use is during mapping
of already allocated blocks, but watch this space) which iterates
over a number of pointers in a block and returns the extent length.
If the initial pointer is 0 (i.e. unallocated) it will return the
number of unallocated blocks in the extent. If the initial pointer
is allocated, then it returns the number of contiguously allocated
blocks in the extent.
Signed-off-by: Steven Whitehouse <swhiteho@redhat.com>
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c
index 7f72564..6780aa5 100644
--- a/fs/gfs2/bmap.c
+++ b/fs/gfs2/bmap.c
@@ -422,6 +422,42 @@ static void release_metapath(struct metapath *mp)
brelse(mp->mp_bh[i]);
}
+/**
+ * gfs2_extent_length - Returns length of an extent of blocks
+ * @start: Start of the buffer
+ * @len: Length of the buffer in bytes
+ * @ptr: Current position in the buffer
+ * @limit: Max extent length to return (0 = unlimited)
+ * @eob: Set to 1 if we hit "end of block"
+ *
+ * If the first block is zero (unallocated) it will return the number of
+ * unallocated blocks in the extent, otherwise it will return the number
+ * of contiguous blocks in the extent.
+ *
+ * Returns: The length of the extent (minimum of one block)
+ */
+
+static inline unsigned int gfs2_extent_length(void *start, unsigned int len, __be64 *ptr, unsigned limit, int *eob)
+{
+ const __be64 *end = (start + len);
+ const __be64 *first = ptr;
+ u64 d = be64_to_cpu(*ptr);
+
+ *eob = 0;
+ do {
+ ptr++;
+ if (ptr >= end)
+ break;
+ if (limit && --limit == 0)
+ break;
+ if (d)
+ d++;
+ } while(be64_to_cpu(*ptr) == d);
+ if (ptr >= end)
+ *eob = 1;
+ return (ptr - first);
+}
+
static inline void bmap_lock(struct inode *inode, int create)
{
struct gfs2_inode *ip = GFS2_I(inode);
@@ -499,26 +535,26 @@ int gfs2_block_map(struct inode *inode, sector_t lblock,
goto out_fail;
boundary = error;
+ if (new) {
+ map_bh(bh_map, inode->i_sb, dblock);
+ if (boundary)
+ set_buffer_boundary(bh_map);
+ gfs2_trans_add_bh(ip->i_gl, mp.mp_bh[0], 1);
+ gfs2_dinode_out(ip, mp.mp_bh[0]->b_data);
+ set_buffer_new(bh_map);
+ goto out_ok;
+ }
+
if (dblock) {
+ unsigned int len;
+ struct buffer_head *bh = mp.mp_bh[ip->i_height - 1];
+ __be64 *ptr = metapointer(&boundary, ip->i_height - 1, &mp);
map_bh(bh_map, inode->i_sb, dblock);
+ len = gfs2_extent_length(bh->b_data, bh->b_size, ptr, maxlen,
+ &boundary);
+ bh_map->b_size = (len << inode->i_blkbits);
if (boundary)
set_buffer_boundary(bh_map);
- if (new) {
- gfs2_trans_add_bh(ip->i_gl, mp.mp_bh[0], 1);
- gfs2_dinode_out(ip, mp.mp_bh[0]->b_data);
- set_buffer_new(bh_map);
- goto out_ok;
- }
- while(--maxlen && !buffer_boundary(bh_map)) {
- u64 eblock;
- mp.mp_list[ip->i_height - 1]++;
- boundary = lookup_block(ip, ip->i_height - 1, &mp, 0, &new, &eblock);
- if (eblock != ++dblock)
- break;
- bh_map->b_size += (1 << inode->i_blkbits);
- if (boundary)
- set_buffer_boundary(bh_map);
- }
}
out_ok:
error = 0;
--
1.5.1.2
next prev parent reply other threads:[~2008-02-12 15:33 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-02-12 15:33 [Cluster-devel] [GFS2] More cleanup/bug fixes swhiteho
2008-02-12 15:33 ` swhiteho [this message]
2008-02-12 15:33 ` [Cluster-devel] [PATCH 2/4] [GFS2] Eliminate (almost) duplicate field from gfs2_inode swhiteho
2008-02-12 15:34 ` [Cluster-devel] [PATCH 3/4] [GFS2] Get inode buffer only once per block map call swhiteho
2008-02-12 15:34 ` [Cluster-devel] [PATCH 4/4] [GFS2] Fix bug where we called drop_bh incorrectly swhiteho
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=12028304492208-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).