]> git.ipfire.org Git - ipfire-2.x.git/blame - src/patches/suse-2.6.27.39/patches.suse/reiserfs-clean-up-xattrs
Imported linux-2.6.27.39 suse/xen patches.
[ipfire-2.x.git] / src / patches / suse-2.6.27.39 / patches.suse / reiserfs-clean-up-xattrs
CommitLineData
2cb7cef9
BS
1From: Jeff Mahoney <jeffm@suse.com>
2Subject: 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
13Signed-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 }