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>
This commit is contained in:
parent
bf02f5d2c0
commit
b6ba11773d
101
fs/xattr.c
101
fs/xattr.c
|
@ -24,6 +24,56 @@
|
|||
|
||||
#include <asm/uaccess.h>
|
||||
|
||||
static const char *
|
||||
strcmp_prefix(const char *a, const char *a_prefix)
|
||||
{
|
||||
while (*a_prefix && *a == *a_prefix) {
|
||||
a++;
|
||||
a_prefix++;
|
||||
}
|
||||
return *a_prefix ? NULL : a;
|
||||
}
|
||||
|
||||
/*
|
||||
* In order to implement different sets of xattr operations for each xattr
|
||||
* prefix with the generic xattr API, a filesystem should create a
|
||||
* null-terminated array of struct xattr_handler (one for each prefix) and
|
||||
* hang a pointer to it off of the s_xattr field of the superblock.
|
||||
*
|
||||
* The generic_fooxattr() functions will use this list to dispatch xattr
|
||||
* operations to the correct xattr_handler.
|
||||
*/
|
||||
#define for_each_xattr_handler(handlers, handler) \
|
||||
if (handlers) \
|
||||
for ((handler) = *(handlers)++; \
|
||||
(handler) != NULL; \
|
||||
(handler) = *(handlers)++)
|
||||
|
||||
/*
|
||||
* Find the xattr_handler with the matching prefix.
|
||||
*/
|
||||
static const struct xattr_handler *
|
||||
xattr_resolve_name(const struct xattr_handler **handlers, const char **name)
|
||||
{
|
||||
const struct xattr_handler *handler;
|
||||
|
||||
for_each_xattr_handler(handlers, handler) {
|
||||
const char *n;
|
||||
|
||||
n = strcmp_prefix(*name, xattr_prefix(handler));
|
||||
if (n) {
|
||||
if (!handler->prefix ^ !*n) {
|
||||
if (*n)
|
||||
continue;
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
*name = n;
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check permissions for extended attribute access. This is a bit complicated
|
||||
* because different namespaces have very different rules.
|
||||
|
@ -641,57 +691,6 @@ SYSCALL_DEFINE2(fremovexattr, int, fd, const char __user *, name)
|
|||
return error;
|
||||
}
|
||||
|
||||
|
||||
static const char *
|
||||
strcmp_prefix(const char *a, const char *a_prefix)
|
||||
{
|
||||
while (*a_prefix && *a == *a_prefix) {
|
||||
a++;
|
||||
a_prefix++;
|
||||
}
|
||||
return *a_prefix ? NULL : a;
|
||||
}
|
||||
|
||||
/*
|
||||
* In order to implement different sets of xattr operations for each xattr
|
||||
* prefix with the generic xattr API, a filesystem should create a
|
||||
* null-terminated array of struct xattr_handler (one for each prefix) and
|
||||
* hang a pointer to it off of the s_xattr field of the superblock.
|
||||
*
|
||||
* The generic_fooxattr() functions will use this list to dispatch xattr
|
||||
* operations to the correct xattr_handler.
|
||||
*/
|
||||
#define for_each_xattr_handler(handlers, handler) \
|
||||
if (handlers) \
|
||||
for ((handler) = *(handlers)++; \
|
||||
(handler) != NULL; \
|
||||
(handler) = *(handlers)++)
|
||||
|
||||
/*
|
||||
* Find the xattr_handler with the matching prefix.
|
||||
*/
|
||||
static const struct xattr_handler *
|
||||
xattr_resolve_name(const struct xattr_handler **handlers, const char **name)
|
||||
{
|
||||
const struct xattr_handler *handler;
|
||||
|
||||
for_each_xattr_handler(handlers, handler) {
|
||||
const char *n;
|
||||
|
||||
n = strcmp_prefix(*name, xattr_prefix(handler));
|
||||
if (n) {
|
||||
if (!handler->prefix ^ !*n) {
|
||||
if (*n)
|
||||
continue;
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
*name = n;
|
||||
return handler;
|
||||
}
|
||||
}
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the handler for the prefix and dispatch its get() operation.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue