Tao Ma
2008-Dec-04 22:20 UTC
[Ocfs2-devel] [PATCH 1/3] ocfs2/xattr: Remove one extend_trans and add its credit in the beginning.
Actually, when setting a new xattr value, we know it from the very
beginning, and it isn't like the extension of bucket in which case
we can't figure it out. So remove ocfs2_extend_trans in that function
and calculate it before the transaction. It also relieve acl operation
from the worry about the side effect of ocfs2_extend_trans.
Signed-off-by: Tao Ma <tao.ma at oracle.com>
---
fs/ocfs2/xattr.c | 23 ++++++++++-------------
1 files changed, 10 insertions(+), 13 deletions(-)
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 7e0d62a..8fb8457 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -1138,7 +1138,7 @@ static int __ocfs2_xattr_set_value_outside(struct inode
*inode,
const void *value,
int value_len)
{
- int ret = 0, i, cp_len, credits;
+ int ret = 0, i, cp_len;
u16 blocksize = inode->i_sb->s_blocksize;
u32 p_cluster, num_clusters;
u32 cpos = 0, bpc = ocfs2_clusters_to_blocks(inode->i_sb, 1);
@@ -1148,18 +1148,6 @@ static int __ocfs2_xattr_set_value_outside(struct inode
*inode,
BUG_ON(clusters > le32_to_cpu(xv->xr_clusters));
- /*
- * In __ocfs2_xattr_set_value_outside has already been dirtied,
- * so we don't need to worry about whether ocfs2_extend_trans
- * will create a new transactio for us or not.
- */
- credits = clusters * bpc;
- ret = ocfs2_extend_trans(handle, credits);
- if (ret) {
- mlog_errno(ret);
- goto out;
- }
-
while (cpos < clusters) {
ret = ocfs2_xattr_get_clusters(inode, cpos, &p_cluster,
&num_clusters, &xv->xr_list);
@@ -2184,6 +2172,15 @@ static int ocfs2_calc_xattr_set_need(struct inode *inode,
xi->value_len);
u64 value_size;
+ /*
+ * Calculate the clusters we need to write.
+ * No matter whether we replace an old one or add a new one,
+ * we need this for writing.
+ */
+ if (xi->value_len > OCFS2_XATTR_INLINE_SIZE)
+ credits += new_clusters *
+ ocfs2_clusters_to_blocks(inode->i_sb, 1);
+
if (xis->not_found && xbs->not_found) {
credits += ocfs2_blocks_per_xattr_bucket(inode->i_sb);
--
1.5.4.GIT
Tao Ma
2008-Dec-04 22:20 UTC
[Ocfs2-devel] [PATCH 2/3] ocfs2/xattr: Always updating ctime in xattr set.
In xattr set, we should always update ctime if the operation goes
sucessfully. The old one mistakenly put it in ocfs2_xattr_set_entry
which is only called when we set xattr in inode or xattr block. The
side benefit is that it resolve the bug 1052 since in that scenario,
ocfs2_calc_xattr_set_need only calc out the xattr set credits while
ocfs2_xattr_set_entry update the inode also which isn't concerned with
the process of xattr set.
Signed-off-by: Tao Ma <tao.ma at oracle.com>
---
fs/ocfs2/xattr.c | 20 ++++++++++++++++----
1 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 8fb8457..34c6850 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -1609,10 +1609,6 @@ static int ocfs2_xattr_set_entry(struct inode *inode,
oi->ip_dyn_features |= flag;
di->i_dyn_features = cpu_to_le16(oi->ip_dyn_features);
spin_unlock(&oi->ip_lock);
- /* Update inode ctime */
- inode->i_ctime = CURRENT_TIME;
- di->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec);
- di->i_ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec);
ret = ocfs2_journal_dirty(handle, xs->inode_bh);
if (ret < 0)
@@ -2525,6 +2521,20 @@ static int __ocfs2_xattr_set_handle(struct inode *inode,
}
}
+ if (!ret) {
+ /* Update inode ctime. */
+ ret = ocfs2_journal_access(ctxt->handle, inode, xis->inode_bh,
+ OCFS2_JOURNAL_ACCESS_WRITE);
+ if (ret) {
+ mlog_errno(ret);
+ goto out;
+ }
+
+ inode->i_ctime = CURRENT_TIME;
+ di->i_ctime = cpu_to_le64(inode->i_ctime.tv_sec);
+ di->i_ctime_nsec = cpu_to_le32(inode->i_ctime.tv_nsec);
+ ocfs2_journal_dirty(ctxt->handle, xis->inode_bh);
+ }
out:
return ret;
}
@@ -2701,6 +2711,8 @@ int ocfs2_xattr_set(struct inode *inode,
goto cleanup;
}
+ /* we need to update inode's ctime field, so add credit for it. */
+ credits += OCFS2_INODE_UPDATE_CREDITS;
ctxt.handle = ocfs2_start_trans(osb, credits);
if (IS_ERR(ctxt.handle)) {
ret = PTR_ERR(ctxt.handle);
--
1.5.4.GIT
Tao Ma
2008-Dec-04 22:20 UTC
[Ocfs2-devel] [PATCH 3/3] ocfs2/xattr: bug fix for credits of creating index block.
When creating a xattr index block, the old calculation forget
to add credits for the meta change of the alloc file. So add
more credits and more comments to explain it.
Signed-off-by: Tao Ma <tao.ma at oracle.com>
---
fs/ocfs2/xattr.c | 10 +++++++++-
1 files changed, 9 insertions(+), 1 deletions(-)
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 34c6850..6860134 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -2310,13 +2310,21 @@ meta_guess:
} else
xb = (struct ocfs2_xattr_block *)xbs->xattr_bh->b_data;
+ /*
+ * If there is already an xattr tree, good, we can calculate
+ * like other b-trees. Otherwise we may have the chance of
+ * create a tree, the credit calculation is borrowed from
+ * ocfs2_calc_extend_credits with root_el = NULL. And the
+ * new tree will be cluster based, so no meta is needed.
+ */
if (le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED) {
struct ocfs2_extent_list *el &xb->xb_attrs.xb_root.xt_list;
meta_add += ocfs2_extend_meta_needed(el);
credits += ocfs2_calc_extend_credits(inode->i_sb,
el, 1);
- }
+ } else
+ credits += OCFS2_SUBALLOC_ALLOC + 1;
/*
* This cluster will be used either for new bucket or for
--
1.5.4.GIT
Hi Mark, These 3 fixes are based on xattr transaction merge. So they should be merged into your merge_window. Thanks. patch 1 isn't a bug fix actually. This patch can relieve acl from handling the pain of journal_extend. patch 2 is the fix for ctime. Joel should have reviewed it already. http://oss.oracle.com/pipermail/ocfs2-devel/2008-December/003475.html. and the place of journal_access should be there as we may call journal_extend(which may cause journal restart) during xattr set. patch 3 is a bug fix for xattr journal calculation. Regards, Tao