Hi,
@@ -1784,8 +1822,23 @@ static int fuse_iomap_begin(struct inode *inode,
loff_t pos, loff_t length,
if (pos >= i_size_read(inode))
goto iomap_hole;
- alloc_dmap = alloc_dax_mapping(fc);
- if (!alloc_dmap)
+ /* Can't do reclaim in fault path yet due to lock ordering.
+ * Read path takes shared inode lock and that's not
sufficient
+ * for inline range reclaim. Caller needs to drop lock,
wait
+ * and retry.
+ */
+ if (flags & IOMAP_FAULT || !(flags & IOMAP_WRITE)) {
+ alloc_dmap = alloc_dax_mapping(fc);
+ if (!alloc_dmap)
+ return -ENOSPC;
+ } else {
+ alloc_dmap = alloc_dax_mapping_reclaim(fc, inode);
alloc_dmap could be NULL as follows:
alloc_dax_mapping_reclaim
-->fuse_dax_reclaim_first_mapping
-->fuse_dax_reclaim_first_mapping_locked
--> fuse_dax_interval_tree_iter_first ==> return NULL
and
IS_ERR(NULL) is false, so we may miss that error case.
+ if (IS_ERR(alloc_dmap))
+ return PTR_ERR(alloc_dmap);
+ }
Regards,
Eric