aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2008-11-25 21:36:42 -0500
committerMark Fasheh <mfasheh@suse.com>2009-01-05 11:40:27 -0500
commit15d609293d1954465a4788b9b182214323c6a2a1 (patch)
tree3a044a10a8c09397703964c23bc7156baf12747d /fs
parent92de109ade7999084fb0bfcc65d603252504e0d0 (diff)
ocfs2: Dirty the entire first bucket in ocfs2_cp_xattr_cluster().
ocfs2_cp_xattr_cluster() takes the last bucket of a full extent and copies it over to a new extent. It then updates the headers of both extents to reflect the new state. It is passed the first bh of the first bucket in order to update that first extent's bucket count. It reads and dirties the first bh of the new extent for the same reason. However, future code wants to always dirty the entire bucket when it is changed. So it is changed to read the entire bucket it is updating for both extents. Signed-off-by: Joel Becker <joel.becker@oracle.com> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/ocfs2/xattr.c80
1 files changed, 48 insertions, 32 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index ed1e95967565..4dba34758827 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -3936,9 +3936,10 @@ out:
3936} 3936}
3937 3937
3938/* 3938/*
3939 * Copy one xattr cluster from src_blk to to_blk. 3939 * src_blk points to the last cluster of an existing extent. to_blk
3940 * The to_blk will become the first bucket header of the cluster, so its 3940 * points to a newly allocated extent. We copy the cluster over to the
3941 * xh_num_buckets will be initialized as the bucket num in the cluster. 3941 * new extent, initializing its xh_num_buckets. The old extent's
3942 * xh_num_buckets shrinks by the same amount.
3942 */ 3943 */
3943static int ocfs2_cp_xattr_cluster(struct inode *inode, 3944static int ocfs2_cp_xattr_cluster(struct inode *inode,
3944 handle_t *handle, 3945 handle_t *handle,
@@ -3950,27 +3951,42 @@ static int ocfs2_cp_xattr_cluster(struct inode *inode,
3950 int i, ret, credits; 3951 int i, ret, credits;
3951 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 3952 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
3952 int bpc = ocfs2_clusters_to_blocks(inode->i_sb, 1); 3953 int bpc = ocfs2_clusters_to_blocks(inode->i_sb, 1);
3954 int blks_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
3953 int num_buckets = ocfs2_xattr_buckets_per_cluster(osb); 3955 int num_buckets = ocfs2_xattr_buckets_per_cluster(osb);
3954 struct buffer_head *bh = NULL; 3956 struct ocfs2_xattr_bucket *old_first, *new_first;
3955 struct ocfs2_xattr_header *xh;
3956 u64 to_blk_start = to_blk;
3957 3957
3958 mlog(0, "cp xattrs from cluster %llu to %llu\n", 3958 mlog(0, "cp xattrs from cluster %llu to %llu\n",
3959 (unsigned long long)src_blk, (unsigned long long)to_blk); 3959 (unsigned long long)src_blk, (unsigned long long)to_blk);
3960 3960
3961 /* The first bucket of the original extent */
3962 old_first = ocfs2_xattr_bucket_new(inode);
3963 /* The first bucket of the new extent */
3964 new_first = ocfs2_xattr_bucket_new(inode);
3965 if (!old_first || !new_first) {
3966 ret = -ENOMEM;
3967 mlog_errno(ret);
3968 goto out;
3969 }
3970
3971 ret = ocfs2_read_xattr_bucket(old_first, first_bh->b_blocknr);
3972 if (ret) {
3973 mlog_errno(ret);
3974 goto out;
3975 }
3976
3961 /* 3977 /*
3962 * We need to update the new cluster and 1 more for the update of 3978 * We need to update the first bucket of the old extent and the
3963 * the 1st bucket of the previous extent rec. 3979 * entire first cluster of the new extent.
3964 */ 3980 */
3965 credits = bpc + 1 + handle->h_buffer_credits; 3981 credits = blks_per_bucket + bpc + handle->h_buffer_credits;
3966 ret = ocfs2_extend_trans(handle, credits); 3982 ret = ocfs2_extend_trans(handle, credits);
3967 if (ret) { 3983 if (ret) {
3968 mlog_errno(ret); 3984 mlog_errno(ret);
3969 goto out; 3985 goto out;
3970 } 3986 }
3971 3987
3972 ret = ocfs2_journal_access(handle, inode, first_bh, 3988 ret = ocfs2_xattr_bucket_journal_access(handle, old_first,
3973 OCFS2_JOURNAL_ACCESS_WRITE); 3989 OCFS2_JOURNAL_ACCESS_WRITE);
3974 if (ret) { 3990 if (ret) {
3975 mlog_errno(ret); 3991 mlog_errno(ret);
3976 goto out; 3992 goto out;
@@ -3978,45 +3994,45 @@ static int ocfs2_cp_xattr_cluster(struct inode *inode,
3978 3994
3979 for (i = 0; i < num_buckets; i++) { 3995 for (i = 0; i < num_buckets; i++) {
3980 ret = ocfs2_cp_xattr_bucket(inode, handle, 3996 ret = ocfs2_cp_xattr_bucket(inode, handle,
3981 src_blk, to_blk, 1); 3997 src_blk + (i * blks_per_bucket),
3998 to_blk + (i * blks_per_bucket),
3999 1);
3982 if (ret) { 4000 if (ret) {
3983 mlog_errno(ret); 4001 mlog_errno(ret);
3984 goto out; 4002 goto out;
3985 } 4003 }
3986
3987 src_blk += ocfs2_blocks_per_xattr_bucket(inode->i_sb);
3988 to_blk += ocfs2_blocks_per_xattr_bucket(inode->i_sb);
3989 } 4004 }
3990 4005
3991 /* update the old bucket header. */ 4006 /*
3992 xh = (struct ocfs2_xattr_header *)first_bh->b_data; 4007 * Get the new bucket ready before we dirty anything
3993 le16_add_cpu(&xh->xh_num_buckets, -num_buckets); 4008 * (This actually shouldn't fail, because we already dirtied
3994 4009 * it once in ocfs2_cp_xattr_bucket()).
3995 ocfs2_journal_dirty(handle, first_bh); 4010 */
3996 4011 ret = ocfs2_read_xattr_bucket(new_first, to_blk);
3997 /* update the new bucket header. */ 4012 if (ret) {
3998 ret = ocfs2_read_block(inode, to_blk_start, &bh, NULL);
3999 if (ret < 0) {
4000 mlog_errno(ret); 4013 mlog_errno(ret);
4001 goto out; 4014 goto out;
4002 } 4015 }
4003 4016 ret = ocfs2_xattr_bucket_journal_access(handle, new_first,
4004 ret = ocfs2_journal_access(handle, inode, bh, 4017 OCFS2_JOURNAL_ACCESS_WRITE);
4005 OCFS2_JOURNAL_ACCESS_WRITE);
4006 if (ret) { 4018 if (ret) {
4007 mlog_errno(ret); 4019 mlog_errno(ret);
4008 goto out; 4020 goto out;
4009 } 4021 }
4010 4022
4011 xh = (struct ocfs2_xattr_header *)bh->b_data; 4023 /* Now update the headers */
4012 xh->xh_num_buckets = cpu_to_le16(num_buckets); 4024 le16_add_cpu(&bucket_xh(old_first)->xh_num_buckets, -num_buckets);
4025 ocfs2_xattr_bucket_journal_dirty(handle, old_first);
4013 4026
4014 ocfs2_journal_dirty(handle, bh); 4027 bucket_xh(new_first)->xh_num_buckets = cpu_to_le16(num_buckets);
4028 ocfs2_xattr_bucket_journal_dirty(handle, new_first);
4015 4029
4016 if (first_hash) 4030 if (first_hash)
4017 *first_hash = le32_to_cpu(xh->xh_entries[0].xe_name_hash); 4031 *first_hash = le32_to_cpu(bucket_xh(new_first)->xh_entries[0].xe_name_hash);
4032
4018out: 4033out:
4019 brelse(bh); 4034 ocfs2_xattr_bucket_free(new_first);
4035 ocfs2_xattr_bucket_free(old_first);
4020 return ret; 4036 return ret;
4021} 4037}
4022 4038