| From e547f2628327fec6afd2e03b46f113f614cca05b Mon Sep 17 00:00:00 2001 |
| From: Trond Myklebust <trond.myklebust@primarydata.com> |
| Date: Sat, 25 Jun 2016 19:19:28 -0400 |
| Subject: NFS: Fix another OPEN_DOWNGRADE bug |
| |
| From: Trond Myklebust <trond.myklebust@primarydata.com> |
| |
| commit e547f2628327fec6afd2e03b46f113f614cca05b upstream. |
| |
| Olga Kornievskaia reports that the following test fails to trigger |
| an OPEN_DOWNGRADE on the wire, and only triggers the final CLOSE. |
| |
| fd0 = open(foo, RDRW) -- should be open on the wire for "both" |
| fd1 = open(foo, RDONLY) -- should be open on the wire for "read" |
| close(fd0) -- should trigger an open_downgrade |
| read(fd1) |
| close(fd1) |
| |
| The issue is that we're missing a check for whether or not the current |
| state transitioned from an O_RDWR state as opposed to having transitioned |
| from a combination of O_RDONLY and O_WRONLY. |
| |
| Reported-by: Olga Kornievskaia <aglo@umich.edu> |
| Fixes: cd9288ffaea4 ("NFSv4: Fix another bug in the close/open_downgrade code") |
| Signed-off-by: Trond Myklebust <trond.myklebust@primarydata.com> |
| Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| fs/nfs/nfs4proc.c | 5 ++--- |
| 1 file changed, 2 insertions(+), 3 deletions(-) |
| |
| --- a/fs/nfs/nfs4proc.c |
| +++ b/fs/nfs/nfs4proc.c |
| @@ -2854,12 +2854,11 @@ static void nfs4_close_prepare(struct rp |
| call_close |= is_wronly; |
| else if (is_wronly) |
| calldata->arg.fmode |= FMODE_WRITE; |
| + if (calldata->arg.fmode != (FMODE_READ|FMODE_WRITE)) |
| + call_close |= is_rdwr; |
| } else if (is_rdwr) |
| calldata->arg.fmode |= FMODE_READ|FMODE_WRITE; |
| |
| - if (calldata->arg.fmode == 0) |
| - call_close |= is_rdwr; |
| - |
| if (!nfs4_valid_open_stateid(state)) |
| call_close = 0; |
| spin_unlock(&state->owner->so_lock); |