Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/fs/ext3/xattr.c |  242 ++++++++++++++++++++++++------------------------
 25-akpm/fs/ext3/xattr.h |    8 +
 2 files changed, 129 insertions(+), 121 deletions(-)

diff -puN fs/ext3/xattr.c~ext3-ea-revert-cleanup fs/ext3/xattr.c
--- 25/fs/ext3/xattr.c~ext3-ea-revert-cleanup	Wed Jan 12 16:55:13 2005
+++ 25-akpm/fs/ext3/xattr.c	Wed Jan 12 16:55:13 2005
@@ -139,11 +139,22 @@ ext3_xattr_handler(int name_index)
 }
 
 /*
+ * Inode operation listxattr()
+ *
+ * dentry->d_inode->i_sem: don't care
+ */
+ssize_t
+ext3_listxattr(struct dentry *dentry, char *buffer, size_t size)
+{
+	return ext3_xattr_list(dentry->d_inode, buffer, size);
+}
+
+/*
  * ext3_xattr_block_get()
  *
  * routine looks for attribute in EA block and returns it's value and size
  */
-static int
+int
 ext3_xattr_block_get(struct inode *inode, int name_index, const char *name,
 	       void *buffer, size_t buffer_size)
 {
@@ -239,7 +250,7 @@ cleanup:
  *
  * routine looks for attribute in inode body and returns it's value and size
  */
-static int
+int
 ext3_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
 	       void *buffer, size_t buffer_size)
 {
@@ -341,7 +352,7 @@ ext3_xattr_get(struct inode *inode, int 
  *
  * generate list of attributes stored in EA block
  */
-static int
+int
 ext3_xattr_block_list(struct inode *inode, char *buffer, size_t buffer_size)
 {
 	struct buffer_head *bh = NULL;
@@ -417,7 +428,7 @@ cleanup:
  *
  * generate list of attributes stored in inode body
  */
-static int
+int
 ext3_xattr_ibody_list(struct inode *inode, char *buffer, size_t buffer_size)
 {
 	struct ext3_xattr_entry *last;
@@ -496,7 +507,7 @@ cleanup:
  * Returns a negative error number on failure, or the number of bytes
  * used / required on success.
  */
-static int
+int
 ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size)
 {
 	int size = buffer_size;
@@ -535,17 +546,6 @@ cleanup:
 }
 
 /*
- * Inode operation listxattr()
- *
- * dentry->d_inode->i_sem: don't care
- */
-ssize_t
-ext3_listxattr(struct dentry *dentry, char *buffer, size_t size)
-{
-	return ext3_xattr_list(dentry->d_inode, buffer, size);
-}
-
-/*
  * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is
  * not set, set it.
  */
@@ -571,7 +571,7 @@ static void ext3_xattr_update_super_bloc
  * search attribute and calculate free space in inode body
  * NOTE: free space includes space our attribute hold
  */
-static int
+int
 ext3_xattr_ibody_find(struct inode *inode, int name_index,
 			const char *name, int *free)
 {
@@ -638,7 +638,7 @@ ext3_xattr_ibody_find(struct inode *inod
  * search attribute and calculate free space in EA block (if it allocated)
  * NOTE: free space includes space our attribute hold
  */
-static int
+int
 ext3_xattr_block_find(struct inode *inode, int name_index,
 			const char *name, int *free)
 {
@@ -698,7 +698,7 @@ bad_block:	ext3_error(inode->i_sb, "ext3
  *
  * this routine add/remove/replace attribute in inode body
  */
-static int
+int
 ext3_xattr_ibody_set(handle_t *handle, struct inode *inode, int name_index,
 		      const char *name, const void *value, size_t value_len,
 		      int flags)
@@ -846,11 +846,112 @@ done:
 }
 
 /*
+ * ext3_xattr_set_handle()
+ *
+ * Create, replace or remove an extended attribute for this inode. Buffer
+ * is NULL to remove an existing extended attribute, and non-NULL to
+ * either replace an existing extended attribute, or create a new extended
+ * attribute. The flags XATTR_REPLACE and XATTR_CREATE
+ * specify that an extended attribute must exist and must not exist
+ * previous to the call, respectively.
+ *
+ * Returns 0, or a negative error number on failure.
+ */
+int
+ext3_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
+		const char *name, const void *value, size_t value_len,
+		int flags)
+{
+	int free1 = -1, free2 = -1;
+	int err, where = 0, total;
+	int name_len;
+
+	ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
+		  name_index, name, value, (long)value_len);
+
+	if (IS_RDONLY(inode))
+		return -EROFS;
+	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
+		return -EPERM;
+	if (value == NULL)
+		value_len = 0;
+	if (name == NULL)
+		return -EINVAL;
+	name_len = strlen(name);
+	if (name_len > 255 || value_len > inode->i_sb->s_blocksize)
+		return -ERANGE;
+	down_write(&EXT3_I(inode)->xattr_sem);
+
+#define EX_FOUND_IN_IBODY	1
+#define EX_FOUND_IN_BLOCK	2
+
+	/* try to find attribute in inode body */
+	err = ext3_xattr_ibody_find(inode, name_index, name, &free1);
+	if (err == 0) {
+		/* found EA in inode */
+		where = EX_FOUND_IN_IBODY;
+	} else if (err == -ENOENT) {
+		/* there is no such attribute in inode body */
+		/* try to find attribute in dedicated block */
+		err = ext3_xattr_block_find(inode, name_index, name, &free2);
+		if (err != 0 && err != -ENOENT) {
+			/* not found EA in block */
+			goto finish;
+		} else if (err == 0) {
+			/* found EA in block */
+			where = EX_FOUND_IN_BLOCK;
+		}
+	} else
+		goto finish;
+
+	/* check flags: may replace? may create ? */
+	if (where && (flags & XATTR_CREATE)) {
+		err = -EEXIST;
+		goto finish;
+	} else if (!where && (flags & XATTR_REPLACE)) {
+		err = -ENODATA;
+		goto finish;
+	}
+
+	/* check if we have enough space to store attribute */
+	total = EXT3_XATTR_LEN(strlen(name)) + value_len;
+	if (total > free1 && free2 > 0 && total > free2) {
+		/* have no enough space */
+		err = -ENOSPC;
+		goto finish;
+	}
+
+	/* there are two cases when we want to remove EA from original storage:
+	 * a) EA is stored in the inode, but new value doesn't fit
+	 * b) EA is stored in the block, but new value fit in inode
+	 */
+	if (where == EX_FOUND_IN_IBODY && total > free1)
+		ext3_xattr_ibody_set(handle, inode, name_index, name,
+					NULL, 0, flags);
+	else if (where == EX_FOUND_IN_BLOCK && total <= free1)
+		ext3_xattr_block_set(handle, inode, name_index,
+					name, NULL, 0, flags);
+
+	/* try to store EA in inode body */
+	err = ext3_xattr_ibody_set(handle, inode, name_index, name,
+					value, value_len, flags);
+	if (err) {
+		/* can't store EA in inode body: try to store in block */
+		err = ext3_xattr_block_set(handle, inode, name_index, name,
+						value, value_len, flags);
+	}
+
+finish:
+	up_write(&EXT3_I(inode)->xattr_sem);
+	return err;
+}
+
+/*
  * ext3_xattr_block_set()
  *
  * this routine add/remove/replace attribute in EA block
  */
-static int
+int
 ext3_xattr_block_set(handle_t *handle, struct inode *inode, int name_index,
 		      const char *name, const void *value, size_t value_len,
 		      int flags)
@@ -1105,107 +1206,6 @@ cleanup:
 }
 
 /*
- * ext3_xattr_set_handle()
- *
- * Create, replace or remove an extended attribute for this inode. Buffer
- * is NULL to remove an existing extended attribute, and non-NULL to
- * either replace an existing extended attribute, or create a new extended
- * attribute. The flags XATTR_REPLACE and XATTR_CREATE
- * specify that an extended attribute must exist and must not exist
- * previous to the call, respectively.
- *
- * Returns 0, or a negative error number on failure.
- */
-int
-ext3_xattr_set_handle(handle_t *handle, struct inode *inode, int name_index,
-		const char *name, const void *value, size_t value_len,
-		int flags)
-{
-	int free1 = -1, free2 = -1;
-	int err, where = 0, total;
-	int name_len;
-
-	ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld",
-		  name_index, name, value, (long)value_len);
-
-	if (IS_RDONLY(inode))
-		return -EROFS;
-	if (IS_IMMUTABLE(inode) || IS_APPEND(inode))
-		return -EPERM;
-	if (value == NULL)
-		value_len = 0;
-	if (name == NULL)
-		return -EINVAL;
-	name_len = strlen(name);
-	if (name_len > 255 || value_len > inode->i_sb->s_blocksize)
-		return -ERANGE;
-	down_write(&EXT3_I(inode)->xattr_sem);
-
-#define EX_FOUND_IN_IBODY	1
-#define EX_FOUND_IN_BLOCK	2
-
-	/* try to find attribute in inode body */
-	err = ext3_xattr_ibody_find(inode, name_index, name, &free1);
-	if (err == 0) {
-		/* found EA in inode */
-		where = EX_FOUND_IN_IBODY;
-	} else if (err == -ENOENT) {
-		/* there is no such attribute in inode body */
-		/* try to find attribute in dedicated block */
-		err = ext3_xattr_block_find(inode, name_index, name, &free2);
-		if (err != 0 && err != -ENOENT) {
-			/* not found EA in block */
-			goto finish;
-		} else if (err == 0) {
-			/* found EA in block */
-			where = EX_FOUND_IN_BLOCK;
-		}
-	} else
-		goto finish;
-
-	/* check flags: may replace? may create ? */
-	if (where && (flags & XATTR_CREATE)) {
-		err = -EEXIST;
-		goto finish;
-	} else if (!where && (flags & XATTR_REPLACE)) {
-		err = -ENODATA;
-		goto finish;
-	}
-
-	/* check if we have enough space to store attribute */
-	total = EXT3_XATTR_LEN(strlen(name)) + value_len;
-	if (total > free1 && free2 > 0 && total > free2) {
-		/* have no enough space */
-		err = -ENOSPC;
-		goto finish;
-	}
-
-	/* there are two cases when we want to remove EA from original storage:
-	 * a) EA is stored in the inode, but new value doesn't fit
-	 * b) EA is stored in the block, but new value fit in inode
-	 */
-	if (where == EX_FOUND_IN_IBODY && total > free1)
-		ext3_xattr_ibody_set(handle, inode, name_index, name,
-					NULL, 0, flags);
-	else if (where == EX_FOUND_IN_BLOCK && total <= free1)
-		ext3_xattr_block_set(handle, inode, name_index,
-					name, NULL, 0, flags);
-
-	/* try to store EA in inode body */
-	err = ext3_xattr_ibody_set(handle, inode, name_index, name,
-					value, value_len, flags);
-	if (err) {
-		/* can't store EA in inode body: try to store in block */
-		err = ext3_xattr_block_set(handle, inode, name_index, name,
-						value, value_len, flags);
-	}
-
-finish:
-	up_write(&EXT3_I(inode)->xattr_sem);
-	return err;
-}
-
-/*
  * Second half of ext3_xattr_set_handle(): Update the file system.
  */
 static int
diff -puN fs/ext3/xattr.h~ext3-ea-revert-cleanup fs/ext3/xattr.h
--- 25/fs/ext3/xattr.h~ext3-ea-revert-cleanup	Wed Jan 12 16:55:13 2005
+++ 25-akpm/fs/ext3/xattr.h	Wed Jan 12 16:55:13 2005
@@ -65,8 +65,10 @@ extern struct xattr_handler ext3_xattr_s
 extern ssize_t ext3_listxattr(struct dentry *, char *, size_t);
 
 extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t);
+extern int ext3_xattr_list(struct inode *, char *, size_t);
 extern int ext3_xattr_set(struct inode *, int, const char *, const void *, size_t, int);
 extern int ext3_xattr_set_handle(handle_t *, struct inode *, int, const char *,const void *,size_t,int);
+extern int ext3_xattr_block_set(handle_t *, struct inode *, int, const char *,const void *,size_t,int);
 
 extern void ext3_xattr_delete_inode(handle_t *, struct inode *);
 extern void ext3_xattr_put_super(struct super_block *);
@@ -84,6 +86,12 @@ ext3_xattr_get(struct inode *inode, int 
 {
 	return -EOPNOTSUPP;
 }
+
+static inline int
+ext3_xattr_list(struct inode *inode, void *buffer, size_t size)
+{
+	return -EOPNOTSUPP;
+}
 
 static inline int
 ext3_xattr_set(struct inode *inode, int name_index, const char *name,
_