diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-10-18 23:20:21 +0200 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2005-10-18 23:20:21 +0200 |
commit | 550f57470c6506f5ef3c708335dea6bd48bf3dc4 (patch) | |
tree | be34cc170cce1e103baec1976f7903528eb4ff4d /fs | |
parent | NFSv4: If a delegated open fails, ensure that we return the delegation (diff) | |
download | linux-550f57470c6506f5ef3c708335dea6bd48bf3dc4.tar.xz linux-550f57470c6506f5ef3c708335dea6bd48bf3dc4.zip |
NFSv4: Ensure that we recover from the OPEN + OPEN_CONFIRM BAD_STATEID race
If the server is in the unconfirmed OPEN state for a given open owner
and receives a second OPEN for the same open owner, it will cancel the
state of the first request and set up an OPEN_CONFIRM for the second.
This can cause a race that is discussed in rfc3530 on page 181.
The following patch allows the client to recover by retrying the
original open request.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/nfs/nfs4proc.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index a8be9af610ac..ff378126ccd7 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c @@ -785,6 +785,16 @@ static struct nfs4_state *nfs4_do_open(struct inode *dir, struct dentry *dentry, exception.retry = 1; continue; } + /* + * BAD_STATEID on OPEN means that the server cancelled our + * state before it received the OPEN_CONFIRM. + * Recover by retrying the request as per the discussion + * on Page 181 of RFC3530. + */ + if (status == -NFS4ERR_BAD_STATEID) { + exception.retry = 1; + continue; + } res = ERR_PTR(nfs4_handle_exception(NFS_SERVER(dir), status, &exception)); } while (exception.retry); |