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