diff options
author | Andy Adamson <andros@netapp.com> | 2009-04-03 01:28:35 -0400 |
---|---|---|
committer | J. Bruce Fields <bfields@citi.umich.edu> | 2009-04-03 20:41:19 -0400 |
commit | bf864a31d50e3e94d6e76537b97d664913906ff8 (patch) | |
tree | 8de829d0cdc0c88fe523fc4a288b8e16eedc6a2e /fs/nfsd/nfs4state.c | |
parent | 38eb76a54d803e6792816623651b1a9cb85f8d01 (diff) |
nfsd41: non-page DRC for solo sequence responses
A session inactivity time compound (lease renewal) or a compound where the
sequence operation has sa_cachethis set to FALSE do not require any pages
to be held in the v4.1 DRC. This is because struct nfsd4_slot is already
caching the session information.
Add logic to the nfs41 server to not cache response pages for solo sequence
responses.
Return nfserr_replay_uncached_rep on the operation following the sequence
operation when sa_cachethis is FALSE.
Signed-off-by: Andy Adamson <andros@netapp.com>
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfsd41: use cstate session in nfsd4_replay_cache_entry]
[nfsd41: rename nfsd4_no_page_in_cache]
[nfsd41 rename nfsd4_enc_no_page_replay]
[nfsd41 nfsd4_is_solo_sequence]
[nfsd41 change nfsd4_not_cached return]
Signed-off-by: Andy Adamson <andros@netapp.com>
[changed return type to bool]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
[nfsd41 drop parens in nfsd4_is_solo_sequence call]
Signed-off-by: Andy Adamson <andros@netapp.com>
[changed "== 0" to "!"]
Signed-off-by: Benny Halevy <bhalevy@panasas.com>
Signed-off-by: J. Bruce Fields <bfields@citi.umich.edu>
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r-- | fs/nfsd/nfs4state.c | 47 |
1 files changed, 41 insertions, 6 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c index 58f9797eb09e..04a395fb5dce 100644 --- a/fs/nfsd/nfs4state.c +++ b/fs/nfsd/nfs4state.c | |||
@@ -1049,17 +1049,31 @@ nfsd4_store_cache_entry(struct nfsd4_compoundres *resp) | |||
1049 | /* Don't cache a failed OP_SEQUENCE. */ | 1049 | /* Don't cache a failed OP_SEQUENCE. */ |
1050 | if (resp->opcnt == 1 && op->opnum == OP_SEQUENCE && resp->cstate.status) | 1050 | if (resp->opcnt == 1 && op->opnum == OP_SEQUENCE && resp->cstate.status) |
1051 | return; | 1051 | return; |
1052 | |||
1052 | nfsd4_release_respages(entry->ce_respages, entry->ce_resused); | 1053 | nfsd4_release_respages(entry->ce_respages, entry->ce_resused); |
1054 | entry->ce_opcnt = resp->opcnt; | ||
1055 | entry->ce_status = resp->cstate.status; | ||
1056 | |||
1057 | /* | ||
1058 | * Don't need a page to cache just the sequence operation - the slot | ||
1059 | * does this for us! | ||
1060 | */ | ||
1061 | |||
1062 | if (nfsd4_not_cached(resp)) { | ||
1063 | entry->ce_resused = 0; | ||
1064 | entry->ce_rpchdrlen = 0; | ||
1065 | dprintk("%s Just cache SEQUENCE. ce_cachethis %d\n", __func__, | ||
1066 | resp->cstate.slot->sl_cache_entry.ce_cachethis); | ||
1067 | return; | ||
1068 | } | ||
1053 | entry->ce_resused = rqstp->rq_resused; | 1069 | entry->ce_resused = rqstp->rq_resused; |
1054 | if (entry->ce_resused > NFSD_PAGES_PER_SLOT + 1) | 1070 | if (entry->ce_resused > NFSD_PAGES_PER_SLOT + 1) |
1055 | entry->ce_resused = NFSD_PAGES_PER_SLOT + 1; | 1071 | entry->ce_resused = NFSD_PAGES_PER_SLOT + 1; |
1056 | nfsd4_copy_pages(entry->ce_respages, rqstp->rq_respages, | 1072 | nfsd4_copy_pages(entry->ce_respages, rqstp->rq_respages, |
1057 | entry->ce_resused); | 1073 | entry->ce_resused); |
1058 | entry->ce_status = resp->cstate.status; | ||
1059 | entry->ce_datav.iov_base = resp->cstate.statp; | 1074 | entry->ce_datav.iov_base = resp->cstate.statp; |
1060 | entry->ce_datav.iov_len = resv->iov_len - ((char *)resp->cstate.statp - | 1075 | entry->ce_datav.iov_len = resv->iov_len - ((char *)resp->cstate.statp - |
1061 | (char *)page_address(rqstp->rq_respages[0])); | 1076 | (char *)page_address(rqstp->rq_respages[0])); |
1062 | entry->ce_opcnt = resp->opcnt; | ||
1063 | /* Current request rpc header length*/ | 1077 | /* Current request rpc header length*/ |
1064 | entry->ce_rpchdrlen = (char *)resp->cstate.statp - | 1078 | entry->ce_rpchdrlen = (char *)resp->cstate.statp - |
1065 | (char *)page_address(rqstp->rq_respages[0]); | 1079 | (char *)page_address(rqstp->rq_respages[0]); |
@@ -1096,13 +1110,28 @@ nfsd41_copy_replay_data(struct nfsd4_compoundres *resp, | |||
1096 | * cached page. Replace any futher replay pages from the cache. | 1110 | * cached page. Replace any futher replay pages from the cache. |
1097 | */ | 1111 | */ |
1098 | __be32 | 1112 | __be32 |
1099 | nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp) | 1113 | nfsd4_replay_cache_entry(struct nfsd4_compoundres *resp, |
1114 | struct nfsd4_sequence *seq) | ||
1100 | { | 1115 | { |
1101 | struct nfsd4_cache_entry *entry = &resp->cstate.slot->sl_cache_entry; | 1116 | struct nfsd4_cache_entry *entry = &resp->cstate.slot->sl_cache_entry; |
1102 | __be32 status; | 1117 | __be32 status; |
1103 | 1118 | ||
1104 | dprintk("--> %s entry %p\n", __func__, entry); | 1119 | dprintk("--> %s entry %p\n", __func__, entry); |
1105 | 1120 | ||
1121 | /* | ||
1122 | * If this is just the sequence operation, we did not keep | ||
1123 | * a page in the cache entry because we can just use the | ||
1124 | * slot info stored in struct nfsd4_sequence that was checked | ||
1125 | * against the slot in nfsd4_sequence(). | ||
1126 | * | ||
1127 | * This occurs when seq->cachethis is FALSE, or when the client | ||
1128 | * session inactivity timer fires and a solo sequence operation | ||
1129 | * is sent (lease renewal). | ||
1130 | */ | ||
1131 | if (seq && nfsd4_not_cached(resp)) { | ||
1132 | seq->maxslots = resp->cstate.session->se_fnumslots; | ||
1133 | return nfs_ok; | ||
1134 | } | ||
1106 | 1135 | ||
1107 | if (!nfsd41_copy_replay_data(resp, entry)) { | 1136 | if (!nfsd41_copy_replay_data(resp, entry)) { |
1108 | /* | 1137 | /* |
@@ -1330,7 +1359,7 @@ nfsd4_create_session(struct svc_rqst *rqstp, | |||
1330 | cstate->slot = slot; | 1359 | cstate->slot = slot; |
1331 | cstate->status = status; | 1360 | cstate->status = status; |
1332 | /* Return the cached reply status */ | 1361 | /* Return the cached reply status */ |
1333 | status = nfsd4_replay_cache_entry(resp); | 1362 | status = nfsd4_replay_cache_entry(resp, NULL); |
1334 | goto out; | 1363 | goto out; |
1335 | } else if (cr_ses->seqid != conf->cl_slot.sl_seqid + 1) { | 1364 | } else if (cr_ses->seqid != conf->cl_slot.sl_seqid + 1) { |
1336 | status = nfserr_seq_misordered; | 1365 | status = nfserr_seq_misordered; |
@@ -1380,6 +1409,8 @@ nfsd4_create_session(struct svc_rqst *rqstp, | |||
1380 | 1409 | ||
1381 | slot->sl_inuse = true; | 1410 | slot->sl_inuse = true; |
1382 | cstate->slot = slot; | 1411 | cstate->slot = slot; |
1412 | /* Ensure a page is used for the cache */ | ||
1413 | slot->sl_cache_entry.ce_cachethis = 1; | ||
1383 | out: | 1414 | out: |
1384 | nfs4_unlock_state(); | 1415 | nfs4_unlock_state(); |
1385 | dprintk("%s returns %d\n", __func__, ntohl(status)); | 1416 | dprintk("%s returns %d\n", __func__, ntohl(status)); |
@@ -1425,8 +1456,8 @@ nfsd4_sequence(struct svc_rqst *rqstp, | |||
1425 | cstate->slot = slot; | 1456 | cstate->slot = slot; |
1426 | cstate->session = session; | 1457 | cstate->session = session; |
1427 | /* Return the cached reply status and set cstate->status | 1458 | /* Return the cached reply status and set cstate->status |
1428 | * for nfsd4_svc_encode_compoundres processing*/ | 1459 | * for nfsd4_svc_encode_compoundres processing */ |
1429 | status = nfsd4_replay_cache_entry(resp); | 1460 | status = nfsd4_replay_cache_entry(resp, seq); |
1430 | cstate->status = nfserr_replay_cache; | 1461 | cstate->status = nfserr_replay_cache; |
1431 | goto replay_cache; | 1462 | goto replay_cache; |
1432 | } | 1463 | } |
@@ -1436,6 +1467,10 @@ nfsd4_sequence(struct svc_rqst *rqstp, | |||
1436 | /* Success! bump slot seqid */ | 1467 | /* Success! bump slot seqid */ |
1437 | slot->sl_inuse = true; | 1468 | slot->sl_inuse = true; |
1438 | slot->sl_seqid = seq->seqid; | 1469 | slot->sl_seqid = seq->seqid; |
1470 | slot->sl_cache_entry.ce_cachethis = seq->cachethis; | ||
1471 | /* Always set the cache entry cachethis for solo sequence */ | ||
1472 | if (nfsd4_is_solo_sequence(resp)) | ||
1473 | slot->sl_cache_entry.ce_cachethis = 1; | ||
1439 | 1474 | ||
1440 | cstate->slot = slot; | 1475 | cstate->slot = slot; |
1441 | cstate->session = session; | 1476 | cstate->session = session; |