|
@@ -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.
|
|
|
*/
|