diff mbox series

cifs: destage dirty pages before re-reading them for cache=none

Message ID 20220920043202.503191-1-lsahlber@redhat.com
State New
Headers show
Series cifs: destage dirty pages before re-reading them for cache=none | expand

Commit Message

Ronnie Sahlberg Sept. 20, 2022, 4:32 a.m. UTC
This is the opposite case of kernel bugzilla 216301.
If we mmap a file using cache=none and then proceed to update the mmapped
area these updates are not reflected in a later pread() of that part of the
file.
To fix this we must first destage any dirty pages in the range before
we allow the pread() to proceed.

Cc: stable@vger.kernel.org
Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
Reviewed-by: Enzo Matsumiya <ematsumiya@suse.de>
Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/file.c | 9 +++++++++
 1 file changed, 9 insertions(+)

Comments

Steve French Sept. 20, 2022, 4:44 a.m. UTC | #1
tentatively merged into cifs-2.6.git for-next pending testing

Will be curious if this impacts performance of any of the buildbot
tests and also curious if it addresses any of the buildbot tests which
fail and are currently skipped

On Mon, Sep 19, 2022 at 11:32 PM Ronnie Sahlberg <lsahlber@redhat.com> wrote:
>
> This is the opposite case of kernel bugzilla 216301.
> If we mmap a file using cache=none and then proceed to update the mmapped
> area these updates are not reflected in a later pread() of that part of the
> file.
> To fix this we must first destage any dirty pages in the range before
> we allow the pread() to proceed.
>
> Cc: stable@vger.kernel.org
> Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
> Reviewed-by: Enzo Matsumiya <ematsumiya@suse.de>
> Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
> ---
>  fs/cifs/file.c | 9 +++++++++
>  1 file changed, 9 insertions(+)
>
> diff --git a/fs/cifs/file.c b/fs/cifs/file.c
> index 6f38b134a346..7d756721e1a6 100644
> --- a/fs/cifs/file.c
> +++ b/fs/cifs/file.c
> @@ -4271,6 +4271,15 @@ static ssize_t __cifs_readv(
>                 len = ctx->len;
>         }
>
> +       if (direct) {
> +               rc = filemap_write_and_wait_range(file->f_inode->i_mapping,
> +                                                 offset, offset + len - 1);
> +               if (rc) {
> +                       kref_put(&ctx->refcount, cifs_aio_ctx_release);
> +                       return -EAGAIN;
> +               }
> +       }
> +
>         /* grab a lock here due to read response handlers can access ctx */
>         mutex_lock(&ctx->aio_mutex);
>
> --
> 2.35.3
>
Tom Talpey Sept. 20, 2022, 7:08 p.m. UTC | #2
On 9/20/2022 12:32 AM, Ronnie Sahlberg wrote:
> This is the opposite case of kernel bugzilla 216301.
> If we mmap a file using cache=none and then proceed to update the mmapped
> area these updates are not reflected in a later pread() of that part of the
> file.
> To fix this we must first destage any dirty pages in the range before
> we allow the pread() to proceed.
> 
> Cc: stable@vger.kernel.org
> Reviewed-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
> Reviewed-by: Enzo Matsumiya <ematsumiya@suse.de>
> Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
> ---
>   fs/cifs/file.c | 9 +++++++++
>   1 file changed, 9 insertions(+)
> 
> diff --git a/fs/cifs/file.c b/fs/cifs/file.c
> index 6f38b134a346..7d756721e1a6 100644
> --- a/fs/cifs/file.c
> +++ b/fs/cifs/file.c
> @@ -4271,6 +4271,15 @@ static ssize_t __cifs_readv(
>   		len = ctx->len;
>   	}
>   
> +	if (direct) {
> +		rc = filemap_write_and_wait_range(file->f_inode->i_mapping,
> +						  offset, offset + len - 1);

It's only a nit, but with the new EAGAIN return code below, it's no
longer necessary to capture "rc" here.

> +		if (rc) {
> +			kref_put(&ctx->refcount, cifs_aio_ctx_release);
> +			return -EAGAIN;
> +		}
> +	}
> +
>   	/* grab a lock here due to read response handlers can access ctx */
>   	mutex_lock(&ctx->aio_mutex);
>
diff mbox series

Patch

diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 6f38b134a346..7d756721e1a6 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -4271,6 +4271,15 @@  static ssize_t __cifs_readv(
 		len = ctx->len;
 	}
 
+	if (direct) {
+		rc = filemap_write_and_wait_range(file->f_inode->i_mapping,
+						  offset, offset + len - 1);
+		if (rc) {
+			kref_put(&ctx->refcount, cifs_aio_ctx_release);
+			return -EAGAIN;
+		}
+	}
+
 	/* grab a lock here due to read response handlers can access ctx */
 	mutex_lock(&ctx->aio_mutex);