URL
https://opencores.org/ocsvn/test_project/test_project/trunk
Subversion Repositories test_project
[/] [test_project/] [trunk/] [linux_sd_driver/] [Documentation/] [rpc-cache.txt] - Rev 62
Compare with Previous | Blame | View Log
This document gives a brief introduction to the cachingmechanisms in the sunrpc layer that is used, in particular,for NFS authentication.CACHES======The caching replaces the old exports table and allows fora wide variety of values to be caches.There are a number of caches that are similar in structure thoughquite possibly very different in content and use. There is a corpusof common code for managing these caches.Examples of caches that are likely to be needed are:- mapping from IP address to client name- mapping from client name and filesystem to export options- mapping from UID to list of GIDs, to work around NFS's limitationof 16 gids.- mappings between local UID/GID and remote UID/GID for sites thatdo not have uniform uid assignment- mapping from network identify to public key for crypto authentication.The common code handles such things as:- general cache lookup with correct locking- supporting 'NEGATIVE' as well as positive entries- allowing an EXPIRED time on cache items, and removingitems after they expire, and are no longer in-use.- making requests to user-space to fill in cache entries- allowing user-space to directly set entries in the cache- delaying RPC requests that depend on as-yet incompletecache entries, and replaying those requests when the cache entryis complete.- clean out old entries as they expire.Creating a Cache----------------1/ A cache needs a datum to store. This is in the form of astructure definition that must contain astruct cache_headas an element, usually the first.It will also contain a key and some content.Each cache element is reference counted and containsexpiry and update times for use in cache management.2/ A cache needs a "cache_detail" structure thatdescribes the cache. This stores the hash table, someparameters for cache management, and some operations detailing howto work with particular cache items.The operations requires are:struct cache_head *alloc(void)This simply allocates appropriate memory and returnsa pointer to the cache_detail embedded within thestructurevoid cache_put(struct kref *)This is called when the last reference to an item isdropped. The pointer passed is to the 'ref' fieldin the cache_head. cache_put should release anyreferences create by 'cache_init' and, if CACHE_VALIDis set, any references created by cache_update.It should then release the memory allocated by'alloc'.int match(struct cache_head *orig, struct cache_head *new)test if the keys in the two structures match. Return1 if they do, 0 if they don't.void init(struct cache_head *orig, struct cache_head *new)Set the 'key' fields in 'new' from 'orig'. This mayinclude taking references to shared objects.void update(struct cache_head *orig, struct cache_head *new)Set the 'content' fileds in 'new' from 'orig'.int cache_show(struct seq_file *m, struct cache_detail *cd,struct cache_head *h)Optional. Used to provide a /proc file that lists thecontents of a cache. This should show one item,usually on just one line.int cache_request(struct cache_detail *cd, struct cache_head *h,char **bpp, int *blen)Format a request to be send to user-space for an itemto be instantiated. *bpp is a buffer of size *blen.bpp should be moved forward over the encoded message,and *blen should be reduced to show how much freespace remains. Return 0 on success or <0 if notenough room or other problem.int cache_parse(struct cache_detail *cd, char *buf, int len)A message from user space has arrived to fill out acache entry. It is in 'buf' of length 'len'.cache_parse should parse this, find the item in thecache with sunrpc_cache_lookup, and update the itemwith sunrpc_cache_update.3/ A cache needs to be registered using cache_register(). Thisincludes it on a list of caches that will be regularlycleaned to discard old data.Using a cache-------------To find a value in a cache, call sunrpc_cache_lookup passing a pointerto the cache_head in a sample item with the 'key' fields filled in.This will be passed to ->match to identify the target entry. If noentry is found, a new entry will be create, added to the cache, andmarked as not containing valid data.The item returned is typically passed to cache_check which will checkif the data is valid, and may initiate an up-call to get fresh data.cache_check will return -ENOENT in the entry is negative or if an upcall is needed but not possible, -EAGAIN if an upcall is pending,or 0 if the data is valid;cache_check can be passed a "struct cache_req *". This structure istypically embedded in the actual request and can be used to create adeferred copy of the request (struct cache_deferred_req). This isdone when the found cache item is not uptodate, but the is reason tobelieve that userspace might provide information soon. When the cacheitem does become valid, the deferred copy of the request will berevisited (->revisit). It is expected that this method willreschedule the request for processing.The value returned by sunrpc_cache_lookup can also be passed tosunrpc_cache_update to set the content for the item. A second item ispassed which should hold the content. If the item found by _lookuphas valid data, then it is discarded and a new item is created. Thissaves any user of an item from worrying about content changing whileit is being inspected. If the item found by _lookup does not containvalid data, then the content is copied across and CACHE_VALID is set.Populating a cache------------------Each cache has a name, and when the cache is registered, a directorywith that name is created in /proc/net/rpcThis directory contains a file called 'channel' which is a channelfor communicating between kernel and user for populating the cache.This directory may later contain other files of interactingwith the cache.The 'channel' works a bit like a datagram socket. Each 'write' ispassed as a whole to the cache for parsing and interpretation.Each cache can treat the write requests differently, but it isexpected that a message written will contain:- a key- an expiry time- a content.with the intention that an item in the cache with the give keyshould be create or updated to have the given content, and theexpiry time should be set on that item.Reading from a channel is a bit more interesting. When a cachelookup fails, or when it succeeds but finds an entry that may soonexpire, a request is lodged for that cache item to be updated byuser-space. These requests appear in the channel file.Successive reads will return successive requests.If there are no more requests to return, read will return EOF, but aselect or poll for read will block waiting for another request to beadded.Thus a user-space helper is likely to:open the channel.select for readableread a requestwrite a responseloop.If it dies and needs to be restarted, any requests that have not beenanswered will still appear in the file and will be read by the newinstance of the helper.Each cache should define a "cache_parse" method which takes a messagewritten from user-space and processes it. It should return an error(which propagates back to the write syscall) or 0.Each cache should also define a "cache_request" method whichtakes a cache item and encodes a request into the bufferprovided.Note: If a cache has no active readers on the channel, and has had notactive readers for more than 60 seconds, further requests will not beadded to the channel but instead all lookups that do not find a validentry will fail. This is partly for backward compatibility: Theprevious nfs exports table was deemed to be authoritative and afailed lookup meant a definite 'no'.request/response format-----------------------While each cache is free to use it's own format for requestsand responses over channel, the following is recommended asappropriate and support routines are available to help:Each request or response record should be printable ASCIIwith precisely one newline character which should be at the end.Fields within the record should be separated by spaces, normally one.If spaces, newlines, or nul characters are needed in a field theymuch be quoted. two mechanisms are available:1/ If a field begins '\x' then it must contain an even number ofhex digits, and pairs of these digits provide the bytes in thefield.2/ otherwise a \ in the field must be followed by 3 octal digitswhich give the code for a byte. Other characters are treatedas them selves. At the very least, space, newline, nul, and'\' must be quoted in this way.
