aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/ocfs2/xattr.c105
1 files changed, 32 insertions, 73 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 4b247047b7aa..5a5a1bd7eede 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -4148,11 +4148,10 @@ static int ocfs2_adjust_xattr_cross_cluster(struct inode *inode,
4148 */ 4148 */
4149static int ocfs2_add_new_xattr_cluster(struct inode *inode, 4149static int ocfs2_add_new_xattr_cluster(struct inode *inode,
4150 struct buffer_head *root_bh, 4150 struct buffer_head *root_bh,
4151 struct buffer_head **first_bh, 4151 struct ocfs2_xattr_bucket *first,
4152 struct buffer_head **header_bh, 4152 struct ocfs2_xattr_bucket *target,
4153 u32 *num_clusters, 4153 u32 *num_clusters,
4154 u32 prev_cpos, 4154 u32 prev_cpos,
4155 u64 prev_blkno,
4156 int *extend, 4155 int *extend,
4157 struct ocfs2_xattr_set_ctxt *ctxt) 4156 struct ocfs2_xattr_set_ctxt *ctxt)
4158{ 4157{
@@ -4164,38 +4163,14 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
4164 handle_t *handle = ctxt->handle; 4163 handle_t *handle = ctxt->handle;
4165 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 4164 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
4166 struct ocfs2_extent_tree et; 4165 struct ocfs2_extent_tree et;
4167 struct ocfs2_xattr_bucket *first, *target;
4168 4166
4169 mlog(0, "Add new xattr cluster for %llu, previous xattr hash = %u, " 4167 mlog(0, "Add new xattr cluster for %llu, previous xattr hash = %u, "
4170 "previous xattr blkno = %llu\n", 4168 "previous xattr blkno = %llu\n",
4171 (unsigned long long)OCFS2_I(inode)->ip_blkno, 4169 (unsigned long long)OCFS2_I(inode)->ip_blkno,
4172 prev_cpos, (unsigned long long)prev_blkno); 4170 prev_cpos, (unsigned long long)bucket_blkno(first));
4173 4171
4174 ocfs2_init_xattr_tree_extent_tree(&et, inode, root_bh); 4172 ocfs2_init_xattr_tree_extent_tree(&et, inode, root_bh);
4175 4173
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
4199 ret = ocfs2_journal_access(handle, inode, root_bh, 4174 ret = ocfs2_journal_access(handle, inode, root_bh,
4200 OCFS2_JOURNAL_ACCESS_WRITE); 4175 OCFS2_JOURNAL_ACCESS_WRITE);
4201 if (ret < 0) { 4176 if (ret < 0) {
@@ -4217,7 +4192,7 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
4217 mlog(0, "Allocating %u clusters at block %u for xattr in inode %llu\n", 4192 mlog(0, "Allocating %u clusters at block %u for xattr in inode %llu\n",
4218 num_bits, bit_off, (unsigned long long)OCFS2_I(inode)->ip_blkno); 4193 num_bits, bit_off, (unsigned long long)OCFS2_I(inode)->ip_blkno);
4219 4194
4220 if (prev_blkno + prev_clusters * bpc == block && 4195 if (bucket_blkno(first) + (prev_clusters * bpc) == block &&
4221 (prev_clusters + num_bits) << osb->s_clustersize_bits <= 4196 (prev_clusters + num_bits) << osb->s_clustersize_bits <=
4222 OCFS2_MAX_XATTR_TREE_LEAF_SIZE) { 4197 OCFS2_MAX_XATTR_TREE_LEAF_SIZE) {
4223 /* 4198 /*
@@ -4246,17 +4221,6 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
4246 mlog_errno(ret); 4221 mlog_errno(ret);
4247 goto leave; 4222 goto leave;
4248 } 4223 }
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 }
4260 } 4224 }
4261 4225
4262 mlog(0, "Insert %u clusters at block %llu for xattr at %u\n", 4226 mlog(0, "Insert %u clusters at block %llu for xattr at %u\n",
@@ -4273,8 +4237,6 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode,
4273 mlog_errno(ret); 4237 mlog_errno(ret);
4274 4238
4275leave: 4239leave:
4276 ocfs2_xattr_bucket_free(first);
4277 ocfs2_xattr_bucket_free(target);
4278 return ret; 4240 return ret;
4279} 4241}
4280 4242
@@ -4357,16 +4319,16 @@ out:
4357 * We will move all the buckets starting from header_bh to the next place. As 4319 * We will move all the buckets starting from header_bh to the next place. As
4358 * for this one, half num of its xattrs will be moved to the next one. 4320 * for this one, half num of its xattrs will be moved to the next one.
4359 * 4321 *
4360 * We will allocate a new cluster if current cluster is full and adjust 4322 * We will allocate a new cluster if current cluster is full. The
4361 * header_bh and first_bh if the insert place is moved to the new cluster. 4323 * underlying calls will make sure that there is space at the target
4324 * bucket, shifting buckets around if necessary. 'target' may be updated
4325 * by those calls.
4362 */ 4326 */
4363static int ocfs2_add_new_xattr_bucket(struct inode *inode, 4327static int ocfs2_add_new_xattr_bucket(struct inode *inode,
4364 struct buffer_head *xb_bh, 4328 struct buffer_head *xb_bh,
4365 struct buffer_head *header_bh, 4329 struct buffer_head *header_bh,
4366 struct ocfs2_xattr_set_ctxt *ctxt) 4330 struct ocfs2_xattr_set_ctxt *ctxt)
4367{ 4331{
4368 struct ocfs2_xattr_header *first_xh = NULL;
4369 struct buffer_head *first_bh = NULL;
4370 struct ocfs2_xattr_block *xb = 4332 struct ocfs2_xattr_block *xb =
4371 (struct ocfs2_xattr_block *)xb_bh->b_data; 4333 (struct ocfs2_xattr_block *)xb_bh->b_data;
4372 struct ocfs2_xattr_tree_root *xb_root = &xb->xb_attrs.xb_root; 4334 struct ocfs2_xattr_tree_root *xb_root = &xb->xb_attrs.xb_root;
@@ -4374,31 +4336,26 @@ static int ocfs2_add_new_xattr_bucket(struct inode *inode,
4374 struct ocfs2_xattr_header *xh = 4336 struct ocfs2_xattr_header *xh =
4375 (struct ocfs2_xattr_header *)header_bh->b_data; 4337 (struct ocfs2_xattr_header *)header_bh->b_data;
4376 u32 name_hash = le32_to_cpu(xh->xh_entries[0].xe_name_hash); 4338 u32 name_hash = le32_to_cpu(xh->xh_entries[0].xe_name_hash);
4377 struct super_block *sb = inode->i_sb; 4339 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
4378 struct ocfs2_super *osb = OCFS2_SB(sb);
4379 int ret, num_buckets, extend = 1; 4340 int ret, num_buckets, extend = 1;
4380 u64 p_blkno; 4341 u64 p_blkno;
4381 u32 e_cpos, num_clusters; 4342 u32 e_cpos, num_clusters;
4382 /* The bucket at the front of the extent */ 4343 /* The bucket at the front of the extent */
4383 struct ocfs2_xattr_bucket *first; 4344 struct ocfs2_xattr_bucket *first, *target;
4384 4345
4385 mlog(0, "Add new xattr bucket starting form %llu\n", 4346 mlog(0, "Add new xattr bucket starting form %llu\n",
4386 (unsigned long long)header_bh->b_blocknr); 4347 (unsigned long long)header_bh->b_blocknr);
4387 4348
4349 /* The first bucket of the original extent */
4388 first = ocfs2_xattr_bucket_new(inode); 4350 first = ocfs2_xattr_bucket_new(inode);
4389 if (!first) { 4351 /* The target bucket for insert */
4352 target = ocfs2_xattr_bucket_new(inode);
4353 if (!first || !target) {
4390 ret = -ENOMEM; 4354 ret = -ENOMEM;
4391 mlog_errno(ret); 4355 mlog_errno(ret);
4392 goto out; 4356 goto out;
4393 } 4357 }
4394 4358
4395 /*
4396 * Add refrence for header_bh here because it may be
4397 * changed in ocfs2_add_new_xattr_cluster and we need
4398 * to free it in the end.
4399 */
4400 get_bh(header_bh);
4401
4402 ret = ocfs2_xattr_get_rec(inode, name_hash, &p_blkno, &e_cpos, 4359 ret = ocfs2_xattr_get_rec(inode, name_hash, &p_blkno, &e_cpos,
4403 &num_clusters, el); 4360 &num_clusters, el);
4404 if (ret) { 4361 if (ret) {
@@ -4406,23 +4363,30 @@ static int ocfs2_add_new_xattr_bucket(struct inode *inode,
4406 goto out; 4363 goto out;
4407 } 4364 }
4408 4365
4409 ret = ocfs2_read_block(inode, p_blkno, &first_bh, NULL); 4366 ret = ocfs2_read_xattr_bucket(first, p_blkno);
4410 if (ret) { 4367 if (ret) {
4411 mlog_errno(ret); 4368 mlog_errno(ret);
4412 goto out; 4369 goto out;
4413 } 4370 }
4414 4371
4415 num_buckets = ocfs2_xattr_buckets_per_cluster(osb) * num_clusters; 4372 ret = ocfs2_read_xattr_bucket(target, header_bh->b_blocknr);
4416 first_xh = (struct ocfs2_xattr_header *)first_bh->b_data; 4373 if (ret) {
4374 mlog_errno(ret);
4375 goto out;
4376 }
4417 4377
4418 if (num_buckets == le16_to_cpu(first_xh->xh_num_buckets)) { 4378 num_buckets = ocfs2_xattr_buckets_per_cluster(osb) * num_clusters;
4379 if (num_buckets == le16_to_cpu(bucket_xh(first)->xh_num_buckets)) {
4380 /*
4381 * This can move first+target if the target bucket moves
4382 * to the new extent.
4383 */
4419 ret = ocfs2_add_new_xattr_cluster(inode, 4384 ret = ocfs2_add_new_xattr_cluster(inode,
4420 xb_bh, 4385 xb_bh,
4421 &first_bh, 4386 first,
4422 &header_bh, 4387 target,
4423 &num_clusters, 4388 &num_clusters,
4424 e_cpos, 4389 e_cpos,
4425 p_blkno,
4426 &extend, 4390 &extend,
4427 ctxt); 4391 ctxt);
4428 if (ret) { 4392 if (ret) {
@@ -4432,24 +4396,19 @@ static int ocfs2_add_new_xattr_bucket(struct inode *inode,
4432 } 4396 }
4433 4397
4434 if (extend) { 4398 if (extend) {
4435 /* These bucket reads should be cached */
4436 ret = ocfs2_read_xattr_bucket(first, first_bh->b_blocknr);
4437 if (ret) {
4438 mlog_errno(ret);
4439 goto out;
4440 }
4441 ret = ocfs2_extend_xattr_bucket(inode, 4399 ret = ocfs2_extend_xattr_bucket(inode,
4442 ctxt->handle, 4400 ctxt->handle,
4443 first, header_bh->b_blocknr, 4401 first,
4402 bucket_blkno(target),
4444 num_clusters); 4403 num_clusters);
4445 if (ret) 4404 if (ret)
4446 mlog_errno(ret); 4405 mlog_errno(ret);
4447 } 4406 }
4448 4407
4449out: 4408out:
4450 brelse(first_bh);
4451 brelse(header_bh);
4452 ocfs2_xattr_bucket_free(first); 4409 ocfs2_xattr_bucket_free(first);
4410 ocfs2_xattr_bucket_free(target);
4411
4453 return ret; 4412 return ret;
4454} 4413}
4455 4414