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 | } |