diff options
author | Tao Ma <tao.ma@oracle.com> | 2008-08-18 05:38:54 -0400 |
---|---|---|
committer | Mark Fasheh <mfasheh@suse.com> | 2008-10-13 19:57:03 -0400 |
commit | a394425643e1e9c3a624d629fc8ba5633d8474c6 (patch) | |
tree | bf7ae7087452f22530448070cbccee921ba985ef | |
parent | 012255961c9ecfe22b7a1df47ac26ab37818cb1e (diff) |
ocfs2: Delete all xattr buckets during inode removal
In inode removal, we need to iterate all the buckets, remove any
externally-stored EA values and delete the xattr buckets.
Signed-off-by: Tao Ma <tao.ma@oracle.com>
Signed-off-by: Mark Fasheh <mfasheh@suse.com>
-rw-r--r-- | fs/ocfs2/xattr.c | 84 |
1 files changed, 80 insertions, 4 deletions
diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c index 5e8fae948882..9ec7136b3ad7 100644 --- a/fs/ocfs2/xattr.c +++ b/fs/ocfs2/xattr.c | |||
@@ -131,6 +131,9 @@ static int ocfs2_xattr_set_entry_index_block(struct inode *inode, | |||
131 | struct ocfs2_xattr_info *xi, | 131 | struct ocfs2_xattr_info *xi, |
132 | struct ocfs2_xattr_search *xs); | 132 | struct ocfs2_xattr_search *xs); |
133 | 133 | ||
134 | static int ocfs2_delete_xattr_index_block(struct inode *inode, | ||
135 | struct buffer_head *xb_bh); | ||
136 | |||
134 | static inline struct xattr_handler *ocfs2_xattr_handler(int name_index) | 137 | static inline struct xattr_handler *ocfs2_xattr_handler(int name_index) |
135 | { | 138 | { |
136 | struct xattr_handler *handler = NULL; | 139 | struct xattr_handler *handler = NULL; |
@@ -1511,13 +1514,14 @@ static int ocfs2_xattr_block_remove(struct inode *inode, | |||
1511 | struct buffer_head *blk_bh) | 1514 | struct buffer_head *blk_bh) |
1512 | { | 1515 | { |
1513 | struct ocfs2_xattr_block *xb; | 1516 | struct ocfs2_xattr_block *xb; |
1514 | struct ocfs2_xattr_header *header; | ||
1515 | int ret = 0; | 1517 | int ret = 0; |
1516 | 1518 | ||
1517 | xb = (struct ocfs2_xattr_block *)blk_bh->b_data; | 1519 | xb = (struct ocfs2_xattr_block *)blk_bh->b_data; |
1518 | header = &(xb->xb_attrs.xb_header); | 1520 | if (!(le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED)) { |
1519 | 1521 | struct ocfs2_xattr_header *header = &(xb->xb_attrs.xb_header); | |
1520 | ret = ocfs2_remove_value_outside(inode, blk_bh, header); | 1522 | ret = ocfs2_remove_value_outside(inode, blk_bh, header); |
1523 | } else | ||
1524 | ret = ocfs2_delete_xattr_index_block(inode, blk_bh); | ||
1521 | 1525 | ||
1522 | return ret; | 1526 | return ret; |
1523 | } | 1527 | } |
@@ -4738,3 +4742,75 @@ out: | |||
4738 | mlog_exit(ret); | 4742 | mlog_exit(ret); |
4739 | return ret; | 4743 | return ret; |
4740 | } | 4744 | } |
4745 | |||
4746 | static int ocfs2_delete_xattr_in_bucket(struct inode *inode, | ||
4747 | struct ocfs2_xattr_bucket *bucket, | ||
4748 | void *para) | ||
4749 | { | ||
4750 | int ret = 0; | ||
4751 | struct ocfs2_xattr_header *xh = bucket->xh; | ||
4752 | u16 i; | ||
4753 | struct ocfs2_xattr_entry *xe; | ||
4754 | |||
4755 | for (i = 0; i < le16_to_cpu(xh->xh_count); i++) { | ||
4756 | xe = &xh->xh_entries[i]; | ||
4757 | if (ocfs2_xattr_is_local(xe)) | ||
4758 | continue; | ||
4759 | |||
4760 | ret = ocfs2_xattr_bucket_value_truncate(inode, | ||
4761 | bucket->bhs[0], | ||
4762 | i, 0); | ||
4763 | if (ret) { | ||
4764 | mlog_errno(ret); | ||
4765 | break; | ||
4766 | } | ||
4767 | } | ||
4768 | |||
4769 | return ret; | ||
4770 | } | ||
4771 | |||
4772 | static int ocfs2_delete_xattr_index_block(struct inode *inode, | ||
4773 | struct buffer_head *xb_bh) | ||
4774 | { | ||
4775 | struct ocfs2_xattr_block *xb = | ||
4776 | (struct ocfs2_xattr_block *)xb_bh->b_data; | ||
4777 | struct ocfs2_extent_list *el = &xb->xb_attrs.xb_root.xt_list; | ||
4778 | int ret = 0; | ||
4779 | u32 name_hash = UINT_MAX, e_cpos, num_clusters; | ||
4780 | u64 p_blkno; | ||
4781 | |||
4782 | if (le16_to_cpu(el->l_next_free_rec) == 0) | ||
4783 | return 0; | ||
4784 | |||
4785 | while (name_hash > 0) { | ||
4786 | ret = ocfs2_xattr_get_rec(inode, name_hash, &p_blkno, | ||
4787 | &e_cpos, &num_clusters, el); | ||
4788 | if (ret) { | ||
4789 | mlog_errno(ret); | ||
4790 | goto out; | ||
4791 | } | ||
4792 | |||
4793 | ret = ocfs2_iterate_xattr_buckets(inode, p_blkno, num_clusters, | ||
4794 | ocfs2_delete_xattr_in_bucket, | ||
4795 | NULL); | ||
4796 | if (ret) { | ||
4797 | mlog_errno(ret); | ||
4798 | goto out; | ||
4799 | } | ||
4800 | |||
4801 | ret = ocfs2_rm_xattr_cluster(inode, xb_bh, | ||
4802 | p_blkno, e_cpos, num_clusters); | ||
4803 | if (ret) { | ||
4804 | mlog_errno(ret); | ||
4805 | break; | ||
4806 | } | ||
4807 | |||
4808 | if (e_cpos == 0) | ||
4809 | break; | ||
4810 | |||
4811 | name_hash = e_cpos - 1; | ||
4812 | } | ||
4813 | |||
4814 | out: | ||
4815 | return ret; | ||
4816 | } | ||