diff options
author | Andreas Gruenbacher <agruenba@redhat.com> | 2016-09-29 11:48:38 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2016-10-07 20:10:42 -0400 |
commit | b6ba11773d9535fbe068232f2231c99740bb32db (patch) | |
tree | c4e228bae828526948e65ea350a4d03202bf8dce | |
parent | bf02f5d2c080cf61b770e09add602ca360d538fb (diff) |
vfs: Move xattr_resolve_name to the front of fs/xattr.c
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
-rw-r--r-- | fs/xattr.c | 101 |
1 files changed, 50 insertions, 51 deletions
diff --git a/fs/xattr.c b/fs/xattr.c index 1f72c9217398..bb3cbbfd982d 100644 --- a/fs/xattr.c +++ b/fs/xattr.c | |||
@@ -24,6 +24,56 @@ | |||
24 | 24 | ||
25 | #include <asm/uaccess.h> | 25 | #include <asm/uaccess.h> |
26 | 26 | ||
27 | static const char * | ||
28 | strcmp_prefix(const char *a, const char *a_prefix) | ||
29 | { | ||
30 | while (*a_prefix && *a == *a_prefix) { | ||
31 | a++; | ||
32 | a_prefix++; | ||
33 | } | ||
34 | return *a_prefix ? NULL : a; | ||
35 | } | ||
36 | |||
37 | /* | ||
38 | * In order to implement different sets of xattr operations for each xattr | ||
39 | * prefix with the generic xattr API, a filesystem should create a | ||
40 | * null-terminated array of struct xattr_handler (one for each prefix) and | ||
41 | * hang a pointer to it off of the s_xattr field of the superblock. | ||
42 | * | ||
43 | * The generic_fooxattr() functions will use this list to dispatch xattr | ||
44 | * operations to the correct xattr_handler. | ||
45 | */ | ||
46 | #define for_each_xattr_handler(handlers, handler) \ | ||
47 | if (handlers) \ | ||
48 | for ((handler) = *(handlers)++; \ | ||
49 | (handler) != NULL; \ | ||
50 | (handler) = *(handlers)++) | ||
51 | |||
52 | /* | ||
53 | * Find the xattr_handler with the matching prefix. | ||
54 | */ | ||
55 | static const struct xattr_handler * | ||
56 | xattr_resolve_name(const struct xattr_handler **handlers, const char **name) | ||
57 | { | ||
58 | const struct xattr_handler *handler; | ||
59 | |||
60 | for_each_xattr_handler(handlers, handler) { | ||
61 | const char *n; | ||
62 | |||
63 | n = strcmp_prefix(*name, xattr_prefix(handler)); | ||
64 | if (n) { | ||
65 | if (!handler->prefix ^ !*n) { | ||
66 | if (*n) | ||
67 | continue; | ||
68 | return ERR_PTR(-EINVAL); | ||
69 | } | ||
70 | *name = n; | ||
71 | return handler; | ||
72 | } | ||
73 | } | ||
74 | return ERR_PTR(-EOPNOTSUPP); | ||
75 | } | ||
76 | |||
27 | /* | 77 | /* |
28 | * Check permissions for extended attribute access. This is a bit complicated | 78 | * Check permissions for extended attribute access. This is a bit complicated |
29 | * because different namespaces have very different rules. | 79 | * because different namespaces have very different rules. |
@@ -641,57 +691,6 @@ SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name) | |||
641 | return error; | 691 | return error; |
642 | } | 692 | } |
643 | 693 | ||
644 | |||
645 | static const char * | ||
646 | strcmp_prefix(const char *a, const char *a_prefix) | ||
647 | { | ||
648 | while (*a_prefix && *a == *a_prefix) { | ||
649 | a++; | ||
650 | a_prefix++; | ||
651 | } | ||
652 | return *a_prefix ? NULL : a; | ||
653 | } | ||
654 | |||
655 | /* | ||
656 | * In order to implement different sets of xattr operations for each xattr | ||
657 | * prefix with the generic xattr API, a filesystem should create a | ||
658 | * null-terminated array of struct xattr_handler (one for each prefix) and | ||
659 | * hang a pointer to it off of the s_xattr field of the superblock. | ||
660 | * | ||
661 | * The generic_fooxattr() functions will use this list to dispatch xattr | ||
662 | * operations to the correct xattr_handler. | ||
663 | */ | ||
664 | #define for_each_xattr_handler(handlers, handler) \ | ||
665 | if (handlers) \ | ||
666 | for ((handler) = *(handlers)++; \ | ||
667 | (handler) != NULL; \ | ||
668 | (handler) = *(handlers)++) | ||
669 | |||
670 | /* | ||
671 | * Find the xattr_handler with the matching prefix. | ||
672 | */ | ||
673 | static const struct xattr_handler * | ||
674 | xattr_resolve_name(const struct xattr_handler **handlers, const char **name) | ||
675 | { | ||
676 | const struct xattr_handler *handler; | ||
677 | |||
678 | for_each_xattr_handler(handlers, handler) { | ||
679 | const char *n; | ||
680 | |||
681 | n = strcmp_prefix(*name, xattr_prefix(handler)); | ||
682 | if (n) { | ||
683 | if (!handler->prefix ^ !*n) { | ||
684 | if (*n) | ||
685 | continue; | ||
686 | return ERR_PTR(-EINVAL); | ||
687 | } | ||
688 | *name = n; | ||
689 | return handler; | ||
690 | } | ||
691 | } | ||
692 | return ERR_PTR(-EOPNOTSUPP); | ||
693 | } | ||
694 | |||
695 | /* | 694 | /* |
696 | * Find the handler for the prefix and dispatch its get() operation. | 695 | * Find the handler for the prefix and dispatch its get() operation. |
697 | */ | 696 | */ |