Commit 86696966 authored by Chao Yu's avatar Chao Yu Committed by Jaegeuk Kim

f2fs: fix to return error number of read_all_xattrs correctly

We treat all error in read_all_xattrs as a no memory error, which covers
the real reason of failure in it. Fix it by return correct errno in order
to reflect the real cause.
Signed-off-by: default avatarChao Yu <yuchao0@huawei.com>
Signed-off-by: default avatarJaegeuk Kim <jaegeuk@kernel.org>
parent ebfa7322
...@@ -217,18 +217,20 @@ static struct f2fs_xattr_entry *__find_xattr(void *base_addr, int index, ...@@ -217,18 +217,20 @@ static struct f2fs_xattr_entry *__find_xattr(void *base_addr, int index,
return entry; return entry;
} }
static void *read_all_xattrs(struct inode *inode, struct page *ipage) static int read_all_xattrs(struct inode *inode, struct page *ipage,
void **base_addr)
{ {
struct f2fs_sb_info *sbi = F2FS_I_SB(inode); struct f2fs_sb_info *sbi = F2FS_I_SB(inode);
struct f2fs_xattr_header *header; struct f2fs_xattr_header *header;
size_t size = PAGE_SIZE, inline_size = 0; size_t size = PAGE_SIZE, inline_size = 0;
void *txattr_addr; void *txattr_addr;
int err;
inline_size = inline_xattr_size(inode); inline_size = inline_xattr_size(inode);
txattr_addr = kzalloc(inline_size + size, GFP_F2FS_ZERO); txattr_addr = kzalloc(inline_size + size, GFP_F2FS_ZERO);
if (!txattr_addr) if (!txattr_addr)
return NULL; return -ENOMEM;
/* read from inline xattr */ /* read from inline xattr */
if (inline_size) { if (inline_size) {
...@@ -239,8 +241,10 @@ static void *read_all_xattrs(struct inode *inode, struct page *ipage) ...@@ -239,8 +241,10 @@ static void *read_all_xattrs(struct inode *inode, struct page *ipage)
inline_addr = inline_xattr_addr(ipage); inline_addr = inline_xattr_addr(ipage);
} else { } else {
page = get_node_page(sbi, inode->i_ino); page = get_node_page(sbi, inode->i_ino);
if (IS_ERR(page)) if (IS_ERR(page)) {
err = PTR_ERR(page);
goto fail; goto fail;
}
inline_addr = inline_xattr_addr(page); inline_addr = inline_xattr_addr(page);
} }
memcpy(txattr_addr, inline_addr, inline_size); memcpy(txattr_addr, inline_addr, inline_size);
...@@ -254,8 +258,10 @@ static void *read_all_xattrs(struct inode *inode, struct page *ipage) ...@@ -254,8 +258,10 @@ static void *read_all_xattrs(struct inode *inode, struct page *ipage)
/* The inode already has an extended attribute block. */ /* The inode already has an extended attribute block. */
xpage = get_node_page(sbi, F2FS_I(inode)->i_xattr_nid); xpage = get_node_page(sbi, F2FS_I(inode)->i_xattr_nid);
if (IS_ERR(xpage)) if (IS_ERR(xpage)) {
err = PTR_ERR(xpage);
goto fail; goto fail;
}
xattr_addr = page_address(xpage); xattr_addr = page_address(xpage);
memcpy(txattr_addr + inline_size, xattr_addr, PAGE_SIZE); memcpy(txattr_addr + inline_size, xattr_addr, PAGE_SIZE);
...@@ -269,10 +275,11 @@ static void *read_all_xattrs(struct inode *inode, struct page *ipage) ...@@ -269,10 +275,11 @@ static void *read_all_xattrs(struct inode *inode, struct page *ipage)
header->h_magic = cpu_to_le32(F2FS_XATTR_MAGIC); header->h_magic = cpu_to_le32(F2FS_XATTR_MAGIC);
header->h_refcount = cpu_to_le32(1); header->h_refcount = cpu_to_le32(1);
} }
return txattr_addr; *base_addr = txattr_addr;
return 0;
fail: fail:
kzfree(txattr_addr); kzfree(txattr_addr);
return NULL; return err;
} }
static inline int write_all_xattrs(struct inode *inode, __u32 hsize, static inline int write_all_xattrs(struct inode *inode, __u32 hsize,
...@@ -366,9 +373,9 @@ int f2fs_getxattr(struct inode *inode, int index, const char *name, ...@@ -366,9 +373,9 @@ int f2fs_getxattr(struct inode *inode, int index, const char *name,
if (len > F2FS_NAME_LEN) if (len > F2FS_NAME_LEN)
return -ERANGE; return -ERANGE;
base_addr = read_all_xattrs(inode, ipage); error = read_all_xattrs(inode, ipage, &base_addr);
if (!base_addr) if (error)
return -ENOMEM; return error;
entry = __find_xattr(base_addr, index, len, name); entry = __find_xattr(base_addr, index, len, name);
if (IS_XATTR_LAST_ENTRY(entry)) { if (IS_XATTR_LAST_ENTRY(entry)) {
...@@ -402,9 +409,9 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size) ...@@ -402,9 +409,9 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)
int error = 0; int error = 0;
size_t rest = buffer_size; size_t rest = buffer_size;
base_addr = read_all_xattrs(inode, NULL); error = read_all_xattrs(inode, NULL, &base_addr);
if (!base_addr) if (error)
return -ENOMEM; return error;
list_for_each_xattr(entry, base_addr) { list_for_each_xattr(entry, base_addr) {
const struct xattr_handler *handler = const struct xattr_handler *handler =
...@@ -463,9 +470,9 @@ static int __f2fs_setxattr(struct inode *inode, int index, ...@@ -463,9 +470,9 @@ static int __f2fs_setxattr(struct inode *inode, int index,
if (size > MAX_VALUE_LEN(inode)) if (size > MAX_VALUE_LEN(inode))
return -E2BIG; return -E2BIG;
base_addr = read_all_xattrs(inode, ipage); error = read_all_xattrs(inode, ipage, &base_addr);
if (!base_addr) if (error)
return -ENOMEM; return error;
/* find entry with wanted name. */ /* find entry with wanted name. */
here = __find_xattr(base_addr, index, len, name); here = __find_xattr(base_addr, index, len, name);
......
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