diff options
Diffstat (limited to 'fs/overlayfs/file.c')
| -rw-r--r-- | fs/overlayfs/file.c | 15 | 
1 files changed, 14 insertions, 1 deletions
| diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c index d081faa55e83..c88ac571593d 100644 --- a/fs/overlayfs/file.c +++ b/fs/overlayfs/file.c @@ -296,6 +296,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, @@ -320,7 +326,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; @@ -349,6 +355,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); @@ -384,6 +396,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: |