diff options
Diffstat (limited to 'fs/nfs/nfs4state.c')
| -rw-r--r-- | fs/nfs/nfs4state.c | 101 |
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 | ||
| 1072 | void nfs_increment_open_seqid(int status, struct nfs_seqid *seqid) | 1072 | void 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 | */ |
| 1089 | void nfs_increment_lock_seqid(int status, struct nfs_seqid *seqid) | 1091 | void 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 | ||
| 1094 | int nfs_wait_on_sequence(struct nfs_seqid *seqid, struct rpc_task *task) | 1097 | int 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; |
| 1107 | unlock: | 1113 | unlock: |
| 1108 | spin_unlock(&sequence->lock); | 1114 | spin_unlock(&sequence->lock); |
| 1115 | out: | ||
| 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); | 1387 | restart: |
| 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); | ||
| 1412 | out: | 1425 | out: |
| 1413 | up_write(&nfsi->rwsem); | 1426 | up_write(&nfsi->rwsem); |
| 1414 | return status; | 1427 | return status; |
