diff options
Diffstat (limited to 'fs/ocfs2')
-rw-r--r-- | fs/ocfs2/xattr.c | 44 |
1 files changed, 37 insertions, 7 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index c3189286679a..975ba3653feb 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
@@ -4111,28 +4111,54 @@ static int ocfs2_adjust_xattr_cross_cluster(struct inode *inode, | |||
4111 | u32 *v_start, | 4111 | u32 *v_start, |
4112 | int *extend) | 4112 | int *extend) |
4113 | { | 4113 | { |
4114 | int ret = 0; | 4114 | int ret; |
4115 | int bpc = ocfs2_clusters_to_blocks(inode->i_sb, 1); | 4115 | struct ocfs2_xattr_bucket *first, *target; |
4116 | 4116 | ||
4117 | mlog(0, "adjust xattrs from cluster %llu len %u to %llu\n", | 4117 | mlog(0, "adjust xattrs from cluster %llu len %u to %llu\n", |
4118 | (unsigned long long)prev_blk, prev_clusters, | 4118 | (unsigned long long)prev_blk, prev_clusters, |
4119 | (unsigned long long)new_blk); | 4119 | (unsigned long long)new_blk); |
4120 | 4120 | ||
4121 | /* The first bucket of the original extent */ | ||
4122 | first = ocfs2_xattr_bucket_new(inode); | ||
4123 | /* The target bucket for insert */ | ||
4124 | target = ocfs2_xattr_bucket_new(inode); | ||
4125 | if (!first || !target) { | ||
4126 | ret = -ENOMEM; | ||
4127 | mlog_errno(ret); | ||
4128 | goto out; | ||
4129 | } | ||
4130 | |||
4131 | BUG_ON(prev_blk != (*first_bh)->b_blocknr); | ||
4132 | ret = ocfs2_read_xattr_bucket(first, prev_blk); | ||
4133 | if (ret) { | ||
4134 | mlog_errno(ret); | ||
4135 | goto out; | ||
4136 | } | ||
4137 | |||
4138 | ret = ocfs2_read_xattr_bucket(target, (*header_bh)->b_blocknr); | ||
4139 | if (ret) { | ||
4140 | mlog_errno(ret); | ||
4141 | goto out; | ||
4142 | } | ||
4143 | |||
4121 | if (ocfs2_xattr_buckets_per_cluster(OCFS2_SB(inode->i_sb)) > 1) | 4144 | if (ocfs2_xattr_buckets_per_cluster(OCFS2_SB(inode->i_sb)) > 1) |
4122 | ret = ocfs2_mv_xattr_bucket_cross_cluster(inode, | 4145 | ret = ocfs2_mv_xattr_bucket_cross_cluster(inode, |
4123 | handle, | 4146 | handle, |
4124 | first_bh, | 4147 | first_bh, |
4125 | header_bh, | 4148 | header_bh, |
4126 | new_blk, | 4149 | new_blk, |
4127 | prev_blk, | 4150 | bucket_blkno(first), |
4128 | prev_clusters, | 4151 | prev_clusters, |
4129 | v_start); | 4152 | v_start); |
4130 | else { | 4153 | else { |
4131 | u64 last_blk = prev_blk + bpc * (prev_clusters - 1); | 4154 | /* The start of the last cluster in the first extent */ |
4155 | u64 last_blk = bucket_blkno(first) + | ||
4156 | ((prev_clusters - 1) * | ||
4157 | ocfs2_clusters_to_blocks(inode->i_sb, 1)); | ||
4132 | 4158 | ||
4133 | if (prev_clusters > 1 && (*header_bh)->b_blocknr != last_blk) | 4159 | if (prev_clusters > 1 && bucket_blkno(target) != last_blk) |
4134 | ret = ocfs2_mv_xattr_buckets(inode, handle, | 4160 | ret = ocfs2_mv_xattr_buckets(inode, handle, |
4135 | (*first_bh)->b_blocknr, | 4161 | bucket_blkno(first), |
4136 | last_blk, new_blk, 0, | 4162 | last_blk, new_blk, 0, |
4137 | v_start); | 4163 | v_start); |
4138 | else { | 4164 | else { |
@@ -4140,11 +4166,15 @@ static int ocfs2_adjust_xattr_cross_cluster(struct inode *inode, | |||
4140 | last_blk, new_blk, | 4166 | last_blk, new_blk, |
4141 | v_start); | 4167 | v_start); |
4142 | 4168 | ||
4143 | if ((*header_bh)->b_blocknr == last_blk && extend) | 4169 | if ((bucket_blkno(target) == last_blk) && extend) |
4144 | *extend = 0; | 4170 | *extend = 0; |
4145 | } | 4171 | } |
4146 | } | 4172 | } |
4147 | 4173 | ||
4174 | out: | ||
4175 | ocfs2_xattr_bucket_free(first); | ||
4176 | ocfs2_xattr_bucket_free(target); | ||
4177 | |||
4148 | return ret; | 4178 | return ret; |
4149 | } | 4179 | } |
4150 | 4180 | ||