Hi Christoph,
Looks reasonable to me.
In list_one_attr(), which looks based on attr_generic_listadd(),
it does a final:
> + p += len;
which seems useless.
An aside, I noticed in passing (which was in existing code),
how we call vn_revalidate
in xfs_xattr_system_set(). I presume this is because we
call xfs_acl_setmode() in xfs_acl_vset() when we want to sync
the mode bits to the ACL.
If this is the case, then I think it would have been clearer
to put vn_revalidate() in the vicinity of xfs_acl_setmode().
Or is there some other reason?
I'll test it out.
Thanks,
Tim.
Christoph Hellwig wrote:
> On Wed, Apr 30, 2008 at 01:22:17PM +0200, Christoph Hellwig wrote:
>> 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.
>>
>> The code size reduction is not as big as I had hoped, but it's still a
>> worthwile cleanup.
>>
>> I didn't managed to get rid of struct attrnames yet, as it's still used
>> to hack the Linux string prefixes into the output inside the lowest
>> level xattr code. I have some plans to clean that bit up aswell, but
>> that will have to wait for a while.
>
> Updated on top of the case-insensitive filename changes:
>
>
Just my notes (for my reference)...
> Signed-off-by: Christoph Hellwig <hch@xxxxxx>
>
> Index: linux-2.6-xfs/fs/xfs/Makefile
> ===================================================================
> --- linux-2.6-xfs.orig/fs/xfs/Makefile 2008-05-21 09:59:53.000000000
> +0200
> +++ linux-2.6-xfs/fs/xfs/Makefile 2008-05-21 10:06:38.000000000 +0200
> @@ -97,6 +97,7 @@ xfs-y += $(addprefix
> $(XFS_LINUX)/, \
> xfs_lrw.o \
> xfs_super.o \
> xfs_vnode.o \
> + xfs_xattr.o \
> xfs_ksyms.o)
>
Okay adding in a linux-2.6/xfs_xattr.c
(slightly different name than xfs_attr.c)
> # Objects in support/
> Index: linux-2.6-xfs/fs/xfs/linux-2.6/xfs_iops.c
> ===================================================================
> --- linux-2.6-xfs.orig/fs/xfs/linux-2.6/xfs_iops.c 2008-05-21
> 09:59:53.000000000 +0200
> +++ linux-2.6-xfs/fs/xfs/linux-2.6/xfs_iops.c 2008-05-21 10:14:54.000000000
> +0200
> @@ -282,7 +282,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;
>
> /*
> @@ -771,98 +771,6 @@ xfs_vn_truncate(
> WARN_ON(error);
> }
>
So you are removing xfs_vn_setxattr, xfs_vn_getxattr, and
xfs_vn_removexattr and calling generic_xattr and retaining the
code in xattr_handler's.
You leave xfs_vn_listxattr alone. Just like ext3 does its own. Ok.
> -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,
> @@ -910,10 +818,10 @@ const struct inode_operations xfs_inode_
> .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,
> };
>
> @@ -930,10 +838,10 @@ const struct inode_operations xfs_dir_in
> .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 = {
> @@ -949,10 +857,10 @@ const struct inode_operations xfs_dir_ci
> .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 = {
> @@ -962,8 +870,8 @@ const struct inode_operations xfs_symlin
> .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: linux-2.6-xfs/fs/xfs/linux-2.6/xfs_xattr.c
> ===================================================================
> --- /dev/null 1970-01-01 00:00:00.000000000 +0000
> +++ linux-2.6-xfs/fs/xfs/linux-2.6/xfs_xattr.c 2008-05-21
> 10:06:38.000000000 +0200
> @@ -0,0 +1,266 @@
> +/*
> + * Copyright (C) 2008 Christoph Hellwig.
> + * Released under GPL v2.
> + */
> +
> +#include "xfs.h"
> +#include "xfs_attr.h"
> +#include "xfs_acl.h"
> +#include "xfs_vnodeops.h"
> +
> +#include <linux/posix_acl_xattr.h>
> +#include <linux/xattr.h>
> +
> +
> +/*
> + * ACL handling. Should eventually be moved into xfs_acl.c
> + */
> +
> +static int
> +xfs_decode_acl(const char *name)
> +{
> + if (strcmp(name, "posix_acl_access") == 0)
> + return _ACL_TYPE_ACCESS;
> + else if (strcmp(name, "posix_acl_default") == 0)
> + return _ACL_TYPE_DEFAULT;
> + return -EINVAL;
> +}
> +
Fine.
> +static int
> +xfs_xattr_system_get(struct inode *inode, const char *name,
> + void *buffer, size_t size)
> +{
> + int acl;
> +
> + acl = xfs_decode_acl(name);
> + if (acl < 0)
> + return acl;
> +
> + return xfs_acl_vget(inode, buffer, size, acl);
> +}
> +
Fine.
Seems a little funny as we are calling it a system EA but
then directly calling the acl code.
i.e. acknowledging, I guess, that we only have Posix ACLs
as system EAs.
Almost could call it xfs_xattr_acl_get().
It saves on one liner wrappers I guess.
> +static int
> +xfs_xattr_system_set(struct inode *inode, const char *name,
> + const void *value, size_t size, int flags)
> +{
> + int error, acl;
> +
> + acl = xfs_decode_acl(name);
> + if (acl < 0)
> + return acl;
> + if (flags & XATTR_CREATE)
> + return -EINVAL;
> +
> + if (!value)
> + return xfs_acl_vremove(inode, acl);
> +
> + error = xfs_acl_vset(inode, (void *)value, size, acl);
> + if (!error)
> + vn_revalidate(inode);
> + return error;
> +}
> +
Why the vn_revalidate?
b/c we did that in xfs_attr.c/attr_system_set().
It updates the linux inode fields based on the xfs inode fields.
I wonder why.
Because we can modify an ACL which can cause mode changes?
in the call to xfs_acl_setmode(vp, xfs_acl, &basicperms)
I wonder why we do it at this point though as it doesn't
look so obvious.
> +static struct xattr_handler xfs_xattr_system_handler = {
> + .prefix = XATTR_SYSTEM_PREFIX,
> + .get = xfs_xattr_system_get,
> + .set = xfs_xattr_system_set,
> +};
> +
> +
> +/*
> + * Real xattr handling. The only difference between the namespaces is
> + * a flag passed to the low-level attr code.
> + */
> +
> +static int
> +__xfs_xattr_get(struct inode *inode, const char *name,
> + void *value, size_t size, int xflags)
> +{
> + struct xfs_inode *ip = XFS_I(inode);
> + int error, asize = size;
> +
> + if (strcmp(name, "") == 0)
> + return -EINVAL;
> +
> + /* Convert Linux syscall to XFS internal ATTR flags */
> + if (!size) {
> + xflags |= ATTR_KERNOVAL;
> + value = NULL;
> + }
> +
> + error = -xfs_attr_get(ip, name, value, &asize, xflags);
> + if (error)
> + return error;
> + return asize;
> +}
> +
Ok.
> +static int
> +__xfs_xattr_set(struct inode *inode, const char *name, const void *value,
> + size_t size, int flags, int xflags)
> +{
> + struct xfs_inode *ip = XFS_I(inode);
> +
> + if (strcmp(name, "") == 0)
> + return -EINVAL;
> +
> + /* Convert Linux syscall to XFS internal ATTR flags */
> + if (flags & XATTR_CREATE)
> + xflags |= ATTR_CREATE;
> + if (flags & XATTR_REPLACE)
> + xflags |= ATTR_REPLACE;
> +
> + if (!value)
> + return -xfs_attr_remove(ip, name, xflags);
> + return -xfs_attr_set(ip, name, (void *)value, size, xflags);
> +}
> +
Ok.
> +static int
> +xfs_xattr_user_get(struct inode *inode, const char *name,
> + void *value, size_t size)
> +{
> + return __xfs_xattr_get(inode, name, value, size, 0);
> +}
> +
> +static int
> +xfs_xattr_user_set(struct inode *inode, const char *name,
> + const void *value, size_t size, int flags)
> +{
> + return __xfs_xattr_set(inode, name, value, size, flags, 0);
> +}
> +
> +struct attrnames attr_user = {
> + .attr_name = "user.",
> + .attr_namelen = sizeof("user.") - 1,
> +};
> +
> +static struct xattr_handler xfs_xattr_user_handler = {
> + .prefix = XATTR_USER_PREFIX,
> + .get = xfs_xattr_user_get,
> + .set = xfs_xattr_user_set,
> +};
> +
Ok.
> +
> +static int
> +xfs_xattr_trusted_get(struct inode *inode, const char *name,
> + void *value, size_t size)
> +{
> + return __xfs_xattr_get(inode, name, value, size, ATTR_ROOT);
> +}
> +
> +static int
> +xfs_xattr_trusted_set(struct inode *inode, const char *name,
> + const void *value, size_t size, int flags)
> +{
> + return __xfs_xattr_set(inode, name, value, size, flags, ATTR_ROOT);
> +}
> +
> +struct attrnames attr_trusted = {
> + .attr_name = "trusted.",
> + .attr_namelen = sizeof("trusted.") - 1,
> +};
> +
> +static struct xattr_handler xfs_xattr_trusted_handler = {
> + .prefix = XATTR_TRUSTED_PREFIX,
> + .get = xfs_xattr_trusted_get,
> + .set = xfs_xattr_trusted_set,
> +};
> +
Ok.
> +
> +static int
> +xfs_xattr_secure_get(struct inode *inode, const char *name,
> + void *value, size_t size)
> +{
> + return __xfs_xattr_get(inode, name, value, size, ATTR_SECURE);
> +}
> +
> +static int
> +xfs_xattr_secure_set(struct inode *inode, const char *name,
> + const void *value, size_t size, int flags)
> +{
> + return __xfs_xattr_set(inode, name, value, size, flags, ATTR_SECURE);
> +}
> +
> +struct attrnames attr_secure = {
> + .attr_name = "security.",
> + .attr_namelen = sizeof("security.") - 1,
> +};
> +
> +static struct xattr_handler xfs_xattr_security_handler = {
> + .prefix = XATTR_SECURITY_PREFIX,
> + .get = xfs_xattr_secure_get,
> + .set = xfs_xattr_secure_set,
> +};
> +
Ok.
> +
> +struct xattr_handler *xfs_xattr_handlers[] = {
> + &xfs_xattr_user_handler,
> + &xfs_xattr_trusted_handler,
> + &xfs_xattr_security_handler,
> + &xfs_xattr_system_handler,
> + NULL
> +};
> +
So List code is done separately. Hmmmm...
Oh, okay, ATTR_KERNAMELS (for attr_vn_listxattr) uses
concatenated string arrays
whereas for not ATTR_KERNAMELS, such as is used in
xfs_attrlist_by_handle is uses list data in the form:
<u32: valuelen> <char: name-array> <pad-to-4-byte-boundary>
> +static int
> +list_one_attr(const char *name, const size_t len, void *data,
> + size_t size, ssize_t *result)
> +{
> + char *p = data + *result;
> +
> + *result += len;
> + if (!size)
> + return 0;
> + if (*result > size)
> + return -ERANGE;
> +
> + strcpy(p, name);
> + p += len;
Q: Why increment p?
Ok, this code looks like it is coming from attr_generic_listadd().
> + return 0;
> +}
> +
Previously, in attr_generic_list it did:
-> xfs_attr_list
-> attr_system_list
So you've expanded out attr_system_list into xfs_vn_listxattr().
> +ssize_t
> +xfs_vn_listxattr(struct dentry *dentry, char *data, size_t size)
> +{
> + struct inode *inode = dentry->d_inode;
> + struct xfs_inode *ip = XFS_I(inode);
> + attrlist_cursor_kern_t cursor = { 0 };
> + int error, xflags;
> + ssize_t result;
> +
> + xflags = ATTR_KERNAMELS;
> + if (!size)
> + xflags |= ATTR_KERNOVAL;
> +
> + if (capable(CAP_SYS_ADMIN))
> + xflags |= ATTR_KERNFULLS;
> + else
> + xflags |= ATTR_KERNORMALS;
> +
> +
> + /*
> + * First read the regular on-disk attributes.
> + */
> + result = -xfs_attr_list(ip, data, size, xflags, &cursor);
> + if (result < 0)
> + return result;
> +
> + /*
> + * Then add the two synthetic ACL attributes.
> + */
> + if (xfs_acl_vhasacl_access(inode)) {
> + error = list_one_attr(POSIX_ACL_XATTR_ACCESS,
> + strlen(POSIX_ACL_XATTR_ACCESS) + 1,
> + data, size, &result);
> + if (error)
> + return error;
> + }
> +
> + if (xfs_acl_vhasacl_default(inode)) {
> + error = list_one_attr(POSIX_ACL_XATTR_DEFAULT,
> + strlen(POSIX_ACL_XATTR_DEFAULT) + 1,
> + data, size, &result);
> + if (error)
> + return error;
> + }
> +
> + return result;
> +}
Looks reasonable.
> Index: linux-2.6-xfs/fs/xfs/xfs_attr.c
> ===================================================================
> --- linux-2.6-xfs.orig/fs/xfs/xfs_attr.c 2008-05-21 09:59:53.000000000
> +0200
> +++ linux-2.6-xfs/fs/xfs/xfs_attr.c 2008-05-21 10:06:38.000000000 +0200
> @@ -57,11 +57,6 @@
> * 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 *whe
> (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: linux-2.6-xfs/fs/xfs/xfs_attr.h
> ===================================================================
> --- linux-2.6-xfs.orig/fs/xfs/xfs_attr.h 2008-05-21 09:59:53.000000000
> +0200
> +++ linux-2.6-xfs/fs/xfs/xfs_attr.h 2008-05-21 10:06:38.000000000 +0200
> @@ -38,30 +38,14 @@
> 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
> #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 */
> Index: linux-2.6-xfs/fs/xfs/linux-2.6/xfs_iops.h
> ===================================================================
> --- linux-2.6-xfs.orig/fs/xfs/linux-2.6/xfs_iops.h 2008-05-21
> 09:59:53.000000000 +0200
> +++ linux-2.6-xfs/fs/xfs/linux-2.6/xfs_iops.h 2008-05-21 10:14:20.000000000
> +0200
> @@ -27,6 +27,7 @@ extern const struct file_operations xfs_
> 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: linux-2.6-xfs/fs/xfs/linux-2.6/xfs_super.c
> ===================================================================
> --- linux-2.6-xfs.orig/fs/xfs/linux-2.6/xfs_super.c 2008-05-21
> 09:59:53.000000000 +0200
> +++ linux-2.6-xfs/fs/xfs/linux-2.6/xfs_super.c 2008-05-21
> 10:14:20.000000000 +0200
> @@ -1767,6 +1767,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: linux-2.6-xfs/fs/xfs/linux-2.6/xfs_super.h
> ===================================================================
> --- linux-2.6-xfs.orig/fs/xfs/linux-2.6/xfs_super.h 2008-05-21
> 09:59:53.000000000 +0200
> +++ linux-2.6-xfs/fs/xfs/linux-2.6/xfs_super.h 2008-05-21
> 10:14:20.000000000 +0200
> @@ -81,6 +81,7 @@ extern void xfs_flush_device(struct xfs_
> 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))
>
>
|