aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/nfs/nfs4proc.c16
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}