]>
Commit | Line | Data |
---|---|---|
4d1e5b62 AF |
1 | Subject: reiserfs: use generic xattr handlers |
2 | From: Jeff Mahoney <jeffm@suse.com> | |
3 | ||
4 | Christoph Hellwig had asked me quite some time ago to port the reiserfs | |
5 | xattrs to the generic xattr interface. | |
6 | ||
7 | This patch replaces the reiserfs-specific xattr handling code with the | |
8 | generic struct xattr_handler. | |
9 | ||
10 | However, since reiserfs doesn't split the prefix and name when accessing | |
11 | xattrs, it can't leverage generic_{set,get,list,remove}xattr without | |
12 | needlessly reconstructing the name on the back end. | |
13 | ||
14 | Update 7/26/07: Added missing dput() to deletion path. | |
15 | Update 8/30/07: Added missing mark_inode_dirty when i_mode is used to | |
16 | represent an ACL and no previous ACL existed. | |
17 | ||
18 | Signed-off-by: Jeff Mahoney <jeffm@suse.com> | |
19 | ||
20 | --- | |
21 | ||
22 | fs/reiserfs/super.c | 7 | |
23 | fs/reiserfs/xattr.c | 467 ++++++++++++++++------------------------- | |
24 | fs/reiserfs/xattr_acl.c | 79 ++---- | |
25 | fs/reiserfs/xattr_security.c | 26 -- | |
26 | fs/reiserfs/xattr_trusted.c | 45 --- | |
27 | fs/reiserfs/xattr_user.c | 31 -- | |
28 | include/linux/reiserfs_acl.h | 16 - | |
29 | include/linux/reiserfs_fs_sb.h | 3 | |
30 | include/linux/reiserfs_xattr.h | 25 -- | |
31 | 9 files changed, 258 insertions(+), 441 deletions(-) | |
32 | ||
33 | --- a/fs/reiserfs/super.c | |
34 | +++ b/fs/reiserfs/super.c | |
35 | @@ -2261,9 +2261,6 @@ static int __init init_reiserfs_fs(void) | |
36 | return ret; | |
37 | } | |
38 | ||
39 | - if ((ret = reiserfs_xattr_register_handlers())) | |
40 | - goto failed_reiserfs_xattr_register_handlers; | |
41 | - | |
42 | reiserfs_proc_info_global_init(); | |
43 | reiserfs_proc_register_global("version", | |
44 | reiserfs_global_version_in_proc); | |
45 | @@ -2274,9 +2271,6 @@ static int __init init_reiserfs_fs(void) | |
46 | return 0; | |
47 | } | |
48 | ||
49 | - reiserfs_xattr_unregister_handlers(); | |
50 | - | |
51 | - failed_reiserfs_xattr_register_handlers: | |
52 | reiserfs_proc_unregister_global("version"); | |
53 | reiserfs_proc_info_global_done(); | |
54 | destroy_inodecache(); | |
55 | @@ -2286,7 +2280,6 @@ static int __init init_reiserfs_fs(void) | |
56 | ||
57 | static void __exit exit_reiserfs_fs(void) | |
58 | { | |
59 | - reiserfs_xattr_unregister_handlers(); | |
60 | reiserfs_proc_unregister_global("version"); | |
61 | reiserfs_proc_info_global_done(); | |
62 | unregister_filesystem(&reiserfs_fs_type); | |
63 | --- a/fs/reiserfs/xattr_acl.c | |
64 | +++ b/fs/reiserfs/xattr_acl.c | |
65 | @@ -271,7 +271,7 @@ reiserfs_set_acl(struct inode *inode, in | |
66 | char *name; | |
67 | void *value = NULL; | |
68 | struct posix_acl **p_acl; | |
69 | - size_t size; | |
70 | + size_t size = 0; | |
71 | int error; | |
72 | struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode); | |
73 | ||
74 | @@ -308,16 +308,21 @@ reiserfs_set_acl(struct inode *inode, in | |
75 | value = posix_acl_to_disk(acl, &size); | |
76 | if (IS_ERR(value)) | |
77 | return (int)PTR_ERR(value); | |
78 | - error = reiserfs_xattr_set(inode, name, value, size, 0); | |
79 | - } else { | |
80 | - error = reiserfs_xattr_del(inode, name); | |
81 | - if (error == -ENODATA) { | |
82 | - /* This may seem odd here, but it means that the ACL was set | |
83 | - * with a value representable with mode bits. If there was | |
84 | - * an ACL before, reiserfs_xattr_del already dirtied the inode. | |
85 | - */ | |
86 | + } | |
87 | + | |
88 | + error = __reiserfs_xattr_set(inode, name, value, size, 0); | |
89 | + | |
90 | + /* | |
91 | + * Ensure that the inode gets dirtied if we're only using | |
92 | + * the mode bits and an old ACL didn't exist. We don't need | |
93 | + * to check if the inode is hashed here since we won't get | |
94 | + * called by reiserfs_inherit_default_acl(). | |
95 | + */ | |
96 | + if (error == -ENODATA) { | |
97 | + error = 0; | |
98 | + if (type == ACL_TYPE_ACCESS) { | |
99 | + inode->i_ctime = CURRENT_TIME_SEC; | |
100 | mark_inode_dirty(inode); | |
101 | - error = 0; | |
102 | } | |
103 | } | |
104 | ||
105 | @@ -474,33 +479,22 @@ posix_acl_access_set(struct inode *inode | |
106 | return xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size); | |
107 | } | |
108 | ||
109 | -static int posix_acl_access_del(struct inode *inode, const char *name) | |
110 | -{ | |
111 | - struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode); | |
112 | - if (strlen(name) != sizeof(POSIX_ACL_XATTR_ACCESS) - 1) | |
113 | - return -EINVAL; | |
114 | - iset_acl(inode, &reiserfs_i->i_acl_access, ERR_PTR(-ENODATA)); | |
115 | - return 0; | |
116 | -} | |
117 | - | |
118 | -static int | |
119 | -posix_acl_access_list(struct inode *inode, const char *name, int namelen, | |
120 | - char *out) | |
121 | +static size_t posix_acl_access_list(struct inode *inode, char *list, | |
122 | + size_t list_size, const char *name, | |
123 | + size_t name_len) | |
124 | { | |
125 | - int len = namelen; | |
126 | + const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS); | |
127 | if (!reiserfs_posixacl(inode->i_sb)) | |
128 | return 0; | |
129 | - if (out) | |
130 | - memcpy(out, name, len); | |
131 | - | |
132 | - return len; | |
133 | + if (list && size <= list_size) | |
134 | + memcpy(list, POSIX_ACL_XATTR_ACCESS, size); | |
135 | + return size; | |
136 | } | |
137 | ||
138 | -struct reiserfs_xattr_handler posix_acl_access_handler = { | |
139 | +struct xattr_handler reiserfs_posix_acl_access_handler = { | |
140 | .prefix = POSIX_ACL_XATTR_ACCESS, | |
141 | .get = posix_acl_access_get, | |
142 | .set = posix_acl_access_set, | |
143 | - .del = posix_acl_access_del, | |
144 | .list = posix_acl_access_list, | |
145 | }; | |
146 | ||
147 | @@ -522,32 +516,21 @@ posix_acl_default_set(struct inode *inod | |
148 | return xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size); | |
149 | } | |
150 | ||
151 | -static int posix_acl_default_del(struct inode *inode, const char *name) | |
152 | -{ | |
153 | - struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode); | |
154 | - if (strlen(name) != sizeof(POSIX_ACL_XATTR_DEFAULT) - 1) | |
155 | - return -EINVAL; | |
156 | - iset_acl(inode, &reiserfs_i->i_acl_default, ERR_PTR(-ENODATA)); | |
157 | - return 0; | |
158 | -} | |
159 | - | |
160 | -static int | |
161 | -posix_acl_default_list(struct inode *inode, const char *name, int namelen, | |
162 | - char *out) | |
163 | +static size_t posix_acl_default_list(struct inode *inode, char *list, | |
164 | + size_t list_size, const char *name, | |
165 | + size_t name_len) | |
166 | { | |
167 | - int len = namelen; | |
168 | + const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT); | |
169 | if (!reiserfs_posixacl(inode->i_sb)) | |
170 | return 0; | |
171 | - if (out) | |
172 | - memcpy(out, name, len); | |
173 | - | |
174 | - return len; | |
175 | + if (list && size <= list_size) | |
176 | + memcpy(list, POSIX_ACL_XATTR_DEFAULT, size); | |
177 | + return size; | |
178 | } | |
179 | ||
180 | -struct reiserfs_xattr_handler posix_acl_default_handler = { | |
181 | +struct xattr_handler reiserfs_posix_acl_default_handler = { | |
182 | .prefix = POSIX_ACL_XATTR_DEFAULT, | |
183 | .get = posix_acl_default_get, | |
184 | .set = posix_acl_default_set, | |
185 | - .del = posix_acl_default_del, | |
186 | .list = posix_acl_default_list, | |
187 | }; | |
188 | --- a/fs/reiserfs/xattr.c | |
189 | +++ b/fs/reiserfs/xattr.c | |
190 | @@ -53,7 +53,6 @@ | |
191 | #define PRIVROOT_NAME ".reiserfs_priv" | |
192 | #define XAROOT_NAME "xattrs" | |
193 | ||
194 | -static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char *); | |
195 | ||
196 | /* Helpers for inode ops. We do this so that we don't have all the VFS | |
197 | * overhead and also for proper i_mutex annotation. | |
198 | @@ -110,7 +109,6 @@ static int xattr_rmdir(struct inode *dir | |
199 | return error; | |
200 | } | |
201 | ||
202 | - | |
203 | #define xattr_may_create(flags) (!flags || flags & XATTR_CREATE) | |
204 | ||
205 | /* Returns and possibly creates the xattr dir. */ | |
206 | @@ -339,14 +337,17 @@ int xattr_readdir(struct inode *inode, f | |
207 | return res; | |
208 | } | |
209 | ||
210 | -/* expects xadir->d_inode->i_mutex to be locked */ | |
211 | +/* The following are side effects of other operations that aren't explicitly | |
212 | + * modifying extended attributes. This includes operations such as permissions | |
213 | + * or ownership changes, object deletions, etc. */ | |
214 | + | |
215 | static int | |
216 | -__reiserfs_xattr_del(struct dentry *xadir, const char *name, int namelen) | |
217 | +reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen, | |
218 | + loff_t offset, u64 ino, unsigned int d_type) | |
219 | { | |
220 | + struct dentry *xadir = (struct dentry *)buf; | |
221 | struct dentry *dentry; | |
222 | - struct inode *dir = xadir->d_inode; | |
223 | int err = 0; | |
224 | - struct reiserfs_xattr_handler *xah; | |
225 | ||
226 | dentry = lookup_one_len(name, xadir, namelen); | |
227 | if (IS_ERR(dentry)) { | |
228 | @@ -361,28 +362,7 @@ __reiserfs_xattr_del(struct dentry *xadi | |
229 | if (S_ISDIR(dentry->d_inode->i_mode)) | |
230 | goto out_file; | |
231 | ||
232 | - if (!IS_PRIVATE(dentry->d_inode)) { | |
233 | - reiserfs_error(dir->i_sb, "jdm-20003", | |
234 | - "OID %08x [%.*s/%.*s] doesn't have " | |
235 | - "priv flag set [parent is %sset].", | |
236 | - le32_to_cpu(INODE_PKEY(dentry->d_inode)-> | |
237 | - k_objectid), xadir->d_name.len, | |
238 | - xadir->d_name.name, namelen, name, | |
239 | - IS_PRIVATE(xadir->d_inode) ? "" : | |
240 | - "not "); | |
241 | - dput(dentry); | |
242 | - return -EIO; | |
243 | - } | |
244 | - | |
245 | - /* Deletion pre-operation */ | |
246 | - xah = find_xattr_handler_prefix(name); | |
247 | - if (xah && xah->del) { | |
248 | - err = xah->del(dentry->d_inode, name); | |
249 | - if (err) | |
250 | - goto out; | |
251 | - } | |
252 | - | |
253 | - err = xattr_unlink(dir, dentry); | |
254 | + err = xattr_unlink(xadir->d_inode, dentry); | |
255 | ||
256 | out_file: | |
257 | dput(dentry); | |
258 | @@ -391,20 +371,6 @@ out: | |
259 | return err; | |
260 | } | |
261 | ||
262 | -/* The following are side effects of other operations that aren't explicitly | |
263 | - * modifying extended attributes. This includes operations such as permissions | |
264 | - * or ownership changes, object deletions, etc. */ | |
265 | - | |
266 | -static int | |
267 | -reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen, | |
268 | - loff_t offset, u64 ino, unsigned int d_type) | |
269 | -{ | |
270 | - struct dentry *xadir = (struct dentry *)buf; | |
271 | - | |
272 | - return __reiserfs_xattr_del(xadir, name, namelen); | |
273 | - | |
274 | -} | |
275 | - | |
276 | /* This is called w/ inode->i_mutex downed */ | |
277 | int reiserfs_delete_xattrs(struct inode *inode) | |
278 | { | |
279 | @@ -541,14 +507,11 @@ out: | |
280 | } | |
281 | ||
282 | #ifdef CONFIG_REISERFS_FS_XATTR | |
283 | -static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char | |
284 | - *prefix); | |
285 | - | |
286 | /* Returns a dentry corresponding to a specific extended attribute file | |
287 | * for the inode. If flags allow, the file is created. Otherwise, a | |
288 | * valid or negative dentry, or an error is returned. */ | |
289 | -static struct dentry *get_xa_file_dentry(const struct inode *inode, | |
290 | - const char *name, int flags) | |
291 | +static struct dentry *xattr_lookup(struct inode *inode, const char *name, | |
292 | + int flags) | |
293 | { | |
294 | struct dentry *xadir, *xafile; | |
295 | int err = 0; | |
296 | @@ -623,6 +586,45 @@ int reiserfs_commit_write(struct file *f | |
297 | int reiserfs_prepare_write(struct file *f, struct page *page, | |
298 | unsigned from, unsigned to); | |
299 | ||
300 | +static void update_ctime(struct inode *inode) | |
301 | +{ | |
302 | + struct timespec now = current_fs_time(inode->i_sb); | |
303 | + if (hlist_unhashed(&inode->i_hash) || !inode->i_nlink || | |
304 | + timespec_equal(&inode->i_ctime, &now)) | |
305 | + return; | |
306 | + | |
307 | + inode->i_ctime = CURRENT_TIME_SEC; | |
308 | + mark_inode_dirty(inode); | |
309 | +} | |
310 | + | |
311 | +static int lookup_and_delete_xattr(struct inode *inode, const char *name) | |
312 | +{ | |
313 | + int err = 0; | |
314 | + struct dentry *dentry, *xadir; | |
315 | + | |
316 | + xadir = open_xa_dir(inode, XATTR_REPLACE); | |
317 | + if (IS_ERR(xadir)) | |
318 | + return PTR_ERR(xadir); | |
319 | + | |
320 | + dentry = lookup_one_len(name, xadir, strlen(name)); | |
321 | + if (IS_ERR(dentry)) { | |
322 | + err = PTR_ERR(dentry); | |
323 | + goto out_dput; | |
324 | + } | |
325 | + | |
326 | + if (dentry->d_inode) { | |
327 | + mutex_lock_nested(&xadir->d_inode->i_mutex, I_MUTEX_XATTR); | |
328 | + err = xattr_unlink(xadir->d_inode, dentry); | |
329 | + mutex_unlock(&xadir->d_inode->i_mutex); | |
330 | + update_ctime(inode); | |
331 | + } | |
332 | + | |
333 | + dput(dentry); | |
334 | +out_dput: | |
335 | + dput(xadir); | |
336 | + return err; | |
337 | +} | |
338 | + | |
339 | ||
340 | /* Generic extended attribute operations that can be used by xa plugins */ | |
341 | ||
342 | @@ -630,8 +632,8 @@ int reiserfs_prepare_write(struct file * | |
343 | * inode->i_mutex: down | |
344 | */ | |
345 | int | |
346 | -reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, | |
347 | - size_t buffer_size, int flags) | |
348 | +__reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, | |
349 | + size_t buffer_size, int flags) | |
350 | { | |
351 | int err = 0; | |
352 | struct dentry *dentry; | |
353 | @@ -639,37 +641,22 @@ reiserfs_xattr_set(struct inode *inode, | |
354 | char *data; | |
355 | size_t file_pos = 0; | |
356 | size_t buffer_pos = 0; | |
357 | - struct iattr newattrs; | |
358 | + size_t new_size; | |
359 | __u32 xahash = 0; | |
360 | ||
361 | if (get_inode_sd_version(inode) == STAT_DATA_V1) | |
362 | return -EOPNOTSUPP; | |
363 | ||
364 | if (!buffer) | |
365 | - return reiserfs_xattr_del(inode, name); | |
366 | + return lookup_and_delete_xattr(inode, name); | |
367 | ||
368 | - dentry = get_xa_file_dentry(inode, name, flags); | |
369 | - if (IS_ERR(dentry)) { | |
370 | - err = PTR_ERR(dentry); | |
371 | - goto out; | |
372 | - } | |
373 | + dentry = xattr_lookup(inode, name, flags); | |
374 | + if (IS_ERR(dentry)) | |
375 | + return PTR_ERR(dentry); | |
376 | ||
377 | down_write(&REISERFS_I(inode)->i_xattr_sem); | |
378 | ||
379 | xahash = xattr_hash(buffer, buffer_size); | |
380 | - | |
381 | - /* Resize it so we're ok to write there */ | |
382 | - newattrs.ia_size = buffer_size; | |
383 | - newattrs.ia_ctime = current_fs_time(inode->i_sb); | |
384 | - newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; | |
385 | - mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_XATTR); | |
386 | - down_write(&dentry->d_inode->i_alloc_sem); | |
387 | - err = reiserfs_setattr(dentry, &newattrs); | |
388 | - up_write(&dentry->d_inode->i_alloc_sem); | |
389 | - mutex_unlock(&dentry->d_inode->i_mutex); | |
390 | - if (err) | |
391 | - goto out_filp; | |
392 | - | |
393 | while (buffer_pos < buffer_size || buffer_pos == 0) { | |
394 | size_t chunk; | |
395 | size_t skip = 0; | |
396 | @@ -682,7 +669,7 @@ reiserfs_xattr_set(struct inode *inode, | |
397 | page = reiserfs_get_page(dentry->d_inode, file_pos); | |
398 | if (IS_ERR(page)) { | |
399 | err = PTR_ERR(page); | |
400 | - goto out_filp; | |
401 | + goto out_unlock; | |
402 | } | |
403 | ||
404 | lock_page(page); | |
405 | @@ -716,20 +703,33 @@ reiserfs_xattr_set(struct inode *inode, | |
406 | break; | |
407 | } | |
408 | ||
409 | - /* We can't mark the inode dirty if it's not hashed. This is the case | |
410 | - * when we're inheriting the default ACL. If we dirty it, the inode | |
411 | - * gets marked dirty, but won't (ever) make it onto the dirty list until | |
412 | - * it's synced explicitly to clear I_DIRTY. This is bad. */ | |
413 | - if (!hlist_unhashed(&inode->i_hash)) { | |
414 | - inode->i_ctime = CURRENT_TIME_SEC; | |
415 | - mark_inode_dirty(inode); | |
416 | - } | |
417 | - | |
418 | - out_filp: | |
419 | + new_size = buffer_size + sizeof(struct reiserfs_xattr_header); | |
420 | + if (!err && new_size < i_size_read(dentry->d_inode)) { | |
421 | + struct iattr newattrs = { | |
422 | + .ia_ctime = current_fs_time(inode->i_sb), | |
423 | + .ia_size = buffer_size, | |
424 | + .ia_valid = ATTR_SIZE | ATTR_CTIME, | |
425 | + }; | |
426 | + mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_XATTR); | |
427 | + down_write(&dentry->d_inode->i_alloc_sem); | |
428 | + err = reiserfs_setattr(dentry, &newattrs); | |
429 | + up_write(&dentry->d_inode->i_alloc_sem); | |
430 | + mutex_unlock(&dentry->d_inode->i_mutex); | |
431 | + } else | |
432 | + update_ctime(inode); | |
433 | +out_unlock: | |
434 | up_write(&REISERFS_I(inode)->i_xattr_sem); | |
435 | dput(dentry); | |
436 | + return err; | |
437 | +} | |
438 | ||
439 | - out: | |
440 | +int | |
441 | +reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer, | |
442 | + size_t buffer_size, int flags) | |
443 | +{ | |
444 | + int err = __reiserfs_xattr_set(inode, name, buffer, buffer_size, flags); | |
445 | + if (err == -ENODATA) | |
446 | + err = 0; | |
447 | return err; | |
448 | } | |
449 | ||
450 | @@ -737,7 +737,7 @@ reiserfs_xattr_set(struct inode *inode, | |
451 | * inode->i_mutex: down | |
452 | */ | |
453 | int | |
454 | -reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer, | |
455 | +reiserfs_xattr_get(struct inode *inode, const char *name, void *buffer, | |
456 | size_t buffer_size) | |
457 | { | |
458 | ssize_t err = 0; | |
459 | @@ -756,7 +756,7 @@ reiserfs_xattr_get(const struct inode *i | |
460 | if (get_inode_sd_version(inode) == STAT_DATA_V1) | |
461 | return -EOPNOTSUPP; | |
462 | ||
463 | - dentry = get_xa_file_dentry(inode, name, XATTR_REPLACE); | |
464 | + dentry = xattr_lookup(inode, name, XATTR_REPLACE); | |
465 | if (IS_ERR(dentry)) { | |
466 | err = PTR_ERR(dentry); | |
467 | goto out; | |
468 | @@ -837,32 +837,53 @@ out: | |
469 | return err; | |
470 | } | |
471 | ||
472 | -int reiserfs_xattr_del(struct inode *inode, const char *name) | |
473 | -{ | |
474 | - struct dentry *dir; | |
475 | - int err; | |
476 | +/* Actual operations that are exported to VFS-land */ | |
477 | +struct xattr_handler *reiserfs_xattr_handlers[] = { | |
478 | + &reiserfs_xattr_user_handler, | |
479 | + &reiserfs_xattr_trusted_handler, | |
480 | +#ifdef CONFIG_REISERFS_FS_SECURITY | |
481 | + &reiserfs_xattr_security_handler, | |
482 | +#endif | |
483 | +#ifdef CONFIG_REISERFS_FS_POSIX_ACL | |
484 | + &reiserfs_posix_acl_access_handler, | |
485 | + &reiserfs_posix_acl_default_handler, | |
486 | +#endif | |
487 | + NULL | |
488 | +}; | |
489 | ||
490 | - dir = open_xa_dir(inode, XATTR_REPLACE); | |
491 | - if (IS_ERR(dir)) { | |
492 | - err = PTR_ERR(dir); | |
493 | - goto out; | |
494 | - } | |
495 | +/* | |
496 | + * In order to implement different sets of xattr operations for each xattr | |
497 | + * prefix with the generic xattr API, a filesystem should create a | |
498 | + * null-terminated array of struct xattr_handler (one for each prefix) and | |
499 | + * hang a pointer to it off of the s_xattr field of the superblock. | |
500 | + * | |
501 | + * The generic_fooxattr() functions will use this list to dispatch xattr | |
502 | + * operations to the correct xattr_handler. | |
503 | + */ | |
504 | +#define for_each_xattr_handler(handlers, handler) \ | |
505 | + for ((handler) = *(handlers)++; \ | |
506 | + (handler) != NULL; \ | |
507 | + (handler) = *(handlers)++) | |
508 | ||
509 | - mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); | |
510 | - err = __reiserfs_xattr_del(dir, name, strlen(name)); | |
511 | - mutex_unlock(&dir->d_inode->i_mutex); | |
512 | - dput(dir); | |
513 | +/* This is the implementation for the xattr plugin infrastructure */ | |
514 | +static inline struct xattr_handler * | |
515 | +find_xattr_handler_prefix(struct xattr_handler **handlers, | |
516 | + const char *name) | |
517 | +{ | |
518 | + struct xattr_handler *xah; | |
519 | ||
520 | - if (!err) { | |
521 | - inode->i_ctime = CURRENT_TIME_SEC; | |
522 | - mark_inode_dirty(inode); | |
523 | + if (!handlers) | |
524 | + return NULL; | |
525 | + | |
526 | + for_each_xattr_handler(handlers, xah) { | |
527 | + if (strncmp(xah->prefix, name, strlen(xah->prefix)) == 0) | |
528 | + break; | |
529 | } | |
530 | ||
531 | - out: | |
532 | - return err; | |
533 | + return xah; | |
534 | } | |
535 | ||
536 | -/* Actual operations that are exported to VFS-land */ | |
537 | + | |
538 | /* | |
539 | * Inode operation getxattr() | |
540 | */ | |
541 | @@ -870,15 +891,15 @@ ssize_t | |
542 | reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer, | |
543 | size_t size) | |
544 | { | |
545 | - struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix(name); | |
546 | - int err; | |
547 | + struct inode *inode = dentry->d_inode; | |
548 | + struct xattr_handler *handler; | |
549 | ||
550 | - if (!xah || !reiserfs_xattrs(dentry->d_sb) || | |
551 | - get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) | |
552 | + handler = find_xattr_handler_prefix(inode->i_sb->s_xattr, name); | |
553 | + | |
554 | + if (!handler || get_inode_sd_version(inode) == STAT_DATA_V1) | |
555 | return -EOPNOTSUPP; | |
556 | ||
557 | - err = xah->get(dentry->d_inode, name, buffer, size); | |
558 | - return err; | |
559 | + return handler->get(inode, name, buffer, size); | |
560 | } | |
561 | ||
562 | /* | |
563 | @@ -890,15 +911,15 @@ int | |
564 | reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value, | |
565 | size_t size, int flags) | |
566 | { | |
567 | - struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix(name); | |
568 | - int err; | |
569 | + struct inode *inode = dentry->d_inode; | |
570 | + struct xattr_handler *handler; | |
571 | ||
572 | - if (!xah || !reiserfs_xattrs(dentry->d_sb) || | |
573 | - get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) | |
574 | + handler = find_xattr_handler_prefix(inode->i_sb->s_xattr, name); | |
575 | + | |
576 | + if (!handler || get_inode_sd_version(inode) == STAT_DATA_V1) | |
577 | return -EOPNOTSUPP; | |
578 | ||
579 | - err = xah->set(dentry->d_inode, name, value, size, flags); | |
580 | - return err; | |
581 | + return handler->set(inode, name, value, size, flags); | |
582 | } | |
583 | ||
584 | /* | |
585 | @@ -908,71 +929,65 @@ reiserfs_setxattr(struct dentry *dentry, | |
586 | */ | |
587 | int reiserfs_removexattr(struct dentry *dentry, const char *name) | |
588 | { | |
589 | - int err; | |
590 | - struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix(name); | |
591 | + struct inode *inode = dentry->d_inode; | |
592 | + struct xattr_handler *handler; | |
593 | + handler = find_xattr_handler_prefix(inode->i_sb->s_xattr, name); | |
594 | ||
595 | - if (!xah || !reiserfs_xattrs(dentry->d_sb) || | |
596 | - get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1) | |
597 | + if (!handler || get_inode_sd_version(inode) == STAT_DATA_V1) | |
598 | return -EOPNOTSUPP; | |
599 | ||
600 | - err = reiserfs_xattr_del(dentry->d_inode, name); | |
601 | - | |
602 | - dentry->d_inode->i_ctime = CURRENT_TIME_SEC; | |
603 | - mark_inode_dirty(dentry->d_inode); | |
604 | - | |
605 | - return err; | |
606 | + return handler->set(inode, name, NULL, 0, XATTR_REPLACE); | |
607 | } | |
608 | ||
609 | -/* This is what filldir will use: | |
610 | - * r_pos will always contain the amount of space required for the entire | |
611 | - * list. If r_pos becomes larger than r_size, we need more space and we | |
612 | - * return an error indicating this. If r_pos is less than r_size, then we've | |
613 | - * filled the buffer successfully and we return success */ | |
614 | -struct reiserfs_listxattr_buf { | |
615 | - int r_pos; | |
616 | - int r_size; | |
617 | - char *r_buf; | |
618 | - struct inode *r_inode; | |
619 | +struct listxattr_buf { | |
620 | + size_t size; | |
621 | + size_t pos; | |
622 | + char *buf; | |
623 | + struct inode *inode; | |
624 | }; | |
625 | ||
626 | -static int | |
627 | -reiserfs_listxattr_filler(void *buf, const char *name, int namelen, | |
628 | - loff_t offset, u64 ino, unsigned int d_type) | |
629 | +static int listxattr_filler(void *buf, const char *name, int namelen, | |
630 | + loff_t offset, u64 ino, unsigned int d_type) | |
631 | { | |
632 | - struct reiserfs_listxattr_buf *b = (struct reiserfs_listxattr_buf *)buf; | |
633 | - int len = 0; | |
634 | - if (name[0] != '.' | |
635 | - || (namelen != 1 && (name[1] != '.' || namelen != 2))) { | |
636 | - struct reiserfs_xattr_handler *xah = | |
637 | - find_xattr_handler_prefix(name); | |
638 | - if (!xah) | |
639 | - return 0; /* Unsupported xattr name, skip it */ | |
640 | - | |
641 | - /* We call ->list() twice because the operation isn't required to just | |
642 | - * return the name back - we want to make sure we have enough space */ | |
643 | - len += xah->list(b->r_inode, name, namelen, NULL); | |
644 | - | |
645 | - if (len) { | |
646 | - if (b->r_pos + len + 1 <= b->r_size) { | |
647 | - char *p = b->r_buf + b->r_pos; | |
648 | - p += xah->list(b->r_inode, name, namelen, p); | |
649 | - *p++ = '\0'; | |
650 | - } | |
651 | - b->r_pos += len + 1; | |
652 | + struct listxattr_buf *b = (struct listxattr_buf *)buf; | |
653 | + size_t size; | |
654 | + if (name[0] != '.' || | |
655 | + (namelen != 1 && (name[1] != '.' || namelen != 2))) { | |
656 | + struct xattr_handler *handler; | |
657 | + handler = find_xattr_handler_prefix(b->inode->i_sb->s_xattr, | |
658 | + name); | |
659 | + if (!handler) /* Unsupported xattr name */ | |
660 | + return 0; | |
661 | + if (b->buf) { | |
662 | + size = handler->list(b->inode, b->buf + b->pos, | |
663 | + b->size, name, namelen); | |
664 | + if (size > b->size) | |
665 | + return -ERANGE; | |
666 | + } else { | |
667 | + size = handler->list(b->inode, NULL, 0, name, namelen); | |
668 | } | |
669 | - } | |
670 | ||
671 | + b->pos += size; | |
672 | + } | |
673 | return 0; | |
674 | } | |
675 | ||
676 | /* | |
677 | * Inode operation listxattr() | |
678 | + * | |
679 | + * We totally ignore the generic listxattr here because it would be stupid | |
680 | + * not to. Since the xattrs are organized in a directory, we can just | |
681 | + * readdir to find them. | |
682 | */ | |
683 | ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size) | |
684 | { | |
685 | struct dentry *dir; | |
686 | int err = 0; | |
687 | - struct reiserfs_listxattr_buf buf; | |
688 | + struct listxattr_buf buf = { | |
689 | + .inode = dentry->d_inode, | |
690 | + .buf = buffer, | |
691 | + .size = buffer ? size : 0, | |
692 | + }; | |
693 | ||
694 | if (!dentry->d_inode) | |
695 | return -EINVAL; | |
696 | @@ -985,120 +1000,22 @@ ssize_t reiserfs_listxattr(struct dentry | |
697 | if (IS_ERR(dir)) { | |
698 | err = PTR_ERR(dir); | |
699 | if (err == -ENODATA) | |
700 | - err = 0; /* Not an error if there aren't any xattrs */ | |
701 | + err = 0; /* Not an error if there aren't any xattrs */ | |
702 | goto out; | |
703 | } | |
704 | ||
705 | - buf.r_buf = buffer; | |
706 | - buf.r_size = buffer ? size : 0; | |
707 | - buf.r_pos = 0; | |
708 | - buf.r_inode = dentry->d_inode; | |
709 | - | |
710 | mutex_lock_nested(&dir->d_inode->i_mutex, I_MUTEX_XATTR); | |
711 | - err = xattr_readdir(dir->d_inode, reiserfs_listxattr_filler, &buf); | |
712 | + err = xattr_readdir(dir->d_inode, listxattr_filler, &buf); | |
713 | mutex_unlock(&dir->d_inode->i_mutex); | |
714 | ||
715 | - if (!err) { | |
716 | - if (buf.r_pos > buf.r_size && buffer != NULL) | |
717 | - err = -ERANGE; | |
718 | - else | |
719 | - err = buf.r_pos; | |
720 | - } | |
721 | + if (!err) | |
722 | + err = buf.pos; | |
723 | ||
724 | dput(dir); | |
725 | out: | |
726 | return err; | |
727 | } | |
728 | ||
729 | -/* This is the implementation for the xattr plugin infrastructure */ | |
730 | -static LIST_HEAD(xattr_handlers); | |
731 | -static DEFINE_RWLOCK(handler_lock); | |
732 | - | |
733 | -static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char | |
734 | - *prefix) | |
735 | -{ | |
736 | - struct reiserfs_xattr_handler *xah = NULL; | |
737 | - struct list_head *p; | |
738 | - | |
739 | - read_lock(&handler_lock); | |
740 | - list_for_each(p, &xattr_handlers) { | |
741 | - xah = list_entry(p, struct reiserfs_xattr_handler, handlers); | |
742 | - if (strncmp(xah->prefix, prefix, strlen(xah->prefix)) == 0) | |
743 | - break; | |
744 | - xah = NULL; | |
745 | - } | |
746 | - | |
747 | - read_unlock(&handler_lock); | |
748 | - return xah; | |
749 | -} | |
750 | - | |
751 | -static void __unregister_handlers(void) | |
752 | -{ | |
753 | - struct reiserfs_xattr_handler *xah; | |
754 | - struct list_head *p, *tmp; | |
755 | - | |
756 | - list_for_each_safe(p, tmp, &xattr_handlers) { | |
757 | - xah = list_entry(p, struct reiserfs_xattr_handler, handlers); | |
758 | - if (xah->exit) | |
759 | - xah->exit(); | |
760 | - | |
761 | - list_del_init(p); | |
762 | - } | |
763 | - INIT_LIST_HEAD(&xattr_handlers); | |
764 | -} | |
765 | - | |
766 | -int __init reiserfs_xattr_register_handlers(void) | |
767 | -{ | |
768 | - int err = 0; | |
769 | - struct reiserfs_xattr_handler *xah; | |
770 | - struct list_head *p; | |
771 | - | |
772 | - write_lock(&handler_lock); | |
773 | - | |
774 | - /* If we're already initialized, nothing to do */ | |
775 | - if (!list_empty(&xattr_handlers)) { | |
776 | - write_unlock(&handler_lock); | |
777 | - return 0; | |
778 | - } | |
779 | - | |
780 | - /* Add the handlers */ | |
781 | - list_add_tail(&user_handler.handlers, &xattr_handlers); | |
782 | - list_add_tail(&trusted_handler.handlers, &xattr_handlers); | |
783 | -#ifdef CONFIG_REISERFS_FS_SECURITY | |
784 | - list_add_tail(&security_handler.handlers, &xattr_handlers); | |
785 | -#endif | |
786 | -#ifdef CONFIG_REISERFS_FS_POSIX_ACL | |
787 | - list_add_tail(&posix_acl_access_handler.handlers, &xattr_handlers); | |
788 | - list_add_tail(&posix_acl_default_handler.handlers, &xattr_handlers); | |
789 | -#endif | |
790 | - | |
791 | - /* Run initializers, if available */ | |
792 | - list_for_each(p, &xattr_handlers) { | |
793 | - xah = list_entry(p, struct reiserfs_xattr_handler, handlers); | |
794 | - if (xah->init) { | |
795 | - err = xah->init(); | |
796 | - if (err) { | |
797 | - list_del_init(p); | |
798 | - break; | |
799 | - } | |
800 | - } | |
801 | - } | |
802 | - | |
803 | - /* Clean up other handlers, if any failed */ | |
804 | - if (err) | |
805 | - __unregister_handlers(); | |
806 | - | |
807 | - write_unlock(&handler_lock); | |
808 | - return err; | |
809 | -} | |
810 | - | |
811 | -void reiserfs_xattr_unregister_handlers(void) | |
812 | -{ | |
813 | - write_lock(&handler_lock); | |
814 | - __unregister_handlers(); | |
815 | - write_unlock(&handler_lock); | |
816 | -} | |
817 | - | |
818 | static int reiserfs_check_acl(struct inode *inode, int mask) | |
819 | { | |
820 | struct posix_acl *acl; | |
821 | @@ -1157,20 +1074,16 @@ static int xattr_mount_check(struct supe | |
822 | { | |
823 | /* We need generation numbers to ensure that the oid mapping is correct | |
824 | * v3.5 filesystems don't have them. */ | |
825 | - if (!old_format_only(s)) { | |
826 | - set_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt)); | |
827 | - } else if (reiserfs_xattrs_optional(s)) { | |
828 | - /* Old format filesystem, but optional xattrs have been enabled | |
829 | - * at mount time. Error out. */ | |
830 | - reiserfs_warning(s, "jdm-20005", | |
831 | - "xattrs/ACLs not supported on pre v3.6 " | |
832 | - "format filesystem. Failing mount."); | |
833 | - return -EOPNOTSUPP; | |
834 | - } else { | |
835 | - /* Old format filesystem, but no optional xattrs have | |
836 | - * been enabled. This means we silently disable xattrs | |
837 | - * on the filesystem. */ | |
838 | - clear_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt)); | |
839 | + if (old_format_only(s)) { | |
840 | + if (reiserfs_xattrs_optional(s)) { | |
841 | + /* Old format filesystem, but optional xattrs have | |
842 | + * been enabled. Error out. */ | |
843 | + reiserfs_warning(s, "jdm-2005", | |
844 | + "xattrs/ACLs not supported " | |
845 | + "on pre-v3.6 format filesystems. " | |
846 | + "Failing mount."); | |
847 | + return -EOPNOTSUPP; | |
848 | + } | |
849 | } | |
850 | ||
851 | return 0; | |
852 | @@ -1251,9 +1164,11 @@ int reiserfs_xattr_init(struct super_blo | |
853 | } | |
854 | ||
855 | #ifdef CONFIG_REISERFS_FS_XATTR | |
856 | + if (!err) | |
857 | + s->s_xattr = reiserfs_xattr_handlers; | |
858 | + | |
859 | error: | |
860 | if (err) { | |
861 | - clear_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt)); | |
862 | clear_bit(REISERFS_XATTRS_USER, &(REISERFS_SB(s)->s_mount_opt)); | |
863 | clear_bit(REISERFS_POSIXACL, &(REISERFS_SB(s)->s_mount_opt)); | |
864 | } | |
865 | --- a/fs/reiserfs/xattr_security.c | |
866 | +++ b/fs/reiserfs/xattr_security.c | |
867 | @@ -31,35 +31,25 @@ security_set(struct inode *inode, const | |
868 | return reiserfs_xattr_set(inode, name, buffer, size, flags); | |
869 | } | |
870 | ||
871 | -static int security_del(struct inode *inode, const char *name) | |
872 | +static size_t security_list(struct inode *inode, char *list, size_t list_len, | |
873 | + const char *name, size_t namelen) | |
874 | { | |
875 | - if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX)) | |
876 | - return -EINVAL; | |
877 | - | |
878 | - if (IS_PRIVATE(inode)) | |
879 | - return -EPERM; | |
880 | - | |
881 | - return 0; | |
882 | -} | |
883 | - | |
884 | -static int | |
885 | -security_list(struct inode *inode, const char *name, int namelen, char *out) | |
886 | -{ | |
887 | - int len = namelen; | |
888 | + const size_t len = namelen + 1; | |
889 | ||
890 | if (IS_PRIVATE(inode)) | |
891 | return 0; | |
892 | ||
893 | - if (out) | |
894 | - memcpy(out, name, len); | |
895 | + if (list && len <= list_len) { | |
896 | + memcpy(list, name, namelen); | |
897 | + list[namelen] = '\0'; | |
898 | + } | |
899 | ||
900 | return len; | |
901 | } | |
902 | ||
903 | -struct reiserfs_xattr_handler security_handler = { | |
904 | +struct xattr_handler reiserfs_xattr_security_handler = { | |
905 | .prefix = XATTR_SECURITY_PREFIX, | |
906 | .get = security_get, | |
907 | .set = security_set, | |
908 | - .del = security_del, | |
909 | .list = security_list, | |
910 | }; | |
911 | --- a/fs/reiserfs/xattr_trusted.c | |
912 | +++ b/fs/reiserfs/xattr_trusted.c | |
913 | @@ -13,10 +13,7 @@ trusted_get(struct inode *inode, const c | |
914 | if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX)) | |
915 | return -EINVAL; | |
916 | ||
917 | - if (!reiserfs_xattrs(inode->i_sb)) | |
918 | - return -EOPNOTSUPP; | |
919 | - | |
920 | - if (!(capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))) | |
921 | + if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode)) | |
922 | return -EPERM; | |
923 | ||
924 | return reiserfs_xattr_get(inode, name, buffer, size); | |
925 | @@ -29,50 +26,30 @@ trusted_set(struct inode *inode, const c | |
926 | if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX)) | |
927 | return -EINVAL; | |
928 | ||
929 | - if (!reiserfs_xattrs(inode->i_sb)) | |
930 | - return -EOPNOTSUPP; | |
931 | - | |
932 | - if (!(capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))) | |
933 | + if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode)) | |
934 | return -EPERM; | |
935 | ||
936 | return reiserfs_xattr_set(inode, name, buffer, size, flags); | |
937 | } | |
938 | ||
939 | -static int trusted_del(struct inode *inode, const char *name) | |
940 | +static size_t trusted_list(struct inode *inode, char *list, size_t list_size, | |
941 | + const char *name, size_t name_len) | |
942 | { | |
943 | - if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX)) | |
944 | - return -EINVAL; | |
945 | + const size_t len = name_len + 1; | |
946 | ||
947 | - if (!reiserfs_xattrs(inode->i_sb)) | |
948 | - return -EOPNOTSUPP; | |
949 | - | |
950 | - if (!(capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))) | |
951 | - return -EPERM; | |
952 | - | |
953 | - return 0; | |
954 | -} | |
955 | - | |
956 | -static int | |
957 | -trusted_list(struct inode *inode, const char *name, int namelen, char *out) | |
958 | -{ | |
959 | - int len = namelen; | |
960 | - | |
961 | - if (!reiserfs_xattrs(inode->i_sb)) | |
962 | + if (!capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode)) | |
963 | return 0; | |
964 | ||
965 | - if (!(capable(CAP_SYS_ADMIN) || IS_PRIVATE(inode))) | |
966 | - return 0; | |
967 | - | |
968 | - if (out) | |
969 | - memcpy(out, name, len); | |
970 | - | |
971 | + if (list && len <= list_size) { | |
972 | + memcpy(list, name, name_len); | |
973 | + list[name_len] = '\0'; | |
974 | + } | |
975 | return len; | |
976 | } | |
977 | ||
978 | -struct reiserfs_xattr_handler trusted_handler = { | |
979 | +struct xattr_handler reiserfs_xattr_trusted_handler = { | |
980 | .prefix = XATTR_TRUSTED_PREFIX, | |
981 | .get = trusted_get, | |
982 | .set = trusted_set, | |
983 | - .del = trusted_del, | |
984 | .list = trusted_list, | |
985 | }; | |
986 | --- a/fs/reiserfs/xattr_user.c | |
987 | +++ b/fs/reiserfs/xattr_user.c | |
988 | @@ -6,10 +6,6 @@ | |
989 | #include <linux/reiserfs_xattr.h> | |
990 | #include <asm/uaccess.h> | |
991 | ||
992 | -#ifdef CONFIG_REISERFS_FS_POSIX_ACL | |
993 | -# include <linux/reiserfs_acl.h> | |
994 | -#endif | |
995 | - | |
996 | static int | |
997 | user_get(struct inode *inode, const char *name, void *buffer, size_t size) | |
998 | { | |
999 | @@ -25,7 +21,6 @@ static int | |
1000 | user_set(struct inode *inode, const char *name, const void *buffer, | |
1001 | size_t size, int flags) | |
1002 | { | |
1003 | - | |
1004 | if (strlen(name) < sizeof(XATTR_USER_PREFIX)) | |
1005 | return -EINVAL; | |
1006 | ||
1007 | @@ -34,33 +29,23 @@ user_set(struct inode *inode, const char | |
1008 | return reiserfs_xattr_set(inode, name, buffer, size, flags); | |
1009 | } | |
1010 | ||
1011 | -static int user_del(struct inode *inode, const char *name) | |
1012 | +static size_t user_list(struct inode *inode, char *list, size_t list_size, | |
1013 | + const char *name, size_t name_len) | |
1014 | { | |
1015 | - if (strlen(name) < sizeof(XATTR_USER_PREFIX)) | |
1016 | - return -EINVAL; | |
1017 | - | |
1018 | - if (!reiserfs_xattrs_user(inode->i_sb)) | |
1019 | - return -EOPNOTSUPP; | |
1020 | - return 0; | |
1021 | -} | |
1022 | + const size_t len = name_len + 1; | |
1023 | ||
1024 | -static int | |
1025 | -user_list(struct inode *inode, const char *name, int namelen, char *out) | |
1026 | -{ | |
1027 | - int len = namelen; | |
1028 | if (!reiserfs_xattrs_user(inode->i_sb)) | |
1029 | return 0; | |
1030 | - | |
1031 | - if (out) | |
1032 | - memcpy(out, name, len); | |
1033 | - | |
1034 | + if (list && len <= list_size) { | |
1035 | + memcpy(list, name, name_len); | |
1036 | + list[name_len] = '\0'; | |
1037 | + } | |
1038 | return len; | |
1039 | } | |
1040 | ||
1041 | -struct reiserfs_xattr_handler user_handler = { | |
1042 | +struct xattr_handler reiserfs_xattr_user_handler = { | |
1043 | .prefix = XATTR_USER_PREFIX, | |
1044 | .get = user_get, | |
1045 | .set = user_set, | |
1046 | - .del = user_del, | |
1047 | .list = user_list, | |
1048 | }; | |
1049 | --- a/include/linux/reiserfs_acl.h | |
1050 | +++ b/include/linux/reiserfs_acl.h | |
1051 | @@ -52,10 +52,8 @@ int reiserfs_acl_chmod(struct inode *ino | |
1052 | int reiserfs_inherit_default_acl(struct inode *dir, struct dentry *dentry, | |
1053 | struct inode *inode); | |
1054 | int reiserfs_cache_default_acl(struct inode *dir); | |
1055 | -extern int reiserfs_xattr_posix_acl_init(void) __init; | |
1056 | -extern int reiserfs_xattr_posix_acl_exit(void); | |
1057 | -extern struct reiserfs_xattr_handler posix_acl_default_handler; | |
1058 | -extern struct reiserfs_xattr_handler posix_acl_access_handler; | |
1059 | +extern struct xattr_handler reiserfs_posix_acl_default_handler; | |
1060 | +extern struct xattr_handler reiserfs_posix_acl_access_handler; | |
1061 | ||
1062 | static inline void reiserfs_init_acl_access(struct inode *inode) | |
1063 | { | |
1064 | @@ -75,16 +73,6 @@ static inline struct posix_acl *reiserfs | |
1065 | return NULL; | |
1066 | } | |
1067 | ||
1068 | -static inline int reiserfs_xattr_posix_acl_init(void) | |
1069 | -{ | |
1070 | - return 0; | |
1071 | -} | |
1072 | - | |
1073 | -static inline int reiserfs_xattr_posix_acl_exit(void) | |
1074 | -{ | |
1075 | - return 0; | |
1076 | -} | |
1077 | - | |
1078 | static inline int reiserfs_acl_chmod(struct inode *inode) | |
1079 | { | |
1080 | return 0; | |
1081 | --- a/include/linux/reiserfs_fs_sb.h | |
1082 | +++ b/include/linux/reiserfs_fs_sb.h | |
1083 | @@ -450,7 +450,6 @@ enum reiserfs_mount_options { | |
1084 | REISERFS_NO_UNHASHED_RELOCATION, | |
1085 | REISERFS_HASHED_RELOCATION, | |
1086 | REISERFS_ATTRS, | |
1087 | - REISERFS_XATTRS, | |
1088 | REISERFS_XATTRS_USER, | |
1089 | REISERFS_POSIXACL, | |
1090 | REISERFS_BARRIER_NONE, | |
1091 | @@ -488,7 +487,7 @@ enum reiserfs_mount_options { | |
1092 | #define reiserfs_data_log(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_DATA_LOG)) | |
1093 | #define reiserfs_data_ordered(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_DATA_ORDERED)) | |
1094 | #define reiserfs_data_writeback(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_DATA_WRITEBACK)) | |
1095 | -#define reiserfs_xattrs(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_XATTRS)) | |
1096 | +#define reiserfs_xattrs(s) ((s)->s_xattr != NULL) | |
1097 | #define reiserfs_xattrs_user(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_XATTRS_USER)) | |
1098 | #define reiserfs_posixacl(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_POSIXACL)) | |
1099 | #define reiserfs_xattrs_optional(s) (reiserfs_xattrs_user(s) || reiserfs_posixacl(s)) | |
1100 | --- a/include/linux/reiserfs_xattr.h | |
1101 | +++ b/include/linux/reiserfs_xattr.h | |
1102 | @@ -29,20 +29,6 @@ struct iattr; | |
1103 | struct super_block; | |
1104 | struct nameidata; | |
1105 | ||
1106 | -struct reiserfs_xattr_handler { | |
1107 | - char *prefix; | |
1108 | - int (*init) (void); | |
1109 | - void (*exit) (void); | |
1110 | - int (*get) (struct inode * inode, const char *name, void *buffer, | |
1111 | - size_t size); | |
1112 | - int (*set) (struct inode * inode, const char *name, const void *buffer, | |
1113 | - size_t size, int flags); | |
1114 | - int (*del) (struct inode * inode, const char *name); | |
1115 | - int (*list) (struct inode * inode, const char *name, int namelen, | |
1116 | - char *out); | |
1117 | - struct list_head handlers; | |
1118 | -}; | |
1119 | - | |
1120 | int reiserfs_xattr_register_handlers(void) __init; | |
1121 | void reiserfs_xattr_unregister_handlers(void); | |
1122 | int reiserfs_xattr_init(struct super_block *sb, int mount_flags); | |
1123 | @@ -59,13 +45,14 @@ ssize_t reiserfs_listxattr(struct dentry | |
1124 | int reiserfs_removexattr(struct dentry *dentry, const char *name); | |
1125 | int reiserfs_permission(struct inode *inode, int mask); | |
1126 | ||
1127 | -int reiserfs_xattr_del(struct inode *, const char *); | |
1128 | -int reiserfs_xattr_get(const struct inode *, const char *, void *, size_t); | |
1129 | +int reiserfs_xattr_get(struct inode *, const char *, void *, size_t); | |
1130 | +int __reiserfs_xattr_set(struct inode *, const char *, const void *, | |
1131 | + size_t, int); | |
1132 | int reiserfs_xattr_set(struct inode *, const char *, const void *, size_t, int); | |
1133 | ||
1134 | -extern struct reiserfs_xattr_handler user_handler; | |
1135 | -extern struct reiserfs_xattr_handler trusted_handler; | |
1136 | -extern struct reiserfs_xattr_handler security_handler; | |
1137 | +extern struct xattr_handler reiserfs_xattr_user_handler; | |
1138 | +extern struct xattr_handler reiserfs_xattr_trusted_handler; | |
1139 | +extern struct xattr_handler reiserfs_xattr_security_handler; | |
1140 | ||
1141 | static inline void reiserfs_init_xattr_rwsem(struct inode *inode) | |
1142 | { |