[Ocfs2-tools-devel] [PATCH 25/44] libocfs2: Add function for punch hole in refcount tree.
Tao Ma
tao.ma at oracle.com
Mon Dec 28 01:01:10 PST 2009
In fsck.ocfs2, sometimes we need to remove the refcount
from the tree, so this patch add a new function named
ocfs2_refcount_punch_hole which will do like this.
Since the old ocfs2_split_refcount_rec is implemented
to handle the case r_refcount=0, so it is quite easy
for us to punch a hole.
Signed-off-by: Tao Ma <tao.ma at oracle.com>
---
include/ocfs2/ocfs2.h | 2 +
libocfs2/refcount.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 57 insertions(+), 0 deletions(-)
diff --git a/include/ocfs2/ocfs2.h b/include/ocfs2/ocfs2.h
index e8173ca..6589523 100644
--- a/include/ocfs2/ocfs2.h
+++ b/include/ocfs2/ocfs2.h
@@ -430,6 +430,8 @@ errcode_t ocfs2_refcount_tree_get_rec(ocfs2_filesys *fs,
uint64_t *p_blkno,
uint32_t *e_cpos,
uint32_t *num_clusters);
+errcode_t ocfs2_refcount_punch_hole(ocfs2_filesys *fs, uint64_t rf_blkno,
+ uint64_t p_start, uint32_t len);
errcode_t ocfs2_swap_dir_entries_from_cpu(void *buf, uint64_t bytes);
errcode_t ocfs2_swap_dir_entries_to_cpu(void *buf, uint64_t bytes);
void ocfs2_swap_dir_trailer(struct ocfs2_dir_block_trailer *trailer);
diff --git a/libocfs2/refcount.c b/libocfs2/refcount.c
index 3b437fb..38800fd 100644
--- a/libocfs2/refcount.c
+++ b/libocfs2/refcount.c
@@ -1885,6 +1885,61 @@ out:
return ret;
}
+errcode_t ocfs2_refcount_punch_hole(ocfs2_filesys *fs, uint64_t rf_blkno,
+ uint64_t p_start, uint32_t len)
+{
+ errcode_t ret;
+ char *root_buf = NULL, *buf = NULL;
+ struct ocfs2_refcount_rec rec;
+ int index;
+ struct ocfs2_refcount_block *root_rb, *rb;
+
+ ret = ocfs2_malloc_block(fs->fs_io, &root_buf);
+ if (ret)
+ goto out;
+
+ ret = ocfs2_malloc_block(fs->fs_io, &buf);
+ if (ret)
+ goto out;
+
+ ret = ocfs2_read_refcount_block(fs, rf_blkno, root_buf);
+ if (ret)
+ goto out;
+
+ root_rb = (struct ocfs2_refcount_block *)root_buf;
+ rb = (struct ocfs2_refcount_block *)buf;
+ while (len) {
+ ret = ocfs2_get_refcount_rec(fs, root_buf, p_start,
+ len, &rec, &index, buf);
+ if (!rec.r_refcount) {
+ /* There is no refcount for p_start. */
+ len -= rec.r_clusters;
+ p_start += rec.r_clusters;
+ continue;
+ }
+
+ rec.r_clusters = (p_start + len < rec.r_cpos + rec.r_clusters) ?
+ len : (rec.r_cpos + rec.r_clusters - p_start);
+ rec.r_cpos = p_start;
+ rec.r_refcount = 0;
+ ret = ocfs2_split_refcount_rec(fs, root_buf, buf,
+ &rec, index, 1);
+ if (ret)
+ goto out;
+ len -= rec.r_clusters;
+ p_start += rec.r_clusters;
+ /* In user space, we have to sync the buf by ourselves. */
+ if (rb->rf_blkno == root_rb->rf_blkno)
+ memcpy(root_buf, buf, fs->fs_blocksize);
+ }
+out:
+ if (root_buf)
+ ocfs2_free(&root_buf);
+ if (buf)
+ ocfs2_free(&buf);
+ return ret;
+}
+
struct xattr_value_cow_object {
struct ocfs2_xattr_value_root *xv;
uint64_t xe_blkno;
--
1.5.5
More information about the Ocfs2-tools-devel
mailing list