Skip to content
/ linux Public

Commit cead3be

Browse files
Andreas GruenbacherSasha Levin
authored andcommitted
gfs2: fiemap page fault fix
[ Upstream commit e411d74 ] In gfs2_fiemap(), we are calling iomap_fiemap() while holding the inode glock. This can lead to recursive glock taking if the fiemap buffer is memory mapped to the same inode and accessing it triggers a page fault. Fix by disabling page faults for iomap_fiemap() and faulting in the buffer by hand if necessary. Fixes xfstest generic/742. Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 8ce4da0 commit cead3be

File tree

1 file changed

+16
-0
lines changed

1 file changed

+16
-0
lines changed

fs/gfs2/inode.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2073,6 +2073,14 @@ static int gfs2_getattr(struct user_namespace *mnt_userns,
20732073
return 0;
20742074
}
20752075

2076+
static bool fault_in_fiemap(struct fiemap_extent_info *fi)
2077+
{
2078+
struct fiemap_extent __user *dest = fi->fi_extents_start;
2079+
size_t size = sizeof(*dest) * fi->fi_extents_max;
2080+
2081+
return fault_in_safe_writeable((char __user *)dest, size) == 0;
2082+
}
2083+
20762084
static int gfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
20772085
u64 start, u64 len)
20782086
{
@@ -2082,14 +2090,22 @@ static int gfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
20822090

20832091
inode_lock_shared(inode);
20842092

2093+
retry:
20852094
ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh);
20862095
if (ret)
20872096
goto out;
20882097

2098+
pagefault_disable();
20892099
ret = iomap_fiemap(inode, fieinfo, start, len, &gfs2_iomap_ops);
2100+
pagefault_enable();
20902101

20912102
gfs2_glock_dq_uninit(&gh);
20922103

2104+
if (ret == -EFAULT && fault_in_fiemap(fieinfo)) {
2105+
fieinfo->fi_extents_mapped = 0;
2106+
goto retry;
2107+
}
2108+
20932109
out:
20942110
inode_unlock_shared(inode);
20952111
return ret;

0 commit comments

Comments
 (0)