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: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
This commit is contained in:
Родитель
ebfa732217
Коммит
866969668a
|
@ -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)
|
||||||
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)
|
||||||
|
|
||||||
/* 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)
|
||||||
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,
|
||||||
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)
|
||||||
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,
|
||||||
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);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче