Skip to content

Commit 1dc1eed

Browse files
author
Miklos Szeredi
committed
ovl: fix IOCB_DIRECT if underlying fs doesn't support direct IO
Normally the check at open time suffices, but e.g loop device does set IOCB_DIRECT after doing its own checks (which are not sufficent for overlayfs). Make sure we don't call the underlying filesystem read/write method with the IOCB_DIRECT if it's not supported. Reported-by: Huang Jianan <[email protected]> Fixes: 16914e6 ("ovl: add ovl_read_iter()") Cc: <[email protected]> # v4.19 Tested-by: Huang Jianan <[email protected]> Signed-off-by: Miklos Szeredi <[email protected]>
1 parent a295aef commit 1dc1eed

File tree

1 file changed

+14
-1
lines changed

1 file changed

+14
-1
lines changed

fs/overlayfs/file.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,12 @@ static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter)
296296
if (ret)
297297
return ret;
298298

299+
ret = -EINVAL;
300+
if (iocb->ki_flags & IOCB_DIRECT &&
301+
(!real.file->f_mapping->a_ops ||
302+
!real.file->f_mapping->a_ops->direct_IO))
303+
goto out_fdput;
304+
299305
old_cred = ovl_override_creds(file_inode(file)->i_sb);
300306
if (is_sync_kiocb(iocb)) {
301307
ret = vfs_iter_read(real.file, iter, &iocb->ki_pos,
@@ -320,7 +326,7 @@ static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter)
320326
out:
321327
revert_creds(old_cred);
322328
ovl_file_accessed(file);
323-
329+
out_fdput:
324330
fdput(real);
325331

326332
return ret;
@@ -349,6 +355,12 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
349355
if (ret)
350356
goto out_unlock;
351357

358+
ret = -EINVAL;
359+
if (iocb->ki_flags & IOCB_DIRECT &&
360+
(!real.file->f_mapping->a_ops ||
361+
!real.file->f_mapping->a_ops->direct_IO))
362+
goto out_fdput;
363+
352364
if (!ovl_should_sync(OVL_FS(inode->i_sb)))
353365
ifl &= ~(IOCB_DSYNC | IOCB_SYNC);
354366

@@ -384,6 +396,7 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
384396
}
385397
out:
386398
revert_creds(old_cred);
399+
out_fdput:
387400
fdput(real);
388401

389402
out_unlock:

0 commit comments

Comments
 (0)