Much of the file net/sunrpc/svcauth_unix.c is taken up by code implementing a cache of domain/ip-address information for rpc clients communicating with the server. A single element of this cache is represented by the structure struct ip_map { struct cache_head h; char *m_class; /* e.g. "nfsd" */ struct in_addr m_addr; struct unix_domain *m_client; int m_add_change; }; A "client", or, equivalently, a unix auth_domain, is represented by struct unix_domain { struct auth_domain h; int addr_changes; /* other stuff later */ }; The unix_domain.h.name field is the name of the client as it appears in the /etc/exports file (which actually may be the name of a group of clients, as in "*.foo.net"). There is a many-to-one relationship between ip-maps and unix_domains; the m_client field of ip_map gives the unix_domain corresponding to a given ip_map. When we want to change the set of ip_maps corresponding to a given unix_domain (for example, in fs/nfsd/export.c:exp_addclient()), instead of locating each relevant ip_map and destroying it, we first use auth_unix_add_addr to add the new ip_maps, and then use auth_unix_forget_old to increment addr_changes, which has the effect of invalidating the old ip_maps: when a new ip_map is created by auth_unix_add_addr(), it initializes the m_add_change field to one more than the addr_changes of the client; the subsequent auth_unix_forget_old then leaves m_add_change in the new ip_maps equal to addr_changes, and leaves the m_add_change field of all previous ip_maps less than auth_domains. Thus the m_add_change field effectively identifies the "generation" of the unix_domain struct which it is associated with. The auth_unix_lookup function ignores any ip_maps found with m_add_changes less than addr_changes. (Note that actually it appears that if an out-of-date ipmap is never looked up, it may hang around in the cache forever?) Lookups in the ip_map cache are done on class and address. ip_map_parse: expects class, ip address (dotted quad), domainname (may be empty). (In a downcall message this comes *after* the cachename, expiry, and key.) Also does ip.m_add_change = ipm.m_client->addr_changes; ip_map_request: prints class, ip address (dotted-quad) auth_unix_add_addr: given an in_addr and an auth_domain, creates new ip_map with client the given auth_domain. Also does ip.m_add_change = udom->addr_changes + 1. Called in a loop by exp_addclient, which does an auth_unix_forget_old *afterwards*, explaining the +1. auth_unix_forget_old: just does udom->addr_changes++ auth_unix_lookup: does lookup on "nfsd" and given address. Returns ip->m_client->h. Also, if client->addr_changes > m_add_change, marks ip as cache_negative. svcauth_unix_accept does a lookup on the source address of the request, and, on success, assigns the resulting ip_map's client pointer to rq_client. Note that on an -EAGAIN from cache_check() it returns SVC_DROP; an upcall should be made at this point.