diff options
-rw-r--r-- | fs/ocfs2/xattr.c | 84 |
1 files changed, 37 insertions, 47 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 975ba3653feb..2f16f50ebcba 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
@@ -3548,42 +3548,28 @@ out: | |||
3548 | */ | 3548 | */ |
3549 | static int ocfs2_mv_xattr_bucket_cross_cluster(struct inode *inode, | 3549 | static int ocfs2_mv_xattr_bucket_cross_cluster(struct inode *inode, |
3550 | handle_t *handle, | 3550 | handle_t *handle, |
3551 | struct buffer_head **first_bh, | 3551 | struct ocfs2_xattr_bucket *first, |
3552 | struct buffer_head **header_bh, | 3552 | struct ocfs2_xattr_bucket *target, |
3553 | u64 new_blkno, | 3553 | u64 new_blkno, |
3554 | u64 prev_blkno, | ||
3555 | u32 num_clusters, | 3554 | u32 num_clusters, |
3556 | u32 *first_hash) | 3555 | u32 *first_hash) |
3557 | { | 3556 | { |
3558 | int ret; | 3557 | int ret; |
3559 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 3558 | struct super_block *sb = inode->i_sb; |
3560 | int blks_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb); | 3559 | int blks_per_bucket = ocfs2_blocks_per_xattr_bucket(sb); |
3561 | int num_buckets = ocfs2_xattr_buckets_per_cluster(osb); | 3560 | int num_buckets = ocfs2_xattr_buckets_per_cluster(OCFS2_SB(sb)); |
3562 | int to_move = num_buckets / 2; | 3561 | int to_move = num_buckets / 2; |
3563 | u64 src_blkno; | 3562 | u64 src_blkno; |
3564 | u64 last_cluster_blkno = prev_blkno + | 3563 | u64 last_cluster_blkno = bucket_blkno(first) + |
3565 | ((num_clusters - 1) * ocfs2_clusters_to_blocks(inode->i_sb, 1)); | 3564 | ((num_clusters - 1) * ocfs2_clusters_to_blocks(sb, 1)); |
3566 | struct ocfs2_xattr_header *xh = | ||
3567 | (struct ocfs2_xattr_header *)((*first_bh)->b_data); | ||
3568 | struct ocfs2_xattr_bucket *new_target, *new_first; | ||
3569 | 3565 | ||
3570 | BUG_ON(le16_to_cpu(xh->xh_num_buckets) < num_buckets); | 3566 | BUG_ON(le16_to_cpu(bucket_xh(first)->xh_num_buckets) < num_buckets); |
3571 | BUG_ON(OCFS2_XATTR_BUCKET_SIZE == osb->s_clustersize); | 3567 | BUG_ON(OCFS2_XATTR_BUCKET_SIZE == OCFS2_SB(sb)->s_clustersize); |
3572 | 3568 | ||
3573 | mlog(0, "move half of xattrs in cluster %llu to %llu\n", | 3569 | mlog(0, "move half of xattrs in cluster %llu to %llu\n", |
3574 | (unsigned long long)last_cluster_blkno, (unsigned long long)new_blkno); | 3570 | (unsigned long long)last_cluster_blkno, (unsigned long long)new_blkno); |
3575 | 3571 | ||
3576 | /* The first bucket of the new extent */ | 3572 | ret = ocfs2_mv_xattr_buckets(inode, handle, bucket_blkno(first), |
3577 | new_first = ocfs2_xattr_bucket_new(inode); | ||
3578 | /* The target bucket if it was moved to the new extent */ | ||
3579 | new_target = ocfs2_xattr_bucket_new(inode); | ||
3580 | if (!new_target || !new_first) { | ||
3581 | ret = -ENOMEM; | ||
3582 | mlog_errno(ret); | ||
3583 | goto out; | ||
3584 | } | ||
3585 | |||
3586 | ret = ocfs2_mv_xattr_buckets(inode, handle, prev_blkno, | ||
3587 | last_cluster_blkno, new_blkno, | 3573 | last_cluster_blkno, new_blkno, |
3588 | to_move, first_hash); | 3574 | to_move, first_hash); |
3589 | if (ret) { | 3575 | if (ret) { |
@@ -3596,41 +3582,32 @@ static int ocfs2_mv_xattr_bucket_cross_cluster(struct inode *inode, | |||
3596 | 3582 | ||
3597 | /* | 3583 | /* |
3598 | * If the target bucket was part of the moved buckets, we need to | 3584 | * If the target bucket was part of the moved buckets, we need to |
3599 | * update first_bh and header_bh. | 3585 | * update first and target. |
3600 | */ | 3586 | */ |
3601 | if ((*header_bh)->b_blocknr >= src_blkno) { | 3587 | if (bucket_blkno(target) >= src_blkno) { |
3602 | /* Find the block for the new target bucket */ | 3588 | /* Find the block for the new target bucket */ |
3603 | src_blkno = new_blkno + | 3589 | src_blkno = new_blkno + |
3604 | ((*header_bh)->b_blocknr - src_blkno); | 3590 | (bucket_blkno(target) - src_blkno); |
3591 | |||
3592 | ocfs2_xattr_bucket_relse(first); | ||
3593 | ocfs2_xattr_bucket_relse(target); | ||
3605 | 3594 | ||
3606 | /* | 3595 | /* |
3607 | * These shouldn't fail - the buffers are in the | 3596 | * These shouldn't fail - the buffers are in the |
3608 | * journal from ocfs2_cp_xattr_bucket(). | 3597 | * journal from ocfs2_cp_xattr_bucket(). |
3609 | */ | 3598 | */ |
3610 | ret = ocfs2_read_xattr_bucket(new_first, new_blkno); | 3599 | ret = ocfs2_read_xattr_bucket(first, new_blkno); |
3611 | if (ret) { | 3600 | if (ret) { |
3612 | mlog_errno(ret); | 3601 | mlog_errno(ret); |
3613 | goto out; | 3602 | goto out; |
3614 | } | 3603 | } |
3615 | ret = ocfs2_read_xattr_bucket(new_target, src_blkno); | 3604 | ret = ocfs2_read_xattr_bucket(target, src_blkno); |
3616 | if (ret) { | 3605 | if (ret) |
3617 | mlog_errno(ret); | 3606 | mlog_errno(ret); |
3618 | goto out; | ||
3619 | } | ||
3620 | 3607 | ||
3621 | brelse(*first_bh); | ||
3622 | *first_bh = new_first->bu_bhs[0]; | ||
3623 | get_bh(*first_bh); | ||
3624 | |||
3625 | brelse(*header_bh); | ||
3626 | *header_bh = new_target->bu_bhs[0]; | ||
3627 | get_bh(*header_bh); | ||
3628 | } | 3608 | } |
3629 | 3609 | ||
3630 | out: | 3610 | out: |
3631 | ocfs2_xattr_bucket_free(new_first); | ||
3632 | ocfs2_xattr_bucket_free(new_target); | ||
3633 | |||
3634 | return ret; | 3611 | return ret; |
3635 | } | 3612 | } |
3636 | 3613 | ||
@@ -4141,16 +4118,29 @@ static int ocfs2_adjust_xattr_cross_cluster(struct inode *inode, | |||
4141 | goto out; | 4118 | goto out; |
4142 | } | 4119 | } |
4143 | 4120 | ||
4144 | if (ocfs2_xattr_buckets_per_cluster(OCFS2_SB(inode->i_sb)) > 1) | 4121 | if (ocfs2_xattr_buckets_per_cluster(OCFS2_SB(inode->i_sb)) > 1) { |
4145 | ret = ocfs2_mv_xattr_bucket_cross_cluster(inode, | 4122 | ret = ocfs2_mv_xattr_bucket_cross_cluster(inode, |
4146 | handle, | 4123 | handle, |
4147 | first_bh, | 4124 | first, target, |
4148 | header_bh, | ||
4149 | new_blk, | 4125 | new_blk, |
4150 | bucket_blkno(first), | ||
4151 | prev_clusters, | 4126 | prev_clusters, |
4152 | v_start); | 4127 | v_start); |
4153 | else { | 4128 | if (ret) { |
4129 | 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 { | ||
4154 | /* The start of the last cluster in the first extent */ | 4144 | /* The start of the last cluster in the first extent */ |
4155 | u64 last_blk = bucket_blkno(first) + | 4145 | u64 last_blk = bucket_blkno(first) + |
4156 | ((prev_clusters - 1) * | 4146 | ((prev_clusters - 1) * |