[PATCH] xattr: Export xattr_resolve_name

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Export xattr_resolve_name and make it easier to use by filesystems.
Use it to remove reiserfs's own copy of the same functionality.

Signed-off-by: Andreas Gruenbacher <agruenba@xxxxxxxxxx>
---
 fs/reiserfs/xattr.c   | 47 +++++++----------------------------------------
 fs/xattr.c            | 20 ++++++++++++--------
 include/linux/xattr.h |  4 ++++
 3 files changed, 23 insertions(+), 48 deletions(-)

diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index 28f5f8b..08b8dc4 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -732,40 +732,6 @@ out:
 }
 
 /*
- * In order to implement different sets of xattr operations for each xattr
- * prefix with the generic xattr API, a filesystem should create a
- * null-terminated array of struct xattr_handler (one for each prefix) and
- * hang a pointer to it off of the s_xattr field of the superblock.
- *
- * The generic_fooxattr() functions will use this list to dispatch xattr
- * operations to the correct xattr_handler.
- */
-#define for_each_xattr_handler(handlers, handler)		\
-		for ((handler) = *(handlers)++;			\
-			(handler) != NULL;			\
-			(handler) = *(handlers)++)
-
-/* This is the implementation for the xattr plugin infrastructure */
-static inline const struct xattr_handler *
-find_xattr_handler_prefix(const struct xattr_handler **handlers,
-			   const char *name)
-{
-	const struct xattr_handler *xah;
-
-	if (!handlers)
-		return NULL;
-
-	for_each_xattr_handler(handlers, xah) {
-		const char *prefix = xattr_prefix(xah);
-		if (strncmp(prefix, name, strlen(prefix)) == 0)
-			break;
-	}
-
-	return xah;
-}
-
-
-/*
  * Inode operation getxattr()
  */
 ssize_t
@@ -774,7 +740,9 @@ reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer,
 {
 	const struct xattr_handler *handler;
 
-	handler = find_xattr_handler_prefix(dentry->d_sb->s_xattr, name);
+	handler = xattr_resolve_name(dentry->d_sb, name, NULL);
+	if (IS_ERR(handler))
+		return PTR_ERR(handler);
 
 	if (!handler || get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1)
 		return -EOPNOTSUPP;
@@ -793,7 +761,7 @@ reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value,
 {
 	const struct xattr_handler *handler;
 
-	handler = find_xattr_handler_prefix(dentry->d_sb->s_xattr, name);
+	handler = xattr_resolve_name(dentry->d_sb, name, NULL);
 
 	if (!handler || get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1)
 		return -EOPNOTSUPP;
@@ -810,7 +778,7 @@ int reiserfs_removexattr(struct dentry *dentry, const char *name)
 {
 	const struct xattr_handler *handler;
 
-	handler = find_xattr_handler_prefix(dentry->d_sb->s_xattr, name);
+	handler = xattr_resolve_name(dentry->d_sb, name, NULL);
 
 	if (!handler || get_inode_sd_version(d_inode(dentry)) == STAT_DATA_V1)
 		return -EOPNOTSUPP;
@@ -838,9 +806,8 @@ static int listxattr_filler(struct dir_context *ctx, const char *name,
 	    (namelen != 1 && (name[1] != '.' || namelen != 2))) {
 		const struct xattr_handler *handler;
 
-		handler = find_xattr_handler_prefix(b->dentry->d_sb->s_xattr,
-						    name);
-		if (!handler /* Unsupported xattr name */ ||
+		handler = xattr_resolve_name(b->dentry->d_sb, name, NULL);
+		if (IS_ERR(handler) /* Unsupported xattr name */ ||
 		    (handler->list && !handler->list(b->dentry)))
 			return 0;
 		size = namelen + 1;
diff --git a/fs/xattr.c b/fs/xattr.c
index afadc1b..096a3fc 100644
--- a/fs/xattr.c
+++ b/fs/xattr.c
@@ -655,30 +655,34 @@ strcmp_prefix(const char *a, const char *a_prefix)
 /*
  * Find the xattr_handler with the matching prefix.
  */
-static const struct xattr_handler *
-xattr_resolve_name(const struct xattr_handler **handlers, const char **name)
+const struct xattr_handler *
+xattr_resolve_name(const struct super_block *sb, const char *name,
+		   const char **suffix)
 {
+	const struct xattr_handler **handlers = sb->s_xattr;
 	const struct xattr_handler *handler;
 
-	if (!*name)
+	if (!name)
 		return ERR_PTR(-EINVAL);
 
 	for_each_xattr_handler(handlers, handler) {
 		const char *n;
 
-		n = strcmp_prefix(*name, xattr_prefix(handler));
+		n = strcmp_prefix(name, xattr_prefix(handler));
 		if (n) {
 			if (!handler->prefix ^ !*n) {
 				if (*n)
 					continue;
 				return ERR_PTR(-EINVAL);
 			}
-			*name = n;
+			if (suffix)
+				*suffix = n;
 			return handler;
 		}
 	}
 	return ERR_PTR(-EOPNOTSUPP);
 }
+EXPORT_SYMBOL(xattr_resolve_name);
 
 /*
  * Find the handler for the prefix and dispatch its get() operation.
@@ -688,7 +692,7 @@ generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t s
 {
 	const struct xattr_handler *handler;
 
-	handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
+	handler = xattr_resolve_name(dentry->d_sb, name, &name);
 	if (IS_ERR(handler))
 		return PTR_ERR(handler);
 	return handler->get(handler, dentry, name, buffer, size);
@@ -741,7 +745,7 @@ generic_setxattr(struct dentry *dentry, const char *name, const void *value, siz
 
 	if (size == 0)
 		value = "";  /* empty EA, do not remove */
-	handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
+	handler = xattr_resolve_name(dentry->d_sb, name, &name);
 	if (IS_ERR(handler))
 		return PTR_ERR(handler);
 	return handler->set(handler, dentry, name, value, size, flags);
@@ -756,7 +760,7 @@ generic_removexattr(struct dentry *dentry, const char *name)
 {
 	const struct xattr_handler *handler;
 
-	handler = xattr_resolve_name(dentry->d_sb->s_xattr, &name);
+	handler = xattr_resolve_name(dentry->d_sb, name, &name);
 	if (IS_ERR(handler))
 		return PTR_ERR(handler);
 	return handler->set(handler, dentry, name, NULL, 0, XATTR_REPLACE);
diff --git a/include/linux/xattr.h b/include/linux/xattr.h
index 4457541..0a53a17 100644
--- a/include/linux/xattr.h
+++ b/include/linux/xattr.h
@@ -51,6 +51,10 @@ int __vfs_setxattr_noperm(struct dentry *, const char *, const void *, size_t, i
 int vfs_setxattr(struct dentry *, const char *, const void *, size_t, int);
 int vfs_removexattr(struct dentry *, const char *);
 
+struct super_block;
+const struct xattr_handler *xattr_resolve_name(const struct super_block *,
+					       const char *name,
+					       const char **suffix);
 ssize_t generic_getxattr(struct dentry *dentry, const char *name, void *buffer, size_t size);
 ssize_t generic_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size);
 int generic_setxattr(struct dentry *dentry, const char *name, const void *value, size_t size, int flags);
-- 
2.5.5

--
To unsubscribe from this list: send the line "unsubscribe linux-fsdevel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [Samba]     [Device Mapper]     [CEPH Development]
  Powered by Linux