aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/xattr.c
diff options
context:
space:
mode:
authorJoel Becker <joel.becker@oracle.com>2008-11-26 16:36:24 -0500
committerMark Fasheh <mfasheh@suse.com>2009-01-05 11:40:29 -0500
commitc58b6032f93358871361a92d7743dbc85d27084e (patch)
tree0757a1b192ff048ecd4d4c37936db65d5d306fb8 /fs/ocfs2/xattr.c
parent54ecb6b6df54bf72befb359b21f3759b2952f9d9 (diff)
ocfs2: Use ocfs2_mv_xattr_buckets() in ocfs2_mv_xattr_bucket_cross_cluster().
Now that ocfs2_mv_xattr_buckets() can move a partial cluster's worth of buckets, ocfs2_mv_xattr_bucket_cross_cluster() can use it. Signed-off-by: Joel Becker <joel.becker@oracle.com> Signed-off-by: Mark Fasheh <mfasheh@suse.com>
Diffstat (limited to 'fs/ocfs2/xattr.c')
-rw-r--r--fs/ocfs2/xattr.c110
1 files changed, 29 insertions, 81 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 97340940cee2..c3189286679a 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -170,11 +170,10 @@ static int ocfs2_xattr_set_entry_index_block(struct inode *inode,
170 170
171static int ocfs2_delete_xattr_index_block(struct inode *inode, 171static int ocfs2_delete_xattr_index_block(struct inode *inode,
172 struct buffer_head *xb_bh); 172 struct buffer_head *xb_bh);
173static int ocfs2_cp_xattr_bucket(struct inode *inode, 173static int ocfs2_mv_xattr_buckets(struct inode *inode, handle_t *handle,
174 handle_t *handle, 174 u64 src_blk, u64 last_blk, u64 to_blk,
175 u64 s_blkno, 175 unsigned int start_bucket,
176 u64 t_blkno, 176 u32 *first_hash);
177 int t_is_new);
178 177
179static inline u16 ocfs2_xattr_buckets_per_cluster(struct ocfs2_super *osb) 178static inline u16 ocfs2_xattr_buckets_per_cluster(struct ocfs2_super *osb)
180{ 179{
@@ -3556,115 +3555,64 @@ static int ocfs2_mv_xattr_bucket_cross_cluster(struct inode *inode,
3556 u32 num_clusters, 3555 u32 num_clusters,
3557 u32 *first_hash) 3556 u32 *first_hash)
3558{ 3557{
3559 int i, ret, credits; 3558 int ret;
3560 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 3559 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
3561 int blks_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb); 3560 int blks_per_bucket = ocfs2_blocks_per_xattr_bucket(inode->i_sb);
3562 int bpc = ocfs2_clusters_to_blocks(inode->i_sb, 1);
3563 int num_buckets = ocfs2_xattr_buckets_per_cluster(osb); 3561 int num_buckets = ocfs2_xattr_buckets_per_cluster(osb);
3564 int to_move = num_buckets / 2; 3562 int to_move = num_buckets / 2;
3565 u64 last_cluster_blkno, src_blkno; 3563 u64 src_blkno;
3564 u64 last_cluster_blkno = prev_blkno +
3565 ((num_clusters - 1) * ocfs2_clusters_to_blocks(inode->i_sb, 1));
3566 struct ocfs2_xattr_header *xh = 3566 struct ocfs2_xattr_header *xh =
3567 (struct ocfs2_xattr_header *)((*first_bh)->b_data); 3567 (struct ocfs2_xattr_header *)((*first_bh)->b_data);
3568 struct ocfs2_xattr_bucket *old_first, *new_first; 3568 struct ocfs2_xattr_bucket *new_target, *new_first;
3569 3569
3570 BUG_ON(le16_to_cpu(xh->xh_num_buckets) < num_buckets); 3570 BUG_ON(le16_to_cpu(xh->xh_num_buckets) < num_buckets);
3571 BUG_ON(OCFS2_XATTR_BUCKET_SIZE == osb->s_clustersize); 3571 BUG_ON(OCFS2_XATTR_BUCKET_SIZE == osb->s_clustersize);
3572 3572
3573 last_cluster_blkno = prev_blkno + ((num_clusters - 1) * bpc);
3574 src_blkno = last_cluster_blkno + (to_move * blks_per_bucket);
3575
3576 mlog(0, "move half of xattrs in cluster %llu to %llu\n", 3573 mlog(0, "move half of xattrs in cluster %llu to %llu\n",
3577 (unsigned long long)prev_blkno, (unsigned long long)new_blkno); 3574 (unsigned long long)last_cluster_blkno, (unsigned long long)new_blkno);
3578 3575
3579 /* The first bucket of the original extent */
3580 old_first = ocfs2_xattr_bucket_new(inode);
3581 /* The first bucket of the new extent */ 3576 /* The first bucket of the new extent */
3582 new_first = ocfs2_xattr_bucket_new(inode); 3577 new_first = ocfs2_xattr_bucket_new(inode);
3583 if (!old_first || !new_first) { 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) {
3584 ret = -ENOMEM; 3581 ret = -ENOMEM;
3585 mlog_errno(ret); 3582 mlog_errno(ret);
3586 goto out; 3583 goto out;
3587 } 3584 }
3588 3585
3589 ret = ocfs2_read_xattr_bucket(old_first, prev_blkno); 3586 ret = ocfs2_mv_xattr_buckets(inode, handle, prev_blkno,
3587 last_cluster_blkno, new_blkno,
3588 to_move, first_hash);
3590 if (ret) { 3589 if (ret) {
3591 mlog_errno(ret); 3590 mlog_errno(ret);
3592 goto out; 3591 goto out;
3593 } 3592 }
3594 3593
3595 /* 3594 /* This is the first bucket that got moved */
3596 * We need to update the 1st half of the new extent, and we 3595 src_blkno = last_cluster_blkno + (to_move * blks_per_bucket);
3597 * need to update the first bucket of the old extent.
3598 */
3599 credits = ((to_move + 1) * blks_per_bucket) + handle->h_buffer_credits;
3600 ret = ocfs2_extend_trans(handle, credits);
3601 if (ret) {
3602 mlog_errno(ret);
3603 goto out;
3604 }
3605
3606 ret = ocfs2_xattr_bucket_journal_access(handle, old_first,
3607 OCFS2_JOURNAL_ACCESS_WRITE);
3608 if (ret) {
3609 mlog_errno(ret);
3610 goto out;
3611 }
3612
3613 for (i = 0; i < to_move; i++) {
3614 ret = ocfs2_cp_xattr_bucket(inode, handle,
3615 src_blkno + (i * blks_per_bucket),
3616 new_blkno + (i * blks_per_bucket),
3617 1);
3618 if (ret) {
3619 mlog_errno(ret);
3620 goto out;
3621 }
3622 }
3623
3624 /*
3625 * Get the new bucket ready before we dirty anything
3626 * (This actually shouldn't fail, because we already dirtied
3627 * it once in ocfs2_cp_xattr_bucket()).
3628 */
3629 ret = ocfs2_read_xattr_bucket(new_first, new_blkno);
3630 if (ret) {
3631 mlog_errno(ret);
3632 goto out;
3633 }
3634 ret = ocfs2_xattr_bucket_journal_access(handle, new_first,
3635 OCFS2_JOURNAL_ACCESS_WRITE);
3636 if (ret) {
3637 mlog_errno(ret);
3638 goto out;
3639 }
3640
3641 /* Now update the headers */
3642 le16_add_cpu(&bucket_xh(old_first)->xh_num_buckets, -to_move);
3643 ocfs2_xattr_bucket_journal_dirty(handle, old_first);
3644
3645 bucket_xh(new_first)->xh_num_buckets = cpu_to_le16(to_move);
3646 ocfs2_xattr_bucket_journal_dirty(handle, new_first);
3647
3648 if (first_hash)
3649 *first_hash = le32_to_cpu(bucket_xh(new_first)->xh_entries[0].xe_name_hash);
3650 3596
3651 /* 3597 /*
3652 * If the target bucket is anywhere past src_blkno, we moved 3598 * If the target bucket was part of the moved buckets, we need to
3653 * it to the new extent. We need to update first_bh and header_bh. 3599 * update first_bh and header_bh.
3654 */ 3600 */
3655 if ((*header_bh)->b_blocknr >= src_blkno) { 3601 if ((*header_bh)->b_blocknr >= src_blkno) {
3656 /* We're done with old_first, so we can re-use it. */
3657 ocfs2_xattr_bucket_relse(old_first);
3658
3659 /* Find the block for the new target bucket */ 3602 /* Find the block for the new target bucket */
3660 src_blkno = new_blkno + 3603 src_blkno = new_blkno +
3661 ((*header_bh)->b_blocknr - src_blkno); 3604 ((*header_bh)->b_blocknr - src_blkno);
3662 3605
3663 /* 3606 /*
3664 * This shouldn't fail - the buffers are in the 3607 * These shouldn't fail - the buffers are in the
3665 * journal from ocfs2_cp_xattr_bucket(). 3608 * journal from ocfs2_cp_xattr_bucket().
3666 */ 3609 */
3667 ret = ocfs2_read_xattr_bucket(old_first, src_blkno); 3610 ret = ocfs2_read_xattr_bucket(new_first, new_blkno);
3611 if (ret) {
3612 mlog_errno(ret);
3613 goto out;
3614 }
3615 ret = ocfs2_read_xattr_bucket(new_target, src_blkno);
3668 if (ret) { 3616 if (ret) {
3669 mlog_errno(ret); 3617 mlog_errno(ret);
3670 goto out; 3618 goto out;
@@ -3675,13 +3623,13 @@ static int ocfs2_mv_xattr_bucket_cross_cluster(struct inode *inode,
3675 get_bh(*first_bh); 3623 get_bh(*first_bh);
3676 3624
3677 brelse(*header_bh); 3625 brelse(*header_bh);
3678 *header_bh = old_first->bu_bhs[0]; 3626 *header_bh = new_target->bu_bhs[0];
3679 get_bh(*header_bh); 3627 get_bh(*header_bh);
3680 } 3628 }
3681 3629
3682out: 3630out:
3683 ocfs2_xattr_bucket_free(new_first); 3631 ocfs2_xattr_bucket_free(new_first);
3684 ocfs2_xattr_bucket_free(old_first); 3632 ocfs2_xattr_bucket_free(new_target);
3685 3633
3686 return ret; 3634 return ret;
3687} 3635}