From 10658a35b7e2855893e8f6c9dff5177b08fa9d97 Mon Sep 17 00:00:00 2001
From: Andrew Morton <akpm@osdl.org>
Date: Thu, 11 Mar 2004 16:17:10 -0800
Subject: [PATCH] [PATCH] Remove arbitrary #acl entries limits on ext[23] when
 reading

From: Andreas Gruenbacher <agruen@suse.de>

Remove the arbitrary limit of 32 ACL entries on ext[23] when reading from
disk.  This change is backward compatible; we need to have this change in
to be able to also allow writing big ACLs.

The second patch that removes the ACL entry limit for writes is not
included.  I don't want to push that patch now, because large ACLs would
cause 2.4 and current 2.6 kernels to fail.  My plan is to remove the second
limit later, in a half-year or year or so.
---
 fs/ext2/acl.c | 23 +++++++++++++----------
 fs/ext3/acl.c | 21 ++++++++++++---------
 2 files changed, 25 insertions(+), 19 deletions(-)

diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c
index 1fc69c557535..091a3175dce3 100644
--- a/fs/ext2/acl.c
+++ b/fs/ext2/acl.c
@@ -154,10 +154,9 @@ ext2_iset_acl(struct inode *inode, struct posix_acl **i_acl,
 static struct posix_acl *
 ext2_get_acl(struct inode *inode, int type)
 {
-	const size_t max_size = ext2_acl_size(EXT2_ACL_MAX_ENTRIES);
 	struct ext2_inode_info *ei = EXT2_I(inode);
 	int name_index;
-	char *value;
+	char *value = NULL;
 	struct posix_acl *acl;
 	int retval;
 
@@ -182,17 +181,21 @@ ext2_get_acl(struct inode *inode, int type)
 		default:
 			return ERR_PTR(-EINVAL);
 	}
-	value = kmalloc(max_size, GFP_KERNEL);
-	if (!value)
-		return ERR_PTR(-ENOMEM);
-
-	retval = ext2_xattr_get(inode, name_index, "", value, max_size);
-	acl = ERR_PTR(retval);
-	if (retval >= 0)
+	retval = ext2_xattr_get(inode, name_index, "", NULL, 0);
+	if (retval > 0) {
+		value = kmalloc(retval, GFP_KERNEL);
+		if (!value)
+			return ERR_PTR(-ENOMEM);
+		retval = ext2_xattr_get(inode, name_index, "", value, retval);
+	}
+	if (retval > 0)
 		acl = ext2_acl_from_disk(value, retval);
 	else if (retval == -ENODATA || retval == -ENOSYS)
 		acl = NULL;
-	kfree(value);
+	else
+		acl = ERR_PTR(retval);
+	if (value)
+		kfree(value);
 
 	if (!IS_ERR(acl)) {
 		switch(type) {
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c
index 4d243fdeead2..7fd70c88e932 100644
--- a/fs/ext3/acl.c
+++ b/fs/ext3/acl.c
@@ -157,10 +157,9 @@ ext3_iset_acl(struct inode *inode, struct posix_acl **i_acl,
 static struct posix_acl *
 ext3_get_acl(struct inode *inode, int type)
 {
-	const size_t max_size = ext3_acl_size(EXT3_ACL_MAX_ENTRIES);
 	struct ext3_inode_info *ei = EXT3_I(inode);
 	int name_index;
-	char *value;
+	char *value = NULL;
 	struct posix_acl *acl;
 	int retval;
 
@@ -185,17 +184,21 @@ ext3_get_acl(struct inode *inode, int type)
 		default:
 			return ERR_PTR(-EINVAL);
 	}
-	value = kmalloc(max_size, GFP_KERNEL);
-	if (!value)
-		return ERR_PTR(-ENOMEM);
-
-	retval = ext3_xattr_get(inode, name_index, "", value, max_size);
-	acl = ERR_PTR(retval);
+	retval = ext3_xattr_get(inode, name_index, "", NULL, 0);
+	if (retval > 0) {
+		value = kmalloc(retval, GFP_KERNEL);
+		if (!value)
+			return ERR_PTR(-ENOMEM);
+		retval = ext3_xattr_get(inode, name_index, "", value, retval);
+	}
 	if (retval > 0)
 		acl = ext3_acl_from_disk(value, retval);
 	else if (retval == -ENODATA || retval == -ENOSYS)
 		acl = NULL;
-	kfree(value);
+	else
+		acl = ERR_PTR(retval);
+	if (value)
+		kfree(value);
 
 	if (!IS_ERR(acl)) {
 		switch(type) {
-- 
2.30.9