summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTahsin Erdogan <tahsin@google.com>2017-06-22 03:57:36 +0200
committerTheodore Ts'o <tytso@mit.edu>2017-06-22 03:57:36 +0200
commit909666933210eb145bc93426ce07f66bf3d1f798 (patch)
tree2860c6d369f273f7f3854c0c52c4c8bc43753524
parentext4: change ext4_xattr_inode_iget() signature (diff)
downloadlinux-909666933210eb145bc93426ce07f66bf3d1f798.tar.xz
linux-909666933210eb145bc93426ce07f66bf3d1f798.zip
ext4: clean up ext4_xattr_inode_get()
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@google.com> Signed-off-by: Theodore Ts'o <tytso@mit.edu>
-rw-r--r--fs/ext4/xattr.c35
1 files changed, 13 insertions, 22 deletions
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c
index f16a90824d44..61c67a04a7e1 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 @@ error:
*/
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 {