diff options
-rw-r--r-- | nfsd/ChangeLog | 15 | ||||
-rw-r--r-- | nfsd/cache.c | 134 |
2 files changed, 98 insertions, 51 deletions
diff --git a/nfsd/ChangeLog b/nfsd/ChangeLog index 6942b127..078a84e5 100644 --- a/nfsd/ChangeLog +++ b/nfsd/ChangeLog @@ -1,3 +1,18 @@ +2000-12-01 Marcus Brinkmann <marcus@gnu.org> + + * cache.c (scan_creds): Move I inside for-statement. + Replace inner for-loop with a while-loop. New variable + NEXT_I set to I->NEXT, because we might free I. + Set I to NEXT_I at end of while block. + Move update of leastidlastuse inside if block, because + otherwise we will constantly prevent ourself from scanning. + (scan_fhs): Very much the same. + (scan_replies): Likewise. Also free CR. + + (check_cached_reply): Make HASH value absolute (as XID can be + negative, and thus the modulus). + Initialize REFERENCES to 1. + 2000-03-17 Thomas Bushnell, BSG <tb@mit.edu> * cache.c (create_cached_handle): Add comment. diff --git a/nfsd/cache.c b/nfsd/cache.c index 8e8ac14c..b97ea394 100644 --- a/nfsd/cache.c +++ b/nfsd/cache.c @@ -202,33 +202,43 @@ cred_ref (struct idspec *i) void scan_creds () { - struct idspec *i; int n; int newleast = mapped_time->seconds; spin_lock (&idhashlock); + if (mapped_time->seconds - leastidlastuse > ID_KEEP_TIMEOUT) - for (n = 0; n < IDHASH_TABLE_SIZE && nfreeids; n++) - for (i = idhashtable[n]; i && nfreeids; i = i->next) + { + for (n = 0; n < IDHASH_TABLE_SIZE && nfreeids; n++) { - if (!i->references - && mapped_time->seconds - i->lastuse > ID_KEEP_TIMEOUT) + struct idspec *i = idhashtable[n]; + + while (i && nfreeids) { - nfreeids--; - *i->prevp = i->next; - if (i->next) - i->next->prevp = i->prevp; - free (i->uids); - free (i->gids); - free (i); + struct idspec *next_i = i->next; + + if (!i->references + && mapped_time->seconds - i->lastuse > ID_KEEP_TIMEOUT) + { + nfreeids--; + *i->prevp = i->next; + if (i->next) + i->next->prevp = i->prevp; + free (i->uids); + free (i->gids); + free (i); + } + else if (!i->references && newleast > i->lastuse) + newleast = i->lastuse; + + i = next_i; } - else if (!i->references && newleast > i->lastuse) - newleast = i->lastuse; } - /* If we didn't bail early, then this is valid */ - if (nfreeids) - leastidlastuse = newleast; + /* If we didn't bail early, then this is valid */ + if (nfreeids) + leastidlastuse = newleast; + } spin_unlock (&idhashlock); } @@ -320,33 +330,43 @@ cache_handle_rele (struct cache_handle *c) void scan_fhs () { - struct cache_handle *c; int n; int newleast = mapped_time->seconds; mutex_lock (&fhhashlock); + if (mapped_time->seconds - leastfhlastuse > FH_KEEP_TIMEOUT) - for (n = 0; n < FHHASH_TABLE_SIZE && nfreefh; n++) - for (c = fhhashtable[n]; c && nfreefh; c = c->next) + { + for (n = 0; n < FHHASH_TABLE_SIZE && nfreefh; n++) { - if (!c->references - && mapped_time->seconds - c->lastuse > FH_KEEP_TIMEOUT) + struct cache_handle *c = fhhashtable[n]; + + while (c && nfreefh) { - nfreefh--; - *c->prevp = c->next; - if (c->next) - c->next->prevp = c->prevp; - cred_rele (c->ids); - mach_port_deallocate (mach_task_self (), c->port); - free (c); + struct cache_handle *next_c = c->next; + + if (!c->references + && mapped_time->seconds - c->lastuse > FH_KEEP_TIMEOUT) + { + nfreefh--; + *c->prevp = c->next; + if (c->next) + c->next->prevp = c->prevp; + cred_rele (c->ids); + mach_port_deallocate (mach_task_self (), c->port); + free (c); + } + else if (!c->references && newleast > c->lastuse) + newleast = c->lastuse; + + c = next_c; } - else if (!c->references && newleast > c->lastuse) - newleast = c->lastuse; } - /* If we didn't bail early, then this is valid. */ - if (nfreefh) - leastfhlastuse = newleast; + /* If we didn't bail early, then this is valid. */ + if (nfreefh) + leastfhlastuse = newleast; + } mutex_unlock (&fhhashlock); } @@ -452,7 +472,7 @@ check_cached_replies (int xid, struct cached_reply *cr; int hash; - hash = xid % REPLYHASH_TABLE_SIZE; + hash = abs(xid % REPLYHASH_TABLE_SIZE); spin_lock (&replycachelock); for (cr = replyhashtable[hash]; cr; cr = cr->next) @@ -473,6 +493,7 @@ check_cached_replies (int xid, bcopy (sender, &cr->source, sizeof (struct sockaddr_in)); cr->xid = xid; cr->data = 0; + cr->references = 1; cr->next = replyhashtable[hash]; if (replyhashtable[hash]) @@ -505,31 +526,42 @@ release_cached_reply (struct cached_reply *cr) void scan_replies () { - struct cached_reply *cr; int n; int newleast = mapped_time->seconds; spin_lock (&replycachelock); + if (mapped_time->seconds - leastreplylastuse > REPLY_KEEP_TIMEOUT) - for (n = 0; n < REPLYHASH_TABLE_SIZE && nfreereplies; n++) - for (cr = replyhashtable[n]; cr && nfreereplies; cr = cr->next) + { + for (n = 0; n < REPLYHASH_TABLE_SIZE && nfreereplies; n++) { - if (!cr->references - && mapped_time->seconds - cr->lastuse > REPLY_KEEP_TIMEOUT) + struct cached_reply *cr = replyhashtable[n]; + + while (cr && nfreereplies) { - nfreereplies--; - *cr->prevp = cr->next; - if (cr->next) - cr->next->prevp = cr->prevp; - if (cr->data) - free (cr->data); + struct cached_reply *next_cr = cr->next; + + if (!cr->references + && mapped_time->seconds - cr->lastuse > REPLY_KEEP_TIMEOUT) + { + nfreereplies--; + *cr->prevp = cr->next; + if (cr->next) + cr->next->prevp = cr->prevp; + if (cr->data) + free (cr->data); + free (cr); + } + else if (!cr->references && newleast > cr->lastuse) + newleast = cr->lastuse; + + cr = next_cr; } - else if (!cr->references && newleast > cr->lastuse) - newleast = cr->lastuse; } - /* If we didn't bail early, then this is valid */ - if (nfreereplies) - leastreplylastuse = newleast; + /* If we didn't bail early, then this is valid */ + if (nfreereplies) + leastreplylastuse = newleast; + } spin_unlock (&replycachelock); } |