Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+22 −15
Original line number Original line Diff line number Diff line
@@ -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);