]>
Commit | Line | Data |
---|---|---|
00e5a55c BS |
1 | From: Tao Ma <tao.ma@oracle.com> |
2 | Subject: [PATCH 15/16] ocfs2: Delete all xattr buckets during inode removal | |
3 | Patch-mainline: 2.6.28? | |
4 | References: FATE302067 | |
5 | ||
6 | In inode removal, we need to iterate all the buckets, remove any | |
7 | externally-stored EA values and delete the xattr buckets. | |
8 | ||
9 | Signed-off-by: Tao Ma <tao.ma@oracle.com> | |
10 | Signed-off-by: Mark Fasheh <mfasheh@suse.com> | |
11 | --- | |
12 | fs/ocfs2/xattr.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++-- | |
13 | 1 files changed, 80 insertions(+), 4 deletions(-) | |
14 | ||
15 | diff --git a/fs/ocfs2/xattr.c b/fs/ocfs2/xattr.c | |
16 | index 408553c..e78ed7a 100644 | |
17 | --- a/fs/ocfs2/xattr.c | |
18 | +++ b/fs/ocfs2/xattr.c | |
19 | @@ -147,6 +147,9 @@ static int ocfs2_xattr_set_entry_index_block(struct inode *inode, | |
20 | struct ocfs2_xattr_info *xi, | |
21 | struct ocfs2_xattr_search *xs); | |
22 | ||
23 | +static int ocfs2_delete_xattr_index_block(struct inode *inode, | |
24 | + struct buffer_head *xb_bh); | |
25 | + | |
26 | static inline struct xattr_handler *ocfs2_xattr_handler(int name_index) | |
27 | { | |
28 | struct xattr_handler *handler = NULL; | |
29 | @@ -1527,13 +1530,14 @@ static int ocfs2_xattr_block_remove(struct inode *inode, | |
30 | struct buffer_head *blk_bh) | |
31 | { | |
32 | struct ocfs2_xattr_block *xb; | |
33 | - struct ocfs2_xattr_header *header; | |
34 | int ret = 0; | |
35 | ||
36 | xb = (struct ocfs2_xattr_block *)blk_bh->b_data; | |
37 | - header = &(xb->xb_attrs.xb_header); | |
38 | - | |
39 | - ret = ocfs2_remove_value_outside(inode, blk_bh, header); | |
40 | + if (!(le16_to_cpu(xb->xb_flags) & OCFS2_XATTR_INDEXED)) { | |
41 | + struct ocfs2_xattr_header *header = &(xb->xb_attrs.xb_header); | |
42 | + ret = ocfs2_remove_value_outside(inode, blk_bh, header); | |
43 | + } else | |
44 | + ret = ocfs2_delete_xattr_index_block(inode, blk_bh); | |
45 | ||
46 | return ret; | |
47 | } | |
48 | @@ -4754,3 +4758,75 @@ out: | |
49 | mlog_exit(ret); | |
50 | return ret; | |
51 | } | |
52 | + | |
53 | +static int ocfs2_delete_xattr_in_bucket(struct inode *inode, | |
54 | + struct ocfs2_xattr_bucket *bucket, | |
55 | + void *para) | |
56 | +{ | |
57 | + int ret = 0; | |
58 | + struct ocfs2_xattr_header *xh = bucket->xh; | |
59 | + u16 i; | |
60 | + struct ocfs2_xattr_entry *xe; | |
61 | + | |
62 | + for (i = 0; i < le16_to_cpu(xh->xh_count); i++) { | |
63 | + xe = &xh->xh_entries[i]; | |
64 | + if (ocfs2_xattr_is_local(xe)) | |
65 | + continue; | |
66 | + | |
67 | + ret = ocfs2_xattr_bucket_value_truncate(inode, | |
68 | + bucket->bhs[0], | |
69 | + i, 0); | |
70 | + if (ret) { | |
71 | + mlog_errno(ret); | |
72 | + break; | |
73 | + } | |
74 | + } | |
75 | + | |
76 | + return ret; | |
77 | +} | |
78 | + | |
79 | +static int ocfs2_delete_xattr_index_block(struct inode *inode, | |
80 | + struct buffer_head *xb_bh) | |
81 | +{ | |
82 | + struct ocfs2_xattr_block *xb = | |
83 | + (struct ocfs2_xattr_block *)xb_bh->b_data; | |
84 | + struct ocfs2_extent_list *el = &xb->xb_attrs.xb_root.xt_list; | |
85 | + int ret = 0; | |
86 | + u32 name_hash = UINT_MAX, e_cpos, num_clusters; | |
87 | + u64 p_blkno; | |
88 | + | |
89 | + if (le16_to_cpu(el->l_next_free_rec) == 0) | |
90 | + return 0; | |
91 | + | |
92 | + while (name_hash > 0) { | |
93 | + ret = ocfs2_xattr_get_rec(inode, name_hash, &p_blkno, | |
94 | + &e_cpos, &num_clusters, el); | |
95 | + if (ret) { | |
96 | + mlog_errno(ret); | |
97 | + goto out; | |
98 | + } | |
99 | + | |
100 | + ret = ocfs2_iterate_xattr_buckets(inode, p_blkno, num_clusters, | |
101 | + ocfs2_delete_xattr_in_bucket, | |
102 | + NULL); | |
103 | + if (ret) { | |
104 | + mlog_errno(ret); | |
105 | + goto out; | |
106 | + } | |
107 | + | |
108 | + ret = ocfs2_rm_xattr_cluster(inode, xb_bh, | |
109 | + p_blkno, e_cpos, num_clusters); | |
110 | + if (ret) { | |
111 | + mlog_errno(ret); | |
112 | + break; | |
113 | + } | |
114 | + | |
115 | + if (e_cpos == 0) | |
116 | + break; | |
117 | + | |
118 | + name_hash = e_cpos - 1; | |
119 | + } | |
120 | + | |
121 | +out: | |
122 | + return ret; | |
123 | +} | |
124 | -- | |
125 | 1.5.4.5 | |
126 |