diff options
Diffstat (limited to 'fs')
| -rw-r--r-- | fs/nfs/nfs4proc.c | 16 |
1 files changed, 7 insertions, 9 deletions
diff --git a/fs/nfs/nfs4proc.c b/fs/nfs/nfs4proc.c index 6ca2795ccd9c..62b3ae280310 100644 --- a/fs/nfs/nfs4proc.c +++ b/fs/nfs/nfs4proc.c | |||
| @@ -332,11 +332,9 @@ static int can_open_cached(struct nfs4_state *state, int mode) | |||
| 332 | switch (mode & (FMODE_READ|FMODE_WRITE|O_EXCL)) { | 332 | switch (mode & (FMODE_READ|FMODE_WRITE|O_EXCL)) { |
| 333 | case FMODE_READ: | 333 | case FMODE_READ: |
| 334 | ret |= test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0; | 334 | ret |= test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0; |
| 335 | ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0; | ||
| 336 | break; | 335 | break; |
| 337 | case FMODE_WRITE: | 336 | case FMODE_WRITE: |
| 338 | ret |= test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0; | 337 | ret |= test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0; |
| 339 | ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0; | ||
| 340 | break; | 338 | break; |
| 341 | case FMODE_READ|FMODE_WRITE: | 339 | case FMODE_READ|FMODE_WRITE: |
| 342 | ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0; | 340 | ret |= test_bit(NFS_O_RDWR_STATE, &state->flags) != 0; |
| @@ -1260,7 +1258,7 @@ static void nfs4_close_done(struct rpc_task *task, void *data) | |||
| 1260 | nfs_increment_open_seqid(task->tk_status, calldata->arg.seqid); | 1258 | nfs_increment_open_seqid(task->tk_status, calldata->arg.seqid); |
| 1261 | switch (task->tk_status) { | 1259 | switch (task->tk_status) { |
| 1262 | case 0: | 1260 | case 0: |
| 1263 | nfs_set_open_stateid(state, &calldata->res.stateid, calldata->arg.open_flags); | 1261 | nfs_set_open_stateid(state, &calldata->res.stateid, 0); |
| 1264 | renew_lease(server, calldata->timestamp); | 1262 | renew_lease(server, calldata->timestamp); |
| 1265 | break; | 1263 | break; |
| 1266 | case -NFS4ERR_STALE_STATEID: | 1264 | case -NFS4ERR_STALE_STATEID: |
| @@ -1286,23 +1284,19 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data) | |||
| 1286 | .rpc_cred = state->owner->so_cred, | 1284 | .rpc_cred = state->owner->so_cred, |
| 1287 | }; | 1285 | }; |
| 1288 | int clear_rd, clear_wr, clear_rdwr; | 1286 | int clear_rd, clear_wr, clear_rdwr; |
| 1289 | int mode; | ||
| 1290 | 1287 | ||
| 1291 | if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0) | 1288 | if (nfs_wait_on_sequence(calldata->arg.seqid, task) != 0) |
| 1292 | return; | 1289 | return; |
| 1293 | 1290 | ||
| 1294 | mode = FMODE_READ|FMODE_WRITE; | ||
| 1295 | clear_rd = clear_wr = clear_rdwr = 0; | 1291 | clear_rd = clear_wr = clear_rdwr = 0; |
| 1296 | spin_lock(&state->owner->so_lock); | 1292 | spin_lock(&state->owner->so_lock); |
| 1297 | /* Calculate the change in open mode */ | 1293 | /* Calculate the change in open mode */ |
| 1298 | if (state->n_rdwr == 0) { | 1294 | if (state->n_rdwr == 0) { |
| 1299 | if (state->n_rdonly == 0) { | 1295 | if (state->n_rdonly == 0) { |
| 1300 | mode &= ~FMODE_READ; | ||
| 1301 | clear_rd |= test_and_clear_bit(NFS_O_RDONLY_STATE, &state->flags); | 1296 | clear_rd |= test_and_clear_bit(NFS_O_RDONLY_STATE, &state->flags); |
| 1302 | clear_rdwr |= test_and_clear_bit(NFS_O_RDWR_STATE, &state->flags); | 1297 | clear_rdwr |= test_and_clear_bit(NFS_O_RDWR_STATE, &state->flags); |
| 1303 | } | 1298 | } |
| 1304 | if (state->n_wronly == 0) { | 1299 | if (state->n_wronly == 0) { |
| 1305 | mode &= ~FMODE_WRITE; | ||
| 1306 | clear_wr |= test_and_clear_bit(NFS_O_WRONLY_STATE, &state->flags); | 1300 | clear_wr |= test_and_clear_bit(NFS_O_WRONLY_STATE, &state->flags); |
| 1307 | clear_rdwr |= test_and_clear_bit(NFS_O_RDWR_STATE, &state->flags); | 1301 | clear_rdwr |= test_and_clear_bit(NFS_O_RDWR_STATE, &state->flags); |
| 1308 | } | 1302 | } |
| @@ -1314,9 +1308,13 @@ static void nfs4_close_prepare(struct rpc_task *task, void *data) | |||
| 1314 | return; | 1308 | return; |
| 1315 | } | 1309 | } |
| 1316 | nfs_fattr_init(calldata->res.fattr); | 1310 | nfs_fattr_init(calldata->res.fattr); |
| 1317 | if (mode != 0) | 1311 | if (test_bit(NFS_O_RDONLY_STATE, &state->flags) != 0) { |
| 1318 | msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE]; | 1312 | msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE]; |
| 1319 | calldata->arg.open_flags = mode; | 1313 | calldata->arg.open_flags = FMODE_READ; |
| 1314 | } else if (test_bit(NFS_O_WRONLY_STATE, &state->flags) != 0) { | ||
| 1315 | msg.rpc_proc = &nfs4_procedures[NFSPROC4_CLNT_OPEN_DOWNGRADE]; | ||
| 1316 | calldata->arg.open_flags = FMODE_WRITE; | ||
| 1317 | } | ||
| 1320 | calldata->timestamp = jiffies; | 1318 | calldata->timestamp = jiffies; |
| 1321 | rpc_call_setup(task, &msg, 0); | 1319 | rpc_call_setup(task, &msg, 0); |
| 1322 | } | 1320 | } |
