]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: Tao Ma <tao.ma@oracle.com> |
2 | Subject: ocfs2: Refactor xattr list and remove ocfs2_xattr_handler(). | |
3 | Patch-mainline: 2.6.28 | |
4 | ||
5 | According to Christoph Hellwig's advice, we really don't need | |
6 | a ->list to handle one xattr's list. Just a map from index to | |
7 | xattr prefix is enough. And I also refactor the old list method | |
8 | with the reference from fs/xfs/linux-2.6/xfs_xattr.c and the | |
9 | xattr list method in btrfs. | |
10 | ||
11 | Signed-off-by: Tao Ma <tao.ma@oracle.com> | |
12 | Signed-off-by: Mark Fasheh <mfasheh@suse.com> | |
13 | --- | |
14 | fs/ocfs2/xattr.c | 95 ++++++++++++++++++++++++++++++++++-------------------- | |
15 | 1 files changed, 60 insertions(+), 35 deletions(-) | |
16 | ||
17 | Index: linux-2.6.27/fs/ocfs2/xattr.c | |
18 | =================================================================== | |
19 | --- linux-2.6.27.orig/fs/ocfs2/xattr.c | |
20 | +++ linux-2.6.27/fs/ocfs2/xattr.c | |
21 | @@ -153,14 +153,14 @@ static int ocfs2_xattr_set_entry_index_b | |
22 | static int ocfs2_delete_xattr_index_block(struct inode *inode, | |
23 | struct buffer_head *xb_bh); | |
24 | ||
25 | -static inline struct xattr_handler *ocfs2_xattr_handler(int name_index) | |
26 | +static inline const char *ocfs2_xattr_prefix(int name_index) | |
27 | { | |
28 | struct xattr_handler *handler = NULL; | |
29 | ||
30 | if (name_index > 0 && name_index < OCFS2_XATTR_MAX) | |
31 | handler = ocfs2_xattr_handler_map[name_index]; | |
32 | ||
33 | - return handler; | |
34 | + return handler ? handler->prefix : NULL; | |
35 | } | |
36 | ||
37 | static u32 ocfs2_xattr_name_hash(struct inode *inode, | |
38 | @@ -468,33 +468,56 @@ static int ocfs2_xattr_value_truncate(st | |
39 | return ret; | |
40 | } | |
41 | ||
42 | +static int ocfs2_xattr_list_entry(char *buffer, size_t size, | |
43 | + size_t *result, const char *prefix, | |
44 | + const char *name, int name_len) | |
45 | +{ | |
46 | + char *p = buffer + *result; | |
47 | + int prefix_len = strlen(prefix); | |
48 | + int total_len = prefix_len + name_len + 1; | |
49 | + | |
50 | + *result += total_len; | |
51 | + | |
52 | + /* we are just looking for how big our buffer needs to be */ | |
53 | + if (!size) | |
54 | + return 0; | |
55 | + | |
56 | + if (*result > size) | |
57 | + return -ERANGE; | |
58 | + | |
59 | + memcpy(p, prefix, prefix_len); | |
60 | + memcpy(p + prefix_len, name, name_len); | |
61 | + p[prefix_len + name_len] = '\0'; | |
62 | + | |
63 | + return 0; | |
64 | +} | |
65 | + | |
66 | static int ocfs2_xattr_list_entries(struct inode *inode, | |
67 | struct ocfs2_xattr_header *header, | |
68 | char *buffer, size_t buffer_size) | |
69 | { | |
70 | - size_t rest = buffer_size; | |
71 | - int i; | |
72 | + size_t result = 0; | |
73 | + int i, type, ret; | |
74 | + const char *prefix, *name; | |
75 | ||
76 | for (i = 0 ; i < le16_to_cpu(header->xh_count); i++) { | |
77 | struct ocfs2_xattr_entry *entry = &header->xh_entries[i]; | |
78 | - struct xattr_handler *handler = | |
79 | - ocfs2_xattr_handler(ocfs2_xattr_get_type(entry)); | |
80 | + type = ocfs2_xattr_get_type(entry); | |
81 | + prefix = ocfs2_xattr_prefix(type); | |
82 | ||
83 | - if (handler) { | |
84 | - size_t size = handler->list(inode, buffer, rest, | |
85 | - ((char *)header + | |
86 | - le16_to_cpu(entry->xe_name_offset)), | |
87 | - entry->xe_name_len); | |
88 | - if (buffer) { | |
89 | - if (size > rest) | |
90 | - return -ERANGE; | |
91 | - buffer += size; | |
92 | - } | |
93 | - rest -= size; | |
94 | + if (prefix) { | |
95 | + name = (const char *)header + | |
96 | + le16_to_cpu(entry->xe_name_offset); | |
97 | + | |
98 | + ret = ocfs2_xattr_list_entry(buffer, buffer_size, | |
99 | + &result, prefix, name, | |
100 | + entry->xe_name_len); | |
101 | + if (ret) | |
102 | + return ret; | |
103 | } | |
104 | } | |
105 | ||
106 | - return buffer_size - rest; | |
107 | + return result; | |
108 | } | |
109 | ||
110 | static int ocfs2_xattr_ibody_list(struct inode *inode, | |
111 | @@ -2472,6 +2495,7 @@ out: | |
112 | struct ocfs2_xattr_tree_list { | |
113 | char *buffer; | |
114 | size_t buffer_size; | |
115 | + size_t result; | |
116 | }; | |
117 | ||
118 | static int ocfs2_xattr_bucket_get_name_value(struct inode *inode, | |
119 | @@ -2497,17 +2521,17 @@ static int ocfs2_list_xattr_bucket(struc | |
120 | struct ocfs2_xattr_bucket *bucket, | |
121 | void *para) | |
122 | { | |
123 | - int ret = 0; | |
124 | + int ret = 0, type; | |
125 | struct ocfs2_xattr_tree_list *xl = (struct ocfs2_xattr_tree_list *)para; | |
126 | - size_t size; | |
127 | int i, block_off, new_offset; | |
128 | + const char *prefix, *name; | |
129 | ||
130 | for (i = 0 ; i < le16_to_cpu(bucket->xh->xh_count); i++) { | |
131 | struct ocfs2_xattr_entry *entry = &bucket->xh->xh_entries[i]; | |
132 | - struct xattr_handler *handler = | |
133 | - ocfs2_xattr_handler(ocfs2_xattr_get_type(entry)); | |
134 | + type = ocfs2_xattr_get_type(entry); | |
135 | + prefix = ocfs2_xattr_prefix(type); | |
136 | ||
137 | - if (handler) { | |
138 | + if (prefix) { | |
139 | ret = ocfs2_xattr_bucket_get_name_value(inode, | |
140 | bucket->xh, | |
141 | i, | |
142 | @@ -2515,16 +2539,16 @@ static int ocfs2_list_xattr_bucket(struc | |
143 | &new_offset); | |
144 | if (ret) | |
145 | break; | |
146 | - size = handler->list(inode, xl->buffer, xl->buffer_size, | |
147 | - bucket->bhs[block_off]->b_data + | |
148 | - new_offset, | |
149 | - entry->xe_name_len); | |
150 | - if (xl->buffer) { | |
151 | - if (size > xl->buffer_size) | |
152 | - return -ERANGE; | |
153 | - xl->buffer += size; | |
154 | - } | |
155 | - xl->buffer_size -= size; | |
156 | + | |
157 | + name = (const char *)bucket->bhs[block_off]->b_data + | |
158 | + new_offset; | |
159 | + ret = ocfs2_xattr_list_entry(xl->buffer, | |
160 | + xl->buffer_size, | |
161 | + &xl->result, | |
162 | + prefix, name, | |
163 | + entry->xe_name_len); | |
164 | + if (ret) | |
165 | + break; | |
166 | } | |
167 | } | |
168 | ||
169 | @@ -2543,6 +2567,7 @@ static int ocfs2_xattr_tree_list_index_b | |
170 | struct ocfs2_xattr_tree_list xl = { | |
171 | .buffer = buffer, | |
172 | .buffer_size = buffer_size, | |
173 | + .result = 0, | |
174 | }; | |
175 | ||
176 | if (le16_to_cpu(el->l_next_free_rec) == 0) | |
177 | @@ -2570,7 +2595,7 @@ static int ocfs2_xattr_tree_list_index_b | |
178 | name_hash = e_cpos - 1; | |
179 | } | |
180 | ||
181 | - ret = buffer_size - xl.buffer_size; | |
182 | + ret = xl.result; | |
183 | out: | |
184 | return ret; | |
185 | } |