Skip to content

Commit

Permalink
f2fs: do not return EFSCORRUPTED, but try to run online repair
Browse files Browse the repository at this point in the history
commit 50a472b upstream.

If we return the error, there's no way to recover the status as of now, since
fsck does not fix the xattr boundary issue.

Cc: stable@vger.kernel.org
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
  • Loading branch information
Jaegeuk Kim authored and gregkh committed Nov 28, 2023
1 parent 3ec6312 commit e08a8d9
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 8 deletions.
4 changes: 3 additions & 1 deletion fs/f2fs/node.c
Original file line number Diff line number Diff line change
Expand Up @@ -2751,7 +2751,9 @@ int f2fs_recover_xattr_data(struct inode *inode, struct page *page)
f2fs_update_inode_page(inode);

/* 3: update and set xattr node page dirty */
memcpy(F2FS_NODE(xpage), F2FS_NODE(page), VALID_XATTR_BLOCK_SIZE);
if (page)
memcpy(F2FS_NODE(xpage), F2FS_NODE(page),
VALID_XATTR_BLOCK_SIZE);

set_page_dirty(xpage);
f2fs_put_page(xpage, 1);
Expand Down
20 changes: 13 additions & 7 deletions fs/f2fs/xattr.c
Original file line number Diff line number Diff line change
Expand Up @@ -364,10 +364,10 @@ static int lookup_all_xattrs(struct inode *inode, struct page *ipage,

*xe = __find_xattr(cur_addr, last_txattr_addr, NULL, index, len, name);
if (!*xe) {
f2fs_err(F2FS_I_SB(inode), "inode (%lu) has corrupted xattr",
f2fs_err(F2FS_I_SB(inode), "lookup inode (%lu) has corrupted xattr",
inode->i_ino);
set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_FSCK);
err = -EFSCORRUPTED;
err = -ENODATA;
f2fs_handle_error(F2FS_I_SB(inode),
ERROR_CORRUPTED_XATTR);
goto out;
Expand Down Expand Up @@ -584,13 +584,12 @@ ssize_t f2fs_listxattr(struct dentry *dentry, char *buffer, size_t buffer_size)

if ((void *)(entry) + sizeof(__u32) > last_base_addr ||
(void *)XATTR_NEXT_ENTRY(entry) > last_base_addr) {
f2fs_err(F2FS_I_SB(inode), "inode (%lu) has corrupted xattr",
f2fs_err(F2FS_I_SB(inode), "list inode (%lu) has corrupted xattr",
inode->i_ino);
set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_FSCK);
error = -EFSCORRUPTED;
f2fs_handle_error(F2FS_I_SB(inode),
ERROR_CORRUPTED_XATTR);
goto cleanup;
break;
}

if (!prefix)
Expand Down Expand Up @@ -650,7 +649,7 @@ static int __f2fs_setxattr(struct inode *inode, int index,

if (size > MAX_VALUE_LEN(inode))
return -E2BIG;

retry:
error = read_all_xattrs(inode, ipage, &base_addr);
if (error)
return error;
Expand All @@ -660,7 +659,14 @@ static int __f2fs_setxattr(struct inode *inode, int index,
/* find entry with wanted name. */
here = __find_xattr(base_addr, last_base_addr, NULL, index, len, name);
if (!here) {
f2fs_err(F2FS_I_SB(inode), "inode (%lu) has corrupted xattr",
if (!F2FS_I(inode)->i_xattr_nid) {
f2fs_notice(F2FS_I_SB(inode),
"recover xattr in inode (%lu)", inode->i_ino);
f2fs_recover_xattr_data(inode, NULL);
kfree(base_addr);
goto retry;
}
f2fs_err(F2FS_I_SB(inode), "set inode (%lu) has corrupted xattr",
inode->i_ino);
set_sbi_flag(F2FS_I_SB(inode), SBI_NEED_FSCK);
error = -EFSCORRUPTED;
Expand Down

0 comments on commit e08a8d9

Please sign in to comment.