[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