return 0;
}
+static bool fault_in_fiemap(struct fiemap_extent_info *fi)
+{
+ struct fiemap_extent __user *dest = fi->fi_extents_start;
+ size_t size = sizeof(*dest) * fi->fi_extents_max;
+
+ return fault_in_safe_writeable((char __user *)dest, size) == 0;
+}
+
static int gfs2_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
u64 start, u64 len)
{
inode_lock_shared(inode);
+retry:
ret = gfs2_glock_nq_init(ip->i_gl, LM_ST_SHARED, 0, &gh);
if (ret)
goto out;
+ pagefault_disable();
ret = iomap_fiemap(inode, fieinfo, start, len, &gfs2_iomap_ops);
+ pagefault_enable();
gfs2_glock_dq_uninit(&gh);
+ if (ret == -EFAULT && fault_in_fiemap(fieinfo)) {
+ fieinfo->fi_extents_mapped = 0;
+ goto retry;
+ }
+
out:
inode_unlock_shared(inode);
return ret;