9p: xattr simplifications
authorAndreas Gruenbacher <agruenba@redhat.com>
Sun, 4 Oct 2015 17:18:52 +0000 (19:18 +0200)
committerAl Viro <viro@zeniv.linux.org.uk>
Sat, 14 Nov 2015 01:34:33 +0000 (20:34 -0500)
Now that the xattr handler is passed to the xattr handler operations, we
can use the same get and set operations for the user, trusted, and security
xattr namespaces.  In those namespaces, we can access the full attribute
name by "reattaching" the name prefix the vfs has skipped for us.  Add a
xattr_full_name helper to make this obvious in the code.

For the "system.posix_acl_access" and "system.posix_acl_default"
attributes, handler->prefix is the full attribute name; the suffix is the
empty string.

Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Cc: Eric Van Hensbergen <ericvh@gmail.com>
Cc: Ron Minnich <rminnich@sandia.gov>
Cc: Latchesar Ionkov <lucho@ionkov.net>
Cc: v9fs-developer@lists.sourceforge.net
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
fs/9p/Makefile
fs/9p/acl.c
fs/9p/xattr.c
fs/9p/xattr.h
fs/9p/xattr_security.c [deleted file]
fs/9p/xattr_trusted.c [deleted file]
fs/9p/xattr_user.c [deleted file]
fs/xattr.c
include/linux/xattr.h

index ff7be98f84f2412359bba865b34314fc62dd6ae9..9619ccadd2fcd9717bb3e186d8de78db932b9653 100644 (file)
@@ -10,10 +10,7 @@ obj-$(CONFIG_9P_FS) := 9p.o
        vfs_dentry.o \
        v9fs.o \
        fid.o  \
-       xattr.o \
-       xattr_user.o \
-       xattr_trusted.o
+       xattr.o
 
 9p-$(CONFIG_9P_FSCACHE) += cache.o
 9p-$(CONFIG_9P_FS_POSIX_ACL) += acl.o
-9p-$(CONFIG_9P_FS_SECURITY) += xattr_security.o
index e6fe824620439e1717547d32499f8ec06b725e31..a7e28890f5efb4ec8729fc9de4f09e16d4fb91bd 100644 (file)
@@ -212,31 +212,12 @@ int v9fs_acl_mode(struct inode *dir, umode_t *modep,
        return 0;
 }
 
-static int v9fs_remote_get_acl(struct dentry *dentry, const char *name,
-                              void *buffer, size_t size, int type)
-{
-       char *full_name;
-
-       switch (type) {
-       case ACL_TYPE_ACCESS:
-               full_name =  POSIX_ACL_XATTR_ACCESS;
-               break;
-       case ACL_TYPE_DEFAULT:
-               full_name = POSIX_ACL_XATTR_DEFAULT;
-               break;
-       default:
-               BUG();
-       }
-       return v9fs_xattr_get(dentry, full_name, buffer, size);
-}
-
 static int v9fs_xattr_get_acl(const struct xattr_handler *handler,
                              struct dentry *dentry, const char *name,
                              void *buffer, size_t size)
 {
        struct v9fs_session_info *v9ses;
        struct posix_acl *acl;
-       int type = handler->flags;
        int error;
 
        if (strcmp(name, "") != 0)
@@ -247,9 +228,9 @@ static int v9fs_xattr_get_acl(const struct xattr_handler *handler,
         * We allow set/get/list of acl when access=client is not specified
         */
        if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT)
-               return v9fs_remote_get_acl(dentry, name, buffer, size, type);
+               return v9fs_xattr_get(dentry, handler->prefix, buffer, size);
 
-       acl = v9fs_get_cached_acl(d_inode(dentry), type);
+       acl = v9fs_get_cached_acl(d_inode(dentry), handler->flags);
        if (IS_ERR(acl))
                return PTR_ERR(acl);
        if (acl == NULL)
@@ -260,26 +241,6 @@ static int v9fs_xattr_get_acl(const struct xattr_handler *handler,
        return error;
 }
 
-static int v9fs_remote_set_acl(struct dentry *dentry, const char *name,
-                             const void *value, size_t size,
-                             int flags, int type)
-{
-       char *full_name;
-
-       switch (type) {
-       case ACL_TYPE_ACCESS:
-               full_name =  POSIX_ACL_XATTR_ACCESS;
-               break;
-       case ACL_TYPE_DEFAULT:
-               full_name = POSIX_ACL_XATTR_DEFAULT;
-               break;
-       default:
-               BUG();
-       }
-       return v9fs_xattr_set(dentry, full_name, value, size, flags);
-}
-
-
 static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
                              struct dentry *dentry, const char *name,
                              const void *value, size_t size, int flags)
@@ -298,8 +259,8 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
         * xattr value. We leave it to the server to validate
         */
        if ((v9ses->flags & V9FS_ACCESS_MASK) != V9FS_ACCESS_CLIENT)
-               return v9fs_remote_set_acl(dentry, name,
-                                          value, size, flags, handler->flags);
+               return v9fs_xattr_set(dentry, handler->prefix, value, size,
+                                     flags);
 
        if (S_ISLNK(inode->i_mode))
                return -EOPNOTSUPP;
@@ -320,7 +281,6 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
 
        switch (handler->flags) {
        case ACL_TYPE_ACCESS:
-               name = POSIX_ACL_XATTR_ACCESS;
                if (acl) {
                        umode_t mode = inode->i_mode;
                        retval = posix_acl_equiv_mode(acl, &mode);
@@ -351,7 +311,6 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
                }
                break;
        case ACL_TYPE_DEFAULT:
-               name = POSIX_ACL_XATTR_DEFAULT;
                if (!S_ISDIR(inode->i_mode)) {
                        retval = acl ? -EINVAL : 0;
                        goto err_out;
@@ -360,7 +319,7 @@ static int v9fs_xattr_set_acl(const struct xattr_handler *handler,
        default:
                BUG();
        }
-       retval = v9fs_xattr_set(dentry, name, value, size, flags);
+       retval = v9fs_xattr_set(dentry, handler->prefix, value, size, flags);
        if (!retval)
                set_cached_acl(inode, handler->flags, acl);
 err_out:
index 0cf44b6cccd6ee7dd131033845c7619ad778ab89..e3d026ac382eb482c9840140466b946aa554dd78 100644 (file)
@@ -137,6 +137,48 @@ ssize_t v9fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
        return v9fs_xattr_get(dentry, NULL, buffer, buffer_size);
 }
 
+static int v9fs_xattr_handler_get(const struct xattr_handler *handler,
+                                 struct dentry *dentry, const char *name,
+                                 void *buffer, size_t size)
+{
+       const char *full_name = xattr_full_name(handler, name);
+
+       if (strcmp(name, "") == 0)
+               return -EINVAL;
+       return v9fs_xattr_get(dentry, full_name, buffer, size);
+}
+
+static int v9fs_xattr_handler_set(const struct xattr_handler *handler,
+                                 struct dentry *dentry, const char *name,
+                                 const void *value, size_t size, int flags)
+{
+       const char *full_name = xattr_full_name(handler, name);
+
+       if (strcmp(name, "") == 0)
+               return -EINVAL;
+       return v9fs_xattr_set(dentry, full_name, value, size, flags);
+}
+
+static struct xattr_handler v9fs_xattr_user_handler = {
+       .prefix = XATTR_USER_PREFIX,
+       .get    = v9fs_xattr_handler_get,
+       .set    = v9fs_xattr_handler_set,
+};
+
+static struct xattr_handler v9fs_xattr_trusted_handler = {
+       .prefix = XATTR_TRUSTED_PREFIX,
+       .get    = v9fs_xattr_handler_get,
+       .set    = v9fs_xattr_handler_set,
+};
+
+#ifdef CONFIG_9P_FS_SECURITY
+static struct xattr_handler v9fs_xattr_security_handler = {
+       .prefix = XATTR_SECURITY_PREFIX,
+       .get    = v9fs_xattr_handler_get,
+       .set    = v9fs_xattr_handler_set,
+};
+#endif
+
 const struct xattr_handler *v9fs_xattr_handlers[] = {
        &v9fs_xattr_user_handler,
        &v9fs_xattr_trusted_handler,
index d3e2ea3840bedf2f6e3a2f1b0274172810a17ff8..c63c3bea5de550d87159e55ccedb0f057fcebedb 100644 (file)
@@ -19,9 +19,6 @@
 #include <net/9p/client.h>
 
 extern const struct xattr_handler *v9fs_xattr_handlers[];
-extern struct xattr_handler v9fs_xattr_user_handler;
-extern struct xattr_handler v9fs_xattr_trusted_handler;
-extern struct xattr_handler v9fs_xattr_security_handler;
 extern const struct xattr_handler v9fs_xattr_acl_access_handler;
 extern const struct xattr_handler v9fs_xattr_acl_default_handler;
 
diff --git a/fs/9p/xattr_security.c b/fs/9p/xattr_security.c
deleted file mode 100644 (file)
index c0a470a..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright IBM Corporation, 2010
- * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2.1 of the GNU Lesser General Public License
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-
-
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include "xattr.h"
-
-static int v9fs_xattr_security_get(const struct xattr_handler *handler,
-                       struct dentry *dentry, const char *name,
-                       void *buffer, size_t size)
-{
-       int retval;
-       char *full_name;
-       size_t name_len;
-       size_t prefix_len = XATTR_SECURITY_PREFIX_LEN;
-
-       if (name == NULL)
-               return -EINVAL;
-
-       if (strcmp(name, "") == 0)
-               return -EINVAL;
-
-       name_len = strlen(name);
-       full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
-       if (!full_name)
-               return -ENOMEM;
-       memcpy(full_name, XATTR_SECURITY_PREFIX, prefix_len);
-       memcpy(full_name+prefix_len, name, name_len);
-       full_name[prefix_len + name_len] = '\0';
-
-       retval = v9fs_xattr_get(dentry, full_name, buffer, size);
-       kfree(full_name);
-       return retval;
-}
-
-static int v9fs_xattr_security_set(const struct xattr_handler *handler,
-                       struct dentry *dentry, const char *name,
-                       const void *value, size_t size, int flags)
-{
-       int retval;
-       char *full_name;
-       size_t name_len;
-       size_t prefix_len = XATTR_SECURITY_PREFIX_LEN;
-
-       if (name == NULL)
-               return -EINVAL;
-
-       if (strcmp(name, "") == 0)
-               return -EINVAL;
-
-       name_len = strlen(name);
-       full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
-       if (!full_name)
-               return -ENOMEM;
-       memcpy(full_name, XATTR_SECURITY_PREFIX, prefix_len);
-       memcpy(full_name + prefix_len, name, name_len);
-       full_name[prefix_len + name_len] = '\0';
-
-       retval = v9fs_xattr_set(dentry, full_name, value, size, flags);
-       kfree(full_name);
-       return retval;
-}
-
-struct xattr_handler v9fs_xattr_security_handler = {
-       .prefix = XATTR_SECURITY_PREFIX,
-       .get    = v9fs_xattr_security_get,
-       .set    = v9fs_xattr_security_set,
-};
diff --git a/fs/9p/xattr_trusted.c b/fs/9p/xattr_trusted.c
deleted file mode 100644 (file)
index b888a4e..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright IBM Corporation, 2010
- * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2.1 of the GNU Lesser General Public License
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-
-
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include "xattr.h"
-
-static int v9fs_xattr_trusted_get(const struct xattr_handler *handler,
-                       struct dentry *dentry, const char *name,
-                       void *buffer, size_t size)
-{
-       int retval;
-       char *full_name;
-       size_t name_len;
-       size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN;
-
-       if (name == NULL)
-               return -EINVAL;
-
-       if (strcmp(name, "") == 0)
-               return -EINVAL;
-
-       name_len = strlen(name);
-       full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
-       if (!full_name)
-               return -ENOMEM;
-       memcpy(full_name, XATTR_TRUSTED_PREFIX, prefix_len);
-       memcpy(full_name+prefix_len, name, name_len);
-       full_name[prefix_len + name_len] = '\0';
-
-       retval = v9fs_xattr_get(dentry, full_name, buffer, size);
-       kfree(full_name);
-       return retval;
-}
-
-static int v9fs_xattr_trusted_set(const struct xattr_handler *handler,
-                       struct dentry *dentry, const char *name,
-                       const void *value, size_t size, int flags)
-{
-       int retval;
-       char *full_name;
-       size_t name_len;
-       size_t prefix_len = XATTR_TRUSTED_PREFIX_LEN;
-
-       if (name == NULL)
-               return -EINVAL;
-
-       if (strcmp(name, "") == 0)
-               return -EINVAL;
-
-       name_len = strlen(name);
-       full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
-       if (!full_name)
-               return -ENOMEM;
-       memcpy(full_name, XATTR_TRUSTED_PREFIX, prefix_len);
-       memcpy(full_name + prefix_len, name, name_len);
-       full_name[prefix_len + name_len] = '\0';
-
-       retval = v9fs_xattr_set(dentry, full_name, value, size, flags);
-       kfree(full_name);
-       return retval;
-}
-
-struct xattr_handler v9fs_xattr_trusted_handler = {
-       .prefix = XATTR_TRUSTED_PREFIX,
-       .get    = v9fs_xattr_trusted_get,
-       .set    = v9fs_xattr_trusted_set,
-};
diff --git a/fs/9p/xattr_user.c b/fs/9p/xattr_user.c
deleted file mode 100644 (file)
index 06f136c..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright IBM Corporation, 2010
- * Author Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of version 2.1 of the GNU Lesser General Public License
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it would be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-
-
-#include <linux/module.h>
-#include <linux/string.h>
-#include <linux/fs.h>
-#include <linux/slab.h>
-#include "xattr.h"
-
-static int v9fs_xattr_user_get(const struct xattr_handler *handler,
-                       struct dentry *dentry, const char *name,
-                       void *buffer, size_t size)
-{
-       int retval;
-       char *full_name;
-       size_t name_len;
-       size_t prefix_len = XATTR_USER_PREFIX_LEN;
-
-       if (name == NULL)
-               return -EINVAL;
-
-       if (strcmp(name, "") == 0)
-               return -EINVAL;
-
-       name_len = strlen(name);
-       full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
-       if (!full_name)
-               return -ENOMEM;
-       memcpy(full_name, XATTR_USER_PREFIX, prefix_len);
-       memcpy(full_name+prefix_len, name, name_len);
-       full_name[prefix_len + name_len] = '\0';
-
-       retval = v9fs_xattr_get(dentry, full_name, buffer, size);
-       kfree(full_name);
-       return retval;
-}
-
-static int v9fs_xattr_user_set(const struct xattr_handler *handler,
-                       struct dentry *dentry, const char *name,
-                       const void *value, size_t size, int flags)
-{
-       int retval;
-       char *full_name;
-       size_t name_len;
-       size_t prefix_len = XATTR_USER_PREFIX_LEN;
-
-       if (name == NULL)
-               return -EINVAL;
-
-       if (strcmp(name, "") == 0)
-               return -EINVAL;
-
-       name_len = strlen(name);
-       full_name = kmalloc(prefix_len + name_len + 1 , GFP_KERNEL);
-       if (!full_name)
-               return -ENOMEM;
-       memcpy(full_name, XATTR_USER_PREFIX, prefix_len);
-       memcpy(full_name + prefix_len, name, name_len);
-       full_name[prefix_len + name_len] = '\0';
-
-       retval = v9fs_xattr_set(dentry, full_name, value, size, flags);
-       kfree(full_name);
-       return retval;
-}
-
-struct xattr_handler v9fs_xattr_user_handler = {
-       .prefix = XATTR_USER_PREFIX,
-       .get    = v9fs_xattr_user_get,
-       .set    = v9fs_xattr_user_set,
-};
index 44377b6f60012d60dc4424049161008a4705c0ee..9b932b95d74e4faeb5653d1a3c4b11553d1e51e1 100644 (file)
@@ -790,6 +790,30 @@ EXPORT_SYMBOL(generic_listxattr);
 EXPORT_SYMBOL(generic_setxattr);
 EXPORT_SYMBOL(generic_removexattr);
 
+/**
+ * xattr_full_name  -  Compute full attribute name from suffix
+ *
+ * @handler:   handler of the xattr_handler operation
+ * @name:      name passed to the xattr_handler operation
+ *
+ * The get and set xattr handler operations are called with the remainder of
+ * the attribute name after skipping the handler's prefix: for example, "foo"
+ * is passed to the get operation of a handler with prefix "user." to get
+ * attribute "user.foo".  The full name is still "there" in the name though.
+ *
+ * Note: the list xattr handler operation when called from the vfs is passed a
+ * NULL name; some file systems use this operation internally, with varying
+ * semantics.
+ */
+const char *xattr_full_name(const struct xattr_handler *handler,
+                           const char *name)
+{
+       size_t prefix_len = strlen(handler->prefix);
+
+       return name - prefix_len;
+}
+EXPORT_SYMBOL(xattr_full_name);
+
 /*
  * Allocate new xattr and copy in the value; but leave the name to callers.
  */
index 91b0a68d38dc2a4941c1b36a8cac270af0136422..89474b9d260cf44151b21e26ce5d64aecf62b6cb 100644 (file)
@@ -21,15 +21,19 @@ struct dentry;
 
 struct xattr_handler {
        const char *prefix;
-       int flags;      /* fs private flags passed back to the handlers */
-       size_t (*list)(struct dentry *dentry, char *list, size_t list_size,
-                      const char *name, size_t name_len, int handler_flags);
-       int (*get)(struct dentry *dentry, const char *name, void *buffer,
-                  size_t size, int handler_flags);
-       int (*set)(struct dentry *dentry, const char *name, const void *buffer,
-                  size_t size, int flags, int handler_flags);
+       int flags;      /* fs private flags */
+       size_t (*list)(const struct xattr_handler *, struct dentry *dentry,
+                      char *list, size_t list_size, const char *name,
+                      size_t name_len);
+       int (*get)(const struct xattr_handler *, struct dentry *dentry,
+                  const char *name, void *buffer, size_t size);
+       int (*set)(const struct xattr_handler *, struct dentry *dentry,
+                  const char *name, const void *buffer, size_t size,
+                  int flags);
 };
 
+const char *xattr_full_name(const struct xattr_handler *, const char *);
+
 struct xattr {
        const char *name;
        void *value;