diff options
-rw-r--r-- | fs/ocfs2/xattr.c | 100 |
1 files changed, 49 insertions, 51 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 2f16f50ebcba..4b247047b7aa 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
@@ -4080,44 +4080,19 @@ static int ocfs2_divide_xattr_cluster(struct inode *inode, | |||
4080 | */ | 4080 | */ |
4081 | static int ocfs2_adjust_xattr_cross_cluster(struct inode *inode, | 4081 | static int ocfs2_adjust_xattr_cross_cluster(struct inode *inode, |
4082 | handle_t *handle, | 4082 | handle_t *handle, |
4083 | struct buffer_head **first_bh, | 4083 | struct ocfs2_xattr_bucket *first, |
4084 | struct buffer_head **header_bh, | 4084 | struct ocfs2_xattr_bucket *target, |
4085 | u64 new_blk, | 4085 | u64 new_blk, |
4086 | u64 prev_blk, | ||
4087 | u32 prev_clusters, | 4086 | u32 prev_clusters, |
4088 | u32 *v_start, | 4087 | u32 *v_start, |
4089 | int *extend) | 4088 | int *extend) |
4090 | { | 4089 | { |
4091 | int ret; | 4090 | int ret; |
4092 | struct ocfs2_xattr_bucket *first, *target; | ||
4093 | 4091 | ||
4094 | mlog(0, "adjust xattrs from cluster %llu len %u to %llu\n", | 4092 | mlog(0, "adjust xattrs from cluster %llu len %u to %llu\n", |
4095 | (unsigned long long)prev_blk, prev_clusters, | 4093 | (unsigned long long)bucket_blkno(first), prev_clusters, |
4096 | (unsigned long long)new_blk); | 4094 | (unsigned long long)new_blk); |
4097 | 4095 | ||
4098 | /* The first bucket of the original extent */ | ||
4099 | first = ocfs2_xattr_bucket_new(inode); | ||
4100 | /* The target bucket for insert */ | ||
4101 | target = ocfs2_xattr_bucket_new(inode); | ||
4102 | if (!first || !target) { | ||
4103 | ret = -ENOMEM; | ||
4104 | mlog_errno(ret); | ||
4105 | goto out; | ||
4106 | } | ||
4107 | |||
4108 | BUG_ON(prev_blk != (*first_bh)->b_blocknr); | ||
4109 | ret = ocfs2_read_xattr_bucket(first, prev_blk); | ||
4110 | if (ret) { | ||
4111 | mlog_errno(ret); | ||
4112 | goto out; | ||
4113 | } | ||
4114 | |||
4115 | ret = ocfs2_read_xattr_bucket(target, (*header_bh)->b_blocknr); | ||
4116 | if (ret) { | ||
4117 | mlog_errno(ret); | ||
4118 | goto out; | ||
4119 | } | ||
4120 | |||
4121 | if (ocfs2_xattr_buckets_per_cluster(OCFS2_SB(inode->i_sb)) > 1) { | 4096 | if (ocfs2_xattr_buckets_per_cluster(OCFS2_SB(inode->i_sb)) > 1) { |
4122 | ret = ocfs2_mv_xattr_bucket_cross_cluster(inode, | 4097 | ret = ocfs2_mv_xattr_bucket_cross_cluster(inode, |
4123 | handle, | 4098 | handle, |
@@ -4125,46 +4100,33 @@ static int ocfs2_adjust_xattr_cross_cluster(struct inode *inode, | |||
4125 | new_blk, | 4100 | new_blk, |
4126 | prev_clusters, | 4101 | prev_clusters, |
4127 | v_start); | 4102 | v_start); |
4128 | if (ret) { | 4103 | if (ret) |
4129 | mlog_errno(ret); | 4104 | mlog_errno(ret); |
4130 | goto out; | ||
4131 | } | ||
4132 | |||
4133 | /* Did first+target get moved? */ | ||
4134 | if (prev_blk != bucket_blkno(first)) { | ||
4135 | brelse(*first_bh); | ||
4136 | *first_bh = first->bu_bhs[0]; | ||
4137 | get_bh(*first_bh); | ||
4138 | |||
4139 | brelse(*header_bh); | ||
4140 | *header_bh = target->bu_bhs[0]; | ||
4141 | get_bh(*header_bh); | ||
4142 | } | ||
4143 | } else { | 4105 | } else { |
4144 | /* The start of the last cluster in the first extent */ | 4106 | /* The start of the last cluster in the first extent */ |
4145 | u64 last_blk = bucket_blkno(first) + | 4107 | u64 last_blk = bucket_blkno(first) + |
4146 | ((prev_clusters - 1) * | 4108 | ((prev_clusters - 1) * |
4147 | ocfs2_clusters_to_blocks(inode->i_sb, 1)); | 4109 | ocfs2_clusters_to_blocks(inode->i_sb, 1)); |
4148 | 4110 | ||
4149 | if (prev_clusters > 1 && bucket_blkno(target) != last_blk) | 4111 | if (prev_clusters > 1 && bucket_blkno(target) != last_blk) { |
4150 | ret = ocfs2_mv_xattr_buckets(inode, handle, | 4112 | ret = ocfs2_mv_xattr_buckets(inode, handle, |
4151 | bucket_blkno(first), | 4113 | bucket_blkno(first), |
4152 | last_blk, new_blk, 0, | 4114 | last_blk, new_blk, 0, |
4153 | v_start); | 4115 | v_start); |
4154 | else { | 4116 | if (ret) |
4117 | mlog_errno(ret); | ||
4118 | } else { | ||
4155 | ret = ocfs2_divide_xattr_cluster(inode, handle, | 4119 | ret = ocfs2_divide_xattr_cluster(inode, handle, |
4156 | last_blk, new_blk, | 4120 | last_blk, new_blk, |
4157 | v_start); | 4121 | v_start); |
4122 | if (ret) | ||
4123 | mlog_errno(ret); | ||
4158 | 4124 | ||
4159 | if ((bucket_blkno(target) == last_blk) && extend) | 4125 | if ((bucket_blkno(target) == last_blk) && extend) |
4160 | *extend = 0; | 4126 | *extend = 0; |
4161 | } | 4127 | } |
4162 | } | 4128 | } |
4163 | 4129 | ||
4164 | out: | ||
4165 | ocfs2_xattr_bucket_free(first); | ||
4166 | ocfs2_xattr_bucket_free(target); | ||
4167 | |||
4168 | return ret; | 4130 | return ret; |
4169 | } | 4131 | } |
4170 | 4132 | ||
@@ -4202,6 +4164,7 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode, | |||
4202 | handle_t *handle = ctxt->handle; | 4164 | handle_t *handle = ctxt->handle; |
4203 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 4165 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
4204 | struct ocfs2_extent_tree et; | 4166 | struct ocfs2_extent_tree et; |
4167 | struct ocfs2_xattr_bucket *first, *target; | ||
4205 | 4168 | ||
4206 | mlog(0, "Add new xattr cluster for %llu, previous xattr hash = %u, " | 4169 | mlog(0, "Add new xattr cluster for %llu, previous xattr hash = %u, " |
4207 | "previous xattr blkno = %llu\n", | 4170 | "previous xattr blkno = %llu\n", |
@@ -4210,6 +4173,29 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode, | |||
4210 | 4173 | ||
4211 | ocfs2_init_xattr_tree_extent_tree(&et, inode, root_bh); | 4174 | ocfs2_init_xattr_tree_extent_tree(&et, inode, root_bh); |
4212 | 4175 | ||
4176 | /* The first bucket of the original extent */ | ||
4177 | first = ocfs2_xattr_bucket_new(inode); | ||
4178 | /* The target bucket for insert */ | ||
4179 | target = ocfs2_xattr_bucket_new(inode); | ||
4180 | if (!first || !target) { | ||
4181 | ret = -ENOMEM; | ||
4182 | mlog_errno(ret); | ||
4183 | goto leave; | ||
4184 | } | ||
4185 | |||
4186 | BUG_ON(prev_blkno != (*first_bh)->b_blocknr); | ||
4187 | ret = ocfs2_read_xattr_bucket(first, prev_blkno); | ||
4188 | if (ret) { | ||
4189 | mlog_errno(ret); | ||
4190 | goto leave; | ||
4191 | } | ||
4192 | |||
4193 | ret = ocfs2_read_xattr_bucket(target, (*header_bh)->b_blocknr); | ||
4194 | if (ret) { | ||
4195 | mlog_errno(ret); | ||
4196 | goto leave; | ||
4197 | } | ||
4198 | |||
4213 | ret = ocfs2_journal_access(handle, inode, root_bh, | 4199 | ret = ocfs2_journal_access(handle, inode, root_bh, |
4214 | OCFS2_JOURNAL_ACCESS_WRITE); | 4200 | OCFS2_JOURNAL_ACCESS_WRITE); |
4215 | if (ret < 0) { | 4201 | if (ret < 0) { |
@@ -4250,10 +4236,9 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode, | |||
4250 | } else { | 4236 | } else { |
4251 | ret = ocfs2_adjust_xattr_cross_cluster(inode, | 4237 | ret = ocfs2_adjust_xattr_cross_cluster(inode, |
4252 | handle, | 4238 | handle, |
4253 | first_bh, | 4239 | first, |
4254 | header_bh, | 4240 | target, |
4255 | block, | 4241 | block, |
4256 | prev_blkno, | ||
4257 | prev_clusters, | 4242 | prev_clusters, |
4258 | &v_start, | 4243 | &v_start, |
4259 | extend); | 4244 | extend); |
@@ -4261,6 +4246,17 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode, | |||
4261 | mlog_errno(ret); | 4246 | mlog_errno(ret); |
4262 | goto leave; | 4247 | goto leave; |
4263 | } | 4248 | } |
4249 | |||
4250 | /* Did first+target get moved? */ | ||
4251 | if (prev_blkno != bucket_blkno(first)) { | ||
4252 | brelse(*first_bh); | ||
4253 | *first_bh = first->bu_bhs[0]; | ||
4254 | get_bh(*first_bh); | ||
4255 | |||
4256 | brelse(*header_bh); | ||
4257 | *header_bh = target->bu_bhs[0]; | ||
4258 | get_bh(*header_bh); | ||
4259 | } | ||
4264 | } | 4260 | } |
4265 | 4261 | ||
4266 | mlog(0, "Insert %u clusters at block %llu for xattr at %u\n", | 4262 | mlog(0, "Insert %u clusters at block %llu for xattr at %u\n", |
@@ -4277,6 +4273,8 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode, | |||
4277 | mlog_errno(ret); | 4273 | mlog_errno(ret); |
4278 | 4274 | ||
4279 | leave: | 4275 | leave: |
4276 | ocfs2_xattr_bucket_free(first); | ||
4277 | ocfs2_xattr_bucket_free(target); | ||
4280 | return ret; | 4278 | return ret; |
4281 | } | 4279 | } |
4282 | 4280 | ||