aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ocfs2/xattr.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ocfs2/xattr.c')
-rw-r--r--fs/ocfs2/xattr.c200
1 files changed, 135 insertions, 65 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index e97b34842cfe..d03469f61801 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -709,7 +709,7 @@ static int ocfs2_xattr_extend_allocation(struct inode *inode,
709 struct ocfs2_xattr_value_buf *vb, 709 struct ocfs2_xattr_value_buf *vb,
710 struct ocfs2_xattr_set_ctxt *ctxt) 710 struct ocfs2_xattr_set_ctxt *ctxt)
711{ 711{
712 int status = 0; 712 int status = 0, credits;
713 handle_t *handle = ctxt->handle; 713 handle_t *handle = ctxt->handle;
714 enum ocfs2_alloc_restarted why; 714 enum ocfs2_alloc_restarted why;
715 u32 prev_clusters, logical_start = le32_to_cpu(vb->vb_xv->xr_clusters); 715 u32 prev_clusters, logical_start = le32_to_cpu(vb->vb_xv->xr_clusters);
@@ -719,38 +719,54 @@ static int ocfs2_xattr_extend_allocation(struct inode *inode,
719 719
720 ocfs2_init_xattr_value_extent_tree(&et, INODE_CACHE(inode), vb); 720 ocfs2_init_xattr_value_extent_tree(&et, INODE_CACHE(inode), vb);
721 721
722 status = vb->vb_access(handle, INODE_CACHE(inode), vb->vb_bh, 722 while (clusters_to_add) {
723 OCFS2_JOURNAL_ACCESS_WRITE); 723 status = vb->vb_access(handle, INODE_CACHE(inode), vb->vb_bh,
724 if (status < 0) { 724 OCFS2_JOURNAL_ACCESS_WRITE);
725 mlog_errno(status); 725 if (status < 0) {
726 goto leave; 726 mlog_errno(status);
727 } 727 break;
728 }
728 729
729 prev_clusters = le32_to_cpu(vb->vb_xv->xr_clusters); 730 prev_clusters = le32_to_cpu(vb->vb_xv->xr_clusters);
730 status = ocfs2_add_clusters_in_btree(handle, 731 status = ocfs2_add_clusters_in_btree(handle,
731 &et, 732 &et,
732 &logical_start, 733 &logical_start,
733 clusters_to_add, 734 clusters_to_add,
734 0, 735 0,
735 ctxt->data_ac, 736 ctxt->data_ac,
736 ctxt->meta_ac, 737 ctxt->meta_ac,
737 &why); 738 &why);
738 if (status < 0) { 739 if ((status < 0) && (status != -EAGAIN)) {
739 mlog_errno(status); 740 if (status != -ENOSPC)
740 goto leave; 741 mlog_errno(status);
741 } 742 break;
743 }
742 744
743 ocfs2_journal_dirty(handle, vb->vb_bh); 745 ocfs2_journal_dirty(handle, vb->vb_bh);
744 746
745 clusters_to_add -= le32_to_cpu(vb->vb_xv->xr_clusters) - prev_clusters; 747 clusters_to_add -= le32_to_cpu(vb->vb_xv->xr_clusters) -
748 prev_clusters;
746 749
747 /* 750 if (why != RESTART_NONE && clusters_to_add) {
748 * We should have already allocated enough space before the transaction, 751 /*
749 * so no need to restart. 752 * We can only fail in case the alloc file doesn't give
750 */ 753 * up enough clusters.
751 BUG_ON(why != RESTART_NONE || clusters_to_add); 754 */
752 755 BUG_ON(why == RESTART_META);
753leave: 756
757 mlog(0, "restarting xattr value extension for %u"
758 " clusters,.\n", clusters_to_add);
759 credits = ocfs2_calc_extend_credits(inode->i_sb,
760 &vb->vb_xv->xr_list,
761 clusters_to_add);
762 status = ocfs2_extend_trans(handle, credits);
763 if (status < 0) {
764 status = -ENOMEM;
765 mlog_errno(status);
766 break;
767 }
768 }
769 }
754 770
755 return status; 771 return status;
756} 772}
@@ -6788,16 +6804,15 @@ out:
6788 return ret; 6804 return ret;
6789} 6805}
6790 6806
6791static int ocfs2_reflink_xattr_buckets(handle_t *handle, 6807static int ocfs2_reflink_xattr_bucket(handle_t *handle,
6792 u64 blkno, u64 new_blkno, u32 clusters, 6808 u64 blkno, u64 new_blkno, u32 clusters,
6809 u32 *cpos, int num_buckets,
6793 struct ocfs2_alloc_context *meta_ac, 6810 struct ocfs2_alloc_context *meta_ac,
6794 struct ocfs2_alloc_context *data_ac, 6811 struct ocfs2_alloc_context *data_ac,
6795 struct ocfs2_reflink_xattr_tree_args *args) 6812 struct ocfs2_reflink_xattr_tree_args *args)
6796{ 6813{
6797 int i, j, ret = 0; 6814 int i, j, ret = 0;
6798 struct super_block *sb = args->reflink->old_inode->i_sb; 6815 struct super_block *sb = args->reflink->old_inode->i_sb;
6799 u32 bpc = ocfs2_xattr_buckets_per_cluster(OCFS2_SB(sb));
6800 u32 num_buckets = clusters * bpc;
6801 int bpb = args->old_bucket->bu_blocks; 6816 int bpb = args->old_bucket->bu_blocks;
6802 struct ocfs2_xattr_value_buf vb = { 6817 struct ocfs2_xattr_value_buf vb = {
6803 .vb_access = ocfs2_journal_access, 6818 .vb_access = ocfs2_journal_access,
@@ -6816,14 +6831,6 @@ static int ocfs2_reflink_xattr_buckets(handle_t *handle,
6816 break; 6831 break;
6817 } 6832 }
6818 6833
6819 /*
6820 * The real bucket num in this series of blocks is stored
6821 * in the 1st bucket.
6822 */
6823 if (i == 0)
6824 num_buckets = le16_to_cpu(
6825 bucket_xh(args->old_bucket)->xh_num_buckets);
6826
6827 ret = ocfs2_xattr_bucket_journal_access(handle, 6834 ret = ocfs2_xattr_bucket_journal_access(handle,
6828 args->new_bucket, 6835 args->new_bucket,
6829 OCFS2_JOURNAL_ACCESS_CREATE); 6836 OCFS2_JOURNAL_ACCESS_CREATE);
@@ -6837,6 +6844,18 @@ static int ocfs2_reflink_xattr_buckets(handle_t *handle,
6837 bucket_block(args->old_bucket, j), 6844 bucket_block(args->old_bucket, j),
6838 sb->s_blocksize); 6845 sb->s_blocksize);
6839 6846
6847 /*
6848 * Record the start cpos so that we can use it to initialize
6849 * our xattr tree we also set the xh_num_bucket for the new
6850 * bucket.
6851 */
6852 if (i == 0) {
6853 *cpos = le32_to_cpu(bucket_xh(args->new_bucket)->
6854 xh_entries[0].xe_name_hash);
6855 bucket_xh(args->new_bucket)->xh_num_buckets =
6856 cpu_to_le16(num_buckets);
6857 }
6858
6840 ocfs2_xattr_bucket_journal_dirty(handle, args->new_bucket); 6859 ocfs2_xattr_bucket_journal_dirty(handle, args->new_bucket);
6841 6860
6842 ret = ocfs2_reflink_xattr_header(handle, args->reflink, 6861 ret = ocfs2_reflink_xattr_header(handle, args->reflink,
@@ -6866,6 +6885,7 @@ static int ocfs2_reflink_xattr_buckets(handle_t *handle,
6866 } 6885 }
6867 6886
6868 ocfs2_xattr_bucket_journal_dirty(handle, args->new_bucket); 6887 ocfs2_xattr_bucket_journal_dirty(handle, args->new_bucket);
6888
6869 ocfs2_xattr_bucket_relse(args->old_bucket); 6889 ocfs2_xattr_bucket_relse(args->old_bucket);
6870 ocfs2_xattr_bucket_relse(args->new_bucket); 6890 ocfs2_xattr_bucket_relse(args->new_bucket);
6871 } 6891 }
@@ -6874,6 +6894,75 @@ static int ocfs2_reflink_xattr_buckets(handle_t *handle,
6874 ocfs2_xattr_bucket_relse(args->new_bucket); 6894 ocfs2_xattr_bucket_relse(args->new_bucket);
6875 return ret; 6895 return ret;
6876} 6896}
6897
6898static int ocfs2_reflink_xattr_buckets(handle_t *handle,
6899 struct inode *inode,
6900 struct ocfs2_reflink_xattr_tree_args *args,
6901 struct ocfs2_extent_tree *et,
6902 struct ocfs2_alloc_context *meta_ac,
6903 struct ocfs2_alloc_context *data_ac,
6904 u64 blkno, u32 cpos, u32 len)
6905{
6906 int ret, first_inserted = 0;
6907 u32 p_cluster, num_clusters, reflink_cpos = 0;
6908 u64 new_blkno;
6909 unsigned int num_buckets, reflink_buckets;
6910 unsigned int bpc =
6911 ocfs2_xattr_buckets_per_cluster(OCFS2_SB(inode->i_sb));
6912
6913 ret = ocfs2_read_xattr_bucket(args->old_bucket, blkno);
6914 if (ret) {
6915 mlog_errno(ret);
6916 goto out;
6917 }
6918 num_buckets = le16_to_cpu(bucket_xh(args->old_bucket)->xh_num_buckets);
6919 ocfs2_xattr_bucket_relse(args->old_bucket);
6920
6921 while (len && num_buckets) {
6922 ret = ocfs2_claim_clusters(handle, data_ac,
6923 1, &p_cluster, &num_clusters);
6924 if (ret) {
6925 mlog_errno(ret);
6926 goto out;
6927 }
6928
6929 new_blkno = ocfs2_clusters_to_blocks(inode->i_sb, p_cluster);
6930 reflink_buckets = min(num_buckets, bpc * num_clusters);
6931
6932 ret = ocfs2_reflink_xattr_bucket(handle, blkno,
6933 new_blkno, num_clusters,
6934 &reflink_cpos, reflink_buckets,
6935 meta_ac, data_ac, args);
6936 if (ret) {
6937 mlog_errno(ret);
6938 goto out;
6939 }
6940
6941 /*
6942 * For the 1st allocated cluster, we make it use the same cpos
6943 * so that the xattr tree looks the same as the original one
6944 * in the most case.
6945 */
6946 if (!first_inserted) {
6947 reflink_cpos = cpos;
6948 first_inserted = 1;
6949 }
6950 ret = ocfs2_insert_extent(handle, et, reflink_cpos, new_blkno,
6951 num_clusters, 0, meta_ac);
6952 if (ret)
6953 mlog_errno(ret);
6954
6955 mlog(0, "insert new xattr extent rec start %llu len %u to %u\n",
6956 (unsigned long long)new_blkno, num_clusters, reflink_cpos);
6957
6958 len -= num_clusters;
6959 blkno += ocfs2_clusters_to_blocks(inode->i_sb, num_clusters);
6960 num_buckets -= reflink_buckets;
6961 }
6962out:
6963 return ret;
6964}
6965
6877/* 6966/*
6878 * Create the same xattr extent record in the new inode's xattr tree. 6967 * Create the same xattr extent record in the new inode's xattr tree.
6879 */ 6968 */
@@ -6885,8 +6974,6 @@ static int ocfs2_reflink_xattr_rec(struct inode *inode,
6885 void *para) 6974 void *para)
6886{ 6975{
6887 int ret, credits = 0; 6976 int ret, credits = 0;
6888 u32 p_cluster, num_clusters;
6889 u64 new_blkno;
6890 handle_t *handle; 6977 handle_t *handle;
6891 struct ocfs2_reflink_xattr_tree_args *args = 6978 struct ocfs2_reflink_xattr_tree_args *args =
6892 (struct ocfs2_reflink_xattr_tree_args *)para; 6979 (struct ocfs2_reflink_xattr_tree_args *)para;
@@ -6895,6 +6982,9 @@ static int ocfs2_reflink_xattr_rec(struct inode *inode,
6895 struct ocfs2_alloc_context *data_ac = NULL; 6982 struct ocfs2_alloc_context *data_ac = NULL;
6896 struct ocfs2_extent_tree et; 6983 struct ocfs2_extent_tree et;
6897 6984
6985 mlog(0, "reflink xattr buckets %llu len %u\n",
6986 (unsigned long long)blkno, len);
6987
6898 ocfs2_init_xattr_tree_extent_tree(&et, 6988 ocfs2_init_xattr_tree_extent_tree(&et,
6899 INODE_CACHE(args->reflink->new_inode), 6989 INODE_CACHE(args->reflink->new_inode),
6900 args->new_blk_bh); 6990 args->new_blk_bh);
@@ -6914,32 +7004,12 @@ static int ocfs2_reflink_xattr_rec(struct inode *inode,
6914 goto out; 7004 goto out;
6915 } 7005 }
6916 7006
6917 ret = ocfs2_claim_clusters(handle, data_ac, 7007 ret = ocfs2_reflink_xattr_buckets(handle, inode, args, &et,
6918 len, &p_cluster, &num_clusters); 7008 meta_ac, data_ac,
6919 if (ret) { 7009 blkno, cpos, len);
6920 mlog_errno(ret);
6921 goto out_commit;
6922 }
6923
6924 new_blkno = ocfs2_clusters_to_blocks(osb->sb, p_cluster);
6925
6926 mlog(0, "reflink xattr buckets %llu to %llu, len %u\n",
6927 (unsigned long long)blkno, (unsigned long long)new_blkno, len);
6928 ret = ocfs2_reflink_xattr_buckets(handle, blkno, new_blkno, len,
6929 meta_ac, data_ac, args);
6930 if (ret) {
6931 mlog_errno(ret);
6932 goto out_commit;
6933 }
6934
6935 mlog(0, "insert new xattr extent rec start %llu len %u to %u\n",
6936 (unsigned long long)new_blkno, len, cpos);
6937 ret = ocfs2_insert_extent(handle, &et, cpos, new_blkno,
6938 len, 0, meta_ac);
6939 if (ret) 7010 if (ret)
6940 mlog_errno(ret); 7011 mlog_errno(ret);
6941 7012
6942out_commit:
6943 ocfs2_commit_trans(osb, handle); 7013 ocfs2_commit_trans(osb, handle);
6944 7014
6945out: 7015out: