[Ocfs2-tools-devel] [PATCH 1/2] Libocfs2: Truncate should handle inline file and fast symlink.

Tristan Ye tristan.ye at oracle.com
Tue Mar 23 00:50:09 PDT 2010


Truncating for inline file and fast symlink are almost the same
thing per se. we therefore treat it as one by adding a new func
in libocfs2 like in kernel side. that way, both inline file and
fast symlink could benefit from this same func.

Signed-off-by: Tristan Ye <tristan.ye at oracle.com>
---
 include/ocfs2/ocfs2.h |    2 +
 libocfs2/truncate.c   |   63 ++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 64 insertions(+), 1 deletions(-)

diff --git a/include/ocfs2/ocfs2.h b/include/ocfs2/ocfs2.h
index e302eb3..d527768 100644
--- a/include/ocfs2/ocfs2.h
+++ b/include/ocfs2/ocfs2.h
@@ -668,6 +668,8 @@ errcode_t ocfs2_allocate_unwritten_extents(ocfs2_filesys *fs, uint64_t ino,
 					   uint64_t offset, uint64_t len);
 
 errcode_t ocfs2_truncate(ocfs2_filesys *fs, uint64_t ino, uint64_t new_i_size);
+errcode_t ocfs2_truncate_inline(ocfs2_filesys *fs, uint64_t ino,
+				uint64_t new_i_size);
 errcode_t ocfs2_truncate_full(ocfs2_filesys *fs, uint64_t ino,
 			      uint64_t new_i_size,
 			      errcode_t (*free_clusters)(ocfs2_filesys *fs,
diff --git a/libocfs2/truncate.c b/libocfs2/truncate.c
index d4f198c..fbf7459 100644
--- a/libocfs2/truncate.c
+++ b/libocfs2/truncate.c
@@ -31,6 +31,7 @@
 #endif
 
 #include <assert.h>
+#include <errno.h>
 #include "ocfs2/ocfs2.h"
 
 struct truncate_ctxt {
@@ -283,6 +284,60 @@ errcode_t ocfs2_zero_tail_and_truncate(ocfs2_filesys *fs,
 						 new_clusters, NULL, NULL);
 }
 
+/*
+ * NOTE: ocfs2_truncate_inline() also handles fast symlink,
+ * since truncating for inline file and fasy symlink are
+ * almost the same thing per se.
+ */
+errcode_t ocfs2_truncate_inline(ocfs2_filesys *fs, uint64_t ino,
+				uint64_t new_i_size)
+{
+	errcode_t ret = 0;
+	char *buf = NULL;
+	struct ocfs2_dinode* di = NULL;
+	struct ocfs2_inline_data *idata = NULL;
+
+	if (!(fs->fs_flags & OCFS2_FLAG_RW))
+		return OCFS2_ET_RO_FILESYS;
+
+	ret = ocfs2_malloc_block(fs->fs_io, &buf);
+	if (ret)
+		return ret;
+
+	ret = ocfs2_read_inode(fs, ino, buf);
+	if (ret)
+		goto out_free_buf;
+
+	di = (struct ocfs2_dinode *)buf;
+	if (di->i_size < new_i_size) {
+		ret = EINVAL;
+		goto out_free_buf;
+	}
+
+	idata = &di->id2.i_data;
+
+	if (!(di->i_dyn_features & OCFS2_INLINE_DATA_FL) &&
+	    !(S_ISLNK(di->i_mode) && !di->i_clusters)) {
+		ret = EINVAL;
+		goto out_free_buf;
+	}
+
+	if (di->i_dyn_features & OCFS2_INLINE_DATA_FL)
+		memset(idata->id_data + new_i_size, 0, di->i_size - new_i_size);
+	else
+		memset(di->id2.i_symlink + new_i_size, 0,
+		       di->i_size - new_i_size); 
+
+	di->i_size = new_i_size;
+
+	ret = ocfs2_write_inode(fs, ino, buf);
+
+out_free_buf:
+	if (buf)
+		ocfs2_free(&buf);
+	return ret;
+}
+
 /* XXX care about zeroing new clusters and final partially truncated 
  * clusters */
 errcode_t ocfs2_truncate_full(ocfs2_filesys *fs, uint64_t ino,
@@ -304,8 +359,14 @@ errcode_t ocfs2_truncate_full(ocfs2_filesys *fs, uint64_t ino,
 	if (ci->ci_inode->i_size == new_i_size)
 		goto out;
 
-	if (ci->ci_inode->i_size < new_i_size)
+	if (ci->ci_inode->i_size < new_i_size) {
 		ret = ocfs2_extend_file(fs, ino, new_i_size);
+		goto out;
+	}
+
+	if ((S_ISLNK(ci->ci_inode->i_mode) && !ci->ci_inode->i_clusters) ||
+	    (ci->ci_inode->i_dyn_features & OCFS2_INLINE_DATA_FL))
+		ret = ocfs2_truncate_inline(fs, ino, new_i_size);
 	else {
 		ret = ocfs2_zero_tail_and_truncate_full(fs, ci, new_i_size,
 							&new_clusters,
-- 
1.5.5




More information about the Ocfs2-tools-devel mailing list