[PATCH 11/32] ext4: clean up ext4_xattr_inode_get()

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

 



The input and output values of *size parameter are equal on successful
return from ext4_xattr_inode_get(). On error return, the callers ignore
the output value so there is no need to update it.

Also check for NULL return from ext4_bread(). If the actual xattr inode
size happens to be smaller than the expected size, ext4_bread() may
return NULL which would indicate data corruption.

Signed-off-by: Tahsin Erdogan <tahsin@xxxxxxxxxx>
---
 fs/ext4/xattr.c | 35 +++++++++++++----------------------
 1 file changed, 13 insertions(+), 22 deletions(-)

diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index d9477d01be9b..8e855fc2eb03 100644
--- a/fs/ext4/xattr.c
+++ b/fs/ext4/xattr.c
@@ -278,37 +278,28 @@ ext4_xattr_find_entry(struct ext4_xattr_entry **pentry, int name_index,
 /*
  * Read the EA value from an inode.
  */
-static int
-ext4_xattr_inode_read(struct inode *ea_inode, void *buf, size_t *size)
+static int ext4_xattr_inode_read(struct inode *ea_inode, void *buf, size_t size)
 {
 	unsigned long block = 0;
 	struct buffer_head *bh = NULL;
-	int blocksize;
-	size_t csize, ret_size = 0;
-
-	if (*size == 0)
-		return 0;
+	int blocksize = ea_inode->i_sb->s_blocksize;
+	size_t csize, copied = 0;
 
-	blocksize = ea_inode->i_sb->s_blocksize;
-
-	while (ret_size < *size) {
-		csize = (*size - ret_size) > blocksize ? blocksize :
-							*size - ret_size;
+	while (copied < size) {
+		csize = (size - copied) > blocksize ? blocksize : size - copied;
 		bh = ext4_bread(NULL, ea_inode, block, 0);
-		if (IS_ERR(bh)) {
-			*size = ret_size;
+		if (IS_ERR(bh))
 			return PTR_ERR(bh);
-		}
+		if (!bh)
+			return -EFSCORRUPTED;
+
 		memcpy(buf, bh->b_data, csize);
 		brelse(bh);
 
 		buf += csize;
 		block += 1;
-		ret_size += csize;
+		copied += csize;
 	}
-
-	*size = ret_size;
-
 	return 0;
 }
 
@@ -360,7 +351,7 @@ static int ext4_xattr_inode_iget(struct inode *parent, unsigned long ea_ino,
  */
 static int
 ext4_xattr_inode_get(struct inode *inode, unsigned long ea_ino, void *buffer,
-		     size_t *size)
+		     size_t size)
 {
 	struct inode *ea_inode;
 	int ret;
@@ -417,7 +408,7 @@ ext4_xattr_block_get(struct inode *inode, int name_index, const char *name,
 		if (entry->e_value_inum) {
 			error = ext4_xattr_inode_get(inode,
 					     le32_to_cpu(entry->e_value_inum),
-					     buffer, &size);
+					     buffer, size);
 			if (error)
 				goto cleanup;
 		} else {
@@ -467,7 +458,7 @@ ext4_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
 		if (entry->e_value_inum) {
 			error = ext4_xattr_inode_get(inode,
 					     le32_to_cpu(entry->e_value_inum),
-					     buffer, &size);
+					     buffer, size);
 			if (error)
 				goto cleanup;
 		} else {
-- 
2.13.1.611.g7e3b11ae1-goog




[Index of Archives]     [Reiser Filesystem Development]     [Ceph FS]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux FS]     [Yosemite National Park]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Device Mapper]     [Linux Media]

  Powered by Linux