]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.suse/reiserfs-clean-up-xattrs
Updated xen patches taken from suse.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.suse / reiserfs-clean-up-xattrs
1 From: Jeff Mahoney <jeffm@suse.com>
2 Subject: reiserfs: Clean up xattrs when REISERFS_FS_XATTR is unset
3
4 The current reiserfs xattr implementation will not clean up old xattr
5 files if files are deleted when REISERFS_FS_XATTR is unset. This results
6 in inaccessible lost files, wasting space.
7
8 This patch compiles in basic xattr knowledge, such as how to delete them and
9 change ownership for quota tracking. If the file system has never used
10 xattrs, then the operation is quite fast: it returns immediately when
11 it sees there is no .reiserfs_priv directory.
12
13 Signed-off-by: Jeff Mahoney <jeffm@suse.com>
14 ---
15 fs/reiserfs/Makefile | 4
16 fs/reiserfs/xattr.c | 801 +++++++++++++++++++++--------------------
17 include/linux/reiserfs_fs_sb.h | 2
18 include/linux/reiserfs_xattr.h | 29 -
19 4 files changed, 423 insertions(+), 413 deletions(-)
20
21 --- a/fs/reiserfs/Makefile
22 +++ b/fs/reiserfs/Makefile
23 @@ -7,10 +7,10 @@ obj-$(CONFIG_REISERFS_FS) += reiserfs.o
24 reiserfs-objs := bitmap.o do_balan.o namei.o inode.o file.o dir.o fix_node.o \
25 super.o prints.o objectid.o lbalance.o ibalance.o stree.o \
26 hashes.o tail_conversion.o journal.o resize.o \
27 - item_ops.o ioctl.o procfs.o
28 + item_ops.o ioctl.o procfs.o xattr.o
29
30 ifeq ($(CONFIG_REISERFS_FS_XATTR),y)
31 -reiserfs-objs += xattr.o xattr_user.o xattr_trusted.o
32 +reiserfs-objs += xattr_user.o xattr_trusted.o
33 endif
34
35 ifeq ($(CONFIG_REISERFS_FS_SECURITY),y)
36 --- a/fs/reiserfs/xattr.c
37 +++ b/fs/reiserfs/xattr.c
38 @@ -50,9 +50,6 @@
39 #define PRIVROOT_NAME ".reiserfs_priv"
40 #define XAROOT_NAME "xattrs"
41
42 -static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char
43 - *prefix);
44 -
45 /* Returns the dentry referring to the root of the extended attribute
46 * directory tree. If it has already been retrieved, it is used. If it
47 * hasn't been created and the flags indicate creation is allowed, we
48 @@ -143,60 +140,6 @@ static struct dentry *open_xa_dir(const
49 return xadir;
50 }
51
52 -/* Returns a dentry corresponding to a specific extended attribute file
53 - * for the inode. If flags allow, the file is created. Otherwise, a
54 - * valid or negative dentry, or an error is returned. */
55 -static struct dentry *get_xa_file_dentry(const struct inode *inode,
56 - const char *name, int flags)
57 -{
58 - struct dentry *xadir, *xafile;
59 - int err = 0;
60 -
61 - xadir = open_xa_dir(inode, flags);
62 - if (IS_ERR(xadir)) {
63 - return ERR_CAST(xadir);
64 - } else if (xadir && !xadir->d_inode) {
65 - dput(xadir);
66 - return ERR_PTR(-ENODATA);
67 - }
68 -
69 - xafile = lookup_one_len(name, xadir, strlen(name));
70 - if (IS_ERR(xafile)) {
71 - dput(xadir);
72 - return ERR_CAST(xafile);
73 - }
74 -
75 - if (xafile->d_inode) { /* file exists */
76 - if (flags & XATTR_CREATE) {
77 - err = -EEXIST;
78 - dput(xafile);
79 - goto out;
80 - }
81 - } else if (flags & XATTR_REPLACE || flags & FL_READONLY) {
82 - goto out;
83 - } else {
84 - /* inode->i_mutex is down, so nothing else can try to create
85 - * the same xattr */
86 - err = xadir->d_inode->i_op->create(xadir->d_inode, xafile,
87 - 0700 | S_IFREG, NULL);
88 -
89 - if (err) {
90 - dput(xafile);
91 - goto out;
92 - }
93 - }
94 -
95 - out:
96 - dput(xadir);
97 - if (err)
98 - xafile = ERR_PTR(err);
99 - else if (!xafile->d_inode) {
100 - dput(xafile);
101 - xafile = ERR_PTR(-ENODATA);
102 - }
103 - return xafile;
104 -}
105 -
106 /*
107 * this is very similar to fs/reiserfs/dir.c:reiserfs_readdir, but
108 * we need to drop the path before calling the filldir struct. That
109 @@ -369,6 +312,251 @@ int xattr_readdir(struct inode *inode, f
110 return res;
111 }
112
113 +static int
114 +__reiserfs_xattr_del(struct dentry *xadir, const char *name, int namelen)
115 +{
116 + struct dentry *dentry;
117 + struct inode *dir = xadir->d_inode;
118 + int err = 0;
119 +
120 + dentry = lookup_one_len(name, xadir, namelen);
121 + if (IS_ERR(dentry)) {
122 + err = PTR_ERR(dentry);
123 + goto out;
124 + } else if (!dentry->d_inode) {
125 + err = -ENODATA;
126 + goto out_file;
127 + }
128 +
129 + /* Skip directories.. */
130 + if (S_ISDIR(dentry->d_inode->i_mode))
131 + goto out_file;
132 +
133 + if (!IS_PRIVATE(dentry->d_inode)) {
134 + reiserfs_error(dir->i_sb, "jdm-20003",
135 + "OID %08x [%.*s/%.*s] doesn't have "
136 + "priv flag set [parent is %sset].",
137 + le32_to_cpu(INODE_PKEY(dentry->d_inode)->
138 + k_objectid), xadir->d_name.len,
139 + xadir->d_name.name, namelen, name,
140 + IS_PRIVATE(xadir->d_inode) ? "" :
141 + "not ");
142 + dput(dentry);
143 + return -EIO;
144 + }
145 +
146 + err = dir->i_op->unlink(dir, dentry);
147 + if (!err)
148 + d_delete(dentry);
149 +
150 +out_file:
151 + dput(dentry);
152 +
153 +out:
154 + return err;
155 +}
156 +
157 +/* The following are side effects of other operations that aren't explicitly
158 + * modifying extended attributes. This includes operations such as permissions
159 + * or ownership changes, object deletions, etc. */
160 +
161 +static int
162 +reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen,
163 + loff_t offset, u64 ino, unsigned int d_type)
164 +{
165 + struct dentry *xadir = (struct dentry *)buf;
166 +
167 + return __reiserfs_xattr_del(xadir, name, namelen);
168 +
169 +}
170 +
171 +/* This is called w/ inode->i_mutex downed */
172 +int reiserfs_delete_xattrs(struct inode *inode)
173 +{
174 + struct dentry *dir, *root;
175 + int err = 0;
176 +
177 + /* Skip out, an xattr has no xattrs associated with it */
178 + if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1)
179 + return 0;
180 +
181 + reiserfs_read_lock_xattrs(inode->i_sb);
182 + dir = open_xa_dir(inode, FL_READONLY);
183 + reiserfs_read_unlock_xattrs(inode->i_sb);
184 + if (IS_ERR(dir)) {
185 + err = PTR_ERR(dir);
186 + goto out;
187 + } else if (!dir->d_inode) {
188 + dput(dir);
189 + return 0;
190 + }
191 +
192 + lock_kernel();
193 + err = xattr_readdir(dir->d_inode, reiserfs_delete_xattrs_filler, dir);
194 + if (err) {
195 + unlock_kernel();
196 + goto out_dir;
197 + }
198 +
199 + /* Leftovers besides . and .. -- that's not good. */
200 + if (dir->d_inode->i_nlink <= 2) {
201 + root = get_xa_root(inode->i_sb, XATTR_REPLACE);
202 + reiserfs_write_lock_xattrs(inode->i_sb);
203 + err = vfs_rmdir(root->d_inode, dir);
204 + reiserfs_write_unlock_xattrs(inode->i_sb);
205 + dput(root);
206 + } else {
207 + reiserfs_warning(inode->i_sb, "jdm-20006",
208 + "Couldn't remove all entries in directory");
209 + }
210 + unlock_kernel();
211 +
212 +out_dir:
213 + dput(dir);
214 +
215 +out:
216 + if (!err)
217 + REISERFS_I(inode)->i_flags =
218 + REISERFS_I(inode)->i_flags & ~i_has_xattr_dir;
219 + return err;
220 +}
221 +
222 +struct reiserfs_chown_buf {
223 + struct inode *inode;
224 + struct dentry *xadir;
225 + struct iattr *attrs;
226 +};
227 +
228 +/* XXX: If there is a better way to do this, I'd love to hear about it */
229 +static int
230 +reiserfs_chown_xattrs_filler(void *buf, const char *name, int namelen,
231 + loff_t offset, u64 ino, unsigned int d_type)
232 +{
233 + struct reiserfs_chown_buf *chown_buf = (struct reiserfs_chown_buf *)buf;
234 + struct dentry *xafile, *xadir = chown_buf->xadir;
235 + struct iattr *attrs = chown_buf->attrs;
236 + int err = 0;
237 +
238 + xafile = lookup_one_len(name, xadir, namelen);
239 + if (IS_ERR(xafile))
240 + return PTR_ERR(xafile);
241 + else if (!xafile->d_inode) {
242 + dput(xafile);
243 + return -ENODATA;
244 + }
245 +
246 + if (!S_ISDIR(xafile->d_inode->i_mode))
247 + err = notify_change(xafile, attrs);
248 + dput(xafile);
249 +
250 + return err;
251 +}
252 +
253 +int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs)
254 +{
255 + struct dentry *dir;
256 + int err = 0;
257 + struct reiserfs_chown_buf buf;
258 + unsigned int ia_valid = attrs->ia_valid;
259 +
260 + /* Skip out, an xattr has no xattrs associated with it */
261 + if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1)
262 + return 0;
263 +
264 + reiserfs_read_lock_xattrs(inode->i_sb);
265 + dir = open_xa_dir(inode, FL_READONLY);
266 + reiserfs_read_unlock_xattrs(inode->i_sb);
267 + if (IS_ERR(dir)) {
268 + if (PTR_ERR(dir) != -ENODATA)
269 + err = PTR_ERR(dir);
270 + goto out;
271 + } else if (!dir->d_inode) {
272 + dput(dir);
273 + goto out;
274 + }
275 +
276 + lock_kernel();
277 +
278 + attrs->ia_valid &= (ATTR_UID | ATTR_GID | ATTR_CTIME);
279 + buf.xadir = dir;
280 + buf.attrs = attrs;
281 + buf.inode = inode;
282 +
283 + err = xattr_readdir(dir->d_inode, reiserfs_chown_xattrs_filler, &buf);
284 + if (err) {
285 + unlock_kernel();
286 + goto out_dir;
287 + }
288 +
289 + err = notify_change(dir, attrs);
290 + unlock_kernel();
291 +
292 +out_dir:
293 + dput(dir);
294 +
295 +out:
296 + attrs->ia_valid = ia_valid;
297 + return err;
298 +}
299 +
300 +#ifdef CONFIG_REISERFS_FS_XATTR
301 +static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char
302 + *prefix);
303 +
304 +/* Returns a dentry corresponding to a specific extended attribute file
305 + * for the inode. If flags allow, the file is created. Otherwise, a
306 + * valid or negative dentry, or an error is returned. */
307 +static struct dentry *get_xa_file_dentry(const struct inode *inode,
308 + const char *name, int flags)
309 +{
310 + struct dentry *xadir, *xafile;
311 + int err = 0;
312 +
313 + xadir = open_xa_dir(inode, flags);
314 + if (IS_ERR(xadir)) {
315 + return ERR_CAST(xadir);
316 + } else if (xadir && !xadir->d_inode) {
317 + dput(xadir);
318 + return ERR_PTR(-ENODATA);
319 + }
320 +
321 + xafile = lookup_one_len(name, xadir, strlen(name));
322 + if (IS_ERR(xafile)) {
323 + dput(xadir);
324 + return ERR_CAST(xafile);
325 + }
326 +
327 + if (xafile->d_inode) { /* file exists */
328 + if (flags & XATTR_CREATE) {
329 + err = -EEXIST;
330 + dput(xafile);
331 + goto out;
332 + }
333 + } else if (flags & XATTR_REPLACE || flags & FL_READONLY) {
334 + goto out;
335 + } else {
336 + /* inode->i_mutex is down, so nothing else can try to create
337 + * the same xattr */
338 + err = xadir->d_inode->i_op->create(xadir->d_inode, xafile,
339 + 0700 | S_IFREG, NULL);
340 +
341 + if (err) {
342 + dput(xafile);
343 + goto out;
344 + }
345 + }
346 +
347 +out:
348 + dput(xadir);
349 + if (err)
350 + xafile = ERR_PTR(err);
351 + else if (!xafile->d_inode) {
352 + dput(xafile);
353 + xafile = ERR_PTR(-ENODATA);
354 + }
355 + return xafile;
356 +}
357 +
358 /* Internal operations on file data */
359 static inline void reiserfs_put_page(struct page *page)
360 {
361 @@ -554,274 +742,85 @@ reiserfs_xattr_get(const struct inode *i
362 goto out_dput;
363 }
364
365 - while (file_pos < isize) {
366 - size_t chunk;
367 - char *data;
368 - size_t skip = 0;
369 - if (isize - file_pos > PAGE_CACHE_SIZE)
370 - chunk = PAGE_CACHE_SIZE;
371 - else
372 - chunk = isize - file_pos;
373 -
374 - page = reiserfs_get_page(dentry->d_inode, file_pos);
375 - if (IS_ERR(page)) {
376 - err = PTR_ERR(page);
377 - goto out_dput;
378 - }
379 -
380 - lock_page(page);
381 - data = page_address(page);
382 - if (file_pos == 0) {
383 - struct reiserfs_xattr_header *rxh =
384 - (struct reiserfs_xattr_header *)data;
385 - skip = file_pos = sizeof(struct reiserfs_xattr_header);
386 - chunk -= skip;
387 - /* Magic doesn't match up.. */
388 - if (rxh->h_magic != cpu_to_le32(REISERFS_XATTR_MAGIC)) {
389 - unlock_page(page);
390 - reiserfs_put_page(page);
391 - reiserfs_warning(inode->i_sb, "jdm-20001",
392 - "Invalid magic for xattr (%s) "
393 - "associated with %k", name,
394 - INODE_PKEY(inode));
395 - err = -EIO;
396 - goto out_dput;
397 - }
398 - hash = le32_to_cpu(rxh->h_hash);
399 - }
400 - memcpy(buffer + buffer_pos, data + skip, chunk);
401 - unlock_page(page);
402 - reiserfs_put_page(page);
403 - file_pos += chunk;
404 - buffer_pos += chunk;
405 - skip = 0;
406 - }
407 - err = isize - sizeof(struct reiserfs_xattr_header);
408 -
409 - if (xattr_hash(buffer, isize - sizeof(struct reiserfs_xattr_header)) !=
410 - hash) {
411 - reiserfs_warning(inode->i_sb, "jdm-20002",
412 - "Invalid hash for xattr (%s) associated "
413 - "with %k", name, INODE_PKEY(inode));
414 - err = -EIO;
415 - }
416 -
417 - out_dput:
418 - dput(dentry);
419 -
420 - out:
421 - return err;
422 -}
423 -
424 -static int
425 -__reiserfs_xattr_del(struct dentry *xadir, const char *name, int namelen)
426 -{
427 - struct dentry *dentry;
428 - struct inode *dir = xadir->d_inode;
429 - int err = 0;
430 -
431 - dentry = lookup_one_len(name, xadir, namelen);
432 - if (IS_ERR(dentry)) {
433 - err = PTR_ERR(dentry);
434 - goto out;
435 - } else if (!dentry->d_inode) {
436 - err = -ENODATA;
437 - goto out_file;
438 - }
439 -
440 - /* Skip directories.. */
441 - if (S_ISDIR(dentry->d_inode->i_mode))
442 - goto out_file;
443 -
444 - if (!IS_PRIVATE(dentry->d_inode)) {
445 - reiserfs_error(dir->i_sb, "jdm-20003",
446 - "OID %08x [%.*s/%.*s] doesn't have "
447 - "priv flag set [parent is %sset].",
448 - le32_to_cpu(INODE_PKEY(dentry->d_inode)->
449 - k_objectid), xadir->d_name.len,
450 - xadir->d_name.name, namelen, name,
451 - IS_PRIVATE(xadir->d_inode) ? "" :
452 - "not ");
453 - dput(dentry);
454 - return -EIO;
455 - }
456 -
457 - err = dir->i_op->unlink(dir, dentry);
458 - if (!err)
459 - d_delete(dentry);
460 -
461 - out_file:
462 - dput(dentry);
463 -
464 - out:
465 - return err;
466 -}
467 -
468 -int reiserfs_xattr_del(struct inode *inode, const char *name)
469 -{
470 - struct dentry *dir;
471 - int err;
472 -
473 - dir = open_xa_dir(inode, FL_READONLY);
474 - if (IS_ERR(dir)) {
475 - err = PTR_ERR(dir);
476 - goto out;
477 - }
478 -
479 - err = __reiserfs_xattr_del(dir, name, strlen(name));
480 - dput(dir);
481 -
482 - if (!err) {
483 - inode->i_ctime = CURRENT_TIME_SEC;
484 - mark_inode_dirty(inode);
485 - }
486 -
487 - out:
488 - return err;
489 -}
490 -
491 -/* The following are side effects of other operations that aren't explicitly
492 - * modifying extended attributes. This includes operations such as permissions
493 - * or ownership changes, object deletions, etc. */
494 -
495 -static int
496 -reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen,
497 - loff_t offset, u64 ino, unsigned int d_type)
498 -{
499 - struct dentry *xadir = (struct dentry *)buf;
500 -
501 - return __reiserfs_xattr_del(xadir, name, namelen);
502 -
503 -}
504 -
505 -/* This is called w/ inode->i_mutex downed */
506 -int reiserfs_delete_xattrs(struct inode *inode)
507 -{
508 - struct dentry *dir, *root;
509 - int err = 0;
510 -
511 - /* Skip out, an xattr has no xattrs associated with it */
512 - if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1 ||
513 - !reiserfs_xattrs(inode->i_sb)) {
514 - return 0;
515 - }
516 - reiserfs_read_lock_xattrs(inode->i_sb);
517 - dir = open_xa_dir(inode, FL_READONLY);
518 - reiserfs_read_unlock_xattrs(inode->i_sb);
519 - if (IS_ERR(dir)) {
520 - err = PTR_ERR(dir);
521 - goto out;
522 - } else if (!dir->d_inode) {
523 - dput(dir);
524 - return 0;
525 - }
526 -
527 - lock_kernel();
528 - err = xattr_readdir(dir->d_inode, reiserfs_delete_xattrs_filler, dir);
529 - if (err) {
530 - unlock_kernel();
531 - goto out_dir;
532 - }
533 -
534 - /* Leftovers besides . and .. -- that's not good. */
535 - if (dir->d_inode->i_nlink <= 2) {
536 - root = get_xa_root(inode->i_sb, XATTR_REPLACE);
537 - reiserfs_write_lock_xattrs(inode->i_sb);
538 - err = vfs_rmdir(root->d_inode, dir);
539 - reiserfs_write_unlock_xattrs(inode->i_sb);
540 - dput(root);
541 - } else {
542 - reiserfs_warning(inode->i_sb, "jdm-20006",
543 - "Couldn't remove all entries in directory");
544 - }
545 - unlock_kernel();
546 -
547 - out_dir:
548 - dput(dir);
549 -
550 - out:
551 - if (!err)
552 - REISERFS_I(inode)->i_flags =
553 - REISERFS_I(inode)->i_flags & ~i_has_xattr_dir;
554 - return err;
555 -}
556 + while (file_pos < isize) {
557 + size_t chunk;
558 + char *data;
559 + size_t skip = 0;
560 + if (isize - file_pos > PAGE_CACHE_SIZE)
561 + chunk = PAGE_CACHE_SIZE;
562 + else
563 + chunk = isize - file_pos;
564
565 -struct reiserfs_chown_buf {
566 - struct inode *inode;
567 - struct dentry *xadir;
568 - struct iattr *attrs;
569 -};
570 + page = reiserfs_get_page(dentry->d_inode, file_pos);
571 + if (IS_ERR(page)) {
572 + err = PTR_ERR(page);
573 + goto out_dput;
574 + }
575
576 -/* XXX: If there is a better way to do this, I'd love to hear about it */
577 -static int
578 -reiserfs_chown_xattrs_filler(void *buf, const char *name, int namelen,
579 - loff_t offset, u64 ino, unsigned int d_type)
580 -{
581 - struct reiserfs_chown_buf *chown_buf = (struct reiserfs_chown_buf *)buf;
582 - struct dentry *xafile, *xadir = chown_buf->xadir;
583 - struct iattr *attrs = chown_buf->attrs;
584 - int err = 0;
585 + lock_page(page);
586 + data = page_address(page);
587 + if (file_pos == 0) {
588 + struct reiserfs_xattr_header *rxh =
589 + (struct reiserfs_xattr_header *)data;
590 + skip = file_pos = sizeof(struct reiserfs_xattr_header);
591 + chunk -= skip;
592 + /* Magic doesn't match up.. */
593 + if (rxh->h_magic != cpu_to_le32(REISERFS_XATTR_MAGIC)) {
594 + unlock_page(page);
595 + reiserfs_put_page(page);
596 + reiserfs_warning(inode->i_sb, "jdm-20001",
597 + "Invalid magic for xattr (%s) "
598 + "associated with %k", name,
599 + INODE_PKEY(inode));
600 + err = -EIO;
601 + goto out_dput;
602 + }
603 + hash = le32_to_cpu(rxh->h_hash);
604 + }
605 + memcpy(buffer + buffer_pos, data + skip, chunk);
606 + unlock_page(page);
607 + reiserfs_put_page(page);
608 + file_pos += chunk;
609 + buffer_pos += chunk;
610 + skip = 0;
611 + }
612 + err = isize - sizeof(struct reiserfs_xattr_header);
613
614 - xafile = lookup_one_len(name, xadir, namelen);
615 - if (IS_ERR(xafile))
616 - return PTR_ERR(xafile);
617 - else if (!xafile->d_inode) {
618 - dput(xafile);
619 - return -ENODATA;
620 + if (xattr_hash(buffer, isize - sizeof(struct reiserfs_xattr_header)) !=
621 + hash) {
622 + reiserfs_warning(inode->i_sb, "jdm-20002",
623 + "Invalid hash for xattr (%s) associated "
624 + "with %k", name, INODE_PKEY(inode));
625 + err = -EIO;
626 }
627
628 - if (!S_ISDIR(xafile->d_inode->i_mode))
629 - err = notify_change(xafile, attrs);
630 - dput(xafile);
631 +out_dput:
632 + dput(dentry);
633
634 +out:
635 return err;
636 }
637
638 -int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs)
639 +int reiserfs_xattr_del(struct inode *inode, const char *name)
640 {
641 struct dentry *dir;
642 - int err = 0;
643 - struct reiserfs_chown_buf buf;
644 - unsigned int ia_valid = attrs->ia_valid;
645 + int err;
646
647 - /* Skip out, an xattr has no xattrs associated with it */
648 - if (IS_PRIVATE(inode) || get_inode_sd_version(inode) == STAT_DATA_V1 ||
649 - !reiserfs_xattrs(inode->i_sb)) {
650 - return 0;
651 - }
652 - reiserfs_read_lock_xattrs(inode->i_sb);
653 dir = open_xa_dir(inode, FL_READONLY);
654 - reiserfs_read_unlock_xattrs(inode->i_sb);
655 if (IS_ERR(dir)) {
656 - if (PTR_ERR(dir) != -ENODATA)
657 - err = PTR_ERR(dir);
658 - goto out;
659 - } else if (!dir->d_inode) {
660 - dput(dir);
661 + err = PTR_ERR(dir);
662 goto out;
663 }
664
665 - lock_kernel();
666 -
667 - attrs->ia_valid &= (ATTR_UID | ATTR_GID | ATTR_CTIME);
668 - buf.xadir = dir;
669 - buf.attrs = attrs;
670 - buf.inode = inode;
671 + err = __reiserfs_xattr_del(dir, name, strlen(name));
672 + dput(dir);
673
674 - err = xattr_readdir(dir->d_inode, reiserfs_chown_xattrs_filler, &buf);
675 - if (err) {
676 - unlock_kernel();
677 - goto out_dir;
678 + if (!err) {
679 + inode->i_ctime = CURRENT_TIME_SEC;
680 + mark_inode_dirty(inode);
681 }
682
683 - err = notify_change(dir, attrs);
684 - unlock_kernel();
685 -
686 - out_dir:
687 - dput(dir);
688 -
689 out:
690 - attrs->ia_valid = ia_valid;
691 return err;
692 }
693
694 @@ -1101,6 +1100,94 @@ void reiserfs_xattr_unregister_handlers(
695 write_unlock(&handler_lock);
696 }
697
698 +static int reiserfs_check_acl(struct inode *inode, int mask)
699 +{
700 + struct posix_acl *acl;
701 + int error = -EAGAIN; /* do regular unix permission checks by default */
702 +
703 + reiserfs_read_lock_xattr_i(inode);
704 + reiserfs_read_lock_xattrs(inode->i_sb);
705 +
706 + acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS);
707 +
708 + reiserfs_read_unlock_xattrs(inode->i_sb);
709 + reiserfs_read_unlock_xattr_i(inode);
710 +
711 + if (acl) {
712 + if (!IS_ERR(acl)) {
713 + error = posix_acl_permission(inode, acl, mask);
714 + posix_acl_release(acl);
715 + } else if (PTR_ERR(acl) != -ENODATA)
716 + error = PTR_ERR(acl);
717 + }
718 +
719 + return error;
720 +}
721 +
722 +int reiserfs_permission(struct inode *inode, int mask)
723 +{
724 + /*
725 + * We don't do permission checks on the internal objects.
726 + * Permissions are determined by the "owning" object.
727 + */
728 + if (IS_PRIVATE(inode))
729 + return 0;
730 + /*
731 + * Stat data v1 doesn't support ACLs.
732 + */
733 + if (get_inode_sd_version(inode) == STAT_DATA_V1)
734 + return generic_permission(inode, mask, NULL);
735 + else
736 + return generic_permission(inode, mask, reiserfs_check_acl);
737 +}
738 +
739 +static int create_privroot(struct dentry *dentry)
740 +{
741 + int err;
742 + struct inode *inode = dentry->d_parent->d_inode;
743 + mutex_lock_nested(&inode->i_mutex, I_MUTEX_XATTR);
744 + err = inode->i_op->mkdir(inode, dentry, 0700);
745 + mutex_unlock(&inode->i_mutex);
746 + if (err) {
747 + dput(dentry);
748 + dentry = NULL;
749 + }
750 +
751 + if (dentry && dentry->d_inode)
752 + reiserfs_info(dentry->d_sb, "Created %s - reserved for xattr "
753 + "storage.\n", PRIVROOT_NAME);
754 +
755 + return err;
756 +}
757 +
758 +static int xattr_mount_check(struct super_block *s)
759 +{
760 + /* We need generation numbers to ensure that the oid mapping is correct
761 + * v3.5 filesystems don't have them. */
762 + if (!old_format_only(s)) {
763 + set_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt));
764 + } else if (reiserfs_xattrs_optional(s)) {
765 + /* Old format filesystem, but optional xattrs have been enabled
766 + * at mount time. Error out. */
767 + reiserfs_warning(s, "jdm-20005",
768 + "xattrs/ACLs not supported on pre v3.6 "
769 + "format filesystem. Failing mount.");
770 + return -EOPNOTSUPP;
771 + } else {
772 + /* Old format filesystem, but no optional xattrs have
773 + * been enabled. This means we silently disable xattrs
774 + * on the filesystem. */
775 + clear_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt));
776 + }
777 +
778 + return 0;
779 +}
780 +
781 +#else
782 +int __init reiserfs_xattr_register_handlers(void) { return 0; }
783 +void reiserfs_xattr_unregister_handlers(void) {}
784 +#endif
785 +
786 /* This will catch lookups from the fs root to .reiserfs_priv */
787 static int
788 xattr_lookup_poison(struct dentry *dentry, struct qstr *q1, struct qstr *name)
789 @@ -1127,47 +1214,23 @@ int reiserfs_xattr_init(struct super_blo
790 {
791 int err = 0;
792
793 - /* We need generation numbers to ensure that the oid mapping is correct
794 - * v3.5 filesystems don't have them. */
795 - if (!old_format_only(s)) {
796 - set_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt));
797 - } else if (reiserfs_xattrs_optional(s)) {
798 - /* Old format filesystem, but optional xattrs have been enabled
799 - * at mount time. Error out. */
800 - reiserfs_warning(s, "jdm-20005",
801 - "xattrs/ACLs not supported on pre v3.6 "
802 - "format filesystem. Failing mount.");
803 - err = -EOPNOTSUPP;
804 +#ifdef CONFIG_REISERFS_FS_XATTR
805 + err = xattr_mount_check(s);
806 + if (err)
807 goto error;
808 - } else {
809 - /* Old format filesystem, but no optional xattrs have been enabled. This
810 - * means we silently disable xattrs on the filesystem. */
811 - clear_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt));
812 - }
813 +#endif
814
815 /* If we don't have the privroot located yet - go find it */
816 - if (reiserfs_xattrs(s) && !REISERFS_SB(s)->priv_root) {
817 + if (!REISERFS_SB(s)->priv_root) {
818 struct dentry *dentry;
819 dentry = lookup_one_len(PRIVROOT_NAME, s->s_root,
820 strlen(PRIVROOT_NAME));
821 if (!IS_ERR(dentry)) {
822 - if (!(mount_flags & MS_RDONLY) && !dentry->d_inode) {
823 - struct inode *inode = dentry->d_parent->d_inode;
824 - mutex_lock_nested(&inode->i_mutex,
825 - I_MUTEX_XATTR);
826 - err = inode->i_op->mkdir(inode, dentry, 0700);
827 - mutex_unlock(&inode->i_mutex);
828 - if (err) {
829 - dput(dentry);
830 - dentry = NULL;
831 - }
832 -
833 - if (dentry && dentry->d_inode)
834 - reiserfs_info(s, "Created %s - "
835 - "reserved for xattr "
836 - "storage.\n",
837 - PRIVROOT_NAME);
838 - } else if (!dentry->d_inode) {
839 +#ifdef CONFIG_REISERFS_FS_XATTR
840 + if (!(mount_flags & MS_RDONLY) && !dentry->d_inode)
841 + err = create_privroot(dentry);
842 +#endif
843 + if (!dentry->d_inode) {
844 dput(dentry);
845 dentry = NULL;
846 }
847 @@ -1178,73 +1241,37 @@ int reiserfs_xattr_init(struct super_blo
848 s->s_root->d_op = &xattr_lookup_poison_ops;
849 dentry->d_inode->i_flags |= S_PRIVATE;
850 REISERFS_SB(s)->priv_root = dentry;
851 - } else if (!(mount_flags & MS_RDONLY)) { /* xattrs are unavailable */
852 - /* If we're read-only it just means that the dir hasn't been
853 - * created. Not an error -- just no xattrs on the fs. We'll
854 - * check again if we go read-write */
855 +#ifdef CONFIG_REISERFS_FS_XATTR
856 + /* xattrs are unavailable */
857 + } else if (!(mount_flags & MS_RDONLY)) {
858 + /* If we're read-only it just means that the dir
859 + * hasn't been created. Not an error -- just no
860 + * xattrs on the fs. We'll check again if we
861 + * go read-write */
862 reiserfs_warning(s, "jdm-20006",
863 "xattrs/ACLs enabled and couldn't "
864 "find/create .reiserfs_priv. "
865 "Failing mount.");
866 err = -EOPNOTSUPP;
867 +#endif
868 }
869 }
870
871 - error:
872 - /* This is only nonzero if there was an error initializing the xattr
873 - * directory or if there is a condition where we don't support them. */
874 +#ifdef CONFIG_REISERFS_FS_XATTR
875 +error:
876 if (err) {
877 clear_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt));
878 clear_bit(REISERFS_XATTRS_USER, &(REISERFS_SB(s)->s_mount_opt));
879 clear_bit(REISERFS_POSIXACL, &(REISERFS_SB(s)->s_mount_opt));
880 }
881 +#endif
882
883 /* The super_block MS_POSIXACL must mirror the (no)acl mount option. */
884 s->s_flags = s->s_flags & ~MS_POSIXACL;
885 +#ifdef CONFIG_REISERFS_FS_POSIX_ACL
886 if (reiserfs_posixacl(s))
887 s->s_flags |= MS_POSIXACL;
888 +#endif
889
890 return err;
891 }
892 -
893 -static int reiserfs_check_acl(struct inode *inode, int mask)
894 -{
895 - struct posix_acl *acl;
896 - int error = -EAGAIN; /* do regular unix permission checks by default */
897 -
898 - reiserfs_read_lock_xattr_i(inode);
899 - reiserfs_read_lock_xattrs(inode->i_sb);
900 -
901 - acl = reiserfs_get_acl(inode, ACL_TYPE_ACCESS);
902 -
903 - reiserfs_read_unlock_xattrs(inode->i_sb);
904 - reiserfs_read_unlock_xattr_i(inode);
905 -
906 - if (acl) {
907 - if (!IS_ERR(acl)) {
908 - error = posix_acl_permission(inode, acl, mask);
909 - posix_acl_release(acl);
910 - } else if (PTR_ERR(acl) != -ENODATA)
911 - error = PTR_ERR(acl);
912 - }
913 -
914 - return error;
915 -}
916 -
917 -int reiserfs_permission(struct inode *inode, int mask)
918 -{
919 - /*
920 - * We don't do permission checks on the internal objects.
921 - * Permissions are determined by the "owning" object.
922 - */
923 - if (IS_PRIVATE(inode))
924 - return 0;
925 -
926 - /*
927 - * Stat data v1 doesn't support ACLs.
928 - */
929 - if (get_inode_sd_version(inode) == STAT_DATA_V1)
930 - return generic_permission(inode, mask, NULL);
931 - else
932 - return generic_permission(inode, mask, reiserfs_check_acl);
933 -}
934 --- a/include/linux/reiserfs_fs_sb.h
935 +++ b/include/linux/reiserfs_fs_sb.h
936 @@ -401,8 +401,8 @@ struct reiserfs_sb_info {
937 int reserved_blocks; /* amount of blocks reserved for further allocations */
938 spinlock_t bitmap_lock; /* this lock on now only used to protect reserved_blocks variable */
939 struct dentry *priv_root; /* root of /.reiserfs_priv */
940 -#ifdef CONFIG_REISERFS_FS_XATTR
941 struct dentry *xattr_root; /* root of /.reiserfs_priv/.xa */
942 +#ifdef CONFIG_REISERFS_FS_XATTR
943 struct rw_semaphore xattr_dir_sem;
944 #endif
945 int j_errno;
946 --- a/include/linux/reiserfs_xattr.h
947 +++ b/include/linux/reiserfs_xattr.h
948 @@ -43,6 +43,12 @@ struct reiserfs_xattr_handler {
949 struct list_head handlers;
950 };
951
952 +int reiserfs_xattr_register_handlers(void) __init;
953 +void reiserfs_xattr_unregister_handlers(void);
954 +int reiserfs_xattr_init(struct super_block *sb, int mount_flags);
955 +int reiserfs_delete_xattrs(struct inode *inode);
956 +int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs);
957 +
958 #ifdef CONFIG_REISERFS_FS_XATTR
959 #define has_xattr_dir(inode) (REISERFS_I(inode)->i_flags & i_has_xattr_dir)
960 ssize_t reiserfs_getxattr(struct dentry *dentry, const char *name,
961 @@ -51,9 +57,6 @@ int reiserfs_setxattr(struct dentry *den
962 const void *value, size_t size, int flags);
963 ssize_t reiserfs_listxattr(struct dentry *dentry, char *buffer, size_t size);
964 int reiserfs_removexattr(struct dentry *dentry, const char *name);
965 -int reiserfs_delete_xattrs(struct inode *inode);
966 -int reiserfs_chown_xattrs(struct inode *inode, struct iattr *attrs);
967 -int reiserfs_xattr_init(struct super_block *sb, int mount_flags);
968 int reiserfs_permission(struct inode *inode, int mask);
969
970 int reiserfs_xattr_del(struct inode *, const char *);
971 @@ -64,9 +67,6 @@ extern struct reiserfs_xattr_handler use
972 extern struct reiserfs_xattr_handler trusted_handler;
973 extern struct reiserfs_xattr_handler security_handler;
974
975 -int reiserfs_xattr_register_handlers(void) __init;
976 -void reiserfs_xattr_unregister_handlers(void);
977 -
978 static inline void reiserfs_write_lock_xattrs(struct super_block *sb)
979 {
980 down_write(&REISERFS_XATTR_DIR_SEM(sb));
981 @@ -121,23 +121,6 @@ static inline void reiserfs_init_xattr_r
982
983 #define reiserfs_permission NULL
984
985 -#define reiserfs_xattr_register_handlers() 0
986 -#define reiserfs_xattr_unregister_handlers()
987 -
988 -static inline int reiserfs_delete_xattrs(struct inode *inode)
989 -{
990 - return 0;
991 -};
992 -static inline int reiserfs_chown_xattrs(struct inode *inode,
993 - struct iattr *attrs)
994 -{
995 - return 0;
996 -};
997 -static inline int reiserfs_xattr_init(struct super_block *sb, int mount_flags)
998 -{
999 - sb->s_flags = (sb->s_flags & ~MS_POSIXACL); /* to be sure */
1000 - return 0;
1001 -};
1002 static inline void reiserfs_init_xattr_rwsem(struct inode *inode)
1003 {
1004 }