aboutsummaryrefslogtreecommitdiffstats
path: root/fs/nfs/nfs4state.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/nfs/nfs4state.c')
-rw-r--r--fs/nfs/nfs4state.c101
1 files changed, 57 insertions, 44 deletions
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c
index 5194933ed419..5ad908e9ce9c 100644
--- a/fs/nfs/nfs4state.c
+++ b/fs/nfs/nfs4state.c
@@ -1003,11 +1003,11 @@ struct nfs_seqid *nfs_alloc_seqid(struct nfs_seqid_counter *counter, gfp_t gfp_m
1003 struct nfs_seqid *new; 1003 struct nfs_seqid *new;
1004 1004
1005 new = kmalloc(sizeof(*new), gfp_mask); 1005 new = kmalloc(sizeof(*new), gfp_mask);
1006 if (new != NULL) { 1006 if (new == NULL)
1007 new->sequence = counter; 1007 return ERR_PTR(-ENOMEM);
1008 INIT_LIST_HEAD(&new->list); 1008 new->sequence = counter;
1009 new->task = NULL; 1009 INIT_LIST_HEAD(&new->list);
1010 } 1010 new->task = NULL;
1011 return new; 1011 return new;
1012} 1012}
1013 1013
@@ -1015,7 +1015,7 @@ void nfs_release_seqid(struct nfs_seqid *seqid)
1015{ 1015{
1016 struct nfs_seqid_counter *sequence; 1016 struct nfs_seqid_counter *sequence;
1017 1017
1018 if (list_empty(&seqid->list)) 1018 if (seqid == NULL || list_empty(&seqid->list))
1019 return; 1019 return;
1020 sequence = seqid->sequence; 1020 sequence = seqid->sequence;
1021 spin_lock(&sequence->lock); 1021 spin_lock(&sequence->lock);
@@ -1071,13 +1071,15 @@ static void nfs_increment_seqid(int status, struct nfs_seqid *seqid)
1071 1071
1072void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid) 1072void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid)
1073{ 1073{
1074 struct nfs4_state_owner *sp = container_of(seqid->sequence, 1074 struct nfs4_state_owner *sp;
1075 struct nfs4_state_owner, so_seqid); 1075
1076 struct nfs_server *server = sp->so_server; 1076 if (seqid == NULL)
1077 return;
1077 1078
1079 sp = container_of(seqid->sequence, struct nfs4_state_owner, so_seqid);
1078 if (status == -NFS4ERR_BAD_SEQID) 1080 if (status == -NFS4ERR_BAD_SEQID)
1079 nfs4_drop_state_owner(sp); 1081 nfs4_drop_state_owner(sp);
1080 if (!nfs4_has_session(server->nfs_client)) 1082 if (!nfs4_has_session(sp->so_server->nfs_client))
1081 nfs_increment_seqid(status, seqid); 1083 nfs_increment_seqid(status, seqid);
1082} 1084}
1083 1085
@@ -1088,14 +1090,18 @@ void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid)
1088 */ 1090 */
1089void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid) 1091void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid)
1090{ 1092{
1091 nfs_increment_seqid(status, seqid); 1093 if (seqid != NULL)
1094 nfs_increment_seqid(status, seqid);
1092} 1095}
1093 1096
1094int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task) 1097int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task)
1095{ 1098{
1096 struct nfs_seqid_counter *sequence = seqid->sequence; 1099 struct nfs_seqid_counter *sequence;
1097 int status = 0; 1100 int status = 0;
1098 1101
1102 if (seqid == NULL)
1103 goto out;
1104 sequence = seqid->sequence;
1099 spin_lock(&sequence->lock); 1105 spin_lock(&sequence->lock);
1100 seqid->task = task; 1106 seqid->task = task;
1101 if (list_empty(&seqid->list)) 1107 if (list_empty(&seqid->list))
@@ -1106,6 +1112,7 @@ int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task)
1106 status = -EAGAIN; 1112 status = -EAGAIN;
1107unlock: 1113unlock:
1108 spin_unlock(&sequence->lock); 1114 spin_unlock(&sequence->lock);
1115out:
1109 return status; 1116 return status;
1110} 1117}
1111 1118
@@ -1366,49 +1373,55 @@ static int nfs4_reclaim_locks(struct nfs4_state *state, const struct nfs4_state_
1366 struct nfs_inode *nfsi = NFS_I(inode); 1373 struct nfs_inode *nfsi = NFS_I(inode);
1367 struct file_lock *fl; 1374 struct file_lock *fl;
1368 int status = 0; 1375 int status = 0;
1376 struct file_lock_context *flctx = inode->i_flctx;
1377 struct list_head *list;
1369 1378
1370 if (inode->i_flock == NULL) 1379 if (flctx == NULL)
1371 return 0; 1380 return 0;
1372 1381
1382 list = &flctx->flc_posix;
1383
1373 /* Guard against delegation returns and new lock/unlock calls */ 1384 /* Guard against delegation returns and new lock/unlock calls */
1374 down_write(&nfsi->rwsem); 1385 down_write(&nfsi->rwsem);
1375 /* Protect inode->i_flock using the BKL */ 1386 spin_lock(&flctx->flc_lock);
1376 spin_lock(&inode->i_lock); 1387restart:
1377 for (fl = inode->i_flock; fl != NULL; fl = fl->fl_next) { 1388 list_for_each_entry(fl, list, fl_list) {
1378 if (!(fl->fl_flags & (FL_POSIX|FL_FLOCK)))
1379 continue;
1380 if (nfs_file_open_context(fl->fl_file)->state != state) 1389 if (nfs_file_open_context(fl->fl_file)->state != state)
1381 continue; 1390 continue;
1382 spin_unlock(&inode->i_lock); 1391 spin_unlock(&flctx->flc_lock);
1383 status = ops->recover_lock(state, fl); 1392 status = ops->recover_lock(state, fl);
1384 switch (status) { 1393 switch (status) {
1385 case 0: 1394 case 0:
1386 break; 1395 break;
1387 case -ESTALE: 1396 case -ESTALE:
1388 case -NFS4ERR_ADMIN_REVOKED: 1397 case -NFS4ERR_ADMIN_REVOKED:
1389 case -NFS4ERR_STALE_STATEID: 1398 case -NFS4ERR_STALE_STATEID:
1390 case -NFS4ERR_BAD_STATEID: 1399 case -NFS4ERR_BAD_STATEID:
1391 case -NFS4ERR_EXPIRED: 1400 case -NFS4ERR_EXPIRED:
1392 case -NFS4ERR_NO_GRACE: 1401 case -NFS4ERR_NO_GRACE:
1393 case -NFS4ERR_STALE_CLIENTID: 1402 case -NFS4ERR_STALE_CLIENTID:
1394 case -NFS4ERR_BADSESSION: 1403 case -NFS4ERR_BADSESSION:
1395 case -NFS4ERR_BADSLOT: 1404 case -NFS4ERR_BADSLOT:
1396 case -NFS4ERR_BAD_HIGH_SLOT: 1405 case -NFS4ERR_BAD_HIGH_SLOT:
1397 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION: 1406 case -NFS4ERR_CONN_NOT_BOUND_TO_SESSION:
1398 goto out; 1407 goto out;
1399 default: 1408 default:
1400 printk(KERN_ERR "NFS: %s: unhandled error %d\n", 1409 pr_err("NFS: %s: unhandled error %d\n",
1401 __func__, status); 1410 __func__, status);
1402 case -ENOMEM: 1411 case -ENOMEM:
1403 case -NFS4ERR_DENIED: 1412 case -NFS4ERR_DENIED:
1404 case -NFS4ERR_RECLAIM_BAD: 1413 case -NFS4ERR_RECLAIM_BAD:
1405 case -NFS4ERR_RECLAIM_CONFLICT: 1414 case -NFS4ERR_RECLAIM_CONFLICT:
1406 /* kill_proc(fl->fl_pid, SIGLOST, 1); */ 1415 /* kill_proc(fl->fl_pid, SIGLOST, 1); */
1407 status = 0; 1416 status = 0;
1408 } 1417 }
1409 spin_lock(&inode->i_lock); 1418 spin_lock(&flctx->flc_lock);
1410 } 1419 }
1411 spin_unlock(&inode->i_lock); 1420 if (list == &flctx->flc_posix) {
1421 list = &flctx->flc_flock;
1422 goto restart;
1423 }
1424 spin_unlock(&flctx->flc_lock);
1412out: 1425out:
1413 up_write(&nfsi->rwsem); 1426 up_write(&nfsi->rwsem);
1414 return status; 1427 return status;