summaryrefslogtreecommitdiff
path: root/drivers/block/loop.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/block/loop.c')
-rw-r--r--drivers/block/loop.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index 6f12976035b0..758c20678bf6 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -458,12 +458,14 @@ static void loop_update_dio_alignment(struct loop_device *lo)
* Use the dio alignment of the file system if provided. The incomoing
* request's bio_vec is forwarded to the backing file unchanged, so its
* required memory alignment becomes the device's dma_alignment when
- * used for direct-io.
+ * used for direct-io. The file system reports zeroed alignments if the
+ * file can't be used for direct-io at all, so fall back to the block
+ * device limits in that case.
*/
if (!vfs_getattr(&file->f_path, &st, STATX_DIOALIGN, 0) &&
- (st.result_mask & STATX_DIOALIGN)) {
+ (st.result_mask & STATX_DIOALIGN) && st.dio_mem_align) {
lo->lo_min_dio_size = st.dio_offset_align;
- lo->lo_dio_mem_align = st.dio_mem_align - 1;
+ lo->lo_dio_mem_align = min(st.dio_mem_align - 1, PAGE_SIZE - 1);
return;
}