Commit 90966693 authored by Tahsin Erdogan's avatar Tahsin Erdogan Committed by Theodore Ts'o

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: default avatarTahsin Erdogan <tahsin@google.com>
Signed-off-by: default avatarTheodore Ts'o <tytso@mit.edu>
parent bab79b04
...@@ -278,37 +278,28 @@ ext4_xattr_find_entry(struct ext4_xattr_entry **pentry, int name_index, ...@@ -278,37 +278,28 @@ ext4_xattr_find_entry(struct ext4_xattr_entry **pentry, int name_index,
/* /*
* Read the EA value from an inode. * Read the EA value from an inode.
*/ */
static int static int ext4_xattr_inode_read(struct inode *ea_inode, void *buf, size_t size)
ext4_xattr_inode_read(struct inode *ea_inode, void *buf, size_t *size)
{ {
unsigned long block = 0; unsigned long block = 0;
struct buffer_head *bh = NULL; struct buffer_head *bh = NULL;
int blocksize; int blocksize = ea_inode->i_sb->s_blocksize;
size_t csize, ret_size = 0; size_t csize, copied = 0;
if (*size == 0)
return 0;
blocksize = ea_inode->i_sb->s_blocksize; while (copied < size) {
csize = (size - copied) > blocksize ? blocksize : size - copied;
while (ret_size < *size) {
csize = (*size - ret_size) > blocksize ? blocksize :
*size - ret_size;
bh = ext4_bread(NULL, ea_inode, block, 0); bh = ext4_bread(NULL, ea_inode, block, 0);
if (IS_ERR(bh)) { if (IS_ERR(bh))
*size = ret_size;
return PTR_ERR(bh); return PTR_ERR(bh);
} if (!bh)
return -EFSCORRUPTED;
memcpy(buf, bh->b_data, csize); memcpy(buf, bh->b_data, csize);
brelse(bh); brelse(bh);
buf += csize; buf += csize;
block += 1; block += 1;
ret_size += csize; copied += csize;
} }
*size = ret_size;
return 0; return 0;
} }
...@@ -360,7 +351,7 @@ static int ext4_xattr_inode_iget(struct inode *parent, unsigned long ea_ino, ...@@ -360,7 +351,7 @@ static int ext4_xattr_inode_iget(struct inode *parent, unsigned long ea_ino,
*/ */
static int static int
ext4_xattr_inode_get(struct inode *inode, unsigned long ea_ino, void *buffer, ext4_xattr_inode_get(struct inode *inode, unsigned long ea_ino, void *buffer,
size_t *size) size_t size)
{ {
struct inode *ea_inode; struct inode *ea_inode;
int ret; int ret;
...@@ -417,7 +408,7 @@ ext4_xattr_block_get(struct inode *inode, int name_index, const char *name, ...@@ -417,7 +408,7 @@ ext4_xattr_block_get(struct inode *inode, int name_index, const char *name,
if (entry->e_value_inum) { if (entry->e_value_inum) {
error = ext4_xattr_inode_get(inode, error = ext4_xattr_inode_get(inode,
le32_to_cpu(entry->e_value_inum), le32_to_cpu(entry->e_value_inum),
buffer, &size); buffer, size);
if (error) if (error)
goto cleanup; goto cleanup;
} else { } else {
...@@ -467,7 +458,7 @@ ext4_xattr_ibody_get(struct inode *inode, int name_index, const char *name, ...@@ -467,7 +458,7 @@ ext4_xattr_ibody_get(struct inode *inode, int name_index, const char *name,
if (entry->e_value_inum) { if (entry->e_value_inum) {
error = ext4_xattr_inode_get(inode, error = ext4_xattr_inode_get(inode,
le32_to_cpu(entry->e_value_inum), le32_to_cpu(entry->e_value_inum),
buffer, &size); buffer, size);
if (error) if (error)
goto cleanup; goto cleanup;
} else { } else {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment