Skip to content

Commit

Permalink
f2fs: fix to retrieve inline xattr space
Browse files Browse the repository at this point in the history
With below mkfs and mount option, generic/339 of fstest will report that
scratch image becomes corrupted.

MKFS_OPTIONS  -- -O extra_attr -O project_quota -O inode_checksum -O flexible_inline_xattr -O inode_crtime -f /dev/zram1
MOUNT_OPTIONS -- -o acl,user_xattr -o discard,noinline_xattr /dev/zram1 /mnt/scratch_f2fs

[ASSERT] (f2fs_check_dirent_position:1315)  --> Wrong position of dirent pino:1970, name: (...)
level:8, dir_level:0, pgofs:951, correct range:[900, 901]

In old kernel, inline data and directory always reserved 200 bytes in
inode layout, even if inline_xattr is disabled, then new kernel tries
to retrieve that space for non-inline xattr inode, but for inline dentry,
its layout size should be fixed, so we just keep that reserved space.

But the problem here is that, after inline dentry conversion, inline
dentry layout no longer exists, if we still reserve inline xattr space,
after dents updates, there will be a hole in inline xattr space, which
can break hierarchy hash directory structure.

This patch fixes this issue by retrieving inline xattr space after
inline dentry conversion.

Fixes: 6afc662 ("f2fs: support flexible inline xattr size")
Signed-off-by: Chao Yu <[email protected]>
Signed-off-by: Jaegeuk Kim <[email protected]>
  • Loading branch information
chaseyu authored and Jaegeuk Kim committed May 9, 2019
1 parent 9883857 commit 45a7468
Showing 1 changed file with 17 additions and 0 deletions.
17 changes: 17 additions & 0 deletions fs/f2fs/inline.c
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,14 @@ static int f2fs_move_inline_dirents(struct inode *dir, struct page *ipage,
stat_dec_inline_dir(dir);
clear_inode_flag(dir, FI_INLINE_DENTRY);

/*
* should retrieve reserved space which was used to keep
* inline_dentry's structure for backward compatibility.
*/
if (!f2fs_sb_has_flexible_inline_xattr(F2FS_I_SB(dir)) &&
!f2fs_has_inline_xattr(dir))
F2FS_I(dir)->i_inline_xattr_size = 0;

f2fs_i_depth_write(dir, 1);
if (i_size_read(dir) < PAGE_SIZE)
f2fs_i_size_write(dir, PAGE_SIZE);
Expand Down Expand Up @@ -501,6 +509,15 @@ static int f2fs_move_rehashed_dirents(struct inode *dir, struct page *ipage,

stat_dec_inline_dir(dir);
clear_inode_flag(dir, FI_INLINE_DENTRY);

/*
* should retrieve reserved space which was used to keep
* inline_dentry's structure for backward compatibility.
*/
if (!f2fs_sb_has_flexible_inline_xattr(F2FS_I_SB(dir)) &&
!f2fs_has_inline_xattr(dir))
F2FS_I(dir)->i_inline_xattr_size = 0;

kvfree(backup_dentry);
return 0;
recover:
Expand Down

0 comments on commit 45a7468

Please sign in to comment.