[XFS] Use the generic xattr methods.
authorLachlan McIlroy <lachlan@redback.melbourne.sgi.com>
Mon, 23 Jun 2008 03:23:01 +0000 (13:23 +1000)
committerNiv Sardi <xaiki@debian.org>
Mon, 28 Jul 2008 06:58:49 +0000 (16:58 +1000)
Use the generic set, get and removexattr methods and supply the s_xattr
array with fine-grained handlers. All XFS/Linux highlevel attr handling is
rewritten from scratch and placed into fs/xfs/linux-2.6/xfs_xattr.c so
that it's separated from the generic low-level code.

SGI-PV: 982343

SGI-Modid: xfs-linux-melb:xfs-kern:31234a

Signed-off-by: Christoph Hellwig <hch@infradead.org>
Signed-off-by: Tim Shimmin <tes@sgi.com>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
fs/xfs/Makefile
fs/xfs/linux-2.6/xfs_iops.c
fs/xfs/linux-2.6/xfs_iops.h
fs/xfs/linux-2.6/xfs_super.c
fs/xfs/linux-2.6/xfs_super.h
fs/xfs/xfs_attr.c
fs/xfs/xfs_attr.h

index 36ec614..737c9a4 100644 (file)
@@ -106,7 +106,8 @@ xfs-y                               += $(addprefix $(XFS_LINUX)/, \
                                   xfs_iops.o \
                                   xfs_lrw.o \
                                   xfs_super.o \
-                                  xfs_vnode.o)
+                                  xfs_vnode.o \
+                                  xfs_xattr.o)
 
 # Objects in support/
 xfs-y                          += $(addprefix support/, \
index 190ed61..3ae8015 100644 (file)
@@ -275,7 +275,7 @@ xfs_vn_mknod(
        struct xfs_inode *ip = NULL;
        xfs_acl_t       *default_acl = NULL;
        struct xfs_name name;
-       attrexists_t    test_default_acl = _ACL_DEFAULT_EXISTS;
+       int (*test_default_acl)(struct inode *) = _ACL_DEFAULT_EXISTS;
        int             error;
 
        /*
@@ -781,98 +781,6 @@ xfs_vn_truncate(
        WARN_ON(error);
 }
 
-STATIC int
-xfs_vn_setxattr(
-       struct dentry   *dentry,
-       const char      *name,
-       const void      *data,
-       size_t          size,
-       int             flags)
-{
-       bhv_vnode_t     *vp = vn_from_inode(dentry->d_inode);
-       char            *attr = (char *)name;
-       attrnames_t     *namesp;
-       int             xflags = 0;
-
-       namesp = attr_lookup_namespace(attr, attr_namespaces, ATTR_NAMECOUNT);
-       if (!namesp)
-               return -EOPNOTSUPP;
-       attr += namesp->attr_namelen;
-
-       /* Convert Linux syscall to XFS internal ATTR flags */
-       if (flags & XATTR_CREATE)
-               xflags |= ATTR_CREATE;
-       if (flags & XATTR_REPLACE)
-               xflags |= ATTR_REPLACE;
-       xflags |= namesp->attr_flag;
-       return namesp->attr_set(vp, attr, (void *)data, size, xflags);
-}
-
-STATIC ssize_t
-xfs_vn_getxattr(
-       struct dentry   *dentry,
-       const char      *name,
-       void            *data,
-       size_t          size)
-{
-       bhv_vnode_t     *vp = vn_from_inode(dentry->d_inode);
-       char            *attr = (char *)name;
-       attrnames_t     *namesp;
-       int             xflags = 0;
-
-       namesp = attr_lookup_namespace(attr, attr_namespaces, ATTR_NAMECOUNT);
-       if (!namesp)
-               return -EOPNOTSUPP;
-       attr += namesp->attr_namelen;
-
-       /* Convert Linux syscall to XFS internal ATTR flags */
-       if (!size) {
-               xflags |= ATTR_KERNOVAL;
-               data = NULL;
-       }
-       xflags |= namesp->attr_flag;
-       return namesp->attr_get(vp, attr, (void *)data, size, xflags);
-}
-
-STATIC ssize_t
-xfs_vn_listxattr(
-       struct dentry           *dentry,
-       char                    *data,
-       size_t                  size)
-{
-       bhv_vnode_t             *vp = vn_from_inode(dentry->d_inode);
-       int                     error, xflags = ATTR_KERNAMELS;
-       ssize_t                 result;
-
-       if (!size)
-               xflags |= ATTR_KERNOVAL;
-       xflags |= capable(CAP_SYS_ADMIN) ? ATTR_KERNFULLS : ATTR_KERNORMALS;
-
-       error = attr_generic_list(vp, data, size, xflags, &result);
-       if (error < 0)
-               return error;
-       return result;
-}
-
-STATIC int
-xfs_vn_removexattr(
-       struct dentry   *dentry,
-       const char      *name)
-{
-       bhv_vnode_t     *vp = vn_from_inode(dentry->d_inode);
-       char            *attr = (char *)name;
-       attrnames_t     *namesp;
-       int             xflags = 0;
-
-       namesp = attr_lookup_namespace(attr, attr_namespaces, ATTR_NAMECOUNT);
-       if (!namesp)
-               return -EOPNOTSUPP;
-       attr += namesp->attr_namelen;
-
-       xflags |= namesp->attr_flag;
-       return namesp->attr_remove(vp, attr, xflags);
-}
-
 STATIC long
 xfs_vn_fallocate(
        struct inode    *inode,
@@ -920,10 +828,10 @@ const struct inode_operations xfs_inode_operations = {
        .truncate               = xfs_vn_truncate,
        .getattr                = xfs_vn_getattr,
        .setattr                = xfs_vn_setattr,
-       .setxattr               = xfs_vn_setxattr,
-       .getxattr               = xfs_vn_getxattr,
+       .setxattr               = generic_setxattr,
+       .getxattr               = generic_getxattr,
+       .removexattr            = generic_removexattr,
        .listxattr              = xfs_vn_listxattr,
-       .removexattr            = xfs_vn_removexattr,
        .fallocate              = xfs_vn_fallocate,
 };
 
@@ -940,10 +848,10 @@ const struct inode_operations xfs_dir_inode_operations = {
        .permission             = xfs_vn_permission,
        .getattr                = xfs_vn_getattr,
        .setattr                = xfs_vn_setattr,
-       .setxattr               = xfs_vn_setxattr,
-       .getxattr               = xfs_vn_getxattr,
+       .setxattr               = generic_setxattr,
+       .getxattr               = generic_getxattr,
+       .removexattr            = generic_removexattr,
        .listxattr              = xfs_vn_listxattr,
-       .removexattr            = xfs_vn_removexattr,
 };
 
 const struct inode_operations xfs_dir_ci_inode_operations = {
@@ -959,10 +867,10 @@ const struct inode_operations xfs_dir_ci_inode_operations = {
        .permission             = xfs_vn_permission,
        .getattr                = xfs_vn_getattr,
        .setattr                = xfs_vn_setattr,
-       .setxattr               = xfs_vn_setxattr,
-       .getxattr               = xfs_vn_getxattr,
+       .setxattr               = generic_setxattr,
+       .getxattr               = generic_getxattr,
+       .removexattr            = generic_removexattr,
        .listxattr              = xfs_vn_listxattr,
-       .removexattr            = xfs_vn_removexattr,
 };
 
 const struct inode_operations xfs_symlink_inode_operations = {
@@ -972,8 +880,8 @@ const struct inode_operations xfs_symlink_inode_operations = {
        .permission             = xfs_vn_permission,
        .getattr                = xfs_vn_getattr,
        .setattr                = xfs_vn_setattr,
-       .setxattr               = xfs_vn_setxattr,
-       .getxattr               = xfs_vn_getxattr,
+       .setxattr               = generic_setxattr,
+       .getxattr               = generic_getxattr,
+       .removexattr            = generic_removexattr,
        .listxattr              = xfs_vn_listxattr,
-       .removexattr            = xfs_vn_removexattr,
 };
index 3b4df58..d97ba93 100644 (file)
@@ -27,6 +27,7 @@ extern const struct file_operations xfs_file_operations;
 extern const struct file_operations xfs_dir_file_operations;
 extern const struct file_operations xfs_invis_file_operations;
 
+extern ssize_t xfs_vn_listxattr(struct dentry *, char *data, size_t size);
 
 struct xfs_inode;
 extern void xfs_ichgtime(struct xfs_inode *, int);
index cce59cc..967603c 100644 (file)
@@ -1766,6 +1766,7 @@ xfs_fs_fill_super(
                goto out_free_mp;
 
        sb_min_blocksize(sb, BBSIZE);
+       sb->s_xattr = xfs_xattr_handlers;
        sb->s_export_op = &xfs_export_operations;
        sb->s_qcop = &xfs_quotactl_operations;
        sb->s_op = &xfs_super_operations;
index 212bdc7..b7d13da 100644 (file)
@@ -110,6 +110,7 @@ extern void xfs_flush_device(struct xfs_inode *);
 extern void xfs_blkdev_issue_flush(struct xfs_buftarg *);
 
 extern const struct export_operations xfs_export_operations;
+extern struct xattr_handler *xfs_xattr_handlers[];
 
 #define XFS_M(sb)              ((struct xfs_mount *)((sb)->s_fs_info))
 
index 557dad6..9d91af4 100644 (file)
  * Provide the external interfaces to manage attribute lists.
  */
 
-#define ATTR_SYSCOUNT  2
-static struct attrnames posix_acl_access;
-static struct attrnames posix_acl_default;
-static struct attrnames *attr_system_names[ATTR_SYSCOUNT];
-
 /*========================================================================
  * Function prototypes for the kernel.
  *========================================================================*/
@@ -2378,270 +2373,3 @@ xfs_attr_trace_enter(int type, char *where,
                (void *)a13, (void *)a14, (void *)a15);
 }
 #endif /* XFS_ATTR_TRACE */
-
-
-/*========================================================================
- * System (pseudo) namespace attribute interface routines.
- *========================================================================*/
-
-STATIC int
-posix_acl_access_set(
-       bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
-{
-       return xfs_acl_vset(vp, data, size, _ACL_TYPE_ACCESS);
-}
-
-STATIC int
-posix_acl_access_remove(
-       bhv_vnode_t *vp, char *name, int xflags)
-{
-       return xfs_acl_vremove(vp, _ACL_TYPE_ACCESS);
-}
-
-STATIC int
-posix_acl_access_get(
-       bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
-{
-       return xfs_acl_vget(vp, data, size, _ACL_TYPE_ACCESS);
-}
-
-STATIC int
-posix_acl_access_exists(
-       bhv_vnode_t *vp)
-{
-       return xfs_acl_vhasacl_access(vp);
-}
-
-STATIC int
-posix_acl_default_set(
-       bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
-{
-       return xfs_acl_vset(vp, data, size, _ACL_TYPE_DEFAULT);
-}
-
-STATIC int
-posix_acl_default_get(
-       bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
-{
-       return xfs_acl_vget(vp, data, size, _ACL_TYPE_DEFAULT);
-}
-
-STATIC int
-posix_acl_default_remove(
-       bhv_vnode_t *vp, char *name, int xflags)
-{
-       return xfs_acl_vremove(vp, _ACL_TYPE_DEFAULT);
-}
-
-STATIC int
-posix_acl_default_exists(
-       bhv_vnode_t *vp)
-{
-       return xfs_acl_vhasacl_default(vp);
-}
-
-static struct attrnames posix_acl_access = {
-       .attr_name      = "posix_acl_access",
-       .attr_namelen   = sizeof("posix_acl_access") - 1,
-       .attr_get       = posix_acl_access_get,
-       .attr_set       = posix_acl_access_set,
-       .attr_remove    = posix_acl_access_remove,
-       .attr_exists    = posix_acl_access_exists,
-};
-
-static struct attrnames posix_acl_default = {
-       .attr_name      = "posix_acl_default",
-       .attr_namelen   = sizeof("posix_acl_default") - 1,
-       .attr_get       = posix_acl_default_get,
-       .attr_set       = posix_acl_default_set,
-       .attr_remove    = posix_acl_default_remove,
-       .attr_exists    = posix_acl_default_exists,
-};
-
-static struct attrnames *attr_system_names[] =
-       { &posix_acl_access, &posix_acl_default };
-
-
-/*========================================================================
- * Namespace-prefix-style attribute name interface routines.
- *========================================================================*/
-
-STATIC int
-attr_generic_set(
-       bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
-{
-       return -xfs_attr_set(xfs_vtoi(vp), name, data, size, xflags);
-}
-
-STATIC int
-attr_generic_get(
-       bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
-{
-       int     error, asize = size;
-
-       error = xfs_attr_get(xfs_vtoi(vp), name, data, &asize, xflags);
-       if (!error)
-               return asize;
-       return -error;
-}
-
-STATIC int
-attr_generic_remove(
-       bhv_vnode_t *vp, char *name, int xflags)
-{
-       return -xfs_attr_remove(xfs_vtoi(vp), name, xflags);
-}
-
-STATIC int
-attr_generic_listadd(
-       attrnames_t             *prefix,
-       attrnames_t             *namesp,
-       void                    *data,
-       size_t                  size,
-       ssize_t                 *result)
-{
-       char                    *p = data + *result;
-
-       *result += prefix->attr_namelen;
-       *result += namesp->attr_namelen + 1;
-       if (!size)
-               return 0;
-       if (*result > size)
-               return -ERANGE;
-       strcpy(p, prefix->attr_name);
-       p += prefix->attr_namelen;
-       strcpy(p, namesp->attr_name);
-       p += namesp->attr_namelen + 1;
-       return 0;
-}
-
-STATIC int
-attr_system_list(
-       bhv_vnode_t             *vp,
-       void                    *data,
-       size_t                  size,
-       ssize_t                 *result)
-{
-       attrnames_t             *namesp;
-       int                     i, error = 0;
-
-       for (i = 0; i < ATTR_SYSCOUNT; i++) {
-               namesp = attr_system_names[i];
-               if (!namesp->attr_exists || !namesp->attr_exists(vp))
-                       continue;
-               error = attr_generic_listadd(&attr_system, namesp,
-                                               data, size, result);
-               if (error)
-                       break;
-       }
-       return error;
-}
-
-int
-attr_generic_list(
-       bhv_vnode_t *vp, void *data, size_t size, int xflags, ssize_t *result)
-{
-       attrlist_cursor_kern_t  cursor = { 0 };
-       int                     error;
-
-       error = xfs_attr_list(xfs_vtoi(vp), data, size, xflags, &cursor);
-       if (error > 0)
-               return -error;
-       *result = -error;
-       return attr_system_list(vp, data, size, result);
-}
-
-attrnames_t *
-attr_lookup_namespace(
-       char                    *name,
-       struct attrnames        **names,
-       int                     nnames)
-{
-       int                     i;
-
-       for (i = 0; i < nnames; i++)
-               if (!strncmp(name, names[i]->attr_name, names[i]->attr_namelen))
-                       return names[i];
-       return NULL;
-}
-
-STATIC int
-attr_system_set(
-       bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
-{
-       attrnames_t     *namesp;
-       int             error;
-
-       if (xflags & ATTR_CREATE)
-               return -EINVAL;
-
-       namesp = attr_lookup_namespace(name, attr_system_names, ATTR_SYSCOUNT);
-       if (!namesp)
-               return -EOPNOTSUPP;
-       error = namesp->attr_set(vp, name, data, size, xflags);
-       if (!error)
-               error = vn_revalidate(vp);
-       return error;
-}
-
-STATIC int
-attr_system_get(
-       bhv_vnode_t *vp, char *name, void *data, size_t size, int xflags)
-{
-       attrnames_t     *namesp;
-
-       namesp = attr_lookup_namespace(name, attr_system_names, ATTR_SYSCOUNT);
-       if (!namesp)
-               return -EOPNOTSUPP;
-       return namesp->attr_get(vp, name, data, size, xflags);
-}
-
-STATIC int
-attr_system_remove(
-       bhv_vnode_t *vp, char *name, int xflags)
-{
-       attrnames_t     *namesp;
-
-       namesp = attr_lookup_namespace(name, attr_system_names, ATTR_SYSCOUNT);
-       if (!namesp)
-               return -EOPNOTSUPP;
-       return namesp->attr_remove(vp, name, xflags);
-}
-
-struct attrnames attr_system = {
-       .attr_name      = "system.",
-       .attr_namelen   = sizeof("system.") - 1,
-       .attr_flag      = ATTR_SYSTEM,
-       .attr_get       = attr_system_get,
-       .attr_set       = attr_system_set,
-       .attr_remove    = attr_system_remove,
-};
-
-struct attrnames attr_trusted = {
-       .attr_name      = "trusted.",
-       .attr_namelen   = sizeof("trusted.") - 1,
-       .attr_flag      = ATTR_ROOT,
-       .attr_get       = attr_generic_get,
-       .attr_set       = attr_generic_set,
-       .attr_remove    = attr_generic_remove,
-};
-
-struct attrnames attr_secure = {
-       .attr_name      = "security.",
-       .attr_namelen   = sizeof("security.") - 1,
-       .attr_flag      = ATTR_SECURE,
-       .attr_get       = attr_generic_get,
-       .attr_set       = attr_generic_set,
-       .attr_remove    = attr_generic_remove,
-};
-
-struct attrnames attr_user = {
-       .attr_name      = "user.",
-       .attr_namelen   = sizeof("user.") - 1,
-       .attr_get       = attr_generic_get,
-       .attr_set       = attr_generic_set,
-       .attr_remove    = attr_generic_remove,
-};
-
-struct attrnames *attr_namespaces[] =
-       { &attr_system, &attr_trusted, &attr_secure, &attr_user };
index 9b96d17..c1f7d43 100644 (file)
 struct cred;
 struct xfs_attr_list_context;
 
-typedef int (*attrset_t)(bhv_vnode_t *, char *, void *, size_t, int);
-typedef int (*attrget_t)(bhv_vnode_t *, char *, void *, size_t, int);
-typedef int (*attrremove_t)(bhv_vnode_t *, char *, int);
-typedef int (*attrexists_t)(bhv_vnode_t *);
-
 typedef struct attrnames {
        char *          attr_name;
        unsigned int    attr_namelen;
-       unsigned int    attr_flag;
-       attrget_t       attr_get;
-       attrset_t       attr_set;
-       attrremove_t    attr_remove;
-       attrexists_t    attr_exists;
 } attrnames_t;
 
-#define ATTR_NAMECOUNT 4
 extern struct attrnames attr_user;
 extern struct attrnames attr_secure;
-extern struct attrnames attr_system;
 extern struct attrnames attr_trusted;
-extern struct attrnames *attr_namespaces[ATTR_NAMECOUNT];
-
-extern attrnames_t *attr_lookup_namespace(char *, attrnames_t **, int);
-extern int attr_generic_list(bhv_vnode_t *, void *, size_t, int, ssize_t *);
 
 #define ATTR_DONTFOLLOW        0x0001  /* -- unused, from IRIX -- */
 #define ATTR_ROOT      0x0002  /* use attrs in root (trusted) namespace */
@@ -69,7 +53,6 @@ extern int attr_generic_list(bhv_vnode_t *, void *, size_t, int, ssize_t *);
 #define ATTR_SECURE    0x0008  /* use attrs in security namespace */
 #define ATTR_CREATE    0x0010  /* pure create: fail if attr already exists */
 #define ATTR_REPLACE   0x0020  /* pure set: fail if attr does not exist */
-#define ATTR_SYSTEM    0x0100  /* use attrs in system (pseudo) namespace */
 
 #define ATTR_KERNACCESS        0x0400  /* [kernel] iaccess, inode held io-locked */
 #define ATTR_KERNOTIME 0x1000  /* [kernel] don't update inode timestamps */