diff options
author | Pawel Jakub Dawidek <pjd@FreeBSD.org> | 2010-08-26 23:33:04 +0000 |
---|---|---|
committer | Pawel Jakub Dawidek <pjd@FreeBSD.org> | 2010-08-26 23:33:04 +0000 |
commit | 0778b1d117532b23072229cc35a664c9ba5c8544 (patch) | |
tree | 0bed83afcab7f600ce99cdd9e205703a46bac78c /sys/rpc/replay.c | |
parent | 4136388a1815ef48cd2b2005b254293a0986c376 (diff) | |
download | src-0778b1d117532b23072229cc35a664c9ba5c8544.tar.gz src-0778b1d117532b23072229cc35a664c9ba5c8544.zip |
- Check the result of malloc(M_NOWAIT) in replay_alloc(). The caller
(replay_alloc()) knows how to handle replay_alloc() failure.
- Eliminate 'freed_one' variable, it is not needed - when no entry is found
rce will be NULL.
- Add locking assertions where we expect a rc_lock to be held.
Reviewed by: rmacklem
MFC after: 2 weeks
Notes
Notes:
svn path=/head/; revision=211853
Diffstat (limited to 'sys/rpc/replay.c')
-rw-r--r-- | sys/rpc/replay.c | 45 |
1 files changed, 25 insertions, 20 deletions
diff --git a/sys/rpc/replay.c b/sys/rpc/replay.c index 2e92017689a1..1bd5378d9fbe 100644 --- a/sys/rpc/replay.c +++ b/sys/rpc/replay.c @@ -113,8 +113,12 @@ replay_alloc(struct replay_cache *rc, { struct replay_cache_entry *rce; + mtx_assert(&rc->rc_lock, MA_OWNED); + rc->rc_count++; rce = malloc(sizeof(*rce), M_RPC, M_NOWAIT|M_ZERO); + if (!rce) + return (NULL); rce->rce_hash = h; rce->rce_msg = *msg; bcopy(addr, &rce->rce_addr, addr->sa_len); @@ -129,6 +133,8 @@ static void replay_free(struct replay_cache *rc, struct replay_cache_entry *rce) { + mtx_assert(&rc->rc_lock, MA_OWNED); + rc->rc_count--; TAILQ_REMOVE(&rc->rc_cache[rce->rce_hash], rce, rce_link); TAILQ_REMOVE(&rc->rc_all, rce, rce_alllink); @@ -143,26 +149,25 @@ static void replay_prune(struct replay_cache *rc) { struct replay_cache_entry *rce; - bool_t freed_one; - - if (rc->rc_count >= REPLAY_MAX || rc->rc_size > rc->rc_maxsize) { - do { - freed_one = FALSE; - /* - * Try to free an entry. Don't free in-progress entries - */ - TAILQ_FOREACH_REVERSE(rce, &rc->rc_all, - replay_cache_list, rce_alllink) { - if (rce->rce_repmsg.rm_xid) { - replay_free(rc, rce); - freed_one = TRUE; - break; - } - } - } while (freed_one - && (rc->rc_count >= REPLAY_MAX - || rc->rc_size > rc->rc_maxsize)); - } + + mtx_assert(&rc->rc_lock, MA_OWNED); + + if (rc->rc_count < REPLAY_MAX && rc->rc_size <= rc->rc_maxsize) + return; + + do { + /* + * Try to free an entry. Don't free in-progress entries. + */ + TAILQ_FOREACH_REVERSE(rce, &rc->rc_all, replay_cache_list, + rce_alllink) { + if (rce->rce_repmsg.rm_xid) + break; + } + if (rce) + replay_free(rc, rce); + } while (rce && (rc->rc_count >= REPLAY_MAX + || rc->rc_size > rc->rc_maxsize)); } enum replay_state |