[Ocfs2-tools-devel] [PATCH 12/44] ocfs2: Decrement refcount when truncating refcounted extents.
Tao Ma
tao.ma at oracle.com
Mon Dec 28 01:00:57 PST 2009
Add 'Decrement refcount for delete' in to the normal truncate
process. So for a refcounted extent record, call refcount rec
decrementation instead of cluster free.
Note:
Some xattr truncate functions have to be changed to pass
inode number into truncate so that we can find the proper
refcount tree.
Signed-off-by: Tao Ma <tao.ma at oracle.com>
---
include/ocfs2/ocfs2.h | 2 +-
libocfs2/truncate.c | 31 +++++++++++++++++++++++++++++--
tunefs.ocfs2/feature_xattr.c | 17 +++++++++--------
3 files changed, 39 insertions(+), 11 deletions(-)
diff --git a/include/ocfs2/ocfs2.h b/include/ocfs2/ocfs2.h
index 0af90c4..5208cb8 100644
--- a/include/ocfs2/ocfs2.h
+++ b/include/ocfs2/ocfs2.h
@@ -1349,7 +1349,7 @@ errcode_t ocfs2_read_xattr_bucket(ocfs2_filesys *fs,
errcode_t ocfs2_write_xattr_bucket(ocfs2_filesys *fs,
uint64_t blkno,
char *bucket_buf);
-errcode_t ocfs2_xattr_value_truncate(ocfs2_filesys *fs,
+errcode_t ocfs2_xattr_value_truncate(ocfs2_filesys *fs, uint64_t ino,
struct ocfs2_xattr_value_root *xv);
errcode_t ocfs2_xattr_tree_truncate(ocfs2_filesys *fs,
struct ocfs2_xattr_tree_root *xt);
diff --git a/libocfs2/truncate.c b/libocfs2/truncate.c
index 680fca5..16119a6 100644
--- a/libocfs2/truncate.c
+++ b/libocfs2/truncate.c
@@ -30,9 +30,11 @@
#include <unistd.h>
#endif
+#include <assert.h>
#include "ocfs2/ocfs2.h"
struct truncate_ctxt {
+ uint64_t ino;
uint64_t new_size_in_clusters;
uint32_t new_i_clusters;
errcode_t (*free_clusters)(ocfs2_filesys *fs,
@@ -42,6 +44,23 @@ struct truncate_ctxt {
void *free_data;
};
+static int ocfs2_truncate_clusters(ocfs2_filesys *fs,
+ struct ocfs2_extent_rec *rec,
+ uint64_t ino,
+ uint32_t len,
+ uint64_t start)
+{
+ if (!ocfs2_refcount_tree(OCFS2_RAW_SB(fs->fs_super)) ||
+ !(rec->e_flags & OCFS2_EXT_REFCOUNTED))
+ return ocfs2_free_clusters(fs, len, start);
+
+ assert(ino);
+
+ return ocfs2_decrease_refcount(fs, ino,
+ ocfs2_blocks_to_clusters(fs, start),
+ len, 1);
+}
+
/*
* Delete and free clusters if needed. This only works with DEPTH_TRAVERSE.
*/
@@ -129,7 +148,8 @@ static int truncate_iterate(ocfs2_filesys *fs,
ret = ctxt->free_clusters(fs, len, start,
ctxt->free_data);
else
- ret = ocfs2_free_clusters(fs, len, start);
+ ret = ocfs2_truncate_clusters(fs, rec, ctxt->ino,
+ len, start);
if (ret)
goto bail;
ctxt->new_i_clusters -= len;
@@ -213,6 +233,7 @@ static errcode_t ocfs2_zero_tail_and_truncate_full(ocfs2_filesys *fs,
struct truncate_ctxt ctxt;
new_size_in_blocks = ocfs2_blocks_in_bytes(fs, new_i_size);
+ ctxt.ino = ci->ci_blkno;
ctxt.new_i_clusters = ci->ci_inode->i_clusters;
ctxt.new_size_in_clusters =
ocfs2_clusters_in_blocks(fs, new_size_in_blocks);
@@ -299,13 +320,14 @@ errcode_t ocfs2_truncate(ocfs2_filesys *fs, uint64_t ino, uint64_t new_i_size)
return ocfs2_truncate_full(fs, ino, new_i_size, NULL, NULL);
}
-errcode_t ocfs2_xattr_value_truncate(ocfs2_filesys *fs,
+errcode_t ocfs2_xattr_value_truncate(ocfs2_filesys *fs, uint64_t ino,
struct ocfs2_xattr_value_root *xv)
{
struct truncate_ctxt ctxt;
int changed;
struct ocfs2_extent_list *el = &xv->xr_list;
+ ctxt.ino = ino;
ctxt.new_i_clusters = xv->xr_clusters;
ctxt.new_size_in_clusters = 0;
@@ -322,6 +344,11 @@ errcode_t ocfs2_xattr_tree_truncate(ocfs2_filesys *fs,
int changed;
struct ocfs2_extent_list *el = &xt->xt_list;
+ /*
+ * ino is used to find refcount tree, as we never use refcount
+ * in xattr tree, so set it to 0.
+ */
+ ctxt.ino = 0;
ctxt.new_i_clusters = xt->xt_clusters;
ctxt.new_size_in_clusters = 0;
diff --git a/tunefs.ocfs2/feature_xattr.c b/tunefs.ocfs2/feature_xattr.c
index 8eef7df..ebe75e3 100644
--- a/tunefs.ocfs2/feature_xattr.c
+++ b/tunefs.ocfs2/feature_xattr.c
@@ -51,7 +51,7 @@ static void empty_xattr_context(struct xattr_context *ctxt)
}
}
-static errcode_t remove_xattr_entry(ocfs2_filesys *fs,
+static errcode_t remove_xattr_entry(ocfs2_filesys *fs, uint64_t ino,
struct ocfs2_xattr_header *xh)
{
int i;
@@ -65,7 +65,7 @@ static errcode_t remove_xattr_entry(ocfs2_filesys *fs,
(struct ocfs2_xattr_value_root *)
((void *)xh + xe->xe_name_offset +
OCFS2_XATTR_SIZE(xe->xe_name_len));
- ret = ocfs2_xattr_value_truncate(fs, xv);
+ ret = ocfs2_xattr_value_truncate(fs, ino, xv);
if (ret)
break;
}
@@ -75,6 +75,7 @@ static errcode_t remove_xattr_entry(ocfs2_filesys *fs,
}
static errcode_t remove_xattr_buckets(ocfs2_filesys *fs,
+ uint64_t ino,
uint64_t blkno,
uint32_t clusters)
{
@@ -109,7 +110,7 @@ static errcode_t remove_xattr_buckets(ocfs2_filesys *fs,
if (i == 0)
num_buckets = xh->xh_num_buckets;
- ret = remove_xattr_entry(fs, xh);
+ ret = remove_xattr_entry(fs, ino, xh);
if (ret)
break;
}
@@ -121,7 +122,7 @@ out:
}
-static errcode_t remove_xattr_index_block(ocfs2_filesys *fs,
+static errcode_t remove_xattr_index_block(ocfs2_filesys *fs, uint64_t ino,
struct ocfs2_xattr_block *xb)
{
struct ocfs2_extent_list *el = &xb->xb_attrs.xb_root.xt_list;
@@ -141,7 +142,7 @@ static errcode_t remove_xattr_index_block(ocfs2_filesys *fs,
goto out;
}
- ret = remove_xattr_buckets(fs, p_blkno, num_clusters);
+ ret = remove_xattr_buckets(fs, ino, p_blkno, num_clusters);
if (ret) {
tcom_err(ret, "while iterating bucket"
" of extended attributes ");
@@ -184,14 +185,14 @@ static errcode_t remove_xattr_block(ocfs2_filesys *fs,
if (!(xb->xb_flags & OCFS2_XATTR_INDEXED)) {
struct ocfs2_xattr_header *xh = &xb->xb_attrs.xb_header;
- ret = remove_xattr_entry(fs, xh);
+ ret = remove_xattr_entry(fs, di->i_blkno, xh);
if (ret) {
tcom_err(ret, "while trying to remove extended"
" attributes in external block ");
goto out;
}
} else {
- ret = remove_xattr_index_block(fs, xb);
+ ret = remove_xattr_index_block(fs, di->i_blkno, xb);
if (ret) {
tcom_err(ret, "while trying to remove extended"
" attributes in index block ");
@@ -229,7 +230,7 @@ static errcode_t remove_xattr_ibody(ocfs2_filesys *fs,
((void *)di + fs->fs_blocksize -
di->i_xattr_inline_size);
- ret = remove_xattr_entry(fs, xh);
+ ret = remove_xattr_entry(fs, di->i_blkno, xh);
if (ret) {
tcom_err(ret, "while trying to remove extended"
" attributes in ibody ");
--
1.5.5
More information about the Ocfs2-tools-devel
mailing list