diff options
author | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-04-22 11:29:51 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2013-04-22 11:29:51 -0400 |
commit | fd068b200fb86e8fa52368e6f6088d2ab297a5d7 (patch) | |
tree | f2b75692b49b7f263dd0a27d4186b111bc4d24b0 /fs/nfs | |
parent | 1dfd89af8697a299e7982ae740d4695ecd917eef (diff) |
NFSv4: Ensure that we clear the NFS_OPEN_STATE flag when appropriate
We should always clear it before initiating file recovery.
Also ensure that we clear it after a CLOSE and/or after TEST_STATEID fails.
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
Diffstat (limited to 'fs/nfs')
-rw-r--r-- | fs/nfs/nfs4proc.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index ed01a66dc391..c13144911d20 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
@@ -1290,6 +1290,7 @@ static int nfs4_open_recover(struct nfs4_opendata *opendata, struct nfs4_state * | |||
1290 | 1290 | ||
1291 | /* memory barrier prior to reading state->n_* */ | 1291 | /* memory barrier prior to reading state->n_* */ |
1292 | clear_bit(NFS_DELEGATED_STATE, &state->flags); | 1292 | clear_bit(NFS_DELEGATED_STATE, &state->flags); |
1293 | clear_bit(NFS_OPEN_STATE, &state->flags); | ||
1293 | smp_rmb(); | 1294 | smp_rmb(); |
1294 | if (state->n_rdwr != 0) { | 1295 | if (state->n_rdwr != 0) { |
1295 | clear_bit(NFS_O_RDWR_STATE, &state->flags); | 1296 | clear_bit(NFS_O_RDWR_STATE, &state->flags); |
@@ -1893,6 +1894,7 @@ static int nfs41_check_open_stateid(struct nfs4_state *state) | |||
1893 | clear_bit(NFS_O_RDONLY_STATE, &state->flags); | 1894 | clear_bit(NFS_O_RDONLY_STATE, &state->flags); |
1894 | clear_bit(NFS_O_WRONLY_STATE, &state->flags); | 1895 | clear_bit(NFS_O_WRONLY_STATE, &state->flags); |
1895 | clear_bit(NFS_O_RDWR_STATE, &state->flags); | 1896 | clear_bit(NFS_O_RDWR_STATE, &state->flags); |
1897 | clear_bit(NFS_OPEN_STATE, &state->flags); | ||
1896 | } | 1898 | } |
1897 | return status; | 1899 | return status; |
1898 | } | 1900 | } |
@@ -2208,11 +2210,19 @@ static void nfs4_close_clear_stateid_flags(struct nfs4_state *state, | |||
2208 | fmode_t fmode) | 2210 | fmode_t fmode) |
2209 | { | 2211 | { |
2210 | spin_lock(&state->owner->so_lock); | 2212 | spin_lock(&state->owner->so_lock); |
2211 | if (!(fmode & FMODE_READ)) | 2213 | clear_bit(NFS_O_RDWR_STATE, &state->flags); |
2214 | switch (fmode & (FMODE_READ|FMODE_WRITE)) { | ||
2215 | case FMODE_WRITE: | ||
2212 | clear_bit(NFS_O_RDONLY_STATE, &state->flags); | 2216 | clear_bit(NFS_O_RDONLY_STATE, &state->flags); |
2213 | if (!(fmode & FMODE_WRITE)) | 2217 | break; |
2218 | case FMODE_READ: | ||
2214 | clear_bit(NFS_O_WRONLY_STATE, &state->flags); | 2219 | clear_bit(NFS_O_WRONLY_STATE, &state->flags); |
2215 | clear_bit(NFS_O_RDWR_STATE, &state->flags); | 2220 | break; |
2221 | case 0: | ||
2222 | clear_bit(NFS_O_RDONLY_STATE, &state->flags); | ||
2223 | clear_bit(NFS_O_WRONLY_STATE, &state->flags); | ||
2224 | clear_bit(NFS_OPEN_STATE, &state->flags); | ||
2225 | } | ||
2216 | spin_unlock(&state->owner->so_lock); | 2226 | spin_unlock(&state->owner->so_lock); |
2217 | } | 2227 | } |
2218 | 2228 | ||