[Ocfs2-tools-devel] [PATCH 08/22] libocfs2: Make inode_scan notices discontig groups.
Tao Ma
tao.ma at oracle.com
Wed Mar 31 21:41:12 PDT 2010
inode_scan is used to iterate all the inodes in the
ocfs2 volume. So this patch make inode_scan work
with discontiguous block group.
The change includes:
1. Add a new function named get_next_read_blocks which
will get the num_blocks to read and set cur_blkno
properly if a discontig inode group is encountered.
2. Change 'bpos' to b_offset. The old 'bpos' is used
to indicate a block physical position in the block
group, b_offset will be used as a virtual offset
in the whole block group. It is almost the same.
Signed-off-by: Tao Ma <tao.ma at oracle.com>
---
libocfs2/inode_scan.c | 76 ++++++++++++++++++++++++++++++++++++++-----------
1 files changed, 59 insertions(+), 17 deletions(-)
diff --git a/libocfs2/inode_scan.c b/libocfs2/inode_scan.c
index 35e7cb4..89e2a3e 100644
--- a/libocfs2/inode_scan.c
+++ b/libocfs2/inode_scan.c
@@ -53,7 +53,8 @@ struct _ocfs2_inode_scan {
int buffer_blocks;
int blocks_in_buffer;
unsigned int blocks_left;
- uint64_t bpos;
+ uint64_t b_offset; /* bit offset in the group bitmap. */
+ uint16_t cur_discontig_rec; /* Only valid in discontig group. */
};
@@ -67,7 +68,7 @@ static errcode_t get_next_group(ocfs2_inode_scan *scan)
errcode_t ret;
if (!scan->cur_desc) {
- if (scan->bpos)
+ if (scan->b_offset)
abort();
ret = ocfs2_malloc_block(scan->fs->fs_io,
@@ -76,7 +77,7 @@ static errcode_t get_next_group(ocfs2_inode_scan *scan)
return ret;
}
- if (scan->bpos)
+ if (scan->b_offset)
scan->cur_blkno = scan->cur_desc->bg_next_group;
/*
@@ -87,7 +88,7 @@ static errcode_t get_next_group(ocfs2_inode_scan *scan)
abort();
ret = ocfs2_read_group_desc(scan->fs, scan->cur_blkno,
- (char *)scan->cur_desc, 0);
+ (char *)scan->cur_desc, 1);
if (ret)
return (ret);
@@ -98,7 +99,8 @@ static errcode_t get_next_group(ocfs2_inode_scan *scan)
scan->cur_blkno++;
scan->count++;
scan->blocks_left--;
- scan->bpos = scan->cur_blkno;
+ scan->b_offset = 1;
+ scan->cur_discontig_rec = 0;
return 0;
}
@@ -130,13 +132,60 @@ static errcode_t get_next_chain(ocfs2_inode_scan *scan)
scan->cur_rec = &di->id2.i_chain.cl_recs[scan->next_rec];
scan->next_rec++;
scan->count = 0;
- scan->bpos = 0;
+ scan->b_offset = 0;
scan->cur_blkno = scan->cur_rec->c_blkno;
return 0;
}
/*
+ * Get the number of blocks we will read next.
+ * In case of discontiguous group, we will set scan->cur_blkno in case
+ * we need to read next extent record.
+ */
+static int get_next_read_blocks(ocfs2_inode_scan *scan)
+{
+ int num_blocks, rec_end;
+ struct ocfs2_extent_rec *rec;
+
+ if (!scan->cur_desc)
+ abort();
+
+ if (!scan->cur_desc->bg_list.l_next_free_rec) {
+ /* Contiguous group. Just set num_blocks. */
+ num_blocks = scan->cur_desc->bg_bits - scan->b_offset;
+ goto out;
+ }
+
+ /* We shouldn't arrived here. */
+ if (scan->cur_discontig_rec == scan->cur_desc->bg_list.l_next_free_rec)
+ abort();
+
+ rec = &scan->cur_desc->bg_list.l_recs[scan->cur_discontig_rec];
+ rec_end = ocfs2_clusters_to_blocks(scan->fs,
+ rec->e_cpos + rec->e_leaf_clusters);
+ if (rec_end < scan->b_offset)
+ abort();
+ else if (rec_end > scan->b_offset) {
+ /* OK, we have more blocks to read in this rec. */
+ num_blocks = rec_end - scan->b_offset;
+ } else {
+ /* We have to read the next rec now. */
+ scan->cur_discontig_rec++;
+ rec = &scan->cur_desc->bg_list.l_recs[scan->cur_discontig_rec];
+ scan->cur_blkno = rec->e_blkno;
+ num_blocks = ocfs2_clusters_to_blocks(scan->fs,
+ rec->e_leaf_clusters);
+ }
+
+out:
+ if (num_blocks > scan->buffer_blocks)
+ num_blocks = scan->buffer_blocks;
+
+ return num_blocks;
+}
+
+/*
* This function is called by ocfs2_get_next_inode when it needs
* to read in more clusters from the current inode alloc file. It
* must not be called when the current inode alloc file has been read
@@ -151,8 +200,7 @@ static errcode_t fill_group_buffer(ocfs2_inode_scan *scan)
if (scan->cur_rec && (scan->count > scan->cur_rec->c_total))
abort();
- if (scan->cur_rec && (scan->bpos > (scan->cur_desc->bg_blkno +
- scan->cur_desc->bg_bits)))
+ if (scan->cur_rec && (scan->b_offset > scan->cur_desc->bg_bits))
abort();
if (!scan->cur_rec || (scan->count == scan->cur_rec->c_total)) {
@@ -161,26 +209,20 @@ static errcode_t fill_group_buffer(ocfs2_inode_scan *scan)
return ret;
}
- if (!scan->bpos || (scan->bpos == (scan->cur_desc->bg_blkno +
- scan->cur_desc->bg_bits))) {
+ if (!scan->b_offset || (scan->b_offset == scan->cur_desc->bg_bits)) {
ret = get_next_group(scan);
if (ret)
return ret;
}
-
- num_blocks = (scan->cur_desc->bg_blkno +
- scan->cur_desc->bg_bits) - scan->bpos;
-
- if (num_blocks > scan->buffer_blocks)
- num_blocks = scan->buffer_blocks;
+ num_blocks = get_next_read_blocks(scan);
ret = ocfs2_read_blocks(scan->fs, scan->cur_blkno, num_blocks,
scan->group_buffer);
if (ret)
return ret;
- scan->bpos += num_blocks;
+ scan->b_offset += num_blocks;
scan->blocks_in_buffer = num_blocks;
scan->cur_block = scan->group_buffer;
--
1.5.5
More information about the Ocfs2-tools-devel
mailing list