nfs: only show Posix ACLs in listxattr if actually present
authorChristoph Hellwig <hch@lst.de>
Wed, 18 Jun 2014 09:07:03 +0000 (11:07 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 31 Jul 2014 19:52:54 +0000 (12:52 -0700)
commit 74adf83f5d7720925499b4938f930591f947b660 upstream.

The big ACL switched nfs to use generic_listxattr, which calls all existing
->list handlers.  Add a custom .listxattr implementation that only lists
the ACLs if they actually are present on the given inode.

Signed-off-by: Christoph Hellwig <hch@lst.de>
Reported-by: Philippe Troin <phil@fifi.org>
Tested-by: Philippe Troin <phil@fifi.org>
Fixes: 013cdf1088d7 (nfs: use generic posix ACL infrastructure ...)
Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
fs/nfs/nfs3acl.c
fs/nfs/nfs3proc.c

index 871d6ed..8f854dd 100644 (file)
@@ -247,3 +247,46 @@ const struct xattr_handler *nfs3_xattr_handlers[] = {
        &posix_acl_default_xattr_handler,
        NULL,
 };
+
+static int
+nfs3_list_one_acl(struct inode *inode, int type, const char *name, void *data,
+               size_t size, ssize_t *result)
+{
+       struct posix_acl *acl;
+       char *p = data + *result;
+
+       acl = get_acl(inode, type);
+       if (!acl)
+               return 0;
+
+       posix_acl_release(acl);
+
+       *result += strlen(name);
+       *result += 1;
+       if (!size)
+               return 0;
+       if (*result > size)
+               return -ERANGE;
+
+       strcpy(p, name);
+       return 0;
+}
+
+ssize_t
+nfs3_listxattr(struct dentry *dentry, char *data, size_t size)
+{
+       struct inode *inode = dentry->d_inode;
+       ssize_t result = 0;
+       int error;
+
+       error = nfs3_list_one_acl(inode, ACL_TYPE_ACCESS,
+                       POSIX_ACL_XATTR_ACCESS, data, size, &result);
+       if (error)
+               return error;
+
+       error = nfs3_list_one_acl(inode, ACL_TYPE_DEFAULT,
+                       POSIX_ACL_XATTR_DEFAULT, data, size, &result);
+       if (error)
+               return error;
+       return result;
+}
index a462ef0..8a18b4a 100644 (file)
@@ -926,7 +926,7 @@ static const struct inode_operations nfs3_dir_inode_operations = {
        .getattr        = nfs_getattr,
        .setattr        = nfs_setattr,
 #ifdef CONFIG_NFS_V3_ACL
-       .listxattr      = generic_listxattr,
+       .listxattr      = nfs3_listxattr,
        .getxattr       = generic_getxattr,
        .setxattr       = generic_setxattr,
        .removexattr    = generic_removexattr,
@@ -940,7 +940,7 @@ static const struct inode_operations nfs3_file_inode_operations = {
        .getattr        = nfs_getattr,
        .setattr        = nfs_setattr,
 #ifdef CONFIG_NFS_V3_ACL
-       .listxattr      = generic_listxattr,
+       .listxattr      = nfs3_listxattr,
        .getxattr       = generic_getxattr,
        .setxattr       = generic_setxattr,
        .removexattr    = generic_removexattr,