aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTao Ma <tao.ma@oracle.com>2010-07-09 02:53:12 -0400
committerJoel Becker <joel.becker@oracle.com>2010-07-12 16:57:50 -0400
commit121a39bb00b421211f4f590c440a8f636d3ae807 (patch)
tree18219c168c7b35e9d17a283f1217eb802f0d3d11
parenta78f9f4668949a6588b8872f162e86685c63d023 (diff)
ocfs2: Make xattr reflink work with new local alloc reservation.
The new reservation code in local alloc has add the limitation that the caller should handle the case that the local alloc doesn't give use enough contiguous clusters. It make the old xattr reflink code broken. So this patch udpate the xattr reflink code so that it can handle the case that local alloc give us one cluster at a time. Signed-off-by: Tao Ma <tao.ma@oracle.com> Signed-off-by: Joel Becker <joel.becker@oracle.com>
-rw-r--r--fs/ocfs2/xattr.c126
1 files changed, 90 insertions, 36 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c
index 2be19083713f..d03469f61801 100644
--- a/fs/ocfs2/xattr.c
+++ b/fs/ocfs2/xattr.c
@@ -6804,16 +6804,15 @@ out:
6804 return ret; 6804 return ret;
6805} 6805}
6806 6806
6807static int ocfs2_reflink_xattr_buckets(handle_t *handle, 6807static int ocfs2_reflink_xattr_bucket(handle_t *handle,
6808 u64 blkno, u64 new_blkno, u32 clusters, 6808 u64 blkno, u64 new_blkno, u32 clusters,
6809 u32 *cpos, int num_buckets,
6809 struct ocfs2_alloc_context *meta_ac, 6810 struct ocfs2_alloc_context *meta_ac,
6810 struct ocfs2_alloc_context *data_ac, 6811 struct ocfs2_alloc_context *data_ac,
6811 struct ocfs2_reflink_xattr_tree_args *args) 6812 struct ocfs2_reflink_xattr_tree_args *args)
6812{ 6813{
6813 int i, j, ret = 0; 6814 int i, j, ret = 0;
6814 struct super_block *sb = args->reflink->old_inode->i_sb; 6815 struct super_block *sb = args->reflink->old_inode->i_sb;
6815 u32 bpc = ocfs2_xattr_buckets_per_cluster(OCFS2_SB(sb));
6816 u32 num_buckets = clusters * bpc;
6817 int bpb = args->old_bucket->bu_blocks; 6816 int bpb = args->old_bucket->bu_blocks;
6818 struct ocfs2_xattr_value_buf vb = { 6817 struct ocfs2_xattr_value_buf vb = {
6819 .vb_access = ocfs2_journal_access, 6818 .vb_access = ocfs2_journal_access,
@@ -6832,14 +6831,6 @@ static int ocfs2_reflink_xattr_buckets(handle_t *handle,
6832 break; 6831 break;
6833 } 6832 }
6834 6833
6835 /*
6836 * The real bucket num in this series of blocks is stored
6837 * in the 1st bucket.
6838 */
6839 if (i == 0)
6840 num_buckets = le16_to_cpu(
6841 bucket_xh(args->old_bucket)->xh_num_buckets);
6842
6843 ret = ocfs2_xattr_bucket_journal_access(handle, 6834 ret = ocfs2_xattr_bucket_journal_access(handle,
6844 args->new_bucket, 6835 args->new_bucket,
6845 OCFS2_JOURNAL_ACCESS_CREATE); 6836 OCFS2_JOURNAL_ACCESS_CREATE);
@@ -6853,6 +6844,18 @@ static int ocfs2_reflink_xattr_buckets(handle_t *handle,
6853 bucket_block(args->old_bucket, j), 6844 bucket_block(args->old_bucket, j),
6854 sb->s_blocksize); 6845 sb->s_blocksize);
6855 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
6856 ocfs2_xattr_bucket_journal_dirty(handle, args->new_bucket); 6859 ocfs2_xattr_bucket_journal_dirty(handle, args->new_bucket);
6857 6860
6858 ret = ocfs2_reflink_xattr_header(handle, args->reflink, 6861 ret = ocfs2_reflink_xattr_header(handle, args->reflink,
@@ -6882,6 +6885,7 @@ static int ocfs2_reflink_xattr_buckets(handle_t *handle,
6882 } 6885 }
6883 6886
6884 ocfs2_xattr_bucket_journal_dirty(handle, args->new_bucket); 6887 ocfs2_xattr_bucket_journal_dirty(handle, args->new_bucket);
6888
6885 ocfs2_xattr_bucket_relse(args->old_bucket); 6889 ocfs2_xattr_bucket_relse(args->old_bucket);
6886 ocfs2_xattr_bucket_relse(args->new_bucket); 6890 ocfs2_xattr_bucket_relse(args->new_bucket);
6887 } 6891 }
@@ -6890,6 +6894,75 @@ static int ocfs2_reflink_xattr_buckets(handle_t *handle,
6890 ocfs2_xattr_bucket_relse(args->new_bucket); 6894 ocfs2_xattr_bucket_relse(args->new_bucket);
6891 return ret; 6895 return ret;
6892} 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
6893/* 6966/*
6894 * 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.
6895 */ 6968 */
@@ -6901,8 +6974,6 @@ static int ocfs2_reflink_xattr_rec(struct inode *inode,
6901 void *para) 6974 void *para)
6902{ 6975{
6903 int ret, credits = 0; 6976 int ret, credits = 0;
6904 u32 p_cluster, num_clusters;
6905 u64 new_blkno;
6906 handle_t *handle; 6977 handle_t *handle;
6907 struct ocfs2_reflink_xattr_tree_args *args = 6978 struct ocfs2_reflink_xattr_tree_args *args =
6908 (struct ocfs2_reflink_xattr_tree_args *)para; 6979 (struct ocfs2_reflink_xattr_tree_args *)para;
@@ -6911,6 +6982,9 @@ static int ocfs2_reflink_xattr_rec(struct inode *inode,
6911 struct ocfs2_alloc_context *data_ac = NULL; 6982 struct ocfs2_alloc_context *data_ac = NULL;
6912 struct ocfs2_extent_tree et; 6983 struct ocfs2_extent_tree et;
6913 6984
6985 mlog(0, "reflink xattr buckets %llu len %u\n",
6986 (unsigned long long)blkno, len);
6987
6914 ocfs2_init_xattr_tree_extent_tree(&et, 6988 ocfs2_init_xattr_tree_extent_tree(&et,
6915 INODE_CACHE(args->reflink->new_inode), 6989 INODE_CACHE(args->reflink->new_inode),
6916 args->new_blk_bh); 6990 args->new_blk_bh);
@@ -6930,32 +7004,12 @@ static int ocfs2_reflink_xattr_rec(struct inode *inode,
6930 goto out; 7004 goto out;
6931 } 7005 }
6932 7006
6933 ret = ocfs2_claim_clusters(handle, data_ac, 7007 ret = ocfs2_reflink_xattr_buckets(handle, inode, args, &et,
6934 len, &p_cluster, &num_clusters); 7008 meta_ac, data_ac,
6935 if (ret) { 7009 blkno, cpos, len);
6936 mlog_errno(ret);
6937 goto out_commit;
6938 }
6939
6940 new_blkno = ocfs2_clusters_to_blocks(osb->sb, p_cluster);
6941
6942 mlog(0, "reflink xattr buckets %llu to %llu, len %u\n",
6943 (unsigned long long)blkno, (unsigned long long)new_blkno, len);
6944 ret = ocfs2_reflink_xattr_buckets(handle, blkno, new_blkno, len,
6945 meta_ac, data_ac, args);
6946 if (ret) {
6947 mlog_errno(ret);
6948 goto out_commit;
6949 }
6950
6951 mlog(0, "insert new xattr extent rec start %llu len %u to %u\n",
6952 (unsigned long long)new_blkno, len, cpos);
6953 ret = ocfs2_insert_extent(handle, &et, cpos, new_blkno,
6954 len, 0, meta_ac);
6955 if (ret) 7010 if (ret)
6956 mlog_errno(ret); 7011 mlog_errno(ret);
6957 7012
6958out_commit:
6959 ocfs2_commit_trans(osb, handle); 7013 ocfs2_commit_trans(osb, handle);
6960 7014
6961out: 7015out: