ovl: fix IOCB_DIRECT if underlying fs doesn't support direct IO
commit 1dc1eed46f9fa4cb8a07baa24fb44c96d6dd35c9 upstream. 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 <huangjianan@oppo.com> Fixes: 16914e6fc7e1 ("ovl: add ovl_read_iter()") Cc: <stable@vger.kernel.org> # v4.19 Tested-by: Huang Jianan <huangjianan@oppo.com> Signed-off-by: Miklos Szeredi <mszeredi@redhat.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
9763ffd4da
commit
1bc2f315a2
@ -301,6 +301,12 @@ static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter)
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = -EINVAL;
|
||||
if (iocb->ki_flags & IOCB_DIRECT &&
|
||||
(!real.file->f_mapping->a_ops ||
|
||||
!real.file->f_mapping->a_ops->direct_IO))
|
||||
goto out_fdput;
|
||||
|
||||
old_cred = ovl_override_creds(file_inode(file)->i_sb);
|
||||
if (is_sync_kiocb(iocb)) {
|
||||
ret = vfs_iter_read(real.file, iter, &iocb->ki_pos,
|
||||
@ -325,7 +331,7 @@ static ssize_t ovl_read_iter(struct kiocb *iocb, struct iov_iter *iter)
|
||||
out:
|
||||
revert_creds(old_cred);
|
||||
ovl_file_accessed(file);
|
||||
|
||||
out_fdput:
|
||||
fdput(real);
|
||||
|
||||
return ret;
|
||||
@ -354,6 +360,12 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
|
||||
if (ret)
|
||||
goto out_unlock;
|
||||
|
||||
ret = -EINVAL;
|
||||
if (iocb->ki_flags & IOCB_DIRECT &&
|
||||
(!real.file->f_mapping->a_ops ||
|
||||
!real.file->f_mapping->a_ops->direct_IO))
|
||||
goto out_fdput;
|
||||
|
||||
if (!ovl_should_sync(OVL_FS(inode->i_sb)))
|
||||
ifl &= ~(IOCB_DSYNC | IOCB_SYNC);
|
||||
|
||||
@ -389,6 +401,7 @@ static ssize_t ovl_write_iter(struct kiocb *iocb, struct iov_iter *iter)
|
||||
}
|
||||
out:
|
||||
revert_creds(old_cred);
|
||||
out_fdput:
|
||||
fdput(real);
|
||||
|
||||
out_unlock:
|
||||
|
Loading…
x
Reference in New Issue
Block a user