All of lore.kernel.org
 help / color / mirror / Atom feed
From: jeffm@suse.com
To: ReiserFS Mailing List <reiserfs-devel@vger.kernel.org>
Subject: [patch 17/40] reiserfs: use generic xattr handlers
Date: Mon, 11 Jun 2007 15:03:26 -0400	[thread overview]
Message-ID: <20070611190631.197839937@suse.com> (raw)
In-Reply-To: 20070611190309.532091171@suse.com

[-- Attachment #1: reiserfs-use-generic-xattr-handlers.diff --]
[-- Type: text/plain, Size: 31530 bytes --]

 Christoph Hellwig had asked me quite some time ago to port the reiserfs
 xattrs to the generic xattr interface.

 This patch replaces the reiserfs-specific xattr handling code with the
 generic struct xattr_handler.

 However, since reiserfs doesn't split the prefix and name when accessing
 xattrs, it can't leverage generic_{set,get,list,remove}xattr without
 needlessly reconstructing the name on the back end.

Signed-off-by: Jeff Mahoney <jeffm@suse.com>

---
 fs/reiserfs/super.c            |    7 
 fs/reiserfs/xattr.c            |  399 +++++++++++++++--------------------------
 fs/reiserfs/xattr_acl.c        |   72 ++-----
 fs/reiserfs/xattr_security.c   |   26 --
 fs/reiserfs/xattr_trusted.c    |   45 +---
 fs/reiserfs/xattr_user.c       |   30 ---
 include/linux/reiserfs_acl.h   |   16 -
 include/linux/reiserfs_fs_sb.h |    3 
 include/linux/reiserfs_xattr.h |   29 --
 9 files changed, 206 insertions(+), 421 deletions(-)

--- a/fs/reiserfs/super.c	2007-06-11 14:49:36.000000000 -0400
+++ b/fs/reiserfs/super.c	2007-06-11 14:50:04.000000000 -0400
@@ -2132,9 +2132,6 @@ static int __init init_reiserfs_fs(void)
 		return ret;
 	}
 
-	if ((ret = reiserfs_xattr_register_handlers()))
-		goto failed_reiserfs_xattr_register_handlers;
-
 	reiserfs_proc_info_global_init();
 	reiserfs_proc_register_global("version",
 				      reiserfs_global_version_in_proc);
@@ -2145,9 +2142,6 @@ static int __init init_reiserfs_fs(void)
 		return 0;
 	}
 
-	reiserfs_xattr_unregister_handlers();
-
-      failed_reiserfs_xattr_register_handlers:
 	reiserfs_proc_unregister_global("version");
 	reiserfs_proc_info_global_done();
 	destroy_inodecache();
@@ -2157,7 +2151,6 @@ static int __init init_reiserfs_fs(void)
 
 static void __exit exit_reiserfs_fs(void)
 {
-	reiserfs_xattr_unregister_handlers();
 	reiserfs_proc_unregister_global("version");
 	reiserfs_proc_info_global_done();
 	unregister_filesystem(&reiserfs_fs_type);
--- a/fs/reiserfs/xattr.c	2007-06-11 14:49:37.000000000 -0400
+++ b/fs/reiserfs/xattr.c	2007-06-11 14:50:06.000000000 -0400
@@ -53,8 +53,49 @@
 #define PRIVROOT_NAME ".reiserfs_priv"
 #define XAROOT_NAME   "xattrs"
 
-static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char
-								*prefix);
+struct xattr_handler *reiserfs_xattr_handlers[] = {
+	&reiserfs_xattr_user_handler,
+	&reiserfs_xattr_trusted_handler,
+#ifdef CONFIG_REISERFS_FS_SECURITY
+	&reiserfs_xattr_security_handler,
+#endif
+#ifdef CONFIG_REISERFS_FS_POSIX_ACL
+	&reiserfs_posix_acl_access_handler,
+	&reiserfs_posix_acl_default_handler,
+#endif
+	NULL
+};
+
+/*
+ * 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 struct xattr_handler *find_xattr_handler_prefix(struct xattr_handler **handlers,
+                                                       const char *name)
+{
+	struct xattr_handler *xah;
+
+	if (!handlers)
+		return NULL;
+
+	for_each_xattr_handler(handlers, xah) {
+		if (strncmp(xah->prefix, name, strlen(xah->prefix)) == 0)
+			break;
+	}
+
+	return xah;
+}
 
 #define xattr_may_create(flags)	(!flags || flags & XATTR_CREATE)
 
@@ -113,7 +154,7 @@ static struct dentry *open_xa_dir(const 
 
 }
 
-static struct file *open_xattr_file(const struct inode *inode,
+static struct file *open_xattr_file(struct inode *inode,
                                     const char *name, int flags)
 {
 	struct dentry *xadir, *xafile;
@@ -381,8 +422,27 @@ reiserfs_xattr_set(struct inode *inode, 
 	if (get_inode_sd_version(inode) == STAT_DATA_V1)
 		return -EOPNOTSUPP;
 
-	if (!buffer)
-		return reiserfs_xattr_del(inode, name);
+	/* Clearing it out - delete it. */
+	if (!buffer) {
+		struct inode *dir;
+
+		fp = open_xattr_file(inode, name, XATTR_REPLACE);
+		if (IS_ERR(fp)) {
+			err = PTR_ERR(fp);
+			if (err == -ENODATA)
+				err = 0;
+			return err;
+		}
+
+		dir = fp->f_path.dentry->d_parent->d_inode;
+		err = vfs_unlink(dir, fp->f_dentry);
+		fput(fp);
+		if (!err) {
+			inode->i_ctime = CURRENT_TIME_SEC;
+			mark_inode_dirty(inode);
+		}
+		return err;
+	}
 
 	fp = open_xattr_file(inode, name, flags);
 	if (IS_ERR(fp)) {
@@ -449,6 +509,12 @@ reiserfs_xattr_set(struct inode *inode, 
 			break;
 	}
 
+      out_filp:
+	mutex_unlock(&xinode->i_mutex);
+	fput(fp);
+
+      out:
+
 	/* We can't mark the inode dirty if it's not hashed. This is the case
 	 * when we're inheriting the default ACL. If we dirty it, the inode
 	 * gets marked dirty, but won't (ever) make it onto the dirty list until
@@ -458,11 +524,6 @@ reiserfs_xattr_set(struct inode *inode, 
 		mark_inode_dirty(inode);
 	}
 
-      out_filp:
-	mutex_unlock(&xinode->i_mutex);
-	fput(fp);
-
-      out:
 	return err;
 }
 
@@ -470,7 +531,7 @@ reiserfs_xattr_set(struct inode *inode, 
  * inode->i_mutex: down
  */
 int
-reiserfs_xattr_get(const struct inode *inode, const char *name, void *buffer,
+reiserfs_xattr_get(struct inode *inode, const char *name, void *buffer,
 		   size_t buffer_size)
 {
 	ssize_t err = 0;
@@ -573,13 +634,17 @@ reiserfs_xattr_get(const struct inode *i
 	return err;
 }
 
+/* The following are side effects of other operations that aren't explicitly
+ * modifying extended attributes. This includes operations such as permissions
+ * or ownership changes, object deletions, etc. */
+
 static int
-__reiserfs_xattr_del(struct dentry *xadir, const char *name, int namelen)
+reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen,
+			      loff_t offset, u64 ino, unsigned int d_type)
 {
+	struct dentry *xadir = (struct dentry *)buf;
 	struct dentry *dentry;
-	struct inode *dir = xadir->d_inode;
 	int err = 0;
-	struct reiserfs_xattr_handler *xah;
 
 	dentry = lookup_one_len(name, xadir, namelen);
 	if (IS_ERR(dentry)) {
@@ -594,27 +659,6 @@ __reiserfs_xattr_del(struct dentry *xadi
 	if (S_ISDIR(dentry->d_inode->i_mode))
 		goto out_file;
 
-	if (!is_reiserfs_priv_object(dentry->d_inode)) {
-		reiserfs_error(dir->i_sb, "jdm-20003",
-		               "OID %08x [%.*s/%.*s] doesn't have "
-		               "priv flag set [parent is %sset].",
-		               le32_to_cpu(INODE_PKEY(dentry->d_inode)->
-		                           k_objectid), xadir->d_name.len,
-		               xadir->d_name.name, namelen, name,
-		               is_reiserfs_priv_object(xadir-> d_inode) ? "" :
-		               "not ");
-		dput(dentry);
-		return -EIO;
-	}
-
-	/* Deletion pre-operation */
-	xah = find_xattr_handler_prefix(name);
-	if (xah && xah->del) {
-		err = xah->del(inode, name);
-		if (err)
-			goto out;
-	}
-
 	err = vfs_unlink(xadir->d_inode, dentry);
 
       out_file:
@@ -624,45 +668,6 @@ __reiserfs_xattr_del(struct dentry *xadi
 	return err;
 }
 
-int reiserfs_xattr_del(struct inode *inode, const char *name)
-{
-	struct dentry *dir;
-	int err;
-
-	dir = open_xa_dir(inode, XATTR_REPLACE);
-	if (IS_ERR(dir)) {
-		err = PTR_ERR(dir);
-		goto out;
-	}
-
-	mutex_lock(&dir->i_mutex);
-	err = __reiserfs_xattr_del(dir, name, strlen(name));
-	mutex_unlock(&dir->i_mutex);
-	dput(dir);
-
-	if (!err) {
-		inode->i_ctime = CURRENT_TIME_SEC;
-		mark_inode_dirty(inode);
-	}
-
-      out:
-	return err;
-}
-
-/* The following are side effects of other operations that aren't explicitly
- * modifying extended attributes. This includes operations such as permissions
- * or ownership changes, object deletions, etc. */
-
-static int
-reiserfs_delete_xattrs_filler(void *buf, const char *name, int namelen,
-			      loff_t offset, u64 ino, unsigned int d_type)
-{
-	struct dentry *xadir = (struct dentry *)buf;
-
-	return __reiserfs_xattr_del(xadir, name, namelen);
-
-}
-
 /* This is called w/ inode->i_mutex downed */
 int reiserfs_delete_xattrs(struct inode *inode)
 {
@@ -817,15 +822,15 @@ ssize_t
 reiserfs_getxattr(struct dentry * dentry, const char *name, void *buffer,
 		  size_t size)
 {
-	struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix(name);
-	int err;
+	struct inode *inode = dentry->d_inode;
+	struct xattr_handler *handler;
 
-	if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
-	    get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1)
+	handler = find_xattr_handler_prefix(inode->i_sb->s_xattr, name);
+
+	if (!handler || get_inode_sd_version(inode) == STAT_DATA_V1)
 		return -EOPNOTSUPP;
 
-	err = xah->get(dentry->d_inode, name, buffer, size);
-	return err;
+	return handler->get(inode, name, buffer, size);
 }
 
 /*
@@ -837,15 +842,15 @@ int
 reiserfs_setxattr(struct dentry *dentry, const char *name, const void *value,
 		  size_t size, int flags)
 {
-	struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix(name);
-	int err;
+	struct inode *inode = dentry->d_inode;
+	struct xattr_handler *handler;
 
-	if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
-	    get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1)
+	handler = find_xattr_handler_prefix(inode->i_sb->s_xattr, name);
+
+	if (!handler || get_inode_sd_version(inode) == STAT_DATA_V1)
 		return -EOPNOTSUPP;
 
-	err = xah->set(dentry->d_inode, name, value, size, flags);
-	return err;
+	return handler->set(inode, name, value, size, flags);
 }
 
 /*
@@ -855,73 +860,66 @@ reiserfs_setxattr(struct dentry *dentry,
  */
 int reiserfs_removexattr(struct dentry *dentry, const char *name)
 {
-	int err;
-	struct reiserfs_xattr_handler *xah = find_xattr_handler_prefix(name);
+	struct inode *inode = dentry->d_inode;
+	struct xattr_handler *handler;
+	handler = find_xattr_handler_prefix(inode->i_sb->s_xattr, name);
 
-	if (!xah || !reiserfs_xattrs(dentry->d_sb) ||
-	    get_inode_sd_version(dentry->d_inode) == STAT_DATA_V1)
+	if (!handler || get_inode_sd_version(inode) == STAT_DATA_V1)
 		return -EOPNOTSUPP;
 
-	err = reiserfs_xattr_del(dentry->d_inode, name);
-
-	dentry->d_inode->i_ctime = CURRENT_TIME_SEC;
-	mark_inode_dirty(dentry->d_inode);
-
-      out:
-	return err;
+	return handler->set(inode, name, NULL, 0, XATTR_REPLACE);
 }
 
-/* This is what filldir will use:
- * r_pos will always contain the amount of space required for the entire
- * list. If r_pos becomes larger than r_size, we need more space and we
- * return an error indicating this. If r_pos is less than r_size, then we've
- * filled the buffer successfully and we return success */
-struct reiserfs_listxattr_buf {
-	int r_pos;
-	int r_size;
-	char *r_buf;
-	struct inode *r_inode;
+struct listxattr_buf {
+	size_t size;
+	size_t pos;
+	char *buf;
+	struct inode *inode;
 };
 
-static int
-reiserfs_listxattr_filler(void *buf, const char *name, int namelen,
-			  loff_t offset, u64 ino, unsigned int d_type)
+static int listxattr_filler(void *buf, const char *name, int namelen,
+                            loff_t offset, u64 ino, unsigned int d_type)
 {
-	struct reiserfs_listxattr_buf *b = (struct reiserfs_listxattr_buf *)buf;
-	int len = 0;
-	if (name[0] != '.'
-	    || (namelen != 1 && (name[1] != '.' || namelen != 2))) {
-		struct reiserfs_xattr_handler *xah =
-		    find_xattr_handler_prefix(name);
-		if (!xah)
-			return 0;	/* Unsupported xattr name, skip it */
-
-		/* We call ->list() twice because the operation isn't required to just
-		 * return the name back - we want to make sure we have enough space */
-		len += xah->list(b->r_inode, name, namelen, NULL);
-
-		if (len) {
-			if (b->r_pos + len + 1 <= b->r_size) {
-				char *p = b->r_buf + b->r_pos;
-				p += xah->list(b->r_inode, name, namelen, p);
-				*p++ = '\0';
-			}
-			b->r_pos += len + 1;
+	struct listxattr_buf *b = (struct listxattr_buf *)buf;
+	size_t size;
+	if (name[0] != '.' ||
+	    (namelen != 1 && (name[1] != '.' || namelen != 2))) {
+		struct xattr_handler *handler;
+		handler = find_xattr_handler_prefix(b->inode->i_sb->s_xattr,
+		                                    name);
+		if (!handler)	/* Unsupported xattr name */
+			return 0;
+		if (b->buf) {
+			size = handler->list(b->inode, b->buf + b->pos,
+			                 b->size, name, namelen);
+			if (size > b->size)
+				return -ERANGE;
+		} else {
+			size = handler->list(b->inode, NULL, 0, name, namelen);
 		}
-	}
 
+		b->pos += size;
+	}
 	return 0;
 }
 
 /*
  * Inode operation listxattr()
+ *
+ * We totally ignore the generic listxattr here because it would be stupid
+ * not to. Since the xattrs are organized in a directory, we can just
+ * readdir to find them.
  */
 ssize_t reiserfs_listxattr(struct dentry * dentry, char *buffer, size_t size)
 {
 	struct file *fp;
 	struct dentry *dir;
 	int err = 0;
-	struct reiserfs_listxattr_buf buf;
+	struct listxattr_buf buf = {
+		.inode = dentry->d_inode,
+		.buf = buffer,
+		.size = buffer ? size : 0,
+	};
 
 	if (!dentry->d_inode)
 		return -EINVAL;
@@ -934,30 +932,22 @@ ssize_t reiserfs_listxattr(struct dentry
 	if (IS_ERR(dir)) {
 		err = PTR_ERR(dir);
 		if (err == -ENODATA)
-			err = 0;	/* Not an error if there aren't any xattrs */
+			err = 0;  /* Not an error if there aren't any xattrs */
 		goto out;
 	}
 
-	fp = dentry_open(dir, NULL, O_RDWR);
+	fp = dentry_open(dir, NULL, O_RDWR|O_NOATIME|O_DIRECTORY);
 	if (IS_ERR(fp)) {
 		err = PTR_ERR(fp);
 		/* dentry_open dputs the dentry if it fails */
 		goto out;
 	}
 
-	buf.r_buf = buffer;
-	buf.r_size = buffer ? size : 0;
-	buf.r_pos = 0;
-	buf.r_inode = dentry->d_inode;
-
-	err = xattr_readdir(fp, reiserfs_listxattr_filler, &buf);
+	err = xattr_readdir(fp, listxattr_filler, &buf);
 	if (err)
 		goto out_dir;
 
-	if (buf.r_pos > buf.r_size && buffer != NULL)
-		err = -ERANGE;
-	else
-		err = buf.r_pos;
+	err = buf.pos;
 
       out_dir:
 	fput(fp);
@@ -966,95 +956,6 @@ ssize_t reiserfs_listxattr(struct dentry
 	return err;
 }
 
-/* This is the implementation for the xattr plugin infrastructure */
-static struct list_head xattr_handlers = LIST_HEAD_INIT(xattr_handlers);
-static DEFINE_RWLOCK(handler_lock);
-
-static struct reiserfs_xattr_handler *find_xattr_handler_prefix(const char
-								*prefix)
-{
-	struct reiserfs_xattr_handler *xah = NULL;
-	struct list_head *p;
-
-	read_lock(&handler_lock);
-	list_for_each(p, &xattr_handlers) {
-		xah = list_entry(p, struct reiserfs_xattr_handler, handlers);
-		if (strncmp(xah->prefix, prefix, strlen(xah->prefix)) == 0)
-			break;
-		xah = NULL;
-	}
-
-	read_unlock(&handler_lock);
-	return xah;
-}
-
-static void __unregister_handlers(void)
-{
-	struct reiserfs_xattr_handler *xah;
-	struct list_head *p, *tmp;
-
-	list_for_each_safe(p, tmp, &xattr_handlers) {
-		xah = list_entry(p, struct reiserfs_xattr_handler, handlers);
-		if (xah->exit)
-			xah->exit();
-
-		list_del_init(p);
-	}
-	INIT_LIST_HEAD(&xattr_handlers);
-}
-
-int __init reiserfs_xattr_register_handlers(void)
-{
-	int err = 0;
-	struct reiserfs_xattr_handler *xah;
-	struct list_head *p;
-
-	write_lock(&handler_lock);
-
-	/* If we're already initialized, nothing to do */
-	if (!list_empty(&xattr_handlers)) {
-		write_unlock(&handler_lock);
-		return 0;
-	}
-
-	/* Add the handlers */
-	list_add_tail(&user_handler.handlers, &xattr_handlers);
-	list_add_tail(&trusted_handler.handlers, &xattr_handlers);
-#ifdef CONFIG_REISERFS_FS_SECURITY
-	list_add_tail(&security_handler.handlers, &xattr_handlers);
-#endif
-#ifdef CONFIG_REISERFS_FS_POSIX_ACL
-	list_add_tail(&posix_acl_access_handler.handlers, &xattr_handlers);
-	list_add_tail(&posix_acl_default_handler.handlers, &xattr_handlers);
-#endif
-
-	/* Run initializers, if available */
-	list_for_each(p, &xattr_handlers) {
-		xah = list_entry(p, struct reiserfs_xattr_handler, handlers);
-		if (xah->init) {
-			err = xah->init();
-			if (err) {
-				list_del_init(p);
-				break;
-			}
-		}
-	}
-
-	/* Clean up other handlers, if any failed */
-	if (err)
-		__unregister_handlers();
-
-	write_unlock(&handler_lock);
-	return err;
-}
-
-void reiserfs_xattr_unregister_handlers(void)
-{
-	write_lock(&handler_lock);
-	__unregister_handlers();
-	write_unlock(&handler_lock);
-}
-
 /* This will catch lookups from the fs root to .reiserfs_priv */
 static int
 xattr_lookup_poison(struct dentry *dentry, struct qstr *q1, struct qstr *name)
@@ -1083,24 +984,21 @@ int reiserfs_xattr_init(struct super_blo
 
 	/* We need generation numbers to ensure that the oid mapping is correct
 	 * v3.5 filesystems don't have them. */
-	if (!old_format_only(s)) {
-		set_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt));
-	} else if (reiserfs_xattrs_optional(s)) {
-		/* Old format filesystem, but optional xattrs have been enabled
-		 * at mount time. Error out. */
-		reiserfs_warning(s, "jdm-20005",
-		                 "xattrs/ACLs not supported on pre v3.6 "
-				 "format filesystem. Failing mount.");
-		err = -EOPNOTSUPP;
-		goto error;
-	} else {
-		/* Old format filesystem, but no optional xattrs have been enabled. This
-		 * means we silently disable xattrs on the filesystem. */
-		clear_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt));
+	if (old_format_only(s)) {
+		if (reiserfs_xattrs_optional(s)) {
+			/* Old format filesystem, but optional xattrs have
+			 * been enabled. Error out. */
+			reiserfs_warning(s, "jdm-2005",
+			                 "xattrs/ACLs not supported "
+			                 "on pre-v3.6 format filesystems. "
+			                 "Failing mount.");
+			err = -EOPNOTSUPP;
+		}
+		return err;
 	}
 
 	/* If we don't have the privroot located yet - go find it */
-	if (reiserfs_xattrs(s) && !REISERFS_SB(s)->priv_root) {
+	if (!REISERFS_SB(s)->priv_root) {
 		struct dentry *dentry;
 		dentry = lookup_one_len(PRIVROOT_NAME, s->s_root,
 					strlen(PRIVROOT_NAME));
@@ -1141,14 +1039,17 @@ int reiserfs_xattr_init(struct super_blo
 					 "find/create .reiserfs_priv. "
 					 "Failing mount.");
 			err = -EOPNOTSUPP;
+			goto error;
 		}
 	}
 
+	if (!err)
+		s->s_xattr = reiserfs_xattr_handlers;
+
       error:
 	/* This is only nonzero if there was an error initializing the xattr
 	 * directory or if there is a condition where we don't support them. */
 	if (err) {
-		clear_bit(REISERFS_XATTRS, &(REISERFS_SB(s)->s_mount_opt));
 		clear_bit(REISERFS_XATTRS_USER, &(REISERFS_SB(s)->s_mount_opt));
 		clear_bit(REISERFS_POSIXACL, &(REISERFS_SB(s)->s_mount_opt));
 	}
--- a/fs/reiserfs/xattr_acl.c	2007-06-11 14:49:36.000000000 -0400
+++ b/fs/reiserfs/xattr_acl.c	2007-06-11 14:50:06.000000000 -0400
@@ -271,7 +271,7 @@ reiserfs_set_acl(struct inode *inode, in
 	char *name;
 	void *value = NULL;
 	struct posix_acl **p_acl;
-	size_t size;
+	size_t size = 0;
 	int error;
 	struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode);
 
@@ -289,6 +289,9 @@ reiserfs_set_acl(struct inode *inode, in
 				return error;
 			else {
 				inode->i_mode = mode;
+				/* We don't dirty the inode, since
+				 * reiserfs_xattr_set_handle will do it
+				 * for us. */
 				if (error == 0)
 					acl = NULL;
 			}
@@ -308,19 +311,10 @@ reiserfs_set_acl(struct inode *inode, in
 		value = posix_acl_to_disk(acl, &size);
 		if (IS_ERR(value))
 			return (int)PTR_ERR(value);
-		error = reiserfs_xattr_set(inode, name, value, size, 0);
-	} else {
-		error = reiserfs_xattr_del(inode, name);
-		if (error == -ENODATA) {
-			/* This may seem odd here, but it means that the ACL was set
-			 * with a value representable with mode bits. If there was
-			 * an ACL before, reiserfs_xattr_del already dirtied the inode.
-			 */
-			mark_inode_dirty(inode);
-			error = 0;
-		}
 	}
 
+	error = reiserfs_xattr_set(inode, name, value, size, 0);
+
 	kfree(value);
 
 	if (!error)
@@ -474,33 +468,22 @@ posix_acl_access_set(struct inode *inode
 	return xattr_set_acl(inode, ACL_TYPE_ACCESS, value, size);
 }
 
-static int posix_acl_access_del(struct inode *inode, const char *name)
-{
-	struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode);
-	if (strlen(name) != sizeof(POSIX_ACL_XATTR_ACCESS) - 1)
-		return -EINVAL;
-	iset_acl(inode, &reiserfs_i->i_acl_access, ERR_PTR(-ENODATA));
-	return 0;
-}
-
-static int
-posix_acl_access_list(struct inode *inode, const char *name, int namelen,
-		      char *out)
+static size_t posix_acl_access_list(struct inode *inode, char *list,
+                                    size_t list_size, const char *name,
+                                    size_t name_len)
 {
-	int len = namelen;
+	const size_t size = sizeof(POSIX_ACL_XATTR_ACCESS);
 	if (!reiserfs_posixacl(inode->i_sb))
 		return 0;
-	if (out)
-		memcpy(out, name, len);
-
-	return len;
+	if (list && size <= list_size)
+	 	memcpy(list, POSIX_ACL_XATTR_ACCESS, size);
+	return size;
 }
 
-struct reiserfs_xattr_handler posix_acl_access_handler = {
+struct xattr_handler reiserfs_posix_acl_access_handler = {
 	.prefix = POSIX_ACL_XATTR_ACCESS,
 	.get = posix_acl_access_get,
 	.set = posix_acl_access_set,
-	.del = posix_acl_access_del,
 	.list = posix_acl_access_list,
 };
 
@@ -522,32 +505,21 @@ posix_acl_default_set(struct inode *inod
 	return xattr_set_acl(inode, ACL_TYPE_DEFAULT, value, size);
 }
 
-static int posix_acl_default_del(struct inode *inode, const char *name)
+static size_t posix_acl_default_list(struct inode *inode, char *list,
+                                     size_t list_size, const char *name,
+                                     size_t name_len)
 {
-	struct reiserfs_inode_info *reiserfs_i = REISERFS_I(inode);
-	if (strlen(name) != sizeof(POSIX_ACL_XATTR_DEFAULT) - 1)
-		return -EINVAL;
-	iset_acl(inode, &reiserfs_i->i_acl_default, ERR_PTR(-ENODATA));
-	return 0;
-}
-
-static int
-posix_acl_default_list(struct inode *inode, const char *name, int namelen,
-		       char *out)
-{
-	int len = namelen;
+	const size_t size = sizeof(POSIX_ACL_XATTR_DEFAULT);
 	if (!reiserfs_posixacl(inode->i_sb))
 		return 0;
-	if (out)
-		memcpy(out, name, len);
-
-	return len;
+	if (list && size <= list_size)
+	 	memcpy(list, POSIX_ACL_XATTR_DEFAULT, size);
+	return size;
 }
 
-struct reiserfs_xattr_handler posix_acl_default_handler = {
+struct xattr_handler reiserfs_posix_acl_default_handler = {
 	.prefix = POSIX_ACL_XATTR_DEFAULT,
 	.get = posix_acl_default_get,
 	.set = posix_acl_default_set,
-	.del = posix_acl_default_del,
 	.list = posix_acl_default_list,
 };
--- a/fs/reiserfs/xattr_security.c	2007-06-11 14:49:05.000000000 -0400
+++ b/fs/reiserfs/xattr_security.c	2007-06-11 14:50:05.000000000 -0400
@@ -33,35 +33,25 @@ security_set(struct inode *inode, const 
 	return reiserfs_xattr_set(inode, name, buffer, size, flags);
 }
 
-static int security_del(struct inode *inode, const char *name)
+static size_t security_list(struct inode *inode, char *list, size_t list_len,
+			    const char *name, size_t namelen)
 {
-	if (strlen(name) < sizeof(XATTR_SECURITY_PREFIX))
-		return -EINVAL;
-
-	if (is_reiserfs_priv_object(inode))
-		return -EPERM;
-
-	return 0;
-}
-
-static int
-security_list(struct inode *inode, const char *name, int namelen, char *out)
-{
-	int len = namelen;
+	const size_t len = namelen + 1;
 
 	if (is_reiserfs_priv_object(inode))
 		return 0;
 
-	if (out)
-		memcpy(out, name, len);
+	if (list && len <= list_len) {
+		memcpy(list, name, namelen);
+		list[namelen] = '\0';
+	}
 
 	return len;
 }
 
-struct reiserfs_xattr_handler security_handler = {
+struct xattr_handler reiserfs_xattr_security_handler = {
 	.prefix = XATTR_SECURITY_PREFIX,
 	.get = security_get,
 	.set = security_set,
-	.del = security_del,
 	.list = security_list,
 };
--- a/fs/reiserfs/xattr_trusted.c	2007-06-11 14:49:05.000000000 -0400
+++ b/fs/reiserfs/xattr_trusted.c	2007-06-11 14:49:37.000000000 -0400
@@ -15,10 +15,7 @@ trusted_get(struct inode *inode, const c
 	if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
 		return -EINVAL;
 
-	if (!reiserfs_xattrs(inode->i_sb))
-		return -EOPNOTSUPP;
-
-	if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
+	if (!capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode))
 		return -EPERM;
 
 	return reiserfs_xattr_get(inode, name, buffer, size);
@@ -31,50 +28,30 @@ trusted_set(struct inode *inode, const c
 	if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
 		return -EINVAL;
 
-	if (!reiserfs_xattrs(inode->i_sb))
-		return -EOPNOTSUPP;
-
-	if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
+	if (!capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode))
 		return -EPERM;
 
 	return reiserfs_xattr_set(inode, name, buffer, size, flags);
 }
 
-static int trusted_del(struct inode *inode, const char *name)
+static size_t trusted_list(struct inode *inode, char *list, size_t list_size,
+                           const char *name, size_t name_len)
 {
-	if (strlen(name) < sizeof(XATTR_TRUSTED_PREFIX))
-		return -EINVAL;
+	const size_t len = name_len + 1;
 
-	if (!reiserfs_xattrs(inode->i_sb))
-		return -EOPNOTSUPP;
-
-	if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
-		return -EPERM;
-
-	return 0;
-}
-
-static int
-trusted_list(struct inode *inode, const char *name, int namelen, char *out)
-{
-	int len = namelen;
-
-	if (!reiserfs_xattrs(inode->i_sb))
+	if (!capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode))
 		return 0;
 
-	if (!(capable(CAP_SYS_ADMIN) || is_reiserfs_priv_object(inode)))
-		return 0;
-
-	if (out)
-		memcpy(out, name, len);
-
+	if (list && len <= list_size) {
+		memcpy(list, name, name_len);
+		list[name_len] = '\0';
+	}
 	return len;
 }
 
-struct reiserfs_xattr_handler trusted_handler = {
+struct xattr_handler reiserfs_xattr_trusted_handler = {
 	.prefix = XATTR_TRUSTED_PREFIX,
 	.get = trusted_get,
 	.set = trusted_set,
-	.del = trusted_del,
 	.list = trusted_list,
 };
--- a/fs/reiserfs/xattr_user.c	2007-06-11 14:49:05.000000000 -0400
+++ b/fs/reiserfs/xattr_user.c	2007-06-11 14:49:37.000000000 -0400
@@ -6,10 +6,6 @@
 #include <linux/reiserfs_xattr.h>
 #include <asm/uaccess.h>
 
-#ifdef CONFIG_REISERFS_FS_POSIX_ACL
-# include <linux/reiserfs_acl.h>
-#endif
-
 #define XATTR_USER_PREFIX "user."
 
 static int
@@ -36,33 +32,23 @@ user_set(struct inode *inode, const char
 	return reiserfs_xattr_set(inode, name, buffer, size, flags);
 }
 
-static int user_del(struct inode *inode, const char *name)
+static size_t user_list(struct inode *inode, char *list, size_t list_size,
+                        const char *name, size_t name_len)
 {
-	if (strlen(name) < sizeof(XATTR_USER_PREFIX))
-		return -EINVAL;
+	const size_t len = name_len + 1;
 
 	if (!reiserfs_xattrs_user(inode->i_sb))
-		return -EOPNOTSUPP;
-	return 0;
-}
-
-static int
-user_list(struct inode *inode, const char *name, int namelen, char *out)
-{
-	int len = namelen;
-	if (!reiserfs_xattrs_user(inode->i_sb))
 		return 0;
-
-	if (out)
-		memcpy(out, name, len);
-
+	if (list && len <= list_size) {
+		memcpy(list, name, name_len);
+		list[name_len] = '\0';
+	}
 	return len;
 }
 
-struct reiserfs_xattr_handler user_handler = {
+struct xattr_handler reiserfs_xattr_user_handler = {
 	.prefix = XATTR_USER_PREFIX,
 	.get = user_get,
 	.set = user_set,
-	.del = user_del,
 	.list = user_list,
 };
--- a/include/linux/reiserfs_acl.h	2007-06-11 14:49:05.000000000 -0400
+++ b/include/linux/reiserfs_acl.h	2007-06-11 14:50:06.000000000 -0400
@@ -52,10 +52,8 @@ int reiserfs_acl_chmod(struct inode *ino
 int reiserfs_inherit_default_acl(struct inode *dir, struct dentry *dentry,
 				 struct inode *inode);
 int reiserfs_cache_default_acl(struct inode *dir);
-extern int reiserfs_xattr_posix_acl_init(void) __init;
-extern int reiserfs_xattr_posix_acl_exit(void);
-extern struct reiserfs_xattr_handler posix_acl_default_handler;
-extern struct reiserfs_xattr_handler posix_acl_access_handler;
+extern struct xattr_handler reiserfs_posix_acl_default_handler;
+extern struct xattr_handler reiserfs_posix_acl_access_handler;
 
 static inline void reiserfs_init_acl_access(struct inode *inode)
 {
@@ -75,16 +73,6 @@ static inline struct posix_acl *reiserfs
 	return NULL;
 }
 
-static inline int reiserfs_xattr_posix_acl_init(void)
-{
-	return 0;
-}
-
-static inline int reiserfs_xattr_posix_acl_exit(void)
-{
-	return 0;
-}
-
 static inline int reiserfs_acl_chmod(struct inode *inode)
 {
 	return 0;
--- a/include/linux/reiserfs_fs_sb.h	2007-06-11 14:49:36.000000000 -0400
+++ b/include/linux/reiserfs_fs_sb.h	2007-06-11 14:50:04.000000000 -0400
@@ -452,7 +452,6 @@ enum reiserfs_mount_options {
 	REISERFS_NO_UNHASHED_RELOCATION,
 	REISERFS_HASHED_RELOCATION,
 	REISERFS_ATTRS,
-	REISERFS_XATTRS,
 	REISERFS_XATTRS_USER,
 	REISERFS_POSIXACL,
 	REISERFS_BARRIER_NONE,
@@ -490,7 +489,7 @@ enum reiserfs_mount_options {
 #define reiserfs_data_log(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_DATA_LOG))
 #define reiserfs_data_ordered(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_DATA_ORDERED))
 #define reiserfs_data_writeback(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_DATA_WRITEBACK))
-#define reiserfs_xattrs(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_XATTRS))
+#define reiserfs_xattrs(s) ((s)->s_xattr != NULL)
 #define reiserfs_xattrs_user(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_XATTRS_USER))
 #define reiserfs_posixacl(s) (REISERFS_SB(s)->s_mount_opt & (1 << REISERFS_POSIXACL))
 #define reiserfs_xattrs_optional(s) (reiserfs_xattrs_user(s) || reiserfs_posixacl(s))
--- a/include/linux/reiserfs_xattr.h	2007-06-11 14:49:36.000000000 -0400
+++ b/include/linux/reiserfs_xattr.h	2007-06-11 14:50:06.000000000 -0400
@@ -29,20 +29,6 @@ struct iattr;
 struct super_block;
 struct nameidata;
 
-struct reiserfs_xattr_handler {
-	char *prefix;
-	int (*init) (void);
-	void (*exit) (void);
-	int (*get) (struct inode * inode, const char *name, void *buffer,
-		    size_t size);
-	int (*set) (struct inode * inode, const char *name, const void *buffer,
-		    size_t size, int flags);
-	int (*del) (struct inode * inode, const char *name);
-	int (*list) (struct inode * inode, const char *name, int namelen,
-		     char *out);
-	struct list_head handlers;
-};
-
 #ifdef CONFIG_REISERFS_FS_XATTR
 #define is_reiserfs_priv_object(inode) IS_PRIVATE(inode)
 #define has_xattr_dir(inode) (REISERFS_I(inode)->i_flags & i_has_xattr_dir)
@@ -57,16 +43,12 @@ int reiserfs_chown_xattrs(struct inode *
 int reiserfs_xattr_init(struct super_block *sb, int mount_flags);
 int reiserfs_permission(struct inode *inode, int mask, struct nameidata *nd);
 
-int reiserfs_xattr_del(struct inode *, const char *);
-int reiserfs_xattr_get(const struct inode *, const char *, void *, size_t);
+int reiserfs_xattr_get(struct inode *, const char *, void *, size_t);
 int reiserfs_xattr_set(struct inode *, const char *, const void *, size_t, int);
 
-extern struct reiserfs_xattr_handler user_handler;
-extern struct reiserfs_xattr_handler trusted_handler;
-extern struct reiserfs_xattr_handler security_handler;
-
-int reiserfs_xattr_register_handlers(void) __init;
-void reiserfs_xattr_unregister_handlers(void);
+extern struct xattr_handler reiserfs_xattr_user_handler;
+extern struct xattr_handler reiserfs_xattr_trusted_handler;
+extern struct xattr_handler reiserfs_xattr_security_handler;
 
 
 static inline void reiserfs_mark_inode_private(struct inode *inode)
@@ -85,9 +67,6 @@ static inline void reiserfs_mark_inode_p
 
 #define reiserfs_permission NULL
 
-#define reiserfs_xattr_register_handlers() 0
-#define reiserfs_xattr_unregister_handlers()
-
 static inline int reiserfs_delete_xattrs(struct inode *inode)
 {
 	return 0;

-- 
Jeff Mahoney
SUSE Labs


  parent reply	other threads:[~2007-06-11 19:03 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-06-11 19:03 [patch 00/40] reiserfs: patch queue (v2) jeffm
2007-06-11 19:03 ` [patch 01/40] reiserfs: fix up lockdep warnings jeffm
2007-06-11 19:03 ` [patch 02/40] reiserfs: dont use BUG when panicking jeffm
2007-06-11 19:03 ` [patch 03/40] reiserfs: use is_reusable to catch corruption jeffm
2007-06-13 15:54   ` Jeff Mahoney
2007-06-11 19:03 ` [patch 04/40] reiserfs: make bitmap use cached first zero bit jeffm
2007-06-11 19:03 ` [patch 05/40] reiserfs: use more consistent printk formatting jeffm
2007-06-11 19:03 ` [patch 06/40] reiserfs: make some warnings informational jeffm
2007-06-11 19:03 ` [patch 07/40] reiserfs: rework reiserfs_warning jeffm
2007-06-11 19:03 ` [patch 08/40] reiserfs: rework reiserfs_panic jeffm
2007-06-11 19:03 ` [patch 09/40] reiserfs: rearrange journal abort jeffm
2007-06-11 19:03 ` [patch 10/40] reiserfs: introduce reiserfs_error() jeffm
2007-06-11 19:03 ` [patch 11/40] reiserfs: use reiserfs_error() jeffm
2007-06-11 19:03 ` [patch 12/40] reiserfs: simplify xattr internal file lookups/opens jeffm
2007-06-11 19:03 ` [patch 13/40] reiserfs: eliminate per-super xattr lock jeffm
2007-06-11 19:03 ` [patch 14/40] reiserfs: make per-inode xattr locking more fine grained jeffm
2007-06-11 19:03 ` [patch 15/40] reiserfs: remove i_has_xattr_dir jeffm
2007-06-11 19:03 ` [patch 16/40] reiserfs: remove link detection code jeffm
2007-06-11 19:03 ` jeffm [this message]
2007-06-11 19:03 ` [patch 18/40] reiserfs: use better open options for internal files jeffm
2007-06-11 19:03 ` [patch 19/40] reiserfs: add per-file data=ordered mode and use it for xattrs jeffm
2007-06-11 19:03 ` [patch 20/40] reiserfs: journaled xattrs jeffm
2007-06-11 19:03 ` [patch 21/40] reiserfs: use generic readdir for operations across all xattrs jeffm
2007-06-11 19:03 ` [patch 22/40] reiserfs: add atomic addition of selinux attributes during inode creation jeffm
2007-06-11 19:03 ` [patch 23/40] reiserfs: cleanup path functions jeffm
2007-06-11 19:03 ` [patch 24/40] reiserfs: strip trailing whitespace jeffm
2007-06-11 19:03 ` [patch 26/40] reiserfs: rename p_s_bh to bh jeffm
2007-06-11 19:03 ` [patch 27/40] reiserfs: rename p_s_inode to inode jeffm
2007-06-11 19:03 ` [patch 28/40] reiserfs: rename p_s_tb to tb jeffm
2007-06-11 19:03 ` [patch 29/40] reiserfs: rename p_._ variables jeffm
2007-06-11 19:03 ` [patch 30/40] reiserfs: rename _* variables jeffm
2007-06-11 19:03 ` [patch 31/40] reiserfs: factor out buffer_info initialization jeffm
2007-06-11 19:03 ` [patch 32/40] reiserfs: Turn tb->snum and tb->sbytes into an array jeffm
2007-06-11 19:03 ` [patch 33/40] reiserfs: split left balancing part of balance_leaf() off jeffm
2007-06-11 19:03 ` [patch 34/40] reiserfs: split right " jeffm
2007-06-11 19:03 ` [patch 35/40] reiserfs: split balance_leaf new node handling out jeffm
2007-06-11 19:03 ` [patch 36/40] reiserfs: split out current node handling from balance_leaf jeffm
2007-06-11 19:03 ` [patch 37/40] reiserfs: clean up bl_when_delete jeffm
2007-06-11 19:03 ` [patch 38/40] reiserfs: clean up balancing modes jeffm
2007-06-11 19:03 ` [patch 39/40] reiserfs: split bl_when_delete jeffm
2007-06-11 19:03 ` [patch 40/40] reiserfs: reorganize do_balan.c comments jeffm
2007-06-11 19:20 ` [patch 00/40] reiserfs: patch queue (v2) Jeff Mahoney
2007-06-14 19:41 ` Jeff Mahoney

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20070611190631.197839937@suse.com \
    --to=jeffm@suse.com \
    --cc=reiserfs-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.