diff options
Diffstat (limited to 'fs/ocfs2/xattr.c')
-rw-r--r-- | fs/ocfs2/xattr.c | 2056 |
1 files changed, 1878 insertions, 178 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index d1a27cda984f..fe3419068df2 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
@@ -55,7 +55,8 @@ | |||
55 | #include "buffer_head_io.h" | 55 | #include "buffer_head_io.h" |
56 | #include "super.h" | 56 | #include "super.h" |
57 | #include "xattr.h" | 57 | #include "xattr.h" |
58 | 58 | #include "refcounttree.h" | |
59 | #include "acl.h" | ||
59 | 60 | ||
60 | struct ocfs2_xattr_def_value_root { | 61 | struct ocfs2_xattr_def_value_root { |
61 | struct ocfs2_xattr_value_root xv; | 62 | struct ocfs2_xattr_value_root xv; |
@@ -140,7 +141,7 @@ struct ocfs2_xattr_search { | |||
140 | int not_found; | 141 | int not_found; |
141 | }; | 142 | }; |
142 | 143 | ||
143 | static int ocfs2_xattr_bucket_get_name_value(struct inode *inode, | 144 | static int ocfs2_xattr_bucket_get_name_value(struct super_block *sb, |
144 | struct ocfs2_xattr_header *xh, | 145 | struct ocfs2_xattr_header *xh, |
145 | int index, | 146 | int index, |
146 | int *block_off, | 147 | int *block_off, |
@@ -157,7 +158,7 @@ static int ocfs2_xattr_index_block_find(struct inode *inode, | |||
157 | struct ocfs2_xattr_search *xs); | 158 | struct ocfs2_xattr_search *xs); |
158 | 159 | ||
159 | static int ocfs2_xattr_tree_list_index_block(struct inode *inode, | 160 | static int ocfs2_xattr_tree_list_index_block(struct inode *inode, |
160 | struct ocfs2_xattr_tree_root *xt, | 161 | struct buffer_head *blk_bh, |
161 | char *buffer, | 162 | char *buffer, |
162 | size_t buffer_size); | 163 | size_t buffer_size); |
163 | 164 | ||
@@ -170,12 +171,42 @@ static int ocfs2_xattr_set_entry_index_block(struct inode *inode, | |||
170 | struct ocfs2_xattr_search *xs, | 171 | struct ocfs2_xattr_search *xs, |
171 | struct ocfs2_xattr_set_ctxt *ctxt); | 172 | struct ocfs2_xattr_set_ctxt *ctxt); |
172 | 173 | ||
173 | static int ocfs2_delete_xattr_index_block(struct inode *inode, | 174 | typedef int (xattr_tree_rec_func)(struct inode *inode, |
174 | struct buffer_head *xb_bh); | 175 | struct buffer_head *root_bh, |
176 | u64 blkno, u32 cpos, u32 len, void *para); | ||
177 | static int ocfs2_iterate_xattr_index_block(struct inode *inode, | ||
178 | struct buffer_head *root_bh, | ||
179 | xattr_tree_rec_func *rec_func, | ||
180 | void *para); | ||
181 | static int ocfs2_delete_xattr_in_bucket(struct inode *inode, | ||
182 | struct ocfs2_xattr_bucket *bucket, | ||
183 | void *para); | ||
184 | static int ocfs2_rm_xattr_cluster(struct inode *inode, | ||
185 | struct buffer_head *root_bh, | ||
186 | u64 blkno, | ||
187 | u32 cpos, | ||
188 | u32 len, | ||
189 | void *para); | ||
190 | |||
175 | static int ocfs2_mv_xattr_buckets(struct inode *inode, handle_t *handle, | 191 | static int ocfs2_mv_xattr_buckets(struct inode *inode, handle_t *handle, |
176 | u64 src_blk, u64 last_blk, u64 to_blk, | 192 | u64 src_blk, u64 last_blk, u64 to_blk, |
177 | unsigned int start_bucket, | 193 | unsigned int start_bucket, |
178 | u32 *first_hash); | 194 | u32 *first_hash); |
195 | static int ocfs2_prepare_refcount_xattr(struct inode *inode, | ||
196 | struct ocfs2_dinode *di, | ||
197 | struct ocfs2_xattr_info *xi, | ||
198 | struct ocfs2_xattr_search *xis, | ||
199 | struct ocfs2_xattr_search *xbs, | ||
200 | struct ocfs2_refcount_tree **ref_tree, | ||
201 | int *meta_need, | ||
202 | int *credits); | ||
203 | static int ocfs2_get_xattr_tree_value_root(struct super_block *sb, | ||
204 | struct ocfs2_xattr_bucket *bucket, | ||
205 | int offset, | ||
206 | struct ocfs2_xattr_value_root **xv, | ||
207 | struct buffer_head **bh); | ||
208 | static int ocfs2_xattr_security_set(struct inode *inode, const char *name, | ||
209 | const void *value, size_t size, int flags); | ||
179 | 210 | ||
180 | static inline u16 ocfs2_xattr_buckets_per_cluster(struct ocfs2_super *osb) | 211 | static inline u16 ocfs2_xattr_buckets_per_cluster(struct ocfs2_super *osb) |
181 | { | 212 | { |
@@ -254,9 +285,9 @@ static int ocfs2_init_xattr_bucket(struct ocfs2_xattr_bucket *bucket, | |||
254 | break; | 285 | break; |
255 | } | 286 | } |
256 | 287 | ||
257 | if (!ocfs2_buffer_uptodate(bucket->bu_inode, | 288 | if (!ocfs2_buffer_uptodate(INODE_CACHE(bucket->bu_inode), |
258 | bucket->bu_bhs[i])) | 289 | bucket->bu_bhs[i])) |
259 | ocfs2_set_new_buffer_uptodate(bucket->bu_inode, | 290 | ocfs2_set_new_buffer_uptodate(INODE_CACHE(bucket->bu_inode), |
260 | bucket->bu_bhs[i]); | 291 | bucket->bu_bhs[i]); |
261 | } | 292 | } |
262 | 293 | ||
@@ -271,7 +302,7 @@ static int ocfs2_read_xattr_bucket(struct ocfs2_xattr_bucket *bucket, | |||
271 | { | 302 | { |
272 | int rc; | 303 | int rc; |
273 | 304 | ||
274 | rc = ocfs2_read_blocks(bucket->bu_inode, xb_blkno, | 305 | rc = ocfs2_read_blocks(INODE_CACHE(bucket->bu_inode), xb_blkno, |
275 | bucket->bu_blocks, bucket->bu_bhs, 0, | 306 | bucket->bu_blocks, bucket->bu_bhs, 0, |
276 | NULL); | 307 | NULL); |
277 | if (!rc) { | 308 | if (!rc) { |
@@ -297,7 +328,8 @@ static int ocfs2_xattr_bucket_journal_access(handle_t *handle, | |||
297 | int i, rc = 0; | 328 | int i, rc = 0; |
298 | 329 | ||
299 | for (i = 0; i < bucket->bu_blocks; i++) { | 330 | for (i = 0; i < bucket->bu_blocks; i++) { |
300 | rc = ocfs2_journal_access(handle, bucket->bu_inode, | 331 | rc = ocfs2_journal_access(handle, |
332 | INODE_CACHE(bucket->bu_inode), | ||
301 | bucket->bu_bhs[i], type); | 333 | bucket->bu_bhs[i], type); |
302 | if (rc) { | 334 | if (rc) { |
303 | mlog_errno(rc); | 335 | mlog_errno(rc); |
@@ -399,7 +431,7 @@ static int ocfs2_read_xattr_block(struct inode *inode, u64 xb_blkno, | |||
399 | int rc; | 431 | int rc; |
400 | struct buffer_head *tmp = *bh; | 432 | struct buffer_head *tmp = *bh; |
401 | 433 | ||
402 | rc = ocfs2_read_block(inode, xb_blkno, &tmp, | 434 | rc = ocfs2_read_block(INODE_CACHE(inode), xb_blkno, &tmp, |
403 | ocfs2_validate_xattr_block); | 435 | ocfs2_validate_xattr_block); |
404 | 436 | ||
405 | /* If ocfs2_read_block() got us a new bh, pass it up. */ | 437 | /* If ocfs2_read_block() got us a new bh, pass it up. */ |
@@ -596,15 +628,14 @@ static int ocfs2_xattr_extend_allocation(struct inode *inode, | |||
596 | int status = 0; | 628 | int status = 0; |
597 | handle_t *handle = ctxt->handle; | 629 | handle_t *handle = ctxt->handle; |
598 | enum ocfs2_alloc_restarted why; | 630 | enum ocfs2_alloc_restarted why; |
599 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
600 | u32 prev_clusters, logical_start = le32_to_cpu(vb->vb_xv->xr_clusters); | 631 | u32 prev_clusters, logical_start = le32_to_cpu(vb->vb_xv->xr_clusters); |
601 | struct ocfs2_extent_tree et; | 632 | struct ocfs2_extent_tree et; |
602 | 633 | ||
603 | mlog(0, "(clusters_to_add for xattr= %u)\n", clusters_to_add); | 634 | mlog(0, "(clusters_to_add for xattr= %u)\n", clusters_to_add); |
604 | 635 | ||
605 | ocfs2_init_xattr_value_extent_tree(&et, inode, vb); | 636 | ocfs2_init_xattr_value_extent_tree(&et, INODE_CACHE(inode), vb); |
606 | 637 | ||
607 | status = vb->vb_access(handle, inode, vb->vb_bh, | 638 | status = vb->vb_access(handle, INODE_CACHE(inode), vb->vb_bh, |
608 | OCFS2_JOURNAL_ACCESS_WRITE); | 639 | OCFS2_JOURNAL_ACCESS_WRITE); |
609 | if (status < 0) { | 640 | if (status < 0) { |
610 | mlog_errno(status); | 641 | mlog_errno(status); |
@@ -612,13 +643,11 @@ static int ocfs2_xattr_extend_allocation(struct inode *inode, | |||
612 | } | 643 | } |
613 | 644 | ||
614 | prev_clusters = le32_to_cpu(vb->vb_xv->xr_clusters); | 645 | prev_clusters = le32_to_cpu(vb->vb_xv->xr_clusters); |
615 | status = ocfs2_add_clusters_in_btree(osb, | 646 | status = ocfs2_add_clusters_in_btree(handle, |
616 | inode, | 647 | &et, |
617 | &logical_start, | 648 | &logical_start, |
618 | clusters_to_add, | 649 | clusters_to_add, |
619 | 0, | 650 | 0, |
620 | &et, | ||
621 | handle, | ||
622 | ctxt->data_ac, | 651 | ctxt->data_ac, |
623 | ctxt->meta_ac, | 652 | ctxt->meta_ac, |
624 | &why); | 653 | &why); |
@@ -649,6 +678,7 @@ leave: | |||
649 | static int __ocfs2_remove_xattr_range(struct inode *inode, | 678 | static int __ocfs2_remove_xattr_range(struct inode *inode, |
650 | struct ocfs2_xattr_value_buf *vb, | 679 | struct ocfs2_xattr_value_buf *vb, |
651 | u32 cpos, u32 phys_cpos, u32 len, | 680 | u32 cpos, u32 phys_cpos, u32 len, |
681 | unsigned int ext_flags, | ||
652 | struct ocfs2_xattr_set_ctxt *ctxt) | 682 | struct ocfs2_xattr_set_ctxt *ctxt) |
653 | { | 683 | { |
654 | int ret; | 684 | int ret; |
@@ -656,16 +686,16 @@ static int __ocfs2_remove_xattr_range(struct inode *inode, | |||
656 | handle_t *handle = ctxt->handle; | 686 | handle_t *handle = ctxt->handle; |
657 | struct ocfs2_extent_tree et; | 687 | struct ocfs2_extent_tree et; |
658 | 688 | ||
659 | ocfs2_init_xattr_value_extent_tree(&et, inode, vb); | 689 | ocfs2_init_xattr_value_extent_tree(&et, INODE_CACHE(inode), vb); |
660 | 690 | ||
661 | ret = vb->vb_access(handle, inode, vb->vb_bh, | 691 | ret = vb->vb_access(handle, INODE_CACHE(inode), vb->vb_bh, |
662 | OCFS2_JOURNAL_ACCESS_WRITE); | 692 | OCFS2_JOURNAL_ACCESS_WRITE); |
663 | if (ret) { | 693 | if (ret) { |
664 | mlog_errno(ret); | 694 | mlog_errno(ret); |
665 | goto out; | 695 | goto out; |
666 | } | 696 | } |
667 | 697 | ||
668 | ret = ocfs2_remove_extent(inode, &et, cpos, len, handle, ctxt->meta_ac, | 698 | ret = ocfs2_remove_extent(handle, &et, cpos, len, ctxt->meta_ac, |
669 | &ctxt->dealloc); | 699 | &ctxt->dealloc); |
670 | if (ret) { | 700 | if (ret) { |
671 | mlog_errno(ret); | 701 | mlog_errno(ret); |
@@ -680,7 +710,14 @@ static int __ocfs2_remove_xattr_range(struct inode *inode, | |||
680 | goto out; | 710 | goto out; |
681 | } | 711 | } |
682 | 712 | ||
683 | ret = ocfs2_cache_cluster_dealloc(&ctxt->dealloc, phys_blkno, len); | 713 | if (ext_flags & OCFS2_EXT_REFCOUNTED) |
714 | ret = ocfs2_decrease_refcount(inode, handle, | ||
715 | ocfs2_blocks_to_clusters(inode->i_sb, | ||
716 | phys_blkno), | ||
717 | len, ctxt->meta_ac, &ctxt->dealloc, 1); | ||
718 | else | ||
719 | ret = ocfs2_cache_cluster_dealloc(&ctxt->dealloc, | ||
720 | phys_blkno, len); | ||
684 | if (ret) | 721 | if (ret) |
685 | mlog_errno(ret); | 722 | mlog_errno(ret); |
686 | 723 | ||
@@ -695,6 +732,7 @@ static int ocfs2_xattr_shrink_size(struct inode *inode, | |||
695 | struct ocfs2_xattr_set_ctxt *ctxt) | 732 | struct ocfs2_xattr_set_ctxt *ctxt) |
696 | { | 733 | { |
697 | int ret = 0; | 734 | int ret = 0; |
735 | unsigned int ext_flags; | ||
698 | u32 trunc_len, cpos, phys_cpos, alloc_size; | 736 | u32 trunc_len, cpos, phys_cpos, alloc_size; |
699 | u64 block; | 737 | u64 block; |
700 | 738 | ||
@@ -706,7 +744,7 @@ static int ocfs2_xattr_shrink_size(struct inode *inode, | |||
706 | while (trunc_len) { | 744 | while (trunc_len) { |
707 | ret = ocfs2_xattr_get_clusters(inode, cpos, &phys_cpos, | 745 | ret = ocfs2_xattr_get_clusters(inode, cpos, &phys_cpos, |
708 | &alloc_size, | 746 | &alloc_size, |
709 | &vb->vb_xv->xr_list); | 747 | &vb->vb_xv->xr_list, &ext_flags); |
710 | if (ret) { | 748 | if (ret) { |
711 | mlog_errno(ret); | 749 | mlog_errno(ret); |
712 | goto out; | 750 | goto out; |
@@ -717,15 +755,15 @@ static int ocfs2_xattr_shrink_size(struct inode *inode, | |||
717 | 755 | ||
718 | ret = __ocfs2_remove_xattr_range(inode, vb, cpos, | 756 | ret = __ocfs2_remove_xattr_range(inode, vb, cpos, |
719 | phys_cpos, alloc_size, | 757 | phys_cpos, alloc_size, |
720 | ctxt); | 758 | ext_flags, ctxt); |
721 | if (ret) { | 759 | if (ret) { |
722 | mlog_errno(ret); | 760 | mlog_errno(ret); |
723 | goto out; | 761 | goto out; |
724 | } | 762 | } |
725 | 763 | ||
726 | block = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos); | 764 | block = ocfs2_clusters_to_blocks(inode->i_sb, phys_cpos); |
727 | ocfs2_remove_xattr_clusters_from_cache(inode, block, | 765 | ocfs2_remove_xattr_clusters_from_cache(INODE_CACHE(inode), |
728 | alloc_size); | 766 | block, alloc_size); |
729 | cpos += alloc_size; | 767 | cpos += alloc_size; |
730 | trunc_len -= alloc_size; | 768 | trunc_len -= alloc_size; |
731 | } | 769 | } |
@@ -810,6 +848,23 @@ static int ocfs2_xattr_list_entries(struct inode *inode, | |||
810 | return result; | 848 | return result; |
811 | } | 849 | } |
812 | 850 | ||
851 | int ocfs2_has_inline_xattr_value_outside(struct inode *inode, | ||
852 | struct ocfs2_dinode *di) | ||
853 | { | ||
854 | struct ocfs2_xattr_header *xh; | ||
855 | int i; | ||
856 | |||
857 | xh = (struct ocfs2_xattr_header *) | ||
858 | ((void *)di + inode->i_sb->s_blocksize - | ||
859 | le16_to_cpu(di->i_xattr_inline_size)); | ||
860 | |||
861 | for (i = 0; i < le16_to_cpu(xh->xh_count); i++) | ||
862 | if (!ocfs2_xattr_is_local(&xh->xh_entries[i])) | ||
863 | return 1; | ||
864 | |||
865 | return 0; | ||
866 | } | ||
867 | |||
813 | static int ocfs2_xattr_ibody_list(struct inode *inode, | 868 | static int ocfs2_xattr_ibody_list(struct inode *inode, |
814 | struct ocfs2_dinode *di, | 869 | struct ocfs2_dinode *di, |
815 | char *buffer, | 870 | char *buffer, |
@@ -855,11 +910,9 @@ static int ocfs2_xattr_block_list(struct inode *inode, | |||
855 | struct ocfs2_xattr_header *header = &xb->xb_attrs.xb_header; | 910 | struct ocfs2_xattr_header *header = &xb->xb_attrs.xb_header; |
856 | ret = ocfs2_xattr_list_entries(inode, header, | 911 | ret = ocfs2_xattr_list_entries(inode, header, |
857 | buffer, buffer_size); | 912 | buffer, buffer_size); |
858 | } else { | 913 | } else |
859 | struct ocfs2_xattr_tree_root *xt = &xb->xb_attrs.xb_root; | 914 | ret = ocfs2_xattr_tree_list_index_block(inode, blk_bh, |
860 | ret = ocfs2_xattr_tree_list_index_block(inode, xt, | ||
861 | buffer, buffer_size); | 915 | buffer, buffer_size); |
862 | } | ||
863 | 916 | ||
864 | brelse(blk_bh); | 917 | brelse(blk_bh); |
865 | 918 | ||
@@ -961,7 +1014,7 @@ static int ocfs2_xattr_get_value_outside(struct inode *inode, | |||
961 | cpos = 0; | 1014 | cpos = 0; |
962 | while (cpos < clusters) { | 1015 | while (cpos < clusters) { |
963 | ret = ocfs2_xattr_get_clusters(inode, cpos, &p_cluster, | 1016 | ret = ocfs2_xattr_get_clusters(inode, cpos, &p_cluster, |
964 | &num_clusters, el); | 1017 | &num_clusters, el, NULL); |
965 | if (ret) { | 1018 | if (ret) { |
966 | mlog_errno(ret); | 1019 | mlog_errno(ret); |
967 | goto out; | 1020 | goto out; |
@@ -970,7 +1023,8 @@ static int ocfs2_xattr_get_value_outside(struct inode *inode, | |||
970 | blkno = ocfs2_clusters_to_blocks(inode->i_sb, p_cluster); | 1023 | blkno = ocfs2_clusters_to_blocks(inode->i_sb, p_cluster); |
971 | /* Copy ocfs2_xattr_value */ | 1024 | /* Copy ocfs2_xattr_value */ |
972 | for (i = 0; i < num_clusters * bpc; i++, blkno++) { | 1025 | for (i = 0; i < num_clusters * bpc; i++, blkno++) { |
973 | ret = ocfs2_read_block(inode, blkno, &bh, NULL); | 1026 | ret = ocfs2_read_block(INODE_CACHE(inode), blkno, |
1027 | &bh, NULL); | ||
974 | if (ret) { | 1028 | if (ret) { |
975 | mlog_errno(ret); | 1029 | mlog_errno(ret); |
976 | goto out; | 1030 | goto out; |
@@ -1085,7 +1139,7 @@ static int ocfs2_xattr_block_get(struct inode *inode, | |||
1085 | i = xs->here - xs->header->xh_entries; | 1139 | i = xs->here - xs->header->xh_entries; |
1086 | 1140 | ||
1087 | if (le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED) { | 1141 | if (le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED) { |
1088 | ret = ocfs2_xattr_bucket_get_name_value(inode, | 1142 | ret = ocfs2_xattr_bucket_get_name_value(inode->i_sb, |
1089 | bucket_xh(xs->bucket), | 1143 | bucket_xh(xs->bucket), |
1090 | i, | 1144 | i, |
1091 | &block_off, | 1145 | &block_off, |
@@ -1183,7 +1237,7 @@ static int ocfs2_xattr_get(struct inode *inode, | |||
1183 | 1237 | ||
1184 | static int __ocfs2_xattr_set_value_outside(struct inode *inode, | 1238 | static int __ocfs2_xattr_set_value_outside(struct inode *inode, |
1185 | handle_t *handle, | 1239 | handle_t *handle, |
1186 | struct ocfs2_xattr_value_root *xv, | 1240 | struct ocfs2_xattr_value_buf *vb, |
1187 | const void *value, | 1241 | const void *value, |
1188 | int value_len) | 1242 | int value_len) |
1189 | { | 1243 | { |
@@ -1194,28 +1248,34 @@ static int __ocfs2_xattr_set_value_outside(struct inode *inode, | |||
1194 | u32 clusters = ocfs2_clusters_for_bytes(inode->i_sb, value_len); | 1248 | u32 clusters = ocfs2_clusters_for_bytes(inode->i_sb, value_len); |
1195 | u64 blkno; | 1249 | u64 blkno; |
1196 | struct buffer_head *bh = NULL; | 1250 | struct buffer_head *bh = NULL; |
1251 | unsigned int ext_flags; | ||
1252 | struct ocfs2_xattr_value_root *xv = vb->vb_xv; | ||
1197 | 1253 | ||
1198 | BUG_ON(clusters > le32_to_cpu(xv->xr_clusters)); | 1254 | BUG_ON(clusters > le32_to_cpu(xv->xr_clusters)); |
1199 | 1255 | ||
1200 | while (cpos < clusters) { | 1256 | while (cpos < clusters) { |
1201 | ret = ocfs2_xattr_get_clusters(inode, cpos, &p_cluster, | 1257 | ret = ocfs2_xattr_get_clusters(inode, cpos, &p_cluster, |
1202 | &num_clusters, &xv->xr_list); | 1258 | &num_clusters, &xv->xr_list, |
1259 | &ext_flags); | ||
1203 | if (ret) { | 1260 | if (ret) { |
1204 | mlog_errno(ret); | 1261 | mlog_errno(ret); |
1205 | goto out; | 1262 | goto out; |
1206 | } | 1263 | } |
1207 | 1264 | ||
1265 | BUG_ON(ext_flags & OCFS2_EXT_REFCOUNTED); | ||
1266 | |||
1208 | blkno = ocfs2_clusters_to_blocks(inode->i_sb, p_cluster); | 1267 | blkno = ocfs2_clusters_to_blocks(inode->i_sb, p_cluster); |
1209 | 1268 | ||
1210 | for (i = 0; i < num_clusters * bpc; i++, blkno++) { | 1269 | for (i = 0; i < num_clusters * bpc; i++, blkno++) { |
1211 | ret = ocfs2_read_block(inode, blkno, &bh, NULL); | 1270 | ret = ocfs2_read_block(INODE_CACHE(inode), blkno, |
1271 | &bh, NULL); | ||
1212 | if (ret) { | 1272 | if (ret) { |
1213 | mlog_errno(ret); | 1273 | mlog_errno(ret); |
1214 | goto out; | 1274 | goto out; |
1215 | } | 1275 | } |
1216 | 1276 | ||
1217 | ret = ocfs2_journal_access(handle, | 1277 | ret = ocfs2_journal_access(handle, |
1218 | inode, | 1278 | INODE_CACHE(inode), |
1219 | bh, | 1279 | bh, |
1220 | OCFS2_JOURNAL_ACCESS_WRITE); | 1280 | OCFS2_JOURNAL_ACCESS_WRITE); |
1221 | if (ret < 0) { | 1281 | if (ret < 0) { |
@@ -1266,7 +1326,7 @@ static int ocfs2_xattr_cleanup(struct inode *inode, | |||
1266 | void *val = xs->base + offs; | 1326 | void *val = xs->base + offs; |
1267 | size_t size = OCFS2_XATTR_SIZE(name_len) + OCFS2_XATTR_ROOT_SIZE; | 1327 | size_t size = OCFS2_XATTR_SIZE(name_len) + OCFS2_XATTR_ROOT_SIZE; |
1268 | 1328 | ||
1269 | ret = vb->vb_access(handle, inode, vb->vb_bh, | 1329 | ret = vb->vb_access(handle, INODE_CACHE(inode), vb->vb_bh, |
1270 | OCFS2_JOURNAL_ACCESS_WRITE); | 1330 | OCFS2_JOURNAL_ACCESS_WRITE); |
1271 | if (ret) { | 1331 | if (ret) { |
1272 | mlog_errno(ret); | 1332 | mlog_errno(ret); |
@@ -1294,7 +1354,7 @@ static int ocfs2_xattr_update_entry(struct inode *inode, | |||
1294 | { | 1354 | { |
1295 | int ret; | 1355 | int ret; |
1296 | 1356 | ||
1297 | ret = vb->vb_access(handle, inode, vb->vb_bh, | 1357 | ret = vb->vb_access(handle, INODE_CACHE(inode), vb->vb_bh, |
1298 | OCFS2_JOURNAL_ACCESS_WRITE); | 1358 | OCFS2_JOURNAL_ACCESS_WRITE); |
1299 | if (ret) { | 1359 | if (ret) { |
1300 | mlog_errno(ret); | 1360 | mlog_errno(ret); |
@@ -1355,7 +1415,7 @@ static int ocfs2_xattr_set_value_outside(struct inode *inode, | |||
1355 | mlog_errno(ret); | 1415 | mlog_errno(ret); |
1356 | return ret; | 1416 | return ret; |
1357 | } | 1417 | } |
1358 | ret = __ocfs2_xattr_set_value_outside(inode, ctxt->handle, vb->vb_xv, | 1418 | ret = __ocfs2_xattr_set_value_outside(inode, ctxt->handle, vb, |
1359 | xi->value, xi->value_len); | 1419 | xi->value, xi->value_len); |
1360 | if (ret < 0) | 1420 | if (ret < 0) |
1361 | mlog_errno(ret); | 1421 | mlog_errno(ret); |
@@ -1594,7 +1654,7 @@ static int ocfs2_xattr_set_entry(struct inode *inode, | |||
1594 | 1654 | ||
1595 | ret = __ocfs2_xattr_set_value_outside(inode, | 1655 | ret = __ocfs2_xattr_set_value_outside(inode, |
1596 | handle, | 1656 | handle, |
1597 | vb.vb_xv, | 1657 | &vb, |
1598 | xi->value, | 1658 | xi->value, |
1599 | xi->value_len); | 1659 | xi->value_len); |
1600 | if (ret < 0) | 1660 | if (ret < 0) |
@@ -1615,7 +1675,7 @@ static int ocfs2_xattr_set_entry(struct inode *inode, | |||
1615 | } | 1675 | } |
1616 | } | 1676 | } |
1617 | 1677 | ||
1618 | ret = ocfs2_journal_access_di(handle, inode, xs->inode_bh, | 1678 | ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), xs->inode_bh, |
1619 | OCFS2_JOURNAL_ACCESS_WRITE); | 1679 | OCFS2_JOURNAL_ACCESS_WRITE); |
1620 | if (ret) { | 1680 | if (ret) { |
1621 | mlog_errno(ret); | 1681 | mlog_errno(ret); |
@@ -1623,7 +1683,7 @@ static int ocfs2_xattr_set_entry(struct inode *inode, | |||
1623 | } | 1683 | } |
1624 | 1684 | ||
1625 | if (!(flag & OCFS2_INLINE_XATTR_FL)) { | 1685 | if (!(flag & OCFS2_INLINE_XATTR_FL)) { |
1626 | ret = vb.vb_access(handle, inode, vb.vb_bh, | 1686 | ret = vb.vb_access(handle, INODE_CACHE(inode), vb.vb_bh, |
1627 | OCFS2_JOURNAL_ACCESS_WRITE); | 1687 | OCFS2_JOURNAL_ACCESS_WRITE); |
1628 | if (ret) { | 1688 | if (ret) { |
1629 | mlog_errno(ret); | 1689 | mlog_errno(ret); |
@@ -1700,51 +1760,112 @@ out: | |||
1700 | return ret; | 1760 | return ret; |
1701 | } | 1761 | } |
1702 | 1762 | ||
1763 | /* | ||
1764 | * In xattr remove, if it is stored outside and refcounted, we may have | ||
1765 | * the chance to split the refcount tree. So need the allocators. | ||
1766 | */ | ||
1767 | static int ocfs2_lock_xattr_remove_allocators(struct inode *inode, | ||
1768 | struct ocfs2_xattr_value_root *xv, | ||
1769 | struct ocfs2_caching_info *ref_ci, | ||
1770 | struct buffer_head *ref_root_bh, | ||
1771 | struct ocfs2_alloc_context **meta_ac, | ||
1772 | int *ref_credits) | ||
1773 | { | ||
1774 | int ret, meta_add = 0; | ||
1775 | u32 p_cluster, num_clusters; | ||
1776 | unsigned int ext_flags; | ||
1777 | |||
1778 | *ref_credits = 0; | ||
1779 | ret = ocfs2_xattr_get_clusters(inode, 0, &p_cluster, | ||
1780 | &num_clusters, | ||
1781 | &xv->xr_list, | ||
1782 | &ext_flags); | ||
1783 | if (ret) { | ||
1784 | mlog_errno(ret); | ||
1785 | goto out; | ||
1786 | } | ||
1787 | |||
1788 | if (!(ext_flags & OCFS2_EXT_REFCOUNTED)) | ||
1789 | goto out; | ||
1790 | |||
1791 | ret = ocfs2_refcounted_xattr_delete_need(inode, ref_ci, | ||
1792 | ref_root_bh, xv, | ||
1793 | &meta_add, ref_credits); | ||
1794 | if (ret) { | ||
1795 | mlog_errno(ret); | ||
1796 | goto out; | ||
1797 | } | ||
1798 | |||
1799 | ret = ocfs2_reserve_new_metadata_blocks(OCFS2_SB(inode->i_sb), | ||
1800 | meta_add, meta_ac); | ||
1801 | if (ret) | ||
1802 | mlog_errno(ret); | ||
1803 | |||
1804 | out: | ||
1805 | return ret; | ||
1806 | } | ||
1807 | |||
1703 | static int ocfs2_remove_value_outside(struct inode*inode, | 1808 | static int ocfs2_remove_value_outside(struct inode*inode, |
1704 | struct ocfs2_xattr_value_buf *vb, | 1809 | struct ocfs2_xattr_value_buf *vb, |
1705 | struct ocfs2_xattr_header *header) | 1810 | struct ocfs2_xattr_header *header, |
1811 | struct ocfs2_caching_info *ref_ci, | ||
1812 | struct buffer_head *ref_root_bh) | ||
1706 | { | 1813 | { |
1707 | int ret = 0, i; | 1814 | int ret = 0, i, ref_credits; |
1708 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 1815 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
1709 | struct ocfs2_xattr_set_ctxt ctxt = { NULL, NULL, }; | 1816 | struct ocfs2_xattr_set_ctxt ctxt = { NULL, NULL, }; |
1817 | void *val; | ||
1710 | 1818 | ||
1711 | ocfs2_init_dealloc_ctxt(&ctxt.dealloc); | 1819 | ocfs2_init_dealloc_ctxt(&ctxt.dealloc); |
1712 | 1820 | ||
1713 | ctxt.handle = ocfs2_start_trans(osb, | ||
1714 | ocfs2_remove_extent_credits(osb->sb)); | ||
1715 | if (IS_ERR(ctxt.handle)) { | ||
1716 | ret = PTR_ERR(ctxt.handle); | ||
1717 | mlog_errno(ret); | ||
1718 | goto out; | ||
1719 | } | ||
1720 | |||
1721 | for (i = 0; i < le16_to_cpu(header->xh_count); i++) { | 1821 | for (i = 0; i < le16_to_cpu(header->xh_count); i++) { |
1722 | struct ocfs2_xattr_entry *entry = &header->xh_entries[i]; | 1822 | struct ocfs2_xattr_entry *entry = &header->xh_entries[i]; |
1723 | 1823 | ||
1724 | if (!ocfs2_xattr_is_local(entry)) { | 1824 | if (ocfs2_xattr_is_local(entry)) |
1725 | void *val; | 1825 | continue; |
1726 | 1826 | ||
1727 | val = (void *)header + | 1827 | val = (void *)header + |
1728 | le16_to_cpu(entry->xe_name_offset); | 1828 | le16_to_cpu(entry->xe_name_offset); |
1729 | vb->vb_xv = (struct ocfs2_xattr_value_root *) | 1829 | vb->vb_xv = (struct ocfs2_xattr_value_root *) |
1730 | (val + OCFS2_XATTR_SIZE(entry->xe_name_len)); | 1830 | (val + OCFS2_XATTR_SIZE(entry->xe_name_len)); |
1731 | ret = ocfs2_xattr_value_truncate(inode, vb, 0, &ctxt); | 1831 | |
1732 | if (ret < 0) { | 1832 | ret = ocfs2_lock_xattr_remove_allocators(inode, vb->vb_xv, |
1733 | mlog_errno(ret); | 1833 | ref_ci, ref_root_bh, |
1734 | break; | 1834 | &ctxt.meta_ac, |
1735 | } | 1835 | &ref_credits); |
1836 | |||
1837 | ctxt.handle = ocfs2_start_trans(osb, ref_credits + | ||
1838 | ocfs2_remove_extent_credits(osb->sb)); | ||
1839 | if (IS_ERR(ctxt.handle)) { | ||
1840 | ret = PTR_ERR(ctxt.handle); | ||
1841 | mlog_errno(ret); | ||
1842 | break; | ||
1843 | } | ||
1844 | |||
1845 | ret = ocfs2_xattr_value_truncate(inode, vb, 0, &ctxt); | ||
1846 | if (ret < 0) { | ||
1847 | mlog_errno(ret); | ||
1848 | break; | ||
1849 | } | ||
1850 | |||
1851 | ocfs2_commit_trans(osb, ctxt.handle); | ||
1852 | if (ctxt.meta_ac) { | ||
1853 | ocfs2_free_alloc_context(ctxt.meta_ac); | ||
1854 | ctxt.meta_ac = NULL; | ||
1736 | } | 1855 | } |
1737 | } | 1856 | } |
1738 | 1857 | ||
1739 | ocfs2_commit_trans(osb, ctxt.handle); | 1858 | if (ctxt.meta_ac) |
1859 | ocfs2_free_alloc_context(ctxt.meta_ac); | ||
1740 | ocfs2_schedule_truncate_log_flush(osb, 1); | 1860 | ocfs2_schedule_truncate_log_flush(osb, 1); |
1741 | ocfs2_run_deallocs(osb, &ctxt.dealloc); | 1861 | ocfs2_run_deallocs(osb, &ctxt.dealloc); |
1742 | out: | ||
1743 | return ret; | 1862 | return ret; |
1744 | } | 1863 | } |
1745 | 1864 | ||
1746 | static int ocfs2_xattr_ibody_remove(struct inode *inode, | 1865 | static int ocfs2_xattr_ibody_remove(struct inode *inode, |
1747 | struct buffer_head *di_bh) | 1866 | struct buffer_head *di_bh, |
1867 | struct ocfs2_caching_info *ref_ci, | ||
1868 | struct buffer_head *ref_root_bh) | ||
1748 | { | 1869 | { |
1749 | 1870 | ||
1750 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; | 1871 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; |
@@ -1759,13 +1880,21 @@ static int ocfs2_xattr_ibody_remove(struct inode *inode, | |||
1759 | ((void *)di + inode->i_sb->s_blocksize - | 1880 | ((void *)di + inode->i_sb->s_blocksize - |
1760 | le16_to_cpu(di->i_xattr_inline_size)); | 1881 | le16_to_cpu(di->i_xattr_inline_size)); |
1761 | 1882 | ||
1762 | ret = ocfs2_remove_value_outside(inode, &vb, header); | 1883 | ret = ocfs2_remove_value_outside(inode, &vb, header, |
1884 | ref_ci, ref_root_bh); | ||
1763 | 1885 | ||
1764 | return ret; | 1886 | return ret; |
1765 | } | 1887 | } |
1766 | 1888 | ||
1889 | struct ocfs2_rm_xattr_bucket_para { | ||
1890 | struct ocfs2_caching_info *ref_ci; | ||
1891 | struct buffer_head *ref_root_bh; | ||
1892 | }; | ||
1893 | |||
1767 | static int ocfs2_xattr_block_remove(struct inode *inode, | 1894 | static int ocfs2_xattr_block_remove(struct inode *inode, |
1768 | struct buffer_head *blk_bh) | 1895 | struct buffer_head *blk_bh, |
1896 | struct ocfs2_caching_info *ref_ci, | ||
1897 | struct buffer_head *ref_root_bh) | ||
1769 | { | 1898 | { |
1770 | struct ocfs2_xattr_block *xb; | 1899 | struct ocfs2_xattr_block *xb; |
1771 | int ret = 0; | 1900 | int ret = 0; |
@@ -1773,19 +1902,29 @@ static int ocfs2_xattr_block_remove(struct inode *inode, | |||
1773 | .vb_bh = blk_bh, | 1902 | .vb_bh = blk_bh, |
1774 | .vb_access = ocfs2_journal_access_xb, | 1903 | .vb_access = ocfs2_journal_access_xb, |
1775 | }; | 1904 | }; |
1905 | struct ocfs2_rm_xattr_bucket_para args = { | ||
1906 | .ref_ci = ref_ci, | ||
1907 | .ref_root_bh = ref_root_bh, | ||
1908 | }; | ||
1776 | 1909 | ||
1777 | xb = (struct ocfs2_xattr_block *)blk_bh->b_data; | 1910 | xb = (struct ocfs2_xattr_block *)blk_bh->b_data; |
1778 | if (!(le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED)) { | 1911 | if (!(le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED)) { |
1779 | struct ocfs2_xattr_header *header = &(xb->xb_attrs.xb_header); | 1912 | struct ocfs2_xattr_header *header = &(xb->xb_attrs.xb_header); |
1780 | ret = ocfs2_remove_value_outside(inode, &vb, header); | 1913 | ret = ocfs2_remove_value_outside(inode, &vb, header, |
1914 | ref_ci, ref_root_bh); | ||
1781 | } else | 1915 | } else |
1782 | ret = ocfs2_delete_xattr_index_block(inode, blk_bh); | 1916 | ret = ocfs2_iterate_xattr_index_block(inode, |
1917 | blk_bh, | ||
1918 | ocfs2_rm_xattr_cluster, | ||
1919 | &args); | ||
1783 | 1920 | ||
1784 | return ret; | 1921 | return ret; |
1785 | } | 1922 | } |
1786 | 1923 | ||
1787 | static int ocfs2_xattr_free_block(struct inode *inode, | 1924 | static int ocfs2_xattr_free_block(struct inode *inode, |
1788 | u64 block) | 1925 | u64 block, |
1926 | struct ocfs2_caching_info *ref_ci, | ||
1927 | struct buffer_head *ref_root_bh) | ||
1789 | { | 1928 | { |
1790 | struct inode *xb_alloc_inode; | 1929 | struct inode *xb_alloc_inode; |
1791 | struct buffer_head *xb_alloc_bh = NULL; | 1930 | struct buffer_head *xb_alloc_bh = NULL; |
@@ -1803,7 +1942,7 @@ static int ocfs2_xattr_free_block(struct inode *inode, | |||
1803 | goto out; | 1942 | goto out; |
1804 | } | 1943 | } |
1805 | 1944 | ||
1806 | ret = ocfs2_xattr_block_remove(inode, blk_bh); | 1945 | ret = ocfs2_xattr_block_remove(inode, blk_bh, ref_ci, ref_root_bh); |
1807 | if (ret < 0) { | 1946 | if (ret < 0) { |
1808 | mlog_errno(ret); | 1947 | mlog_errno(ret); |
1809 | goto out; | 1948 | goto out; |
@@ -1863,6 +2002,9 @@ int ocfs2_xattr_remove(struct inode *inode, struct buffer_head *di_bh) | |||
1863 | { | 2002 | { |
1864 | struct ocfs2_inode_info *oi = OCFS2_I(inode); | 2003 | struct ocfs2_inode_info *oi = OCFS2_I(inode); |
1865 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; | 2004 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)di_bh->b_data; |
2005 | struct ocfs2_refcount_tree *ref_tree = NULL; | ||
2006 | struct buffer_head *ref_root_bh = NULL; | ||
2007 | struct ocfs2_caching_info *ref_ci = NULL; | ||
1866 | handle_t *handle; | 2008 | handle_t *handle; |
1867 | int ret; | 2009 | int ret; |
1868 | 2010 | ||
@@ -1872,8 +2014,21 @@ int ocfs2_xattr_remove(struct inode *inode, struct buffer_head *di_bh) | |||
1872 | if (!(oi->ip_dyn_features & OCFS2_HAS_XATTR_FL)) | 2014 | if (!(oi->ip_dyn_features & OCFS2_HAS_XATTR_FL)) |
1873 | return 0; | 2015 | return 0; |
1874 | 2016 | ||
2017 | if (OCFS2_I(inode)->ip_dyn_features & OCFS2_HAS_REFCOUNT_FL) { | ||
2018 | ret = ocfs2_lock_refcount_tree(OCFS2_SB(inode->i_sb), | ||
2019 | le64_to_cpu(di->i_refcount_loc), | ||
2020 | 1, &ref_tree, &ref_root_bh); | ||
2021 | if (ret) { | ||
2022 | mlog_errno(ret); | ||
2023 | goto out; | ||
2024 | } | ||
2025 | ref_ci = &ref_tree->rf_ci; | ||
2026 | |||
2027 | } | ||
2028 | |||
1875 | if (oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL) { | 2029 | if (oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL) { |
1876 | ret = ocfs2_xattr_ibody_remove(inode, di_bh); | 2030 | ret = ocfs2_xattr_ibody_remove(inode, di_bh, |
2031 | ref_ci, ref_root_bh); | ||
1877 | if (ret < 0) { | 2032 | if (ret < 0) { |
1878 | mlog_errno(ret); | 2033 | mlog_errno(ret); |
1879 | goto out; | 2034 | goto out; |
@@ -1882,7 +2037,8 @@ int ocfs2_xattr_remove(struct inode *inode, struct buffer_head *di_bh) | |||
1882 | 2037 | ||
1883 | if (di->i_xattr_loc) { | 2038 | if (di->i_xattr_loc) { |
1884 | ret = ocfs2_xattr_free_block(inode, | 2039 | ret = ocfs2_xattr_free_block(inode, |
1885 | le64_to_cpu(di->i_xattr_loc)); | 2040 | le64_to_cpu(di->i_xattr_loc), |
2041 | ref_ci, ref_root_bh); | ||
1886 | if (ret < 0) { | 2042 | if (ret < 0) { |
1887 | mlog_errno(ret); | 2043 | mlog_errno(ret); |
1888 | goto out; | 2044 | goto out; |
@@ -1896,7 +2052,7 @@ int ocfs2_xattr_remove(struct inode *inode, struct buffer_head *di_bh) | |||
1896 | mlog_errno(ret); | 2052 | mlog_errno(ret); |
1897 | goto out; | 2053 | goto out; |
1898 | } | 2054 | } |
1899 | ret = ocfs2_journal_access_di(handle, inode, di_bh, | 2055 | ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), di_bh, |
1900 | OCFS2_JOURNAL_ACCESS_WRITE); | 2056 | OCFS2_JOURNAL_ACCESS_WRITE); |
1901 | if (ret) { | 2057 | if (ret) { |
1902 | mlog_errno(ret); | 2058 | mlog_errno(ret); |
@@ -1916,6 +2072,9 @@ int ocfs2_xattr_remove(struct inode *inode, struct buffer_head *di_bh) | |||
1916 | out_commit: | 2072 | out_commit: |
1917 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); | 2073 | ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle); |
1918 | out: | 2074 | out: |
2075 | if (ref_tree) | ||
2076 | ocfs2_unlock_refcount_tree(OCFS2_SB(inode->i_sb), ref_tree, 1); | ||
2077 | brelse(ref_root_bh); | ||
1919 | return ret; | 2078 | return ret; |
1920 | } | 2079 | } |
1921 | 2080 | ||
@@ -2083,6 +2242,84 @@ cleanup: | |||
2083 | return ret; | 2242 | return ret; |
2084 | } | 2243 | } |
2085 | 2244 | ||
2245 | static int ocfs2_create_xattr_block(handle_t *handle, | ||
2246 | struct inode *inode, | ||
2247 | struct buffer_head *inode_bh, | ||
2248 | struct ocfs2_alloc_context *meta_ac, | ||
2249 | struct buffer_head **ret_bh, | ||
2250 | int indexed) | ||
2251 | { | ||
2252 | int ret; | ||
2253 | u16 suballoc_bit_start; | ||
2254 | u32 num_got; | ||
2255 | u64 first_blkno; | ||
2256 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)inode_bh->b_data; | ||
2257 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
2258 | struct buffer_head *new_bh = NULL; | ||
2259 | struct ocfs2_xattr_block *xblk; | ||
2260 | |||
2261 | ret = ocfs2_journal_access_di(handle, INODE_CACHE(inode), inode_bh, | ||
2262 | OCFS2_JOURNAL_ACCESS_CREATE); | ||
2263 | if (ret < 0) { | ||
2264 | mlog_errno(ret); | ||
2265 | goto end; | ||
2266 | } | ||
2267 | |||
2268 | ret = ocfs2_claim_metadata(osb, handle, meta_ac, 1, | ||
2269 | &suballoc_bit_start, &num_got, | ||
2270 | &first_blkno); | ||
2271 | if (ret < 0) { | ||
2272 | mlog_errno(ret); | ||
2273 | goto end; | ||
2274 | } | ||
2275 | |||
2276 | new_bh = sb_getblk(inode->i_sb, first_blkno); | ||
2277 | ocfs2_set_new_buffer_uptodate(INODE_CACHE(inode), new_bh); | ||
2278 | |||
2279 | ret = ocfs2_journal_access_xb(handle, INODE_CACHE(inode), | ||
2280 | new_bh, | ||
2281 | OCFS2_JOURNAL_ACCESS_CREATE); | ||
2282 | if (ret < 0) { | ||
2283 | mlog_errno(ret); | ||
2284 | goto end; | ||
2285 | } | ||
2286 | |||
2287 | /* Initialize ocfs2_xattr_block */ | ||
2288 | xblk = (struct ocfs2_xattr_block *)new_bh->b_data; | ||
2289 | memset(xblk, 0, inode->i_sb->s_blocksize); | ||
2290 | strcpy((void *)xblk, OCFS2_XATTR_BLOCK_SIGNATURE); | ||
2291 | xblk->xb_suballoc_slot = cpu_to_le16(osb->slot_num); | ||
2292 | xblk->xb_suballoc_bit = cpu_to_le16(suballoc_bit_start); | ||
2293 | xblk->xb_fs_generation = cpu_to_le32(osb->fs_generation); | ||
2294 | xblk->xb_blkno = cpu_to_le64(first_blkno); | ||
2295 | |||
2296 | if (indexed) { | ||
2297 | struct ocfs2_xattr_tree_root *xr = &xblk->xb_attrs.xb_root; | ||
2298 | xr->xt_clusters = cpu_to_le32(1); | ||
2299 | xr->xt_last_eb_blk = 0; | ||
2300 | xr->xt_list.l_tree_depth = 0; | ||
2301 | xr->xt_list.l_count = cpu_to_le16( | ||
2302 | ocfs2_xattr_recs_per_xb(inode->i_sb)); | ||
2303 | xr->xt_list.l_next_free_rec = cpu_to_le16(1); | ||
2304 | xblk->xb_flags = cpu_to_le16(OCFS2_XATTR_INDEXED); | ||
2305 | } | ||
2306 | |||
2307 | ret = ocfs2_journal_dirty(handle, new_bh); | ||
2308 | if (ret < 0) { | ||
2309 | mlog_errno(ret); | ||
2310 | goto end; | ||
2311 | } | ||
2312 | di->i_xattr_loc = cpu_to_le64(first_blkno); | ||
2313 | ocfs2_journal_dirty(handle, inode_bh); | ||
2314 | |||
2315 | *ret_bh = new_bh; | ||
2316 | new_bh = NULL; | ||
2317 | |||
2318 | end: | ||
2319 | brelse(new_bh); | ||
2320 | return ret; | ||
2321 | } | ||
2322 | |||
2086 | /* | 2323 | /* |
2087 | * ocfs2_xattr_block_set() | 2324 | * ocfs2_xattr_block_set() |
2088 | * | 2325 | * |
@@ -2095,63 +2332,24 @@ static int ocfs2_xattr_block_set(struct inode *inode, | |||
2095 | struct ocfs2_xattr_set_ctxt *ctxt) | 2332 | struct ocfs2_xattr_set_ctxt *ctxt) |
2096 | { | 2333 | { |
2097 | struct buffer_head *new_bh = NULL; | 2334 | struct buffer_head *new_bh = NULL; |
2098 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
2099 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)xs->inode_bh->b_data; | ||
2100 | handle_t *handle = ctxt->handle; | 2335 | handle_t *handle = ctxt->handle; |
2101 | struct ocfs2_xattr_block *xblk = NULL; | 2336 | struct ocfs2_xattr_block *xblk = NULL; |
2102 | u16 suballoc_bit_start; | ||
2103 | u32 num_got; | ||
2104 | u64 first_blkno; | ||
2105 | int ret; | 2337 | int ret; |
2106 | 2338 | ||
2107 | if (!xs->xattr_bh) { | 2339 | if (!xs->xattr_bh) { |
2108 | ret = ocfs2_journal_access_di(handle, inode, xs->inode_bh, | 2340 | ret = ocfs2_create_xattr_block(handle, inode, xs->inode_bh, |
2109 | OCFS2_JOURNAL_ACCESS_CREATE); | 2341 | ctxt->meta_ac, &new_bh, 0); |
2110 | if (ret < 0) { | 2342 | if (ret) { |
2111 | mlog_errno(ret); | ||
2112 | goto end; | ||
2113 | } | ||
2114 | |||
2115 | ret = ocfs2_claim_metadata(osb, handle, ctxt->meta_ac, 1, | ||
2116 | &suballoc_bit_start, &num_got, | ||
2117 | &first_blkno); | ||
2118 | if (ret < 0) { | ||
2119 | mlog_errno(ret); | ||
2120 | goto end; | ||
2121 | } | ||
2122 | |||
2123 | new_bh = sb_getblk(inode->i_sb, first_blkno); | ||
2124 | ocfs2_set_new_buffer_uptodate(inode, new_bh); | ||
2125 | |||
2126 | ret = ocfs2_journal_access_xb(handle, inode, new_bh, | ||
2127 | OCFS2_JOURNAL_ACCESS_CREATE); | ||
2128 | if (ret < 0) { | ||
2129 | mlog_errno(ret); | 2343 | mlog_errno(ret); |
2130 | goto end; | 2344 | goto end; |
2131 | } | 2345 | } |
2132 | 2346 | ||
2133 | /* Initialize ocfs2_xattr_block */ | ||
2134 | xs->xattr_bh = new_bh; | 2347 | xs->xattr_bh = new_bh; |
2135 | xblk = (struct ocfs2_xattr_block *)new_bh->b_data; | 2348 | xblk = (struct ocfs2_xattr_block *)xs->xattr_bh->b_data; |
2136 | memset(xblk, 0, inode->i_sb->s_blocksize); | ||
2137 | strcpy((void *)xblk, OCFS2_XATTR_BLOCK_SIGNATURE); | ||
2138 | xblk->xb_suballoc_slot = cpu_to_le16(osb->slot_num); | ||
2139 | xblk->xb_suballoc_bit = cpu_to_le16(suballoc_bit_start); | ||
2140 | xblk->xb_fs_generation = cpu_to_le32(osb->fs_generation); | ||
2141 | xblk->xb_blkno = cpu_to_le64(first_blkno); | ||
2142 | |||
2143 | xs->header = &xblk->xb_attrs.xb_header; | 2349 | xs->header = &xblk->xb_attrs.xb_header; |
2144 | xs->base = (void *)xs->header; | 2350 | xs->base = (void *)xs->header; |
2145 | xs->end = (void *)xblk + inode->i_sb->s_blocksize; | 2351 | xs->end = (void *)xblk + inode->i_sb->s_blocksize; |
2146 | xs->here = xs->header->xh_entries; | 2352 | xs->here = xs->header->xh_entries; |
2147 | |||
2148 | ret = ocfs2_journal_dirty(handle, new_bh); | ||
2149 | if (ret < 0) { | ||
2150 | mlog_errno(ret); | ||
2151 | goto end; | ||
2152 | } | ||
2153 | di->i_xattr_loc = cpu_to_le64(first_blkno); | ||
2154 | ocfs2_journal_dirty(handle, xs->inode_bh); | ||
2155 | } else | 2353 | } else |
2156 | xblk = (struct ocfs2_xattr_block *)xs->xattr_bh->b_data; | 2354 | xblk = (struct ocfs2_xattr_block *)xs->xattr_bh->b_data; |
2157 | 2355 | ||
@@ -2273,7 +2471,7 @@ static int ocfs2_calc_xattr_set_need(struct inode *inode, | |||
2273 | old_in_xb = 1; | 2471 | old_in_xb = 1; |
2274 | 2472 | ||
2275 | if (le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED) { | 2473 | if (le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED) { |
2276 | ret = ocfs2_xattr_bucket_get_name_value(inode, | 2474 | ret = ocfs2_xattr_bucket_get_name_value(inode->i_sb, |
2277 | bucket_xh(xbs->bucket), | 2475 | bucket_xh(xbs->bucket), |
2278 | i, &block_off, | 2476 | i, &block_off, |
2279 | &name_offset); | 2477 | &name_offset); |
@@ -2428,6 +2626,7 @@ static int ocfs2_init_xattr_set_ctxt(struct inode *inode, | |||
2428 | struct ocfs2_xattr_search *xis, | 2626 | struct ocfs2_xattr_search *xis, |
2429 | struct ocfs2_xattr_search *xbs, | 2627 | struct ocfs2_xattr_search *xbs, |
2430 | struct ocfs2_xattr_set_ctxt *ctxt, | 2628 | struct ocfs2_xattr_set_ctxt *ctxt, |
2629 | int extra_meta, | ||
2431 | int *credits) | 2630 | int *credits) |
2432 | { | 2631 | { |
2433 | int clusters_add, meta_add, ret; | 2632 | int clusters_add, meta_add, ret; |
@@ -2444,6 +2643,7 @@ static int ocfs2_init_xattr_set_ctxt(struct inode *inode, | |||
2444 | return ret; | 2643 | return ret; |
2445 | } | 2644 | } |
2446 | 2645 | ||
2646 | meta_add += extra_meta; | ||
2447 | mlog(0, "Set xattr %s, reserve meta blocks = %d, clusters = %d, " | 2647 | mlog(0, "Set xattr %s, reserve meta blocks = %d, clusters = %d, " |
2448 | "credits = %d\n", xi->name, meta_add, clusters_add, *credits); | 2648 | "credits = %d\n", xi->name, meta_add, clusters_add, *credits); |
2449 | 2649 | ||
@@ -2598,7 +2798,7 @@ static int __ocfs2_xattr_set_handle(struct inode *inode, | |||
2598 | 2798 | ||
2599 | if (!ret) { | 2799 | if (!ret) { |
2600 | /* Update inode ctime. */ | 2800 | /* Update inode ctime. */ |
2601 | ret = ocfs2_journal_access_di(ctxt->handle, inode, | 2801 | ret = ocfs2_journal_access_di(ctxt->handle, INODE_CACHE(inode), |
2602 | xis->inode_bh, | 2802 | xis->inode_bh, |
2603 | OCFS2_JOURNAL_ACCESS_WRITE); | 2803 | OCFS2_JOURNAL_ACCESS_WRITE); |
2604 | if (ret) { | 2804 | if (ret) { |
@@ -2711,10 +2911,11 @@ int ocfs2_xattr_set(struct inode *inode, | |||
2711 | { | 2911 | { |
2712 | struct buffer_head *di_bh = NULL; | 2912 | struct buffer_head *di_bh = NULL; |
2713 | struct ocfs2_dinode *di; | 2913 | struct ocfs2_dinode *di; |
2714 | int ret, credits; | 2914 | int ret, credits, ref_meta = 0, ref_credits = 0; |
2715 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 2915 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
2716 | struct inode *tl_inode = osb->osb_tl_inode; | 2916 | struct inode *tl_inode = osb->osb_tl_inode; |
2717 | struct ocfs2_xattr_set_ctxt ctxt = { NULL, NULL, }; | 2917 | struct ocfs2_xattr_set_ctxt ctxt = { NULL, NULL, }; |
2918 | struct ocfs2_refcount_tree *ref_tree = NULL; | ||
2718 | 2919 | ||
2719 | struct ocfs2_xattr_info xi = { | 2920 | struct ocfs2_xattr_info xi = { |
2720 | .name_index = name_index, | 2921 | .name_index = name_index, |
@@ -2779,6 +2980,17 @@ int ocfs2_xattr_set(struct inode *inode, | |||
2779 | goto cleanup; | 2980 | goto cleanup; |
2780 | } | 2981 | } |
2781 | 2982 | ||
2983 | /* Check whether the value is refcounted and do some prepartion. */ | ||
2984 | if (OCFS2_I(inode)->ip_dyn_features & OCFS2_HAS_REFCOUNT_FL && | ||
2985 | (!xis.not_found || !xbs.not_found)) { | ||
2986 | ret = ocfs2_prepare_refcount_xattr(inode, di, &xi, | ||
2987 | &xis, &xbs, &ref_tree, | ||
2988 | &ref_meta, &ref_credits); | ||
2989 | if (ret) { | ||
2990 | mlog_errno(ret); | ||
2991 | goto cleanup; | ||
2992 | } | ||
2993 | } | ||
2782 | 2994 | ||
2783 | mutex_lock(&tl_inode->i_mutex); | 2995 | mutex_lock(&tl_inode->i_mutex); |
2784 | 2996 | ||
@@ -2793,7 +3005,7 @@ int ocfs2_xattr_set(struct inode *inode, | |||
2793 | mutex_unlock(&tl_inode->i_mutex); | 3005 | mutex_unlock(&tl_inode->i_mutex); |
2794 | 3006 | ||
2795 | ret = ocfs2_init_xattr_set_ctxt(inode, di, &xi, &xis, | 3007 | ret = ocfs2_init_xattr_set_ctxt(inode, di, &xi, &xis, |
2796 | &xbs, &ctxt, &credits); | 3008 | &xbs, &ctxt, ref_meta, &credits); |
2797 | if (ret) { | 3009 | if (ret) { |
2798 | mlog_errno(ret); | 3010 | mlog_errno(ret); |
2799 | goto cleanup; | 3011 | goto cleanup; |
@@ -2801,7 +3013,7 @@ int ocfs2_xattr_set(struct inode *inode, | |||
2801 | 3013 | ||
2802 | /* we need to update inode's ctime field, so add credit for it. */ | 3014 | /* we need to update inode's ctime field, so add credit for it. */ |
2803 | credits += OCFS2_INODE_UPDATE_CREDITS; | 3015 | credits += OCFS2_INODE_UPDATE_CREDITS; |
2804 | ctxt.handle = ocfs2_start_trans(osb, credits); | 3016 | ctxt.handle = ocfs2_start_trans(osb, credits + ref_credits); |
2805 | if (IS_ERR(ctxt.handle)) { | 3017 | if (IS_ERR(ctxt.handle)) { |
2806 | ret = PTR_ERR(ctxt.handle); | 3018 | ret = PTR_ERR(ctxt.handle); |
2807 | mlog_errno(ret); | 3019 | mlog_errno(ret); |
@@ -2819,8 +3031,16 @@ int ocfs2_xattr_set(struct inode *inode, | |||
2819 | if (ocfs2_dealloc_has_cluster(&ctxt.dealloc)) | 3031 | if (ocfs2_dealloc_has_cluster(&ctxt.dealloc)) |
2820 | ocfs2_schedule_truncate_log_flush(osb, 1); | 3032 | ocfs2_schedule_truncate_log_flush(osb, 1); |
2821 | ocfs2_run_deallocs(osb, &ctxt.dealloc); | 3033 | ocfs2_run_deallocs(osb, &ctxt.dealloc); |
3034 | |||
2822 | cleanup: | 3035 | cleanup: |
3036 | if (ref_tree) | ||
3037 | ocfs2_unlock_refcount_tree(osb, ref_tree, 1); | ||
2823 | up_write(&OCFS2_I(inode)->ip_xattr_sem); | 3038 | up_write(&OCFS2_I(inode)->ip_xattr_sem); |
3039 | if (!value && !ret) { | ||
3040 | ret = ocfs2_try_remove_refcount_tree(inode, di_bh); | ||
3041 | if (ret) | ||
3042 | mlog_errno(ret); | ||
3043 | } | ||
2824 | ocfs2_inode_unlock(inode, 1); | 3044 | ocfs2_inode_unlock(inode, 1); |
2825 | cleanup_nolock: | 3045 | cleanup_nolock: |
2826 | brelse(di_bh); | 3046 | brelse(di_bh); |
@@ -2849,7 +3069,8 @@ static int ocfs2_xattr_get_rec(struct inode *inode, | |||
2849 | u64 e_blkno = 0; | 3069 | u64 e_blkno = 0; |
2850 | 3070 | ||
2851 | if (el->l_tree_depth) { | 3071 | if (el->l_tree_depth) { |
2852 | ret = ocfs2_find_leaf(inode, el, name_hash, &eb_bh); | 3072 | ret = ocfs2_find_leaf(INODE_CACHE(inode), el, name_hash, |
3073 | &eb_bh); | ||
2853 | if (ret) { | 3074 | if (ret) { |
2854 | mlog_errno(ret); | 3075 | mlog_errno(ret); |
2855 | goto out; | 3076 | goto out; |
@@ -2931,7 +3152,7 @@ static int ocfs2_find_xe_in_bucket(struct inode *inode, | |||
2931 | if (cmp) | 3152 | if (cmp) |
2932 | continue; | 3153 | continue; |
2933 | 3154 | ||
2934 | ret = ocfs2_xattr_bucket_get_name_value(inode, | 3155 | ret = ocfs2_xattr_bucket_get_name_value(inode->i_sb, |
2935 | xh, | 3156 | xh, |
2936 | i, | 3157 | i, |
2937 | &block_off, | 3158 | &block_off, |
@@ -3175,7 +3396,7 @@ struct ocfs2_xattr_tree_list { | |||
3175 | size_t result; | 3396 | size_t result; |
3176 | }; | 3397 | }; |
3177 | 3398 | ||
3178 | static int ocfs2_xattr_bucket_get_name_value(struct inode *inode, | 3399 | static int ocfs2_xattr_bucket_get_name_value(struct super_block *sb, |
3179 | struct ocfs2_xattr_header *xh, | 3400 | struct ocfs2_xattr_header *xh, |
3180 | int index, | 3401 | int index, |
3181 | int *block_off, | 3402 | int *block_off, |
@@ -3188,8 +3409,8 @@ static int ocfs2_xattr_bucket_get_name_value(struct inode *inode, | |||
3188 | 3409 | ||
3189 | name_offset = le16_to_cpu(xh->xh_entries[index].xe_name_offset); | 3410 | name_offset = le16_to_cpu(xh->xh_entries[index].xe_name_offset); |
3190 | 3411 | ||
3191 | *block_off = name_offset >> inode->i_sb->s_blocksize_bits; | 3412 | *block_off = name_offset >> sb->s_blocksize_bits; |
3192 | *new_offset = name_offset % inode->i_sb->s_blocksize; | 3413 | *new_offset = name_offset % sb->s_blocksize; |
3193 | 3414 | ||
3194 | return 0; | 3415 | return 0; |
3195 | } | 3416 | } |
@@ -3209,7 +3430,7 @@ static int ocfs2_list_xattr_bucket(struct inode *inode, | |||
3209 | prefix = ocfs2_xattr_prefix(type); | 3430 | prefix = ocfs2_xattr_prefix(type); |
3210 | 3431 | ||
3211 | if (prefix) { | 3432 | if (prefix) { |
3212 | ret = ocfs2_xattr_bucket_get_name_value(inode, | 3433 | ret = ocfs2_xattr_bucket_get_name_value(inode->i_sb, |
3213 | bucket_xh(bucket), | 3434 | bucket_xh(bucket), |
3214 | i, | 3435 | i, |
3215 | &block_off, | 3436 | &block_off, |
@@ -3232,22 +3453,19 @@ static int ocfs2_list_xattr_bucket(struct inode *inode, | |||
3232 | return ret; | 3453 | return ret; |
3233 | } | 3454 | } |
3234 | 3455 | ||
3235 | static int ocfs2_xattr_tree_list_index_block(struct inode *inode, | 3456 | static int ocfs2_iterate_xattr_index_block(struct inode *inode, |
3236 | struct ocfs2_xattr_tree_root *xt, | 3457 | struct buffer_head *blk_bh, |
3237 | char *buffer, | 3458 | xattr_tree_rec_func *rec_func, |
3238 | size_t buffer_size) | 3459 | void *para) |
3239 | { | 3460 | { |
3240 | struct ocfs2_extent_list *el = &xt->xt_list; | 3461 | struct ocfs2_xattr_block *xb = |
3462 | (struct ocfs2_xattr_block *)blk_bh->b_data; | ||
3463 | struct ocfs2_extent_list *el = &xb->xb_attrs.xb_root.xt_list; | ||
3241 | int ret = 0; | 3464 | int ret = 0; |
3242 | u32 name_hash = UINT_MAX, e_cpos = 0, num_clusters = 0; | 3465 | u32 name_hash = UINT_MAX, e_cpos = 0, num_clusters = 0; |
3243 | u64 p_blkno = 0; | 3466 | u64 p_blkno = 0; |
3244 | struct ocfs2_xattr_tree_list xl = { | ||
3245 | .buffer = buffer, | ||
3246 | .buffer_size = buffer_size, | ||
3247 | .result = 0, | ||
3248 | }; | ||
3249 | 3467 | ||
3250 | if (le16_to_cpu(el->l_next_free_rec) == 0) | 3468 | if (!el->l_next_free_rec || !rec_func) |
3251 | return 0; | 3469 | return 0; |
3252 | 3470 | ||
3253 | while (name_hash > 0) { | 3471 | while (name_hash > 0) { |
@@ -3255,16 +3473,15 @@ static int ocfs2_xattr_tree_list_index_block(struct inode *inode, | |||
3255 | &e_cpos, &num_clusters, el); | 3473 | &e_cpos, &num_clusters, el); |
3256 | if (ret) { | 3474 | if (ret) { |
3257 | mlog_errno(ret); | 3475 | mlog_errno(ret); |
3258 | goto out; | 3476 | break; |
3259 | } | 3477 | } |
3260 | 3478 | ||
3261 | ret = ocfs2_iterate_xattr_buckets(inode, p_blkno, num_clusters, | 3479 | ret = rec_func(inode, blk_bh, p_blkno, e_cpos, |
3262 | ocfs2_list_xattr_bucket, | 3480 | num_clusters, para); |
3263 | &xl); | ||
3264 | if (ret) { | 3481 | if (ret) { |
3265 | if (ret != -ERANGE) | 3482 | if (ret != -ERANGE) |
3266 | mlog_errno(ret); | 3483 | mlog_errno(ret); |
3267 | goto out; | 3484 | break; |
3268 | } | 3485 | } |
3269 | 3486 | ||
3270 | if (e_cpos == 0) | 3487 | if (e_cpos == 0) |
@@ -3273,6 +3490,37 @@ static int ocfs2_xattr_tree_list_index_block(struct inode *inode, | |||
3273 | name_hash = e_cpos - 1; | 3490 | name_hash = e_cpos - 1; |
3274 | } | 3491 | } |
3275 | 3492 | ||
3493 | return ret; | ||
3494 | |||
3495 | } | ||
3496 | |||
3497 | static int ocfs2_list_xattr_tree_rec(struct inode *inode, | ||
3498 | struct buffer_head *root_bh, | ||
3499 | u64 blkno, u32 cpos, u32 len, void *para) | ||
3500 | { | ||
3501 | return ocfs2_iterate_xattr_buckets(inode, blkno, len, | ||
3502 | ocfs2_list_xattr_bucket, para); | ||
3503 | } | ||
3504 | |||
3505 | static int ocfs2_xattr_tree_list_index_block(struct inode *inode, | ||
3506 | struct buffer_head *blk_bh, | ||
3507 | char *buffer, | ||
3508 | size_t buffer_size) | ||
3509 | { | ||
3510 | int ret; | ||
3511 | struct ocfs2_xattr_tree_list xl = { | ||
3512 | .buffer = buffer, | ||
3513 | .buffer_size = buffer_size, | ||
3514 | .result = 0, | ||
3515 | }; | ||
3516 | |||
3517 | ret = ocfs2_iterate_xattr_index_block(inode, blk_bh, | ||
3518 | ocfs2_list_xattr_tree_rec, &xl); | ||
3519 | if (ret) { | ||
3520 | mlog_errno(ret); | ||
3521 | goto out; | ||
3522 | } | ||
3523 | |||
3276 | ret = xl.result; | 3524 | ret = xl.result; |
3277 | out: | 3525 | out: |
3278 | return ret; | 3526 | return ret; |
@@ -3426,7 +3674,7 @@ static int ocfs2_xattr_create_index_block(struct inode *inode, | |||
3426 | */ | 3674 | */ |
3427 | down_write(&oi->ip_alloc_sem); | 3675 | down_write(&oi->ip_alloc_sem); |
3428 | 3676 | ||
3429 | ret = ocfs2_journal_access_xb(handle, inode, xb_bh, | 3677 | ret = ocfs2_journal_access_xb(handle, INODE_CACHE(inode), xb_bh, |
3430 | OCFS2_JOURNAL_ACCESS_WRITE); | 3678 | OCFS2_JOURNAL_ACCESS_WRITE); |
3431 | if (ret) { | 3679 | if (ret) { |
3432 | mlog_errno(ret); | 3680 | mlog_errno(ret); |
@@ -4263,9 +4511,9 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode, | |||
4263 | (unsigned long long)OCFS2_I(inode)->ip_blkno, | 4511 | (unsigned long long)OCFS2_I(inode)->ip_blkno, |
4264 | prev_cpos, (unsigned long long)bucket_blkno(first)); | 4512 | prev_cpos, (unsigned long long)bucket_blkno(first)); |
4265 | 4513 | ||
4266 | ocfs2_init_xattr_tree_extent_tree(&et, inode, root_bh); | 4514 | ocfs2_init_xattr_tree_extent_tree(&et, INODE_CACHE(inode), root_bh); |
4267 | 4515 | ||
4268 | ret = ocfs2_journal_access_xb(handle, inode, root_bh, | 4516 | ret = ocfs2_journal_access_xb(handle, INODE_CACHE(inode), root_bh, |
4269 | OCFS2_JOURNAL_ACCESS_WRITE); | 4517 | OCFS2_JOURNAL_ACCESS_WRITE); |
4270 | if (ret < 0) { | 4518 | if (ret < 0) { |
4271 | mlog_errno(ret); | 4519 | mlog_errno(ret); |
@@ -4319,7 +4567,7 @@ static int ocfs2_add_new_xattr_cluster(struct inode *inode, | |||
4319 | 4567 | ||
4320 | mlog(0, "Insert %u clusters at block %llu for xattr at %u\n", | 4568 | mlog(0, "Insert %u clusters at block %llu for xattr at %u\n", |
4321 | num_bits, (unsigned long long)block, v_start); | 4569 | num_bits, (unsigned long long)block, v_start); |
4322 | ret = ocfs2_insert_extent(osb, handle, inode, &et, v_start, block, | 4570 | ret = ocfs2_insert_extent(handle, &et, v_start, block, |
4323 | num_bits, 0, ctxt->meta_ac); | 4571 | num_bits, 0, ctxt->meta_ac); |
4324 | if (ret < 0) { | 4572 | if (ret < 0) { |
4325 | mlog_errno(ret); | 4573 | mlog_errno(ret); |
@@ -4798,10 +5046,13 @@ static int ocfs2_xattr_bucket_set_value_outside(struct inode *inode, | |||
4798 | struct ocfs2_xattr_entry *xe = xs->here; | 5046 | struct ocfs2_xattr_entry *xe = xs->here; |
4799 | struct ocfs2_xattr_header *xh = bucket_xh(xs->bucket); | 5047 | struct ocfs2_xattr_header *xh = bucket_xh(xs->bucket); |
4800 | void *base; | 5048 | void *base; |
5049 | struct ocfs2_xattr_value_buf vb = { | ||
5050 | .vb_access = ocfs2_journal_access, | ||
5051 | }; | ||
4801 | 5052 | ||
4802 | BUG_ON(!xs->base || !xe || ocfs2_xattr_is_local(xe)); | 5053 | BUG_ON(!xs->base || !xe || ocfs2_xattr_is_local(xe)); |
4803 | 5054 | ||
4804 | ret = ocfs2_xattr_bucket_get_name_value(inode, xh, | 5055 | ret = ocfs2_xattr_bucket_get_name_value(inode->i_sb, xh, |
4805 | xe - xh->xh_entries, | 5056 | xe - xh->xh_entries, |
4806 | &block_off, | 5057 | &block_off, |
4807 | &offset); | 5058 | &offset); |
@@ -4814,8 +5065,10 @@ static int ocfs2_xattr_bucket_set_value_outside(struct inode *inode, | |||
4814 | xv = (struct ocfs2_xattr_value_root *)(base + offset + | 5065 | xv = (struct ocfs2_xattr_value_root *)(base + offset + |
4815 | OCFS2_XATTR_SIZE(xe->xe_name_len)); | 5066 | OCFS2_XATTR_SIZE(xe->xe_name_len)); |
4816 | 5067 | ||
5068 | vb.vb_xv = xv; | ||
5069 | vb.vb_bh = xs->bucket->bu_bhs[block_off]; | ||
4817 | ret = __ocfs2_xattr_set_value_outside(inode, handle, | 5070 | ret = __ocfs2_xattr_set_value_outside(inode, handle, |
4818 | xv, val, value_len); | 5071 | &vb, val, value_len); |
4819 | if (ret) | 5072 | if (ret) |
4820 | mlog_errno(ret); | 5073 | mlog_errno(ret); |
4821 | out: | 5074 | out: |
@@ -4826,7 +5079,8 @@ static int ocfs2_rm_xattr_cluster(struct inode *inode, | |||
4826 | struct buffer_head *root_bh, | 5079 | struct buffer_head *root_bh, |
4827 | u64 blkno, | 5080 | u64 blkno, |
4828 | u32 cpos, | 5081 | u32 cpos, |
4829 | u32 len) | 5082 | u32 len, |
5083 | void *para) | ||
4830 | { | 5084 | { |
4831 | int ret; | 5085 | int ret; |
4832 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | 5086 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); |
@@ -4838,14 +5092,22 @@ static int ocfs2_rm_xattr_cluster(struct inode *inode, | |||
4838 | struct ocfs2_cached_dealloc_ctxt dealloc; | 5092 | struct ocfs2_cached_dealloc_ctxt dealloc; |
4839 | struct ocfs2_extent_tree et; | 5093 | struct ocfs2_extent_tree et; |
4840 | 5094 | ||
4841 | ocfs2_init_xattr_tree_extent_tree(&et, inode, root_bh); | 5095 | ret = ocfs2_iterate_xattr_buckets(inode, blkno, len, |
5096 | ocfs2_delete_xattr_in_bucket, para); | ||
5097 | if (ret) { | ||
5098 | mlog_errno(ret); | ||
5099 | return ret; | ||
5100 | } | ||
5101 | |||
5102 | ocfs2_init_xattr_tree_extent_tree(&et, INODE_CACHE(inode), root_bh); | ||
4842 | 5103 | ||
4843 | ocfs2_init_dealloc_ctxt(&dealloc); | 5104 | ocfs2_init_dealloc_ctxt(&dealloc); |
4844 | 5105 | ||
4845 | mlog(0, "rm xattr extent rec at %u len = %u, start from %llu\n", | 5106 | mlog(0, "rm xattr extent rec at %u len = %u, start from %llu\n", |
4846 | cpos, len, (unsigned long long)blkno); | 5107 | cpos, len, (unsigned long long)blkno); |
4847 | 5108 | ||
4848 | ocfs2_remove_xattr_clusters_from_cache(inode, blkno, len); | 5109 | ocfs2_remove_xattr_clusters_from_cache(INODE_CACHE(inode), blkno, |
5110 | len); | ||
4849 | 5111 | ||
4850 | ret = ocfs2_lock_allocators(inode, &et, 0, 1, NULL, &meta_ac); | 5112 | ret = ocfs2_lock_allocators(inode, &et, 0, 1, NULL, &meta_ac); |
4851 | if (ret) { | 5113 | if (ret) { |
@@ -4870,14 +5132,14 @@ static int ocfs2_rm_xattr_cluster(struct inode *inode, | |||
4870 | goto out; | 5132 | goto out; |
4871 | } | 5133 | } |
4872 | 5134 | ||
4873 | ret = ocfs2_journal_access_xb(handle, inode, root_bh, | 5135 | ret = ocfs2_journal_access_xb(handle, INODE_CACHE(inode), root_bh, |
4874 | OCFS2_JOURNAL_ACCESS_WRITE); | 5136 | OCFS2_JOURNAL_ACCESS_WRITE); |
4875 | if (ret) { | 5137 | if (ret) { |
4876 | mlog_errno(ret); | 5138 | mlog_errno(ret); |
4877 | goto out_commit; | 5139 | goto out_commit; |
4878 | } | 5140 | } |
4879 | 5141 | ||
4880 | ret = ocfs2_remove_extent(inode, &et, cpos, len, handle, meta_ac, | 5142 | ret = ocfs2_remove_extent(handle, &et, cpos, len, meta_ac, |
4881 | &dealloc); | 5143 | &dealloc); |
4882 | if (ret) { | 5144 | if (ret) { |
4883 | mlog_errno(ret); | 5145 | mlog_errno(ret); |
@@ -5220,7 +5482,7 @@ static int ocfs2_delete_xattr_in_bucket(struct inode *inode, | |||
5220 | struct ocfs2_xattr_bucket *bucket, | 5482 | struct ocfs2_xattr_bucket *bucket, |
5221 | void *para) | 5483 | void *para) |
5222 | { | 5484 | { |
5223 | int ret = 0; | 5485 | int ret = 0, ref_credits; |
5224 | struct ocfs2_xattr_header *xh = bucket_xh(bucket); | 5486 | struct ocfs2_xattr_header *xh = bucket_xh(bucket); |
5225 | u16 i; | 5487 | u16 i; |
5226 | struct ocfs2_xattr_entry *xe; | 5488 | struct ocfs2_xattr_entry *xe; |
@@ -5228,7 +5490,9 @@ static int ocfs2_delete_xattr_in_bucket(struct inode *inode, | |||
5228 | struct ocfs2_xattr_set_ctxt ctxt = {NULL, NULL,}; | 5490 | struct ocfs2_xattr_set_ctxt ctxt = {NULL, NULL,}; |
5229 | int credits = ocfs2_remove_extent_credits(osb->sb) + | 5491 | int credits = ocfs2_remove_extent_credits(osb->sb) + |
5230 | ocfs2_blocks_per_xattr_bucket(inode->i_sb); | 5492 | ocfs2_blocks_per_xattr_bucket(inode->i_sb); |
5231 | 5493 | struct ocfs2_xattr_value_root *xv; | |
5494 | struct ocfs2_rm_xattr_bucket_para *args = | ||
5495 | (struct ocfs2_rm_xattr_bucket_para *)para; | ||
5232 | 5496 | ||
5233 | ocfs2_init_dealloc_ctxt(&ctxt.dealloc); | 5497 | ocfs2_init_dealloc_ctxt(&ctxt.dealloc); |
5234 | 5498 | ||
@@ -5237,7 +5501,16 @@ static int ocfs2_delete_xattr_in_bucket(struct inode *inode, | |||
5237 | if (ocfs2_xattr_is_local(xe)) | 5501 | if (ocfs2_xattr_is_local(xe)) |
5238 | continue; | 5502 | continue; |
5239 | 5503 | ||
5240 | ctxt.handle = ocfs2_start_trans(osb, credits); | 5504 | ret = ocfs2_get_xattr_tree_value_root(inode->i_sb, bucket, |
5505 | i, &xv, NULL); | ||
5506 | |||
5507 | ret = ocfs2_lock_xattr_remove_allocators(inode, xv, | ||
5508 | args->ref_ci, | ||
5509 | args->ref_root_bh, | ||
5510 | &ctxt.meta_ac, | ||
5511 | &ref_credits); | ||
5512 | |||
5513 | ctxt.handle = ocfs2_start_trans(osb, credits + ref_credits); | ||
5241 | if (IS_ERR(ctxt.handle)) { | 5514 | if (IS_ERR(ctxt.handle)) { |
5242 | ret = PTR_ERR(ctxt.handle); | 5515 | ret = PTR_ERR(ctxt.handle); |
5243 | mlog_errno(ret); | 5516 | mlog_errno(ret); |
@@ -5248,57 +5521,1439 @@ static int ocfs2_delete_xattr_in_bucket(struct inode *inode, | |||
5248 | i, 0, &ctxt); | 5521 | i, 0, &ctxt); |
5249 | 5522 | ||
5250 | ocfs2_commit_trans(osb, ctxt.handle); | 5523 | ocfs2_commit_trans(osb, ctxt.handle); |
5524 | if (ctxt.meta_ac) { | ||
5525 | ocfs2_free_alloc_context(ctxt.meta_ac); | ||
5526 | ctxt.meta_ac = NULL; | ||
5527 | } | ||
5251 | if (ret) { | 5528 | if (ret) { |
5252 | mlog_errno(ret); | 5529 | mlog_errno(ret); |
5253 | break; | 5530 | break; |
5254 | } | 5531 | } |
5255 | } | 5532 | } |
5256 | 5533 | ||
5534 | if (ctxt.meta_ac) | ||
5535 | ocfs2_free_alloc_context(ctxt.meta_ac); | ||
5257 | ocfs2_schedule_truncate_log_flush(osb, 1); | 5536 | ocfs2_schedule_truncate_log_flush(osb, 1); |
5258 | ocfs2_run_deallocs(osb, &ctxt.dealloc); | 5537 | ocfs2_run_deallocs(osb, &ctxt.dealloc); |
5259 | return ret; | 5538 | return ret; |
5260 | } | 5539 | } |
5261 | 5540 | ||
5262 | static int ocfs2_delete_xattr_index_block(struct inode *inode, | 5541 | /* |
5263 | struct buffer_head *xb_bh) | 5542 | * Whenever we modify a xattr value root in the bucket(e.g, CoW |
5543 | * or change the extent record flag), we need to recalculate | ||
5544 | * the metaecc for the whole bucket. So it is done here. | ||
5545 | * | ||
5546 | * Note: | ||
5547 | * We have to give the extra credits for the caller. | ||
5548 | */ | ||
5549 | static int ocfs2_xattr_bucket_post_refcount(struct inode *inode, | ||
5550 | handle_t *handle, | ||
5551 | void *para) | ||
5552 | { | ||
5553 | int ret; | ||
5554 | struct ocfs2_xattr_bucket *bucket = | ||
5555 | (struct ocfs2_xattr_bucket *)para; | ||
5556 | |||
5557 | ret = ocfs2_xattr_bucket_journal_access(handle, bucket, | ||
5558 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
5559 | if (ret) { | ||
5560 | mlog_errno(ret); | ||
5561 | return ret; | ||
5562 | } | ||
5563 | |||
5564 | ocfs2_xattr_bucket_journal_dirty(handle, bucket); | ||
5565 | |||
5566 | return 0; | ||
5567 | } | ||
5568 | |||
5569 | /* | ||
5570 | * Special action we need if the xattr value is refcounted. | ||
5571 | * | ||
5572 | * 1. If the xattr is refcounted, lock the tree. | ||
5573 | * 2. CoW the xattr if we are setting the new value and the value | ||
5574 | * will be stored outside. | ||
5575 | * 3. In other case, decrease_refcount will work for us, so just | ||
5576 | * lock the refcount tree, calculate the meta and credits is OK. | ||
5577 | * | ||
5578 | * We have to do CoW before ocfs2_init_xattr_set_ctxt since | ||
5579 | * currently CoW is a completed transaction, while this function | ||
5580 | * will also lock the allocators and let us deadlock. So we will | ||
5581 | * CoW the whole xattr value. | ||
5582 | */ | ||
5583 | static int ocfs2_prepare_refcount_xattr(struct inode *inode, | ||
5584 | struct ocfs2_dinode *di, | ||
5585 | struct ocfs2_xattr_info *xi, | ||
5586 | struct ocfs2_xattr_search *xis, | ||
5587 | struct ocfs2_xattr_search *xbs, | ||
5588 | struct ocfs2_refcount_tree **ref_tree, | ||
5589 | int *meta_add, | ||
5590 | int *credits) | ||
5264 | { | 5591 | { |
5265 | struct ocfs2_xattr_block *xb = | ||
5266 | (struct ocfs2_xattr_block *)xb_bh->b_data; | ||
5267 | struct ocfs2_extent_list *el = &xb->xb_attrs.xb_root.xt_list; | ||
5268 | int ret = 0; | 5592 | int ret = 0; |
5269 | u32 name_hash = UINT_MAX, e_cpos, num_clusters; | 5593 | struct ocfs2_xattr_block *xb; |
5270 | u64 p_blkno; | 5594 | struct ocfs2_xattr_entry *xe; |
5595 | char *base; | ||
5596 | u32 p_cluster, num_clusters; | ||
5597 | unsigned int ext_flags; | ||
5598 | int name_offset, name_len; | ||
5599 | struct ocfs2_xattr_value_buf vb; | ||
5600 | struct ocfs2_xattr_bucket *bucket = NULL; | ||
5601 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
5602 | struct ocfs2_post_refcount refcount; | ||
5603 | struct ocfs2_post_refcount *p = NULL; | ||
5604 | struct buffer_head *ref_root_bh = NULL; | ||
5271 | 5605 | ||
5272 | if (le16_to_cpu(el->l_next_free_rec) == 0) | 5606 | if (!xis->not_found) { |
5273 | return 0; | 5607 | xe = xis->here; |
5608 | name_offset = le16_to_cpu(xe->xe_name_offset); | ||
5609 | name_len = OCFS2_XATTR_SIZE(xe->xe_name_len); | ||
5610 | base = xis->base; | ||
5611 | vb.vb_bh = xis->inode_bh; | ||
5612 | vb.vb_access = ocfs2_journal_access_di; | ||
5613 | } else { | ||
5614 | int i, block_off = 0; | ||
5615 | xb = (struct ocfs2_xattr_block *)xbs->xattr_bh->b_data; | ||
5616 | xe = xbs->here; | ||
5617 | name_offset = le16_to_cpu(xe->xe_name_offset); | ||
5618 | name_len = OCFS2_XATTR_SIZE(xe->xe_name_len); | ||
5619 | i = xbs->here - xbs->header->xh_entries; | ||
5274 | 5620 | ||
5275 | while (name_hash > 0) { | 5621 | if (le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED) { |
5276 | ret = ocfs2_xattr_get_rec(inode, name_hash, &p_blkno, | 5622 | ret = ocfs2_xattr_bucket_get_name_value(inode->i_sb, |
5277 | &e_cpos, &num_clusters, el); | 5623 | bucket_xh(xbs->bucket), |
5624 | i, &block_off, | ||
5625 | &name_offset); | ||
5626 | if (ret) { | ||
5627 | mlog_errno(ret); | ||
5628 | goto out; | ||
5629 | } | ||
5630 | base = bucket_block(xbs->bucket, block_off); | ||
5631 | vb.vb_bh = xbs->bucket->bu_bhs[block_off]; | ||
5632 | vb.vb_access = ocfs2_journal_access; | ||
5633 | |||
5634 | if (ocfs2_meta_ecc(osb)) { | ||
5635 | /*create parameters for ocfs2_post_refcount. */ | ||
5636 | bucket = xbs->bucket; | ||
5637 | refcount.credits = bucket->bu_blocks; | ||
5638 | refcount.para = bucket; | ||
5639 | refcount.func = | ||
5640 | ocfs2_xattr_bucket_post_refcount; | ||
5641 | p = &refcount; | ||
5642 | } | ||
5643 | } else { | ||
5644 | base = xbs->base; | ||
5645 | vb.vb_bh = xbs->xattr_bh; | ||
5646 | vb.vb_access = ocfs2_journal_access_xb; | ||
5647 | } | ||
5648 | } | ||
5649 | |||
5650 | if (ocfs2_xattr_is_local(xe)) | ||
5651 | goto out; | ||
5652 | |||
5653 | vb.vb_xv = (struct ocfs2_xattr_value_root *) | ||
5654 | (base + name_offset + name_len); | ||
5655 | |||
5656 | ret = ocfs2_xattr_get_clusters(inode, 0, &p_cluster, | ||
5657 | &num_clusters, &vb.vb_xv->xr_list, | ||
5658 | &ext_flags); | ||
5659 | if (ret) { | ||
5660 | mlog_errno(ret); | ||
5661 | goto out; | ||
5662 | } | ||
5663 | |||
5664 | /* | ||
5665 | * We just need to check the 1st extent record, since we always | ||
5666 | * CoW the whole xattr. So there shouldn't be a xattr with | ||
5667 | * some REFCOUNT extent recs after the 1st one. | ||
5668 | */ | ||
5669 | if (!(ext_flags & OCFS2_EXT_REFCOUNTED)) | ||
5670 | goto out; | ||
5671 | |||
5672 | ret = ocfs2_lock_refcount_tree(osb, le64_to_cpu(di->i_refcount_loc), | ||
5673 | 1, ref_tree, &ref_root_bh); | ||
5674 | if (ret) { | ||
5675 | mlog_errno(ret); | ||
5676 | goto out; | ||
5677 | } | ||
5678 | |||
5679 | /* | ||
5680 | * If we are deleting the xattr or the new size will be stored inside, | ||
5681 | * cool, leave it there, the xattr truncate process will remove them | ||
5682 | * for us(it still needs the refcount tree lock and the meta, credits). | ||
5683 | * And the worse case is that every cluster truncate will split the | ||
5684 | * refcount tree, and make the original extent become 3. So we will need | ||
5685 | * 2 * cluster more extent recs at most. | ||
5686 | */ | ||
5687 | if (!xi->value || xi->value_len <= OCFS2_XATTR_INLINE_SIZE) { | ||
5688 | |||
5689 | ret = ocfs2_refcounted_xattr_delete_need(inode, | ||
5690 | &(*ref_tree)->rf_ci, | ||
5691 | ref_root_bh, vb.vb_xv, | ||
5692 | meta_add, credits); | ||
5693 | if (ret) | ||
5694 | mlog_errno(ret); | ||
5695 | goto out; | ||
5696 | } | ||
5697 | |||
5698 | ret = ocfs2_refcount_cow_xattr(inode, di, &vb, | ||
5699 | *ref_tree, ref_root_bh, 0, | ||
5700 | le32_to_cpu(vb.vb_xv->xr_clusters), p); | ||
5701 | if (ret) | ||
5702 | mlog_errno(ret); | ||
5703 | |||
5704 | out: | ||
5705 | brelse(ref_root_bh); | ||
5706 | return ret; | ||
5707 | } | ||
5708 | |||
5709 | /* | ||
5710 | * Add the REFCOUNTED flags for all the extent rec in ocfs2_xattr_value_root. | ||
5711 | * The physical clusters will be added to refcount tree. | ||
5712 | */ | ||
5713 | static int ocfs2_xattr_value_attach_refcount(struct inode *inode, | ||
5714 | struct ocfs2_xattr_value_root *xv, | ||
5715 | struct ocfs2_extent_tree *value_et, | ||
5716 | struct ocfs2_caching_info *ref_ci, | ||
5717 | struct buffer_head *ref_root_bh, | ||
5718 | struct ocfs2_cached_dealloc_ctxt *dealloc, | ||
5719 | struct ocfs2_post_refcount *refcount) | ||
5720 | { | ||
5721 | int ret = 0; | ||
5722 | u32 clusters = le32_to_cpu(xv->xr_clusters); | ||
5723 | u32 cpos, p_cluster, num_clusters; | ||
5724 | struct ocfs2_extent_list *el = &xv->xr_list; | ||
5725 | unsigned int ext_flags; | ||
5726 | |||
5727 | cpos = 0; | ||
5728 | while (cpos < clusters) { | ||
5729 | ret = ocfs2_xattr_get_clusters(inode, cpos, &p_cluster, | ||
5730 | &num_clusters, el, &ext_flags); | ||
5731 | |||
5732 | cpos += num_clusters; | ||
5733 | if ((ext_flags & OCFS2_EXT_REFCOUNTED)) | ||
5734 | continue; | ||
5735 | |||
5736 | BUG_ON(!p_cluster); | ||
5737 | |||
5738 | ret = ocfs2_add_refcount_flag(inode, value_et, | ||
5739 | ref_ci, ref_root_bh, | ||
5740 | cpos - num_clusters, | ||
5741 | p_cluster, num_clusters, | ||
5742 | dealloc, refcount); | ||
5743 | if (ret) { | ||
5744 | mlog_errno(ret); | ||
5745 | break; | ||
5746 | } | ||
5747 | } | ||
5748 | |||
5749 | return ret; | ||
5750 | } | ||
5751 | |||
5752 | /* | ||
5753 | * Given a normal ocfs2_xattr_header, refcount all the entries which | ||
5754 | * have value stored outside. | ||
5755 | * Used for xattrs stored in inode and ocfs2_xattr_block. | ||
5756 | */ | ||
5757 | static int ocfs2_xattr_attach_refcount_normal(struct inode *inode, | ||
5758 | struct ocfs2_xattr_value_buf *vb, | ||
5759 | struct ocfs2_xattr_header *header, | ||
5760 | struct ocfs2_caching_info *ref_ci, | ||
5761 | struct buffer_head *ref_root_bh, | ||
5762 | struct ocfs2_cached_dealloc_ctxt *dealloc) | ||
5763 | { | ||
5764 | |||
5765 | struct ocfs2_xattr_entry *xe; | ||
5766 | struct ocfs2_xattr_value_root *xv; | ||
5767 | struct ocfs2_extent_tree et; | ||
5768 | int i, ret = 0; | ||
5769 | |||
5770 | for (i = 0; i < le16_to_cpu(header->xh_count); i++) { | ||
5771 | xe = &header->xh_entries[i]; | ||
5772 | |||
5773 | if (ocfs2_xattr_is_local(xe)) | ||
5774 | continue; | ||
5775 | |||
5776 | xv = (struct ocfs2_xattr_value_root *)((void *)header + | ||
5777 | le16_to_cpu(xe->xe_name_offset) + | ||
5778 | OCFS2_XATTR_SIZE(xe->xe_name_len)); | ||
5779 | |||
5780 | vb->vb_xv = xv; | ||
5781 | ocfs2_init_xattr_value_extent_tree(&et, INODE_CACHE(inode), vb); | ||
5782 | |||
5783 | ret = ocfs2_xattr_value_attach_refcount(inode, xv, &et, | ||
5784 | ref_ci, ref_root_bh, | ||
5785 | dealloc, NULL); | ||
5786 | if (ret) { | ||
5787 | mlog_errno(ret); | ||
5788 | break; | ||
5789 | } | ||
5790 | } | ||
5791 | |||
5792 | return ret; | ||
5793 | } | ||
5794 | |||
5795 | static int ocfs2_xattr_inline_attach_refcount(struct inode *inode, | ||
5796 | struct buffer_head *fe_bh, | ||
5797 | struct ocfs2_caching_info *ref_ci, | ||
5798 | struct buffer_head *ref_root_bh, | ||
5799 | struct ocfs2_cached_dealloc_ctxt *dealloc) | ||
5800 | { | ||
5801 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)fe_bh->b_data; | ||
5802 | struct ocfs2_xattr_header *header = (struct ocfs2_xattr_header *) | ||
5803 | (fe_bh->b_data + inode->i_sb->s_blocksize - | ||
5804 | le16_to_cpu(di->i_xattr_inline_size)); | ||
5805 | struct ocfs2_xattr_value_buf vb = { | ||
5806 | .vb_bh = fe_bh, | ||
5807 | .vb_access = ocfs2_journal_access_di, | ||
5808 | }; | ||
5809 | |||
5810 | return ocfs2_xattr_attach_refcount_normal(inode, &vb, header, | ||
5811 | ref_ci, ref_root_bh, dealloc); | ||
5812 | } | ||
5813 | |||
5814 | struct ocfs2_xattr_tree_value_refcount_para { | ||
5815 | struct ocfs2_caching_info *ref_ci; | ||
5816 | struct buffer_head *ref_root_bh; | ||
5817 | struct ocfs2_cached_dealloc_ctxt *dealloc; | ||
5818 | }; | ||
5819 | |||
5820 | static int ocfs2_get_xattr_tree_value_root(struct super_block *sb, | ||
5821 | struct ocfs2_xattr_bucket *bucket, | ||
5822 | int offset, | ||
5823 | struct ocfs2_xattr_value_root **xv, | ||
5824 | struct buffer_head **bh) | ||
5825 | { | ||
5826 | int ret, block_off, name_offset; | ||
5827 | struct ocfs2_xattr_header *xh = bucket_xh(bucket); | ||
5828 | struct ocfs2_xattr_entry *xe = &xh->xh_entries[offset]; | ||
5829 | void *base; | ||
5830 | |||
5831 | ret = ocfs2_xattr_bucket_get_name_value(sb, | ||
5832 | bucket_xh(bucket), | ||
5833 | offset, | ||
5834 | &block_off, | ||
5835 | &name_offset); | ||
5836 | if (ret) { | ||
5837 | mlog_errno(ret); | ||
5838 | goto out; | ||
5839 | } | ||
5840 | |||
5841 | base = bucket_block(bucket, block_off); | ||
5842 | |||
5843 | *xv = (struct ocfs2_xattr_value_root *)(base + name_offset + | ||
5844 | OCFS2_XATTR_SIZE(xe->xe_name_len)); | ||
5845 | |||
5846 | if (bh) | ||
5847 | *bh = bucket->bu_bhs[block_off]; | ||
5848 | out: | ||
5849 | return ret; | ||
5850 | } | ||
5851 | |||
5852 | /* | ||
5853 | * For a given xattr bucket, refcount all the entries which | ||
5854 | * have value stored outside. | ||
5855 | */ | ||
5856 | static int ocfs2_xattr_bucket_value_refcount(struct inode *inode, | ||
5857 | struct ocfs2_xattr_bucket *bucket, | ||
5858 | void *para) | ||
5859 | { | ||
5860 | int i, ret = 0; | ||
5861 | struct ocfs2_extent_tree et; | ||
5862 | struct ocfs2_xattr_tree_value_refcount_para *ref = | ||
5863 | (struct ocfs2_xattr_tree_value_refcount_para *)para; | ||
5864 | struct ocfs2_xattr_header *xh = | ||
5865 | (struct ocfs2_xattr_header *)bucket->bu_bhs[0]->b_data; | ||
5866 | struct ocfs2_xattr_entry *xe; | ||
5867 | struct ocfs2_xattr_value_buf vb = { | ||
5868 | .vb_access = ocfs2_journal_access, | ||
5869 | }; | ||
5870 | struct ocfs2_post_refcount refcount = { | ||
5871 | .credits = bucket->bu_blocks, | ||
5872 | .para = bucket, | ||
5873 | .func = ocfs2_xattr_bucket_post_refcount, | ||
5874 | }; | ||
5875 | struct ocfs2_post_refcount *p = NULL; | ||
5876 | |||
5877 | /* We only need post_refcount if we support metaecc. */ | ||
5878 | if (ocfs2_meta_ecc(OCFS2_SB(inode->i_sb))) | ||
5879 | p = &refcount; | ||
5880 | |||
5881 | mlog(0, "refcount bucket %llu, count = %u\n", | ||
5882 | (unsigned long long)bucket_blkno(bucket), | ||
5883 | le16_to_cpu(xh->xh_count)); | ||
5884 | for (i = 0; i < le16_to_cpu(xh->xh_count); i++) { | ||
5885 | xe = &xh->xh_entries[i]; | ||
5886 | |||
5887 | if (ocfs2_xattr_is_local(xe)) | ||
5888 | continue; | ||
5889 | |||
5890 | ret = ocfs2_get_xattr_tree_value_root(inode->i_sb, bucket, i, | ||
5891 | &vb.vb_xv, &vb.vb_bh); | ||
5892 | if (ret) { | ||
5893 | mlog_errno(ret); | ||
5894 | break; | ||
5895 | } | ||
5896 | |||
5897 | ocfs2_init_xattr_value_extent_tree(&et, | ||
5898 | INODE_CACHE(inode), &vb); | ||
5899 | |||
5900 | ret = ocfs2_xattr_value_attach_refcount(inode, vb.vb_xv, | ||
5901 | &et, ref->ref_ci, | ||
5902 | ref->ref_root_bh, | ||
5903 | ref->dealloc, p); | ||
5904 | if (ret) { | ||
5905 | mlog_errno(ret); | ||
5906 | break; | ||
5907 | } | ||
5908 | } | ||
5909 | |||
5910 | return ret; | ||
5911 | |||
5912 | } | ||
5913 | |||
5914 | static int ocfs2_refcount_xattr_tree_rec(struct inode *inode, | ||
5915 | struct buffer_head *root_bh, | ||
5916 | u64 blkno, u32 cpos, u32 len, void *para) | ||
5917 | { | ||
5918 | return ocfs2_iterate_xattr_buckets(inode, blkno, len, | ||
5919 | ocfs2_xattr_bucket_value_refcount, | ||
5920 | para); | ||
5921 | } | ||
5922 | |||
5923 | static int ocfs2_xattr_block_attach_refcount(struct inode *inode, | ||
5924 | struct buffer_head *blk_bh, | ||
5925 | struct ocfs2_caching_info *ref_ci, | ||
5926 | struct buffer_head *ref_root_bh, | ||
5927 | struct ocfs2_cached_dealloc_ctxt *dealloc) | ||
5928 | { | ||
5929 | int ret = 0; | ||
5930 | struct ocfs2_xattr_block *xb = | ||
5931 | (struct ocfs2_xattr_block *)blk_bh->b_data; | ||
5932 | |||
5933 | if (!(le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED)) { | ||
5934 | struct ocfs2_xattr_header *header = &xb->xb_attrs.xb_header; | ||
5935 | struct ocfs2_xattr_value_buf vb = { | ||
5936 | .vb_bh = blk_bh, | ||
5937 | .vb_access = ocfs2_journal_access_xb, | ||
5938 | }; | ||
5939 | |||
5940 | ret = ocfs2_xattr_attach_refcount_normal(inode, &vb, header, | ||
5941 | ref_ci, ref_root_bh, | ||
5942 | dealloc); | ||
5943 | } else { | ||
5944 | struct ocfs2_xattr_tree_value_refcount_para para = { | ||
5945 | .ref_ci = ref_ci, | ||
5946 | .ref_root_bh = ref_root_bh, | ||
5947 | .dealloc = dealloc, | ||
5948 | }; | ||
5949 | |||
5950 | ret = ocfs2_iterate_xattr_index_block(inode, blk_bh, | ||
5951 | ocfs2_refcount_xattr_tree_rec, | ||
5952 | ¶); | ||
5953 | } | ||
5954 | |||
5955 | return ret; | ||
5956 | } | ||
5957 | |||
5958 | int ocfs2_xattr_attach_refcount_tree(struct inode *inode, | ||
5959 | struct buffer_head *fe_bh, | ||
5960 | struct ocfs2_caching_info *ref_ci, | ||
5961 | struct buffer_head *ref_root_bh, | ||
5962 | struct ocfs2_cached_dealloc_ctxt *dealloc) | ||
5963 | { | ||
5964 | int ret = 0; | ||
5965 | struct ocfs2_inode_info *oi = OCFS2_I(inode); | ||
5966 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)fe_bh->b_data; | ||
5967 | struct buffer_head *blk_bh = NULL; | ||
5968 | |||
5969 | if (oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL) { | ||
5970 | ret = ocfs2_xattr_inline_attach_refcount(inode, fe_bh, | ||
5971 | ref_ci, ref_root_bh, | ||
5972 | dealloc); | ||
5278 | if (ret) { | 5973 | if (ret) { |
5279 | mlog_errno(ret); | 5974 | mlog_errno(ret); |
5280 | goto out; | 5975 | goto out; |
5281 | } | 5976 | } |
5977 | } | ||
5978 | |||
5979 | if (!di->i_xattr_loc) | ||
5980 | goto out; | ||
5981 | |||
5982 | ret = ocfs2_read_xattr_block(inode, le64_to_cpu(di->i_xattr_loc), | ||
5983 | &blk_bh); | ||
5984 | if (ret < 0) { | ||
5985 | mlog_errno(ret); | ||
5986 | goto out; | ||
5987 | } | ||
5988 | |||
5989 | ret = ocfs2_xattr_block_attach_refcount(inode, blk_bh, ref_ci, | ||
5990 | ref_root_bh, dealloc); | ||
5991 | if (ret) | ||
5992 | mlog_errno(ret); | ||
5993 | |||
5994 | brelse(blk_bh); | ||
5995 | out: | ||
5996 | |||
5997 | return ret; | ||
5998 | } | ||
5999 | |||
6000 | typedef int (should_xattr_reflinked)(struct ocfs2_xattr_entry *xe); | ||
6001 | /* | ||
6002 | * Store the information we need in xattr reflink. | ||
6003 | * old_bh and new_bh are inode bh for the old and new inode. | ||
6004 | */ | ||
6005 | struct ocfs2_xattr_reflink { | ||
6006 | struct inode *old_inode; | ||
6007 | struct inode *new_inode; | ||
6008 | struct buffer_head *old_bh; | ||
6009 | struct buffer_head *new_bh; | ||
6010 | struct ocfs2_caching_info *ref_ci; | ||
6011 | struct buffer_head *ref_root_bh; | ||
6012 | struct ocfs2_cached_dealloc_ctxt *dealloc; | ||
6013 | should_xattr_reflinked *xattr_reflinked; | ||
6014 | }; | ||
6015 | |||
6016 | /* | ||
6017 | * Given a xattr header and xe offset, | ||
6018 | * return the proper xv and the corresponding bh. | ||
6019 | * xattr in inode, block and xattr tree have different implementaions. | ||
6020 | */ | ||
6021 | typedef int (get_xattr_value_root)(struct super_block *sb, | ||
6022 | struct buffer_head *bh, | ||
6023 | struct ocfs2_xattr_header *xh, | ||
6024 | int offset, | ||
6025 | struct ocfs2_xattr_value_root **xv, | ||
6026 | struct buffer_head **ret_bh, | ||
6027 | void *para); | ||
6028 | |||
6029 | /* | ||
6030 | * Calculate all the xattr value root metadata stored in this xattr header and | ||
6031 | * credits we need if we create them from the scratch. | ||
6032 | * We use get_xattr_value_root so that all types of xattr container can use it. | ||
6033 | */ | ||
6034 | static int ocfs2_value_metas_in_xattr_header(struct super_block *sb, | ||
6035 | struct buffer_head *bh, | ||
6036 | struct ocfs2_xattr_header *xh, | ||
6037 | int *metas, int *credits, | ||
6038 | int *num_recs, | ||
6039 | get_xattr_value_root *func, | ||
6040 | void *para) | ||
6041 | { | ||
6042 | int i, ret = 0; | ||
6043 | struct ocfs2_xattr_value_root *xv; | ||
6044 | struct ocfs2_xattr_entry *xe; | ||
6045 | |||
6046 | for (i = 0; i < le16_to_cpu(xh->xh_count); i++) { | ||
6047 | xe = &xh->xh_entries[i]; | ||
6048 | if (ocfs2_xattr_is_local(xe)) | ||
6049 | continue; | ||
6050 | |||
6051 | ret = func(sb, bh, xh, i, &xv, NULL, para); | ||
6052 | if (ret) { | ||
6053 | mlog_errno(ret); | ||
6054 | break; | ||
6055 | } | ||
6056 | |||
6057 | *metas += le16_to_cpu(xv->xr_list.l_tree_depth) * | ||
6058 | le16_to_cpu(xv->xr_list.l_next_free_rec); | ||
6059 | |||
6060 | *credits += ocfs2_calc_extend_credits(sb, | ||
6061 | &def_xv.xv.xr_list, | ||
6062 | le32_to_cpu(xv->xr_clusters)); | ||
6063 | |||
6064 | /* | ||
6065 | * If the value is a tree with depth > 1, We don't go deep | ||
6066 | * to the extent block, so just calculate a maximum record num. | ||
6067 | */ | ||
6068 | if (!xv->xr_list.l_tree_depth) | ||
6069 | *num_recs += xv->xr_list.l_next_free_rec; | ||
6070 | else | ||
6071 | *num_recs += ocfs2_clusters_for_bytes(sb, | ||
6072 | XATTR_SIZE_MAX); | ||
6073 | } | ||
6074 | |||
6075 | return ret; | ||
6076 | } | ||
6077 | |||
6078 | /* Used by xattr inode and block to return the right xv and buffer_head. */ | ||
6079 | static int ocfs2_get_xattr_value_root(struct super_block *sb, | ||
6080 | struct buffer_head *bh, | ||
6081 | struct ocfs2_xattr_header *xh, | ||
6082 | int offset, | ||
6083 | struct ocfs2_xattr_value_root **xv, | ||
6084 | struct buffer_head **ret_bh, | ||
6085 | void *para) | ||
6086 | { | ||
6087 | struct ocfs2_xattr_entry *xe = &xh->xh_entries[offset]; | ||
6088 | |||
6089 | *xv = (struct ocfs2_xattr_value_root *)((void *)xh + | ||
6090 | le16_to_cpu(xe->xe_name_offset) + | ||
6091 | OCFS2_XATTR_SIZE(xe->xe_name_len)); | ||
6092 | |||
6093 | if (ret_bh) | ||
6094 | *ret_bh = bh; | ||
6095 | |||
6096 | return 0; | ||
6097 | } | ||
6098 | |||
6099 | /* | ||
6100 | * Lock the meta_ac and caculate how much credits we need for reflink xattrs. | ||
6101 | * It is only used for inline xattr and xattr block. | ||
6102 | */ | ||
6103 | static int ocfs2_reflink_lock_xattr_allocators(struct ocfs2_super *osb, | ||
6104 | struct ocfs2_xattr_header *xh, | ||
6105 | struct buffer_head *ref_root_bh, | ||
6106 | int *credits, | ||
6107 | struct ocfs2_alloc_context **meta_ac) | ||
6108 | { | ||
6109 | int ret, meta_add = 0, num_recs = 0; | ||
6110 | struct ocfs2_refcount_block *rb = | ||
6111 | (struct ocfs2_refcount_block *)ref_root_bh->b_data; | ||
6112 | |||
6113 | *credits = 0; | ||
6114 | |||
6115 | ret = ocfs2_value_metas_in_xattr_header(osb->sb, NULL, xh, | ||
6116 | &meta_add, credits, &num_recs, | ||
6117 | ocfs2_get_xattr_value_root, | ||
6118 | NULL); | ||
6119 | if (ret) { | ||
6120 | mlog_errno(ret); | ||
6121 | goto out; | ||
6122 | } | ||
6123 | |||
6124 | /* | ||
6125 | * We need to add/modify num_recs in refcount tree, so just calculate | ||
6126 | * an approximate number we need for refcount tree change. | ||
6127 | * Sometimes we need to split the tree, and after split, half recs | ||
6128 | * will be moved to the new block, and a new block can only provide | ||
6129 | * half number of recs. So we multiple new blocks by 2. | ||
6130 | */ | ||
6131 | num_recs = num_recs / ocfs2_refcount_recs_per_rb(osb->sb) * 2; | ||
6132 | meta_add += num_recs; | ||
6133 | *credits += num_recs + num_recs * OCFS2_EXPAND_REFCOUNT_TREE_CREDITS; | ||
6134 | if (le32_to_cpu(rb->rf_flags) & OCFS2_REFCOUNT_TREE_FL) | ||
6135 | *credits += le16_to_cpu(rb->rf_list.l_tree_depth) * | ||
6136 | le16_to_cpu(rb->rf_list.l_next_free_rec) + 1; | ||
6137 | else | ||
6138 | *credits += 1; | ||
6139 | |||
6140 | ret = ocfs2_reserve_new_metadata_blocks(osb, meta_add, meta_ac); | ||
6141 | if (ret) | ||
6142 | mlog_errno(ret); | ||
6143 | |||
6144 | out: | ||
6145 | return ret; | ||
6146 | } | ||
5282 | 6147 | ||
5283 | ret = ocfs2_iterate_xattr_buckets(inode, p_blkno, num_clusters, | 6148 | /* |
5284 | ocfs2_delete_xattr_in_bucket, | 6149 | * Given a xattr header, reflink all the xattrs in this container. |
5285 | NULL); | 6150 | * It can be used for inode, block and bucket. |
6151 | * | ||
6152 | * NOTE: | ||
6153 | * Before we call this function, the caller has memcpy the xattr in | ||
6154 | * old_xh to the new_xh. | ||
6155 | * | ||
6156 | * If args.xattr_reflinked is set, call it to decide whether the xe should | ||
6157 | * be reflinked or not. If not, remove it from the new xattr header. | ||
6158 | */ | ||
6159 | static int ocfs2_reflink_xattr_header(handle_t *handle, | ||
6160 | struct ocfs2_xattr_reflink *args, | ||
6161 | struct buffer_head *old_bh, | ||
6162 | struct ocfs2_xattr_header *xh, | ||
6163 | struct buffer_head *new_bh, | ||
6164 | struct ocfs2_xattr_header *new_xh, | ||
6165 | struct ocfs2_xattr_value_buf *vb, | ||
6166 | struct ocfs2_alloc_context *meta_ac, | ||
6167 | get_xattr_value_root *func, | ||
6168 | void *para) | ||
6169 | { | ||
6170 | int ret = 0, i, j; | ||
6171 | struct super_block *sb = args->old_inode->i_sb; | ||
6172 | struct buffer_head *value_bh; | ||
6173 | struct ocfs2_xattr_entry *xe, *last; | ||
6174 | struct ocfs2_xattr_value_root *xv, *new_xv; | ||
6175 | struct ocfs2_extent_tree data_et; | ||
6176 | u32 clusters, cpos, p_cluster, num_clusters; | ||
6177 | unsigned int ext_flags = 0; | ||
6178 | |||
6179 | mlog(0, "reflink xattr in container %llu, count = %u\n", | ||
6180 | (unsigned long long)old_bh->b_blocknr, le16_to_cpu(xh->xh_count)); | ||
6181 | |||
6182 | last = &new_xh->xh_entries[le16_to_cpu(new_xh->xh_count)]; | ||
6183 | for (i = 0, j = 0; i < le16_to_cpu(xh->xh_count); i++, j++) { | ||
6184 | xe = &xh->xh_entries[i]; | ||
6185 | |||
6186 | if (args->xattr_reflinked && !args->xattr_reflinked(xe)) { | ||
6187 | xe = &new_xh->xh_entries[j]; | ||
6188 | |||
6189 | le16_add_cpu(&new_xh->xh_count, -1); | ||
6190 | if (new_xh->xh_count) { | ||
6191 | memmove(xe, xe + 1, | ||
6192 | (void *)last - (void *)xe); | ||
6193 | memset(last, 0, | ||
6194 | sizeof(struct ocfs2_xattr_entry)); | ||
6195 | } | ||
6196 | |||
6197 | /* | ||
6198 | * We don't want j to increase in the next round since | ||
6199 | * it is already moved ahead. | ||
6200 | */ | ||
6201 | j--; | ||
6202 | continue; | ||
6203 | } | ||
6204 | |||
6205 | if (ocfs2_xattr_is_local(xe)) | ||
6206 | continue; | ||
6207 | |||
6208 | ret = func(sb, old_bh, xh, i, &xv, NULL, para); | ||
6209 | if (ret) { | ||
6210 | mlog_errno(ret); | ||
6211 | break; | ||
6212 | } | ||
6213 | |||
6214 | ret = func(sb, new_bh, new_xh, j, &new_xv, &value_bh, para); | ||
6215 | if (ret) { | ||
6216 | mlog_errno(ret); | ||
6217 | break; | ||
6218 | } | ||
6219 | |||
6220 | /* | ||
6221 | * For the xattr which has l_tree_depth = 0, all the extent | ||
6222 | * recs have already be copied to the new xh with the | ||
6223 | * propriate OCFS2_EXT_REFCOUNTED flag we just need to | ||
6224 | * increase the refount count int the refcount tree. | ||
6225 | * | ||
6226 | * For the xattr which has l_tree_depth > 0, we need | ||
6227 | * to initialize it to the empty default value root, | ||
6228 | * and then insert the extents one by one. | ||
6229 | */ | ||
6230 | if (xv->xr_list.l_tree_depth) { | ||
6231 | memcpy(new_xv, &def_xv, sizeof(def_xv)); | ||
6232 | vb->vb_xv = new_xv; | ||
6233 | vb->vb_bh = value_bh; | ||
6234 | ocfs2_init_xattr_value_extent_tree(&data_et, | ||
6235 | INODE_CACHE(args->new_inode), vb); | ||
6236 | } | ||
6237 | |||
6238 | clusters = le32_to_cpu(xv->xr_clusters); | ||
6239 | cpos = 0; | ||
6240 | while (cpos < clusters) { | ||
6241 | ret = ocfs2_xattr_get_clusters(args->old_inode, | ||
6242 | cpos, | ||
6243 | &p_cluster, | ||
6244 | &num_clusters, | ||
6245 | &xv->xr_list, | ||
6246 | &ext_flags); | ||
6247 | if (ret) { | ||
6248 | mlog_errno(ret); | ||
6249 | goto out; | ||
6250 | } | ||
6251 | |||
6252 | BUG_ON(!p_cluster); | ||
6253 | |||
6254 | if (xv->xr_list.l_tree_depth) { | ||
6255 | ret = ocfs2_insert_extent(handle, | ||
6256 | &data_et, cpos, | ||
6257 | ocfs2_clusters_to_blocks( | ||
6258 | args->old_inode->i_sb, | ||
6259 | p_cluster), | ||
6260 | num_clusters, ext_flags, | ||
6261 | meta_ac); | ||
6262 | if (ret) { | ||
6263 | mlog_errno(ret); | ||
6264 | goto out; | ||
6265 | } | ||
6266 | } | ||
6267 | |||
6268 | ret = ocfs2_increase_refcount(handle, args->ref_ci, | ||
6269 | args->ref_root_bh, | ||
6270 | p_cluster, num_clusters, | ||
6271 | meta_ac, args->dealloc); | ||
6272 | if (ret) { | ||
6273 | mlog_errno(ret); | ||
6274 | goto out; | ||
6275 | } | ||
6276 | |||
6277 | cpos += num_clusters; | ||
6278 | } | ||
6279 | } | ||
6280 | |||
6281 | out: | ||
6282 | return ret; | ||
6283 | } | ||
6284 | |||
6285 | static int ocfs2_reflink_xattr_inline(struct ocfs2_xattr_reflink *args) | ||
6286 | { | ||
6287 | int ret = 0, credits = 0; | ||
6288 | handle_t *handle; | ||
6289 | struct ocfs2_super *osb = OCFS2_SB(args->old_inode->i_sb); | ||
6290 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)args->old_bh->b_data; | ||
6291 | int inline_size = le16_to_cpu(di->i_xattr_inline_size); | ||
6292 | int header_off = osb->sb->s_blocksize - inline_size; | ||
6293 | struct ocfs2_xattr_header *xh = (struct ocfs2_xattr_header *) | ||
6294 | (args->old_bh->b_data + header_off); | ||
6295 | struct ocfs2_xattr_header *new_xh = (struct ocfs2_xattr_header *) | ||
6296 | (args->new_bh->b_data + header_off); | ||
6297 | struct ocfs2_alloc_context *meta_ac = NULL; | ||
6298 | struct ocfs2_inode_info *new_oi; | ||
6299 | struct ocfs2_dinode *new_di; | ||
6300 | struct ocfs2_xattr_value_buf vb = { | ||
6301 | .vb_bh = args->new_bh, | ||
6302 | .vb_access = ocfs2_journal_access_di, | ||
6303 | }; | ||
6304 | |||
6305 | ret = ocfs2_reflink_lock_xattr_allocators(osb, xh, args->ref_root_bh, | ||
6306 | &credits, &meta_ac); | ||
6307 | if (ret) { | ||
6308 | mlog_errno(ret); | ||
6309 | goto out; | ||
6310 | } | ||
6311 | |||
6312 | handle = ocfs2_start_trans(osb, credits); | ||
6313 | if (IS_ERR(handle)) { | ||
6314 | ret = PTR_ERR(handle); | ||
6315 | mlog_errno(ret); | ||
6316 | goto out; | ||
6317 | } | ||
6318 | |||
6319 | ret = ocfs2_journal_access_di(handle, INODE_CACHE(args->new_inode), | ||
6320 | args->new_bh, OCFS2_JOURNAL_ACCESS_WRITE); | ||
6321 | if (ret) { | ||
6322 | mlog_errno(ret); | ||
6323 | goto out_commit; | ||
6324 | } | ||
6325 | |||
6326 | memcpy(args->new_bh->b_data + header_off, | ||
6327 | args->old_bh->b_data + header_off, inline_size); | ||
6328 | |||
6329 | new_di = (struct ocfs2_dinode *)args->new_bh->b_data; | ||
6330 | new_di->i_xattr_inline_size = cpu_to_le16(inline_size); | ||
6331 | |||
6332 | ret = ocfs2_reflink_xattr_header(handle, args, args->old_bh, xh, | ||
6333 | args->new_bh, new_xh, &vb, meta_ac, | ||
6334 | ocfs2_get_xattr_value_root, NULL); | ||
6335 | if (ret) { | ||
6336 | mlog_errno(ret); | ||
6337 | goto out_commit; | ||
6338 | } | ||
6339 | |||
6340 | new_oi = OCFS2_I(args->new_inode); | ||
6341 | spin_lock(&new_oi->ip_lock); | ||
6342 | new_oi->ip_dyn_features |= OCFS2_HAS_XATTR_FL | OCFS2_INLINE_XATTR_FL; | ||
6343 | new_di->i_dyn_features = cpu_to_le16(new_oi->ip_dyn_features); | ||
6344 | spin_unlock(&new_oi->ip_lock); | ||
6345 | |||
6346 | ocfs2_journal_dirty(handle, args->new_bh); | ||
6347 | |||
6348 | out_commit: | ||
6349 | ocfs2_commit_trans(osb, handle); | ||
6350 | |||
6351 | out: | ||
6352 | if (meta_ac) | ||
6353 | ocfs2_free_alloc_context(meta_ac); | ||
6354 | return ret; | ||
6355 | } | ||
6356 | |||
6357 | static int ocfs2_create_empty_xattr_block(struct inode *inode, | ||
6358 | struct buffer_head *fe_bh, | ||
6359 | struct buffer_head **ret_bh, | ||
6360 | int indexed) | ||
6361 | { | ||
6362 | int ret; | ||
6363 | handle_t *handle; | ||
6364 | struct ocfs2_alloc_context *meta_ac; | ||
6365 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
6366 | |||
6367 | ret = ocfs2_reserve_new_metadata_blocks(osb, 1, &meta_ac); | ||
6368 | if (ret < 0) { | ||
6369 | mlog_errno(ret); | ||
6370 | return ret; | ||
6371 | } | ||
6372 | |||
6373 | handle = ocfs2_start_trans(osb, OCFS2_XATTR_BLOCK_CREATE_CREDITS); | ||
6374 | if (IS_ERR(handle)) { | ||
6375 | ret = PTR_ERR(handle); | ||
6376 | mlog_errno(ret); | ||
6377 | goto out; | ||
6378 | } | ||
6379 | |||
6380 | mlog(0, "create new xattr block for inode %llu, index = %d\n", | ||
6381 | (unsigned long long)fe_bh->b_blocknr, indexed); | ||
6382 | ret = ocfs2_create_xattr_block(handle, inode, fe_bh, | ||
6383 | meta_ac, ret_bh, indexed); | ||
6384 | if (ret) | ||
6385 | mlog_errno(ret); | ||
6386 | |||
6387 | ocfs2_commit_trans(osb, handle); | ||
6388 | out: | ||
6389 | ocfs2_free_alloc_context(meta_ac); | ||
6390 | return ret; | ||
6391 | } | ||
6392 | |||
6393 | static int ocfs2_reflink_xattr_block(struct ocfs2_xattr_reflink *args, | ||
6394 | struct buffer_head *blk_bh, | ||
6395 | struct buffer_head *new_blk_bh) | ||
6396 | { | ||
6397 | int ret = 0, credits = 0; | ||
6398 | handle_t *handle; | ||
6399 | struct ocfs2_inode_info *new_oi = OCFS2_I(args->new_inode); | ||
6400 | struct ocfs2_dinode *new_di; | ||
6401 | struct ocfs2_super *osb = OCFS2_SB(args->new_inode->i_sb); | ||
6402 | int header_off = offsetof(struct ocfs2_xattr_block, xb_attrs.xb_header); | ||
6403 | struct ocfs2_xattr_block *xb = | ||
6404 | (struct ocfs2_xattr_block *)blk_bh->b_data; | ||
6405 | struct ocfs2_xattr_header *xh = &xb->xb_attrs.xb_header; | ||
6406 | struct ocfs2_xattr_block *new_xb = | ||
6407 | (struct ocfs2_xattr_block *)new_blk_bh->b_data; | ||
6408 | struct ocfs2_xattr_header *new_xh = &new_xb->xb_attrs.xb_header; | ||
6409 | struct ocfs2_alloc_context *meta_ac; | ||
6410 | struct ocfs2_xattr_value_buf vb = { | ||
6411 | .vb_bh = new_blk_bh, | ||
6412 | .vb_access = ocfs2_journal_access_xb, | ||
6413 | }; | ||
6414 | |||
6415 | ret = ocfs2_reflink_lock_xattr_allocators(osb, xh, args->ref_root_bh, | ||
6416 | &credits, &meta_ac); | ||
6417 | if (ret) { | ||
6418 | mlog_errno(ret); | ||
6419 | return ret; | ||
6420 | } | ||
6421 | |||
6422 | /* One more credits in case we need to add xattr flags in new inode. */ | ||
6423 | handle = ocfs2_start_trans(osb, credits + 1); | ||
6424 | if (IS_ERR(handle)) { | ||
6425 | ret = PTR_ERR(handle); | ||
6426 | mlog_errno(ret); | ||
6427 | goto out; | ||
6428 | } | ||
6429 | |||
6430 | if (!(new_oi->ip_dyn_features & OCFS2_HAS_XATTR_FL)) { | ||
6431 | ret = ocfs2_journal_access_di(handle, | ||
6432 | INODE_CACHE(args->new_inode), | ||
6433 | args->new_bh, | ||
6434 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
6435 | if (ret) { | ||
6436 | mlog_errno(ret); | ||
6437 | goto out_commit; | ||
6438 | } | ||
6439 | } | ||
6440 | |||
6441 | ret = ocfs2_journal_access_xb(handle, INODE_CACHE(args->new_inode), | ||
6442 | new_blk_bh, OCFS2_JOURNAL_ACCESS_WRITE); | ||
6443 | if (ret) { | ||
6444 | mlog_errno(ret); | ||
6445 | goto out_commit; | ||
6446 | } | ||
6447 | |||
6448 | memcpy(new_blk_bh->b_data + header_off, blk_bh->b_data + header_off, | ||
6449 | osb->sb->s_blocksize - header_off); | ||
6450 | |||
6451 | ret = ocfs2_reflink_xattr_header(handle, args, blk_bh, xh, | ||
6452 | new_blk_bh, new_xh, &vb, meta_ac, | ||
6453 | ocfs2_get_xattr_value_root, NULL); | ||
6454 | if (ret) { | ||
6455 | mlog_errno(ret); | ||
6456 | goto out_commit; | ||
6457 | } | ||
6458 | |||
6459 | ocfs2_journal_dirty(handle, new_blk_bh); | ||
6460 | |||
6461 | if (!(new_oi->ip_dyn_features & OCFS2_HAS_XATTR_FL)) { | ||
6462 | new_di = (struct ocfs2_dinode *)args->new_bh->b_data; | ||
6463 | spin_lock(&new_oi->ip_lock); | ||
6464 | new_oi->ip_dyn_features |= OCFS2_HAS_XATTR_FL; | ||
6465 | new_di->i_dyn_features = cpu_to_le16(new_oi->ip_dyn_features); | ||
6466 | spin_unlock(&new_oi->ip_lock); | ||
6467 | |||
6468 | ocfs2_journal_dirty(handle, args->new_bh); | ||
6469 | } | ||
6470 | |||
6471 | out_commit: | ||
6472 | ocfs2_commit_trans(osb, handle); | ||
6473 | |||
6474 | out: | ||
6475 | ocfs2_free_alloc_context(meta_ac); | ||
6476 | return ret; | ||
6477 | } | ||
6478 | |||
6479 | struct ocfs2_reflink_xattr_tree_args { | ||
6480 | struct ocfs2_xattr_reflink *reflink; | ||
6481 | struct buffer_head *old_blk_bh; | ||
6482 | struct buffer_head *new_blk_bh; | ||
6483 | struct ocfs2_xattr_bucket *old_bucket; | ||
6484 | struct ocfs2_xattr_bucket *new_bucket; | ||
6485 | }; | ||
6486 | |||
6487 | /* | ||
6488 | * NOTE: | ||
6489 | * We have to handle the case that both old bucket and new bucket | ||
6490 | * will call this function to get the right ret_bh. | ||
6491 | * So The caller must give us the right bh. | ||
6492 | */ | ||
6493 | static int ocfs2_get_reflink_xattr_value_root(struct super_block *sb, | ||
6494 | struct buffer_head *bh, | ||
6495 | struct ocfs2_xattr_header *xh, | ||
6496 | int offset, | ||
6497 | struct ocfs2_xattr_value_root **xv, | ||
6498 | struct buffer_head **ret_bh, | ||
6499 | void *para) | ||
6500 | { | ||
6501 | struct ocfs2_reflink_xattr_tree_args *args = | ||
6502 | (struct ocfs2_reflink_xattr_tree_args *)para; | ||
6503 | struct ocfs2_xattr_bucket *bucket; | ||
6504 | |||
6505 | if (bh == args->old_bucket->bu_bhs[0]) | ||
6506 | bucket = args->old_bucket; | ||
6507 | else | ||
6508 | bucket = args->new_bucket; | ||
6509 | |||
6510 | return ocfs2_get_xattr_tree_value_root(sb, bucket, offset, | ||
6511 | xv, ret_bh); | ||
6512 | } | ||
6513 | |||
6514 | struct ocfs2_value_tree_metas { | ||
6515 | int num_metas; | ||
6516 | int credits; | ||
6517 | int num_recs; | ||
6518 | }; | ||
6519 | |||
6520 | static int ocfs2_value_tree_metas_in_bucket(struct super_block *sb, | ||
6521 | struct buffer_head *bh, | ||
6522 | struct ocfs2_xattr_header *xh, | ||
6523 | int offset, | ||
6524 | struct ocfs2_xattr_value_root **xv, | ||
6525 | struct buffer_head **ret_bh, | ||
6526 | void *para) | ||
6527 | { | ||
6528 | struct ocfs2_xattr_bucket *bucket = | ||
6529 | (struct ocfs2_xattr_bucket *)para; | ||
6530 | |||
6531 | return ocfs2_get_xattr_tree_value_root(sb, bucket, offset, | ||
6532 | xv, ret_bh); | ||
6533 | } | ||
6534 | |||
6535 | static int ocfs2_calc_value_tree_metas(struct inode *inode, | ||
6536 | struct ocfs2_xattr_bucket *bucket, | ||
6537 | void *para) | ||
6538 | { | ||
6539 | struct ocfs2_value_tree_metas *metas = | ||
6540 | (struct ocfs2_value_tree_metas *)para; | ||
6541 | struct ocfs2_xattr_header *xh = | ||
6542 | (struct ocfs2_xattr_header *)bucket->bu_bhs[0]->b_data; | ||
6543 | |||
6544 | /* Add the credits for this bucket first. */ | ||
6545 | metas->credits += bucket->bu_blocks; | ||
6546 | return ocfs2_value_metas_in_xattr_header(inode->i_sb, bucket->bu_bhs[0], | ||
6547 | xh, &metas->num_metas, | ||
6548 | &metas->credits, &metas->num_recs, | ||
6549 | ocfs2_value_tree_metas_in_bucket, | ||
6550 | bucket); | ||
6551 | } | ||
6552 | |||
6553 | /* | ||
6554 | * Given a xattr extent rec starting from blkno and having len clusters, | ||
6555 | * iterate all the buckets calculate how much metadata we need for reflinking | ||
6556 | * all the ocfs2_xattr_value_root and lock the allocators accordingly. | ||
6557 | */ | ||
6558 | static int ocfs2_lock_reflink_xattr_rec_allocators( | ||
6559 | struct ocfs2_reflink_xattr_tree_args *args, | ||
6560 | struct ocfs2_extent_tree *xt_et, | ||
6561 | u64 blkno, u32 len, int *credits, | ||
6562 | struct ocfs2_alloc_context **meta_ac, | ||
6563 | struct ocfs2_alloc_context **data_ac) | ||
6564 | { | ||
6565 | int ret, num_free_extents; | ||
6566 | struct ocfs2_value_tree_metas metas; | ||
6567 | struct ocfs2_super *osb = OCFS2_SB(args->reflink->old_inode->i_sb); | ||
6568 | struct ocfs2_refcount_block *rb; | ||
6569 | |||
6570 | memset(&metas, 0, sizeof(metas)); | ||
6571 | |||
6572 | ret = ocfs2_iterate_xattr_buckets(args->reflink->old_inode, blkno, len, | ||
6573 | ocfs2_calc_value_tree_metas, &metas); | ||
6574 | if (ret) { | ||
6575 | mlog_errno(ret); | ||
6576 | goto out; | ||
6577 | } | ||
6578 | |||
6579 | *credits = metas.credits; | ||
6580 | |||
6581 | /* | ||
6582 | * Calculate we need for refcount tree change. | ||
6583 | * | ||
6584 | * We need to add/modify num_recs in refcount tree, so just calculate | ||
6585 | * an approximate number we need for refcount tree change. | ||
6586 | * Sometimes we need to split the tree, and after split, half recs | ||
6587 | * will be moved to the new block, and a new block can only provide | ||
6588 | * half number of recs. So we multiple new blocks by 2. | ||
6589 | * In the end, we have to add credits for modifying the already | ||
6590 | * existed refcount block. | ||
6591 | */ | ||
6592 | rb = (struct ocfs2_refcount_block *)args->reflink->ref_root_bh->b_data; | ||
6593 | metas.num_recs = | ||
6594 | (metas.num_recs + ocfs2_refcount_recs_per_rb(osb->sb) - 1) / | ||
6595 | ocfs2_refcount_recs_per_rb(osb->sb) * 2; | ||
6596 | metas.num_metas += metas.num_recs; | ||
6597 | *credits += metas.num_recs + | ||
6598 | metas.num_recs * OCFS2_EXPAND_REFCOUNT_TREE_CREDITS; | ||
6599 | if (le32_to_cpu(rb->rf_flags) & OCFS2_REFCOUNT_TREE_FL) | ||
6600 | *credits += le16_to_cpu(rb->rf_list.l_tree_depth) * | ||
6601 | le16_to_cpu(rb->rf_list.l_next_free_rec) + 1; | ||
6602 | else | ||
6603 | *credits += 1; | ||
6604 | |||
6605 | /* count in the xattr tree change. */ | ||
6606 | num_free_extents = ocfs2_num_free_extents(osb, xt_et); | ||
6607 | if (num_free_extents < 0) { | ||
6608 | ret = num_free_extents; | ||
6609 | mlog_errno(ret); | ||
6610 | goto out; | ||
6611 | } | ||
6612 | |||
6613 | if (num_free_extents < len) | ||
6614 | metas.num_metas += ocfs2_extend_meta_needed(xt_et->et_root_el); | ||
6615 | |||
6616 | *credits += ocfs2_calc_extend_credits(osb->sb, | ||
6617 | xt_et->et_root_el, len); | ||
6618 | |||
6619 | if (metas.num_metas) { | ||
6620 | ret = ocfs2_reserve_new_metadata_blocks(osb, metas.num_metas, | ||
6621 | meta_ac); | ||
5286 | if (ret) { | 6622 | if (ret) { |
5287 | mlog_errno(ret); | 6623 | mlog_errno(ret); |
5288 | goto out; | 6624 | goto out; |
5289 | } | 6625 | } |
6626 | } | ||
5290 | 6627 | ||
5291 | ret = ocfs2_rm_xattr_cluster(inode, xb_bh, | 6628 | if (len) { |
5292 | p_blkno, e_cpos, num_clusters); | 6629 | ret = ocfs2_reserve_clusters(osb, len, data_ac); |
6630 | if (ret) | ||
6631 | mlog_errno(ret); | ||
6632 | } | ||
6633 | out: | ||
6634 | if (ret) { | ||
6635 | if (*meta_ac) { | ||
6636 | ocfs2_free_alloc_context(*meta_ac); | ||
6637 | meta_ac = NULL; | ||
6638 | } | ||
6639 | } | ||
6640 | |||
6641 | return ret; | ||
6642 | } | ||
6643 | |||
6644 | static int ocfs2_reflink_xattr_buckets(handle_t *handle, | ||
6645 | u64 blkno, u64 new_blkno, u32 clusters, | ||
6646 | struct ocfs2_alloc_context *meta_ac, | ||
6647 | struct ocfs2_alloc_context *data_ac, | ||
6648 | struct ocfs2_reflink_xattr_tree_args *args) | ||
6649 | { | ||
6650 | int i, j, ret = 0; | ||
6651 | struct super_block *sb = args->reflink->old_inode->i_sb; | ||
6652 | u32 bpc = ocfs2_xattr_buckets_per_cluster(OCFS2_SB(sb)); | ||
6653 | u32 num_buckets = clusters * bpc; | ||
6654 | int bpb = args->old_bucket->bu_blocks; | ||
6655 | struct ocfs2_xattr_value_buf vb = { | ||
6656 | .vb_access = ocfs2_journal_access, | ||
6657 | }; | ||
6658 | |||
6659 | for (i = 0; i < num_buckets; i++, blkno += bpb, new_blkno += bpb) { | ||
6660 | ret = ocfs2_read_xattr_bucket(args->old_bucket, blkno); | ||
5293 | if (ret) { | 6661 | if (ret) { |
5294 | mlog_errno(ret); | 6662 | mlog_errno(ret); |
5295 | break; | 6663 | break; |
5296 | } | 6664 | } |
5297 | 6665 | ||
5298 | if (e_cpos == 0) | 6666 | ret = ocfs2_init_xattr_bucket(args->new_bucket, new_blkno); |
6667 | if (ret) { | ||
6668 | mlog_errno(ret); | ||
5299 | break; | 6669 | break; |
6670 | } | ||
5300 | 6671 | ||
5301 | name_hash = e_cpos - 1; | 6672 | /* |
6673 | * The real bucket num in this series of blocks is stored | ||
6674 | * in the 1st bucket. | ||
6675 | */ | ||
6676 | if (i == 0) | ||
6677 | num_buckets = le16_to_cpu( | ||
6678 | bucket_xh(args->old_bucket)->xh_num_buckets); | ||
6679 | |||
6680 | ret = ocfs2_xattr_bucket_journal_access(handle, | ||
6681 | args->new_bucket, | ||
6682 | OCFS2_JOURNAL_ACCESS_CREATE); | ||
6683 | if (ret) { | ||
6684 | mlog_errno(ret); | ||
6685 | break; | ||
6686 | } | ||
6687 | |||
6688 | for (j = 0; j < bpb; j++) | ||
6689 | memcpy(bucket_block(args->new_bucket, j), | ||
6690 | bucket_block(args->old_bucket, j), | ||
6691 | sb->s_blocksize); | ||
6692 | |||
6693 | ocfs2_xattr_bucket_journal_dirty(handle, args->new_bucket); | ||
6694 | |||
6695 | ret = ocfs2_reflink_xattr_header(handle, args->reflink, | ||
6696 | args->old_bucket->bu_bhs[0], | ||
6697 | bucket_xh(args->old_bucket), | ||
6698 | args->new_bucket->bu_bhs[0], | ||
6699 | bucket_xh(args->new_bucket), | ||
6700 | &vb, meta_ac, | ||
6701 | ocfs2_get_reflink_xattr_value_root, | ||
6702 | args); | ||
6703 | if (ret) { | ||
6704 | mlog_errno(ret); | ||
6705 | break; | ||
6706 | } | ||
6707 | |||
6708 | /* | ||
6709 | * Re-access and dirty the bucket to calculate metaecc. | ||
6710 | * Because we may extend the transaction in reflink_xattr_header | ||
6711 | * which will let the already accessed block gone. | ||
6712 | */ | ||
6713 | ret = ocfs2_xattr_bucket_journal_access(handle, | ||
6714 | args->new_bucket, | ||
6715 | OCFS2_JOURNAL_ACCESS_WRITE); | ||
6716 | if (ret) { | ||
6717 | mlog_errno(ret); | ||
6718 | break; | ||
6719 | } | ||
6720 | |||
6721 | ocfs2_xattr_bucket_journal_dirty(handle, args->new_bucket); | ||
6722 | ocfs2_xattr_bucket_relse(args->old_bucket); | ||
6723 | ocfs2_xattr_bucket_relse(args->new_bucket); | ||
6724 | } | ||
6725 | |||
6726 | ocfs2_xattr_bucket_relse(args->old_bucket); | ||
6727 | ocfs2_xattr_bucket_relse(args->new_bucket); | ||
6728 | return ret; | ||
6729 | } | ||
6730 | /* | ||
6731 | * Create the same xattr extent record in the new inode's xattr tree. | ||
6732 | */ | ||
6733 | static int ocfs2_reflink_xattr_rec(struct inode *inode, | ||
6734 | struct buffer_head *root_bh, | ||
6735 | u64 blkno, | ||
6736 | u32 cpos, | ||
6737 | u32 len, | ||
6738 | void *para) | ||
6739 | { | ||
6740 | int ret, credits = 0; | ||
6741 | u32 p_cluster, num_clusters; | ||
6742 | u64 new_blkno; | ||
6743 | handle_t *handle; | ||
6744 | struct ocfs2_reflink_xattr_tree_args *args = | ||
6745 | (struct ocfs2_reflink_xattr_tree_args *)para; | ||
6746 | struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); | ||
6747 | struct ocfs2_alloc_context *meta_ac = NULL; | ||
6748 | struct ocfs2_alloc_context *data_ac = NULL; | ||
6749 | struct ocfs2_extent_tree et; | ||
6750 | |||
6751 | ocfs2_init_xattr_tree_extent_tree(&et, | ||
6752 | INODE_CACHE(args->reflink->new_inode), | ||
6753 | args->new_blk_bh); | ||
6754 | |||
6755 | ret = ocfs2_lock_reflink_xattr_rec_allocators(args, &et, blkno, | ||
6756 | len, &credits, | ||
6757 | &meta_ac, &data_ac); | ||
6758 | if (ret) { | ||
6759 | mlog_errno(ret); | ||
6760 | goto out; | ||
6761 | } | ||
6762 | |||
6763 | handle = ocfs2_start_trans(osb, credits); | ||
6764 | if (IS_ERR(handle)) { | ||
6765 | ret = PTR_ERR(handle); | ||
6766 | mlog_errno(ret); | ||
6767 | goto out; | ||
6768 | } | ||
6769 | |||
6770 | ret = ocfs2_claim_clusters(osb, handle, data_ac, | ||
6771 | len, &p_cluster, &num_clusters); | ||
6772 | if (ret) { | ||
6773 | mlog_errno(ret); | ||
6774 | goto out_commit; | ||
6775 | } | ||
6776 | |||
6777 | new_blkno = ocfs2_clusters_to_blocks(osb->sb, p_cluster); | ||
6778 | |||
6779 | mlog(0, "reflink xattr buckets %llu to %llu, len %u\n", | ||
6780 | (unsigned long long)blkno, (unsigned long long)new_blkno, len); | ||
6781 | ret = ocfs2_reflink_xattr_buckets(handle, blkno, new_blkno, len, | ||
6782 | meta_ac, data_ac, args); | ||
6783 | if (ret) { | ||
6784 | mlog_errno(ret); | ||
6785 | goto out_commit; | ||
6786 | } | ||
6787 | |||
6788 | mlog(0, "insert new xattr extent rec start %llu len %u to %u\n", | ||
6789 | (unsigned long long)new_blkno, len, cpos); | ||
6790 | ret = ocfs2_insert_extent(handle, &et, cpos, new_blkno, | ||
6791 | len, 0, meta_ac); | ||
6792 | if (ret) | ||
6793 | mlog_errno(ret); | ||
6794 | |||
6795 | out_commit: | ||
6796 | ocfs2_commit_trans(osb, handle); | ||
6797 | |||
6798 | out: | ||
6799 | if (meta_ac) | ||
6800 | ocfs2_free_alloc_context(meta_ac); | ||
6801 | if (data_ac) | ||
6802 | ocfs2_free_alloc_context(data_ac); | ||
6803 | return ret; | ||
6804 | } | ||
6805 | |||
6806 | /* | ||
6807 | * Create reflinked xattr buckets. | ||
6808 | * We will add bucket one by one, and refcount all the xattrs in the bucket | ||
6809 | * if they are stored outside. | ||
6810 | */ | ||
6811 | static int ocfs2_reflink_xattr_tree(struct ocfs2_xattr_reflink *args, | ||
6812 | struct buffer_head *blk_bh, | ||
6813 | struct buffer_head *new_blk_bh) | ||
6814 | { | ||
6815 | int ret; | ||
6816 | struct ocfs2_reflink_xattr_tree_args para; | ||
6817 | |||
6818 | memset(¶, 0, sizeof(para)); | ||
6819 | para.reflink = args; | ||
6820 | para.old_blk_bh = blk_bh; | ||
6821 | para.new_blk_bh = new_blk_bh; | ||
6822 | |||
6823 | para.old_bucket = ocfs2_xattr_bucket_new(args->old_inode); | ||
6824 | if (!para.old_bucket) { | ||
6825 | mlog_errno(-ENOMEM); | ||
6826 | return -ENOMEM; | ||
6827 | } | ||
6828 | |||
6829 | para.new_bucket = ocfs2_xattr_bucket_new(args->new_inode); | ||
6830 | if (!para.new_bucket) { | ||
6831 | ret = -ENOMEM; | ||
6832 | mlog_errno(ret); | ||
6833 | goto out; | ||
6834 | } | ||
6835 | |||
6836 | ret = ocfs2_iterate_xattr_index_block(args->old_inode, blk_bh, | ||
6837 | ocfs2_reflink_xattr_rec, | ||
6838 | ¶); | ||
6839 | if (ret) | ||
6840 | mlog_errno(ret); | ||
6841 | |||
6842 | out: | ||
6843 | ocfs2_xattr_bucket_free(para.old_bucket); | ||
6844 | ocfs2_xattr_bucket_free(para.new_bucket); | ||
6845 | return ret; | ||
6846 | } | ||
6847 | |||
6848 | static int ocfs2_reflink_xattr_in_block(struct ocfs2_xattr_reflink *args, | ||
6849 | struct buffer_head *blk_bh) | ||
6850 | { | ||
6851 | int ret, indexed = 0; | ||
6852 | struct buffer_head *new_blk_bh = NULL; | ||
6853 | struct ocfs2_xattr_block *xb = | ||
6854 | (struct ocfs2_xattr_block *)blk_bh->b_data; | ||
6855 | |||
6856 | |||
6857 | if (le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED) | ||
6858 | indexed = 1; | ||
6859 | |||
6860 | ret = ocfs2_create_empty_xattr_block(args->new_inode, args->new_bh, | ||
6861 | &new_blk_bh, indexed); | ||
6862 | if (ret) { | ||
6863 | mlog_errno(ret); | ||
6864 | goto out; | ||
6865 | } | ||
6866 | |||
6867 | if (!(le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED)) | ||
6868 | ret = ocfs2_reflink_xattr_block(args, blk_bh, new_blk_bh); | ||
6869 | else | ||
6870 | ret = ocfs2_reflink_xattr_tree(args, blk_bh, new_blk_bh); | ||
6871 | if (ret) | ||
6872 | mlog_errno(ret); | ||
6873 | |||
6874 | out: | ||
6875 | brelse(new_blk_bh); | ||
6876 | return ret; | ||
6877 | } | ||
6878 | |||
6879 | static int ocfs2_reflink_xattr_no_security(struct ocfs2_xattr_entry *xe) | ||
6880 | { | ||
6881 | int type = ocfs2_xattr_get_type(xe); | ||
6882 | |||
6883 | return type != OCFS2_XATTR_INDEX_SECURITY && | ||
6884 | type != OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS && | ||
6885 | type != OCFS2_XATTR_INDEX_POSIX_ACL_DEFAULT; | ||
6886 | } | ||
6887 | |||
6888 | int ocfs2_reflink_xattrs(struct inode *old_inode, | ||
6889 | struct buffer_head *old_bh, | ||
6890 | struct inode *new_inode, | ||
6891 | struct buffer_head *new_bh, | ||
6892 | bool preserve_security) | ||
6893 | { | ||
6894 | int ret; | ||
6895 | struct ocfs2_xattr_reflink args; | ||
6896 | struct ocfs2_inode_info *oi = OCFS2_I(old_inode); | ||
6897 | struct ocfs2_dinode *di = (struct ocfs2_dinode *)old_bh->b_data; | ||
6898 | struct buffer_head *blk_bh = NULL; | ||
6899 | struct ocfs2_cached_dealloc_ctxt dealloc; | ||
6900 | struct ocfs2_refcount_tree *ref_tree; | ||
6901 | struct buffer_head *ref_root_bh = NULL; | ||
6902 | |||
6903 | ret = ocfs2_lock_refcount_tree(OCFS2_SB(old_inode->i_sb), | ||
6904 | le64_to_cpu(di->i_refcount_loc), | ||
6905 | 1, &ref_tree, &ref_root_bh); | ||
6906 | if (ret) { | ||
6907 | mlog_errno(ret); | ||
6908 | goto out; | ||
6909 | } | ||
6910 | |||
6911 | ocfs2_init_dealloc_ctxt(&dealloc); | ||
6912 | |||
6913 | args.old_inode = old_inode; | ||
6914 | args.new_inode = new_inode; | ||
6915 | args.old_bh = old_bh; | ||
6916 | args.new_bh = new_bh; | ||
6917 | args.ref_ci = &ref_tree->rf_ci; | ||
6918 | args.ref_root_bh = ref_root_bh; | ||
6919 | args.dealloc = &dealloc; | ||
6920 | if (preserve_security) | ||
6921 | args.xattr_reflinked = NULL; | ||
6922 | else | ||
6923 | args.xattr_reflinked = ocfs2_reflink_xattr_no_security; | ||
6924 | |||
6925 | if (oi->ip_dyn_features & OCFS2_INLINE_XATTR_FL) { | ||
6926 | ret = ocfs2_reflink_xattr_inline(&args); | ||
6927 | if (ret) { | ||
6928 | mlog_errno(ret); | ||
6929 | goto out_unlock; | ||
6930 | } | ||
6931 | } | ||
6932 | |||
6933 | if (!di->i_xattr_loc) | ||
6934 | goto out_unlock; | ||
6935 | |||
6936 | ret = ocfs2_read_xattr_block(old_inode, le64_to_cpu(di->i_xattr_loc), | ||
6937 | &blk_bh); | ||
6938 | if (ret < 0) { | ||
6939 | mlog_errno(ret); | ||
6940 | goto out_unlock; | ||
6941 | } | ||
6942 | |||
6943 | ret = ocfs2_reflink_xattr_in_block(&args, blk_bh); | ||
6944 | if (ret) | ||
6945 | mlog_errno(ret); | ||
6946 | |||
6947 | brelse(blk_bh); | ||
6948 | |||
6949 | out_unlock: | ||
6950 | ocfs2_unlock_refcount_tree(OCFS2_SB(old_inode->i_sb), | ||
6951 | ref_tree, 1); | ||
6952 | brelse(ref_root_bh); | ||
6953 | |||
6954 | if (ocfs2_dealloc_has_cluster(&dealloc)) { | ||
6955 | ocfs2_schedule_truncate_log_flush(OCFS2_SB(old_inode->i_sb), 1); | ||
6956 | ocfs2_run_deallocs(OCFS2_SB(old_inode->i_sb), &dealloc); | ||
5302 | } | 6957 | } |
5303 | 6958 | ||
5304 | out: | 6959 | out: |
@@ -5306,6 +6961,51 @@ out: | |||
5306 | } | 6961 | } |
5307 | 6962 | ||
5308 | /* | 6963 | /* |
6964 | * Initialize security and acl for a already created inode. | ||
6965 | * Used for reflink a non-preserve-security file. | ||
6966 | * | ||
6967 | * It uses common api like ocfs2_xattr_set, so the caller | ||
6968 | * must not hold any lock expect i_mutex. | ||
6969 | */ | ||
6970 | int ocfs2_init_security_and_acl(struct inode *dir, | ||
6971 | struct inode *inode) | ||
6972 | { | ||
6973 | int ret = 0; | ||
6974 | struct buffer_head *dir_bh = NULL; | ||
6975 | struct ocfs2_security_xattr_info si = { | ||
6976 | .enable = 1, | ||
6977 | }; | ||
6978 | |||
6979 | ret = ocfs2_init_security_get(inode, dir, &si); | ||
6980 | if (!ret) { | ||
6981 | ret = ocfs2_xattr_security_set(inode, si.name, | ||
6982 | si.value, si.value_len, | ||
6983 | XATTR_CREATE); | ||
6984 | if (ret) { | ||
6985 | mlog_errno(ret); | ||
6986 | goto leave; | ||
6987 | } | ||
6988 | } else if (ret != -EOPNOTSUPP) { | ||
6989 | mlog_errno(ret); | ||
6990 | goto leave; | ||
6991 | } | ||
6992 | |||
6993 | ret = ocfs2_inode_lock(dir, &dir_bh, 0); | ||
6994 | if (ret) { | ||
6995 | mlog_errno(ret); | ||
6996 | goto leave; | ||
6997 | } | ||
6998 | |||
6999 | ret = ocfs2_init_acl(NULL, inode, dir, NULL, dir_bh, NULL, NULL); | ||
7000 | if (ret) | ||
7001 | mlog_errno(ret); | ||
7002 | |||
7003 | ocfs2_inode_unlock(dir, 0); | ||
7004 | brelse(dir_bh); | ||
7005 | leave: | ||
7006 | return ret; | ||
7007 | } | ||
7008 | /* | ||
5309 | * 'security' attributes support | 7009 | * 'security' attributes support |
5310 | */ | 7010 | */ |
5311 | static size_t ocfs2_xattr_security_list(struct inode *inode, char *list, | 7011 | static size_t ocfs2_xattr_security_list(struct inode *inode, char *list, |