f2fs: fix to adapt small inline xattr space in __find_inline_xattr()
[ Upstream commit 2c28aba8b2e2a51749fa66e01b68e1cd5b53e022 ] With below testcase, we will fail to find existed xattr entry: 1. mkfs.f2fs -O extra_attr -O flexible_inline_xattr /dev/zram0 2. mount -t f2fs -o inline_xattr_size=1 /dev/zram0 /mnt/f2fs/ 3. touch /mnt/f2fs/file 4. setfattr -n "user.name" -v 0 /mnt/f2fs/file 5. getfattr -n "user.name" /mnt/f2fs/file /mnt/f2fs/file: user.name: No such attribute The reason is for inode which has very small inline xattr size, __find_inline_xattr() will fail to traverse any entry due to first entry may not be loaded from xattr node yet, later, we may skip to check entire xattr datas in __find_xattr(), result in such wrong condition. This patch adds condition to check such case to avoid this issue. Signed-off-by: Chao Yu <yuchao0@huawei.com> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
56bb66c502
commit
198c99857b
1 changed files with 10 additions and 3 deletions
|
@ -227,11 +227,11 @@ static struct f2fs_xattr_entry *__find_inline_xattr(struct inode *inode,
|
|||
{
|
||||
struct f2fs_xattr_entry *entry;
|
||||
unsigned int inline_size = inline_xattr_size(inode);
|
||||
void *max_addr = base_addr + inline_size;
|
||||
|
||||
list_for_each_xattr(entry, base_addr) {
|
||||
if ((void *)entry + sizeof(__u32) > base_addr + inline_size ||
|
||||
(void *)XATTR_NEXT_ENTRY(entry) + sizeof(__u32) >
|
||||
base_addr + inline_size) {
|
||||
if ((void *)entry + sizeof(__u32) > max_addr ||
|
||||
(void *)XATTR_NEXT_ENTRY(entry) > max_addr) {
|
||||
*last_addr = entry;
|
||||
return NULL;
|
||||
}
|
||||
|
@ -242,6 +242,13 @@ static struct f2fs_xattr_entry *__find_inline_xattr(struct inode *inode,
|
|||
if (!memcmp(entry->e_name, name, len))
|
||||
break;
|
||||
}
|
||||
|
||||
/* inline xattr header or entry across max inline xattr size */
|
||||
if (IS_XATTR_LAST_ENTRY(entry) &&
|
||||
(void *)entry + sizeof(__u32) > max_addr) {
|
||||
*last_addr = entry;
|
||||
return NULL;
|
||||
}
|
||||
return entry;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue