xattr: add a function to check if a namespace is supported
authorFrank van der Linden <fllinden@amazon.com>
Tue, 23 Jun 2020 22:39:19 +0000 (22:39 +0000)
committerChuck Lever <chuck.lever@oracle.com>
Mon, 13 Jul 2020 21:27:03 +0000 (17:27 -0400)
Add a function that checks is an extended attribute namespace is
supported for an inode, meaning that a handler must be present
for either the whole namespace, or at least one synthetic
xattr in the namespace.

To be used by the nfs server code when being queried for extended
attributes support.

Cc: linux-fsdevel@vger.kernel.org
Cc: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Frank van der Linden <fllinden@amazon.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
fs/xattr.c
include/linux/xattr.h

index 95f38f57347f5f8410e263e7ea83031834ed5c50..386b45676d7e65b2e9958fb602e01e0c41f3e157 100644 (file)
@@ -134,6 +134,33 @@ xattr_permission(struct inode *inode, const char *name, int mask)
        return inode_permission(inode, mask);
 }
 
+/*
+ * Look for any handler that deals with the specified namespace.
+ */
+int
+xattr_supported_namespace(struct inode *inode, const char *prefix)
+{
+       const struct xattr_handler **handlers = inode->i_sb->s_xattr;
+       const struct xattr_handler *handler;
+       size_t preflen;
+
+       if (!(inode->i_opflags & IOP_XATTR)) {
+               if (unlikely(is_bad_inode(inode)))
+                       return -EIO;
+               return -EOPNOTSUPP;
+       }
+
+       preflen = strlen(prefix);
+
+       for_each_xattr_handler(handlers, handler) {
+               if (!strncmp(xattr_prefix(handler), prefix, preflen))
+                       return 0;
+       }
+
+       return -EOPNOTSUPP;
+}
+EXPORT_SYMBOL(xattr_supported_namespace);
+
 int
 __vfs_setxattr(struct dentry *dentry, struct inode *inode, const char *name,
               const void *value, size_t size, int flags)
index a2f3cd02653c1347411ea90a6c5cf04a2bf71499..fac75810d9d3cbb6288c0528b18a4a46470fe976 100644 (file)
@@ -61,6 +61,8 @@ ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_siz
 ssize_t vfs_getxattr_alloc(struct dentry *dentry, const char *name,
                           char **xattr_value, size_t size, gfp_t flags);
 
+int xattr_supported_namespace(struct inode *inode, const char *prefix);
+
 static inline const char *xattr_prefix(const struct xattr_handler *handler)
 {
        return handler->prefix ?: handler->name;