€•›Œsphinx.addnodes”Œdocument”“”)”}”(Œ rawsource”Œ”Œchildren”]”(Œ translations”Œ LanguagesNode”“”)”}”(hhh]”(hŒ pending_xref”“”)”}”(hhh]”Œdocutils.nodes”ŒText”“”ŒChinese (Simplified)”…””}”Œparent”hsbaŒ attributes”}”(Œids”]”Œclasses”]”Œnames”]”Œdupnames”]”Œbackrefs”]”Œ refdomain”Œstd”Œreftype”Œdoc”Œ reftarget”Œ-/translations/zh_CN/filesystems/nfs/rpc-cache”Œmodname”NŒ classname”NŒ refexplicit”ˆuŒtagname”hhh ubh)”}”(hhh]”hŒChinese (Traditional)”…””}”hh2sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ-/translations/zh_TW/filesystems/nfs/rpc-cache”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒItalian”…””}”hhFsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ-/translations/it_IT/filesystems/nfs/rpc-cache”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒJapanese”…””}”hhZsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ-/translations/ja_JP/filesystems/nfs/rpc-cache”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒKorean”…””}”hhnsbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ-/translations/ko_KR/filesystems/nfs/rpc-cache”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒPortuguese (Brazilian)”…””}”hh‚sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ-/translations/pt_BR/filesystems/nfs/rpc-cache”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubh)”}”(hhh]”hŒSpanish”…””}”hh–sbah}”(h]”h ]”h"]”h$]”h&]”Œ refdomain”h)Œreftype”h+Œ reftarget”Œ-/translations/sp_SP/filesystems/nfs/rpc-cache”Œmodname”NŒ classname”NŒ refexplicit”ˆuh1hhh ubeh}”(h]”h ]”h"]”h$]”h&]”Œcurrent_language”ŒEnglish”uh1h hhŒ _document”hŒsource”NŒline”NubhŒsection”“”)”}”(hhh]”(hŒtitle”“”)”}”(hŒ RPC Cache”h]”hŒ RPC Cache”…””}”(hh¼h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhh·h²hh³ŒG/var/lib/git/docbuild/linux/Documentation/filesystems/nfs/rpc-cache.rst”h´KubhŒ paragraph”“”)”}”(hŒ‹This document gives a brief introduction to the caching mechanisms in the sunrpc layer that is used, in particular, for NFS authentication.”h]”hŒ‹This document gives a brief introduction to the caching mechanisms in the sunrpc layer that is used, in particular, for NFS authentication.”…””}”(hhÍh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khh·h²hubh¶)”}”(hhh]”(h»)”}”(hŒCaches”h]”hŒCaches”…””}”(hhÞh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhhÛh²hh³hÊh´K ubhÌ)”}”(hŒ`The caching replaces the old exports table and allows for a wide variety of values to be caches.”h]”hŒ`The caching replaces the old exports table and allows for a wide variety of values to be caches.”…””}”(hhìh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K hhÛh²hubhÌ)”}”(hŒ°There are a number of caches that are similar in structure though quite possibly very different in content and use. There is a corpus of common code for managing these caches.”h]”hŒ°There are a number of caches that are similar in structure though quite possibly very different in content and use. There is a corpus of common code for managing these caches.”…””}”(hhúh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KhhÛh²hubhÌ)”}”(hŒ4Examples of caches that are likely to be needed are:”h]”hŒ4Examples of caches that are likely to be needed are:”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KhhÛh²hubhŒ block_quote”“”)”}”(hXh- 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 limitation of 16 gids. - mappings between local UID/GID and remote UID/GID for sites that do not have uniform uid assignment - mapping from network identify to public key for crypto authentication. ”h]”hŒ bullet_list”“”)”}”(hhh]”(hŒ list_item”“”)”}”(hŒ&mapping from IP address to client name”h]”hÌ)”}”(hj%h]”hŒ&mapping from IP address to client name”…””}”(hj'h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khj#ubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjubj")”}”(hŒ9mapping from client name and filesystem to export options”h]”hÌ)”}”(hj<h]”hŒ9mapping from client name and filesystem to export options”…””}”(hj>h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khj:ubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjubj")”}”(hŒMmapping from UID to list of GIDs, to work around NFS's limitation of 16 gids.”h]”hÌ)”}”(hŒMmapping from UID to list of GIDs, to work around NFS's limitation of 16 gids.”h]”hŒOmapping from UID to list of GIDs, to work around NFS’s limitation of 16 gids.”…””}”(hjUh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KhjQubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjubj")”}”(hŒcmappings between local UID/GID and remote UID/GID for sites that do not have uniform uid assignment”h]”hÌ)”}”(hŒcmappings between local UID/GID and remote UID/GID for sites that do not have uniform uid assignment”h]”hŒcmappings between local UID/GID and remote UID/GID for sites that do not have uniform uid assignment”…””}”(hjmh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khjiubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjubj")”}”(hŒGmapping from network identify to public key for crypto authentication. ”h]”hÌ)”}”(hŒFmapping from network identify to public key for crypto authentication.”h]”hŒFmapping from network identify to public key for crypto authentication.”…””}”(hj…h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khjubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjubeh}”(h]”h ]”h"]”h$]”h&]”Œbullet”Œ-”uh1jh³hÊh´Khjubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KhhÛh²hubhÌ)”}”(hŒ'The common code handles such things as:”h]”hŒ'The common code handles such things as:”…””}”(hj§h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KhhÛh²hubj)”}”(hXô- general cache lookup with correct locking - supporting 'NEGATIVE' as well as positive entries - allowing an EXPIRED time on cache items, and removing items 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 incomplete cache entries, and replaying those requests when the cache entry is complete. - clean out old entries as they expire. ”h]”j)”}”(hhh]”(j")”}”(hŒ)general cache lookup with correct locking”h]”hÌ)”}”(hj¾h]”hŒ)general cache lookup with correct locking”…””}”(hjÀh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khj¼ubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj¹ubj")”}”(hŒ1supporting 'NEGATIVE' as well as positive entries”h]”hÌ)”}”(hjÕh]”hŒ5supporting ‘NEGATIVE’ as well as positive entries”…””}”(hj×h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K hjÓubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj¹ubj")”}”(hŒhallowing an EXPIRED time on cache items, and removing items after they expire, and are no longer in-use.”h]”hÌ)”}”(hŒhallowing an EXPIRED time on cache items, and removing items after they expire, and are no longer in-use.”h]”hŒhallowing an EXPIRED time on cache items, and removing items after they expire, and are no longer in-use.”…””}”(hjîh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K!hjêubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj¹ubj")”}”(hŒ6making requests to user-space to fill in cache entries”h]”hÌ)”}”(hjh]”hŒ6making requests to user-space to fill in cache entries”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K#hjubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj¹ubj")”}”(hŒ8allowing user-space to directly set entries in the cache”h]”hÌ)”}”(hjh]”hŒ8allowing user-space to directly set entries in the cache”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K$hjubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj¹ubj")”}”(hŒ„delaying RPC requests that depend on as-yet incomplete cache entries, and replaying those requests when the cache entry is complete.”h]”hÌ)”}”(hŒ„delaying RPC requests that depend on as-yet incomplete cache entries, and replaying those requests when the cache entry is complete.”h]”hŒ„delaying RPC requests that depend on as-yet incomplete cache entries, and replaying those requests when the cache entry is complete.”…””}”(hj4h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K%hj0ubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj¹ubj")”}”(hŒ&clean out old entries as they expire. ”h]”hÌ)”}”(hŒ%clean out old entries as they expire.”h]”hŒ%clean out old entries as they expire.”…””}”(hjLh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K(hjHubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj¹ubeh}”(h]”h ]”h"]”h$]”h&]”jŸj uh1jh³hÊh´Khjµubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KhhÛh²hubh¶)”}”(hhh]”(h»)”}”(hŒCreating a Cache”h]”hŒCreating a Cache”…””}”(hjoh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjlh²hh³hÊh´K+ubj)”}”(hhh]”(j")”}”(hX-A cache needs a datum to store. This is in the form of a structure definition that must contain a struct cache_head as an element, usually the first. It will also contain a key and some content. Each cache element is reference counted and contains expiry and update times for use in cache management.”h]”hÌ)”}”(hX-A cache needs a datum to store. This is in the form of a structure definition that must contain a struct cache_head as an element, usually the first. It will also contain a key and some content. Each cache element is reference counted and contains expiry and update times for use in cache management.”h]”hX-A cache needs a datum to store. This is in the form of a structure definition that must contain a struct cache_head as an element, usually the first. It will also contain a key and some content. Each cache element is reference counted and contains expiry and update times for use in cache management.”…””}”(hj„h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K-hj€ubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj}h²hh³hÊh´Nubj")”}”(hXQA cache needs a "cache_detail" structure that describes the cache. This stores the hash table, some parameters for cache management, and some operations detailing how to work with particular cache items. The operations are: struct cache_head \*alloc(void) This simply allocates appropriate memory and returns a pointer to the cache_detail embedded within the structure void cache_put(struct kref \*) This is called when the last reference to an item is dropped. The pointer passed is to the 'ref' field in the cache_head. cache_put should release any references create by 'cache_init' and, if CACHE_VALID is 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. Return 1 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 may include taking references to shared objects. void update(struct cache_head \*orig, struct cache_head \*new) Set the 'content' fields 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 the contents 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 item to 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 free space remains. Return 0 on success or <0 if not enough 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 a cache entry. It is in 'buf' of length 'len'. cache_parse should parse this, find the item in the cache with sunrpc_cache_lookup_rcu, and update the item with sunrpc_cache_update. ”h]”(hÌ)”}”(hŒÌA cache needs a "cache_detail" structure that describes the cache. This stores the hash table, some parameters for cache management, and some operations detailing how to work with particular cache items.”h]”hŒÐA cache needs a “cache_detail†structure that describes the cache. This stores the hash table, some parameters for cache management, and some operations detailing how to work with particular cache items.”…””}”(hjœh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K3hj˜ubhÌ)”}”(hŒThe operations are:”h]”hŒThe operations are:”…””}”(hjªh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K8hj˜ubj)”}”(hXIstruct cache_head \*alloc(void) This simply allocates appropriate memory and returns a pointer to the cache_detail embedded within the structure void cache_put(struct kref \*) This is called when the last reference to an item is dropped. The pointer passed is to the 'ref' field in the cache_head. cache_put should release any references create by 'cache_init' and, if CACHE_VALID is 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. Return 1 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 may include taking references to shared objects. void update(struct cache_head \*orig, struct cache_head \*new) Set the 'content' fields 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 the contents 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 item to 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 free space remains. Return 0 on success or <0 if not enough 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 a cache entry. It is in 'buf' of length 'len'. cache_parse should parse this, find the item in the cache with sunrpc_cache_lookup_rcu, and update the item with sunrpc_cache_update. ”h]”hŒdefinition_list”“”)”}”(hhh]”(hŒdefinition_list_item”“”)”}”(hŒ‘struct cache_head \*alloc(void) This simply allocates appropriate memory and returns a pointer to the cache_detail embedded within the structure ”h]”(hŒterm”“”)”}”(hŒstruct cache_head \*alloc(void)”h]”hŒstruct cache_head *alloc(void)”…””}”(hjÉh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÇh³hÊh´K=hjÃubhŒ definition”“”)”}”(hhh]”hÌ)”}”(hŒpThis simply allocates appropriate memory and returns a pointer to the cache_detail embedded within the structure”h]”hŒpThis simply allocates appropriate memory and returns a pointer to the cache_detail embedded within the structure”…””}”(hjÜh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K;hjÙubah}”(h]”h ]”h"]”h$]”h&]”uh1j×hjÃubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÁh³hÊh´K=hj¾ubjÂ)”}”(hXVvoid cache_put(struct kref \*) This is called when the last reference to an item is dropped. The pointer passed is to the 'ref' field in the cache_head. cache_put should release any references create by 'cache_init' and, if CACHE_VALID is set, any references created by cache_update. It should then release the memory allocated by 'alloc'. ”h]”(jÈ)”}”(hŒvoid cache_put(struct kref \*)”h]”hŒvoid cache_put(struct kref *)”…””}”(hjúh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÇh³hÊh´KFhjöubjØ)”}”(hhh]”hÌ)”}”(hX6This is called when the last reference to an item is dropped. The pointer passed is to the 'ref' field in the cache_head. cache_put should release any references create by 'cache_init' and, if CACHE_VALID is set, any references created by cache_update. It should then release the memory allocated by 'alloc'.”h]”hXBThis is called when the last reference to an item is dropped. The pointer passed is to the ‘ref’ field in the cache_head. cache_put should release any references create by ‘cache_init’ and, if CACHE_VALID is set, any references created by cache_update. It should then release the memory allocated by ‘alloc’.”…””}”(hj h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K@hjubah}”(h]”h ]”h"]”h$]”h&]”uh1j×hjöubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÁh³hÊh´KFhj¾ubjÂ)”}”(hŒ’int match(struct cache_head \*orig, struct cache_head \*new) test if the keys in the two structures match. Return 1 if they do, 0 if they don't. ”h]”(jÈ)”}”(hŒvoid update(struct cache_head \*orig, struct cache_head \*new)”h]”hŒ>void update(struct cache_head *orig, struct cache_head *new)”…””}”(hj‡h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÇh³hÊh´KQhjƒubjØ)”}”(hhh]”hÌ)”}”(hŒ.Set the 'content' fields in 'new' from 'orig'.”h]”hŒ:Set the ‘content’ fields in ‘new’ from ‘orig’.”…””}”(hj˜h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KQhj•ubah}”(h]”h ]”h"]”h$]”h&]”uh1j×hjƒubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÁh³hÊh´KQhj¾ubjÂ)”}”(hŒ×int cache_show(struct seq_file \*m, struct cache_detail \*cd, struct cache_head \*h) Optional. Used to provide a /proc file that lists the contents of a cache. This should show one item, usually on just one line. ”h]”(jÈ)”}”(hŒTint cache_show(struct seq_file \*m, struct cache_detail \*cd, struct cache_head \*h)”h]”hŒTint cache_show(struct seq_file *m, struct cache_detail *cd, struct cache_head *h)”…””}”(hj¶h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÇh³hÊh´KVhj²ubjØ)”}”(hhh]”hÌ)”}”(hŒOptional. Used to provide a /proc file that lists the contents of a cache. This should show one item, usually on just one line.”h]”hŒOptional. Used to provide a /proc file that lists the contents of a cache. This should show one item, usually on just one line.”…””}”(hjÇh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KThjÄubah}”(h]”h ]”h"]”h$]”h&]”uh1j×hj²ubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÁh³hÊh´KVhj¾ubjÂ)”}”(hXƒ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 item to 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 free space remains. Return 0 on success or <0 if not enough room or other problem. ”h]”(jÈ)”}”(hŒ\int cache_request(struct cache_detail \*cd, struct cache_head \*h, char \*\*bpp, int \*blen)”h]”hŒ\int cache_request(struct cache_detail *cd, struct cache_head *h, char **bpp, int *blen)”…””}”(hjåh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÇh³hÊh´K^hjáubjØ)”}”(hhh]”hÌ)”}”(hX%Format a request to be send to user-space for an item to 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 free space remains. Return 0 on success or <0 if not enough room or other problem.”h]”hX%Format a request to be send to user-space for an item to 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 free space remains. Return 0 on success or <0 if not enough room or other problem.”…””}”(hjöh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KYhjóubah}”(h]”h ]”h"]”h$]”h&]”uh1j×hjáubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÁh³hÊh´K^hj¾ubjÂ)”}”(hX(int cache_parse(struct cache_detail \*cd, char \*buf, int len) A message from user space has arrived to fill out a cache entry. It is in 'buf' of length 'len'. cache_parse should parse this, find the item in the cache with sunrpc_cache_lookup_rcu, and update the item with sunrpc_cache_update. ”h]”(jÈ)”}”(hŒ>int cache_parse(struct cache_detail \*cd, char \*buf, int len)”h]”hŒ>int cache_parse(struct cache_detail *cd, char *buf, int len)”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1jÇh³hÊh´KfhjubjØ)”}”(hhh]”hÌ)”}”(hŒçA message from user space has arrived to fill out a cache entry. It is in 'buf' of length 'len'. cache_parse should parse this, find the item in the cache with sunrpc_cache_lookup_rcu, and update the item with sunrpc_cache_update.”h]”hŒïA message from user space has arrived to fill out a cache entry. It is in ‘buf’ of length ‘len’. cache_parse should parse this, find the item in the cache with sunrpc_cache_lookup_rcu, and update the item with sunrpc_cache_update.”…””}”(hj%h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kahj"ubah}”(h]”h ]”h"]”h$]”h&]”uh1j×hjubeh}”(h]”h ]”h"]”h$]”h&]”uh1jÁh³hÊh´Kfhj¾ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j¼hj¸ubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´K:hj˜ubeh}”(h]”h ]”h"]”h$]”h&]”uh1j!hj}h²hh³hÊh´Nubj")”}”(hŒ‘A cache needs to be registered using cache_register(). This includes it on a list of caches that will be regularly cleaned to discard old data. ”h]”hÌ)”}”(hŒA cache needs to be registered using cache_register(). This includes it on a list of caches that will be regularly cleaned to discard old data.”h]”hŒA cache needs to be registered using cache_register(). This includes it on a list of caches that will be regularly cleaned to discard old data.”…””}”(hjUh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KhhjQubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hj}h²hh³hÊh´Nubeh}”(h]”h ]”h"]”h$]”h&]”jŸj uh1jh³hÊh´K-hjlh²hubeh}”(h]”Œcreating-a-cache”ah ]”h"]”Œcreating a cache”ah$]”h&]”uh1hµhhÛh²hh³hÊh´K+ubh¶)”}”(hhh]”(h»)”}”(hŒ Using a cache”h]”hŒ Using a cache”…””}”(hjzh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjwh²hh³hÊh´KmubhÌ)”}”(hX;To find a value in a cache, call sunrpc_cache_lookup_rcu passing a pointer to 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 no entry is found, a new entry will be create, added to the cache, and marked as not containing valid data.”h]”hX?To find a value in a cache, call sunrpc_cache_lookup_rcu passing a pointer to 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 no entry is found, a new entry will be create, added to the cache, and marked as not containing valid data.”…””}”(hjˆh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kohjwh²hubhÌ)”}”(hX,The item returned is typically passed to cache_check which will check if 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 up call is needed but not possible, -EAGAIN if an upcall is pending, or 0 if the data is valid;”h]”hX,The item returned is typically passed to cache_check which will check if 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 up call is needed but not possible, -EAGAIN if an upcall is pending, or 0 if the data is valid;”…””}”(hj–h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kuhjwh²hubhÌ)”}”(hXýcache_check can be passed a "struct cache_req\*". This structure is typically embedded in the actual request and can be used to create a deferred copy of the request (struct cache_deferred_req). This is done when the found cache item is not uptodate, but the is reason to believe that userspace might provide information soon. When the cache item does become valid, the deferred copy of the request will be revisited (->revisit). It is expected that this method will reschedule the request for processing.”h]”hXcache_check can be passed a “struct cache_req*â€. This structure is typically embedded in the actual request and can be used to create a deferred copy of the request (struct cache_deferred_req). This is done when the found cache item is not uptodate, but the is reason to believe that userspace might provide information soon. When the cache item does become valid, the deferred copy of the request will be revisited (->revisit). It is expected that this method will reschedule the request for processing.”…””}”(hj¤h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K{hjwh²hubhÌ)”}”(hXåThe value returned by sunrpc_cache_lookup_rcu can also be passed to sunrpc_cache_update to set the content for the item. A second item is passed which should hold the content. If the item found by _lookup has valid data, then it is discarded and a new item is created. This saves any user of an item from worrying about content changing while it is being inspected. If the item found by _lookup does not contain valid data, then the content is copied across and CACHE_VALID is set.”h]”hXåThe value returned by sunrpc_cache_lookup_rcu can also be passed to sunrpc_cache_update to set the content for the item. A second item is passed which should hold the content. If the item found by _lookup has valid data, then it is discarded and a new item is created. This saves any user of an item from worrying about content changing while it is being inspected. If the item found by _lookup does not contain valid data, then the content is copied across and CACHE_VALID is set.”…””}”(hj²h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K„hjwh²hubeh}”(h]”Œ using-a-cache”ah ]”h"]”Œ using a cache”ah$]”h&]”uh1hµhhÛh²hh³hÊh´Kmubh¶)”}”(hhh]”(h»)”}”(hŒPopulating a cache”h]”hŒPopulating a cache”…””}”(hjËh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjÈh²hh³hÊh´KubhÌ)”}”(hŒoEach cache has a name, and when the cache is registered, a directory with that name is created in /proc/net/rpc”h]”hŒoEach cache has a name, and when the cache is registered, a directory with that name is created in /proc/net/rpc”…””}”(hjÙh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KhjÈh²hubhÌ)”}”(hŒÒThis directory contains a file called 'channel' which is a channel for communicating between kernel and user for populating the cache. This directory may later contain other files of interacting with the cache.”h]”hŒÖThis directory contains a file called ‘channel’ which is a channel for communicating between kernel and user for populating the cache. This directory may later contain other files of interacting with the cache.”…””}”(hjçh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K’hjÈh²hubhÌ)”}”(hŒíThe 'channel' works a bit like a datagram socket. Each 'write' is passed as a whole to the cache for parsing and interpretation. Each cache can treat the write requests differently, but it is expected that a message written will contain:”h]”hŒõThe ‘channel’ works a bit like a datagram socket. Each ‘write’ is passed as a whole to the cache for parsing and interpretation. Each cache can treat the write requests differently, but it is expected that a message written will contain:”…””}”(hjõh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K—hjÈh²hubj)”}”(hŒ&- a key - an expiry time - a content. ”h]”j)”}”(hhh]”(j")”}”(hŒa key”h]”hÌ)”}”(hj h]”hŒa key”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kœhj ubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjubj")”}”(hŒan expiry time”h]”hÌ)”}”(hj#h]”hŒan expiry time”…””}”(hj%h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Khj!ubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjubj")”}”(hŒ a content. ”h]”hÌ)”}”(hŒ a content.”h]”hŒ a content.”…””}”(hj<h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´Kžhj8ubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjubeh}”(h]”h ]”h"]”h$]”h&]”jŸj uh1jh³hÊh´Kœhjubah}”(h]”h ]”h"]”h$]”h&]”uh1jh³hÊh´KœhjÈh²hubhÌ)”}”(hŒ¥with the intention that an item in the cache with the give key should be create or updated to have the given content, and the expiry time should be set on that item.”h]”hŒ¥with the intention that an item in the cache with the give key should be create or updated to have the given content, and the expiry time should be set on that item.”…””}”(hj\h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K hjÈh²hubhÌ)”}”(hŒûReading from a channel is a bit more interesting. When a cache lookup fails, or when it succeeds but finds an entry that may soon expire, a request is lodged for that cache item to be updated by user-space. These requests appear in the channel file.”h]”hŒûReading from a channel is a bit more interesting. When a cache lookup fails, or when it succeeds but finds an entry that may soon expire, a request is lodged for that cache item to be updated by user-space. These requests appear in the channel file.”…””}”(hjjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K¤hjÈh²hubhÌ)”}”(hŒÂSuccessive reads will return successive requests. If there are no more requests to return, read will return EOF, but a select or poll for read will block waiting for another request to be added.”h]”hŒÂSuccessive reads will return successive requests. If there are no more requests to return, read will return EOF, but a select or poll for read will block waiting for another request to be added.”…””}”(hjxh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K©hjÈh²hubhÌ)”}”(hŒ'Thus a user-space helper is likely to::”h]”hŒ&Thus a user-space helper is likely to:”…””}”(hj†h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K®hjÈh²hubhŒ literal_block”“”)”}”(hŒQopen the channel. select for readable read a request write a response loop.”h]”hŒQopen the channel. select for readable read a request write a response loop.”…””}”hj–sbah}”(h]”h ]”h"]”h$]”h&]”Œ xml:space”Œpreserve”uh1j”h³hÊh´K°hjÈh²hubhÌ)”}”(hŒ If it dies and needs to be restarted, any requests that have not been answered will still appear in the file and will be read by the new instance of the helper.”h]”hŒ If it dies and needs to be restarted, any requests that have not been answered will still appear in the file and will be read by the new instance of the helper.”…””}”(hj¦h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K¶hjÈh²hubhÌ)”}”(hŒ½Each cache should define a "cache_parse" method which takes a message written from user-space and processes it. It should return an error (which propagates back to the write syscall) or 0.”h]”hŒÁEach cache should define a “cache_parse†method which takes a message written from user-space and processes it. It should return an error (which propagates back to the write syscall) or 0.”…””}”(hj´h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KºhjÈh²hubhÌ)”}”(hŒEach cache should also define a "cache_request" method which takes a cache item and encodes a request into the buffer provided.”h]”hŒƒEach cache should also define a “cache_request†method which takes a cache item and encodes a request into the buffer provided.”…””}”(hjÂh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´K¾hjÈh²hubhŒnote”“”)”}”(hXrIf a cache has no active readers on the channel, and has had not active readers for more than 60 seconds, further requests will not be added to the channel but instead all lookups that do not find a valid entry will fail. This is partly for backward compatibility: The previous nfs exports table was deemed to be authoritative and a failed lookup meant a definite 'no'.”h]”hÌ)”}”(hXrIf a cache has no active readers on the channel, and has had not active readers for more than 60 seconds, further requests will not be added to the channel but instead all lookups that do not find a valid entry will fail. This is partly for backward compatibility: The previous nfs exports table was deemed to be authoritative and a failed lookup meant a definite 'no'.”h]”hXvIf a cache has no active readers on the channel, and has had not active readers for more than 60 seconds, further requests will not be added to the channel but instead all lookups that do not find a valid entry will fail. This is partly for backward compatibility: The previous nfs exports table was deemed to be authoritative and a failed lookup meant a definite ‘no’.”…””}”(hjÖh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KÃhjÒubah}”(h]”h ]”h"]”h$]”h&]”uh1jÐhjÈh²hh³hÊh´Nubeh}”(h]”Œpopulating-a-cache”ah ]”h"]”Œpopulating a cache”ah$]”h&]”uh1hµhhÛh²hh³hÊh´Kubh¶)”}”(hhh]”(h»)”}”(hŒrequest/response format”h]”hŒrequest/response format”…””}”(hjõh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hºhjòh²hh³hÊh´KËubhÌ)”}”(hXáWhile each cache is free to use its own format for requests and responses over channel, the following is recommended as appropriate and support routines are available to help: Each request or response record should be printable ASCII with 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 they much be quoted. two mechanisms are available:”h]”hXáWhile each cache is free to use its own format for requests and responses over channel, the following is recommended as appropriate and support routines are available to help: Each request or response record should be printable ASCII with 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 they much be quoted. two mechanisms are available:”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KÍhjòh²hubj)”}”(hhh]”(j")”}”(hŒƒIf a field begins '\x' then it must contain an even number of hex digits, and pairs of these digits provide the bytes in the field.”h]”hÌ)”}”(hŒƒIf a field begins '\x' then it must contain an even number of hex digits, and pairs of these digits provide the bytes in the field.”h]”hŒ‡If a field begins ‘x’ then it must contain an even number of hex digits, and pairs of these digits provide the bytes in the field.”…””}”(hjh²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KÖhjubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjh²hh³hÊh´Nubj")”}”(hŒØotherwise a \ in the field must be followed by 3 octal digits which give the code for a byte. Other characters are treated as them selves. At the very least, space, newline, nul, and '\' must be quoted in this way.”h]”hÌ)”}”(hŒØotherwise a \ in the field must be followed by 3 octal digits which give the code for a byte. Other characters are treated as them selves. At the very least, space, newline, nul, and '\' must be quoted in this way.”h]”hŒÚotherwise a in the field must be followed by 3 octal digits which give the code for a byte. Other characters are treated as them selves. At the very least, space, newline, nul, and ‘' must be quoted in this way.”…””}”(hj0h²hh³Nh´Nubah}”(h]”h ]”h"]”h$]”h&]”uh1hËh³hÊh´KÙhj,ubah}”(h]”h ]”h"]”h$]”h&]”uh1j!hjh²hh³hÊh´Nubeh}”(h]”h ]”h"]”h$]”h&]”jŸj uh1jh³hÊh´KÖhjòh²hubeh}”(h]”Œrequest-response-format”ah ]”h"]”Œrequest/response format”ah$]”h&]”uh1hµhhÛh²hh³hÊh´KËubeh}”(h]”Œcaches”ah ]”h"]”Œcaches”ah$]”h&]”uh1hµhh·h²hh³hÊh´K ubeh}”(h]”Œ rpc-cache”ah ]”h"]”Œ rpc cache”ah$]”h&]”uh1hµhhh²hh³hÊh´Kubeh}”(h]”h ]”h"]”h$]”h&]”Œsource”hÊuh1hŒcurrent_source”NŒ current_line”NŒsettings”Œdocutils.frontend”ŒValues”“”)”}”(hºNŒ generator”NŒ datestamp”NŒ source_link”NŒ source_url”NŒ toc_backlinks”Œentry”Œfootnote_backlinks”KŒ sectnum_xform”KŒstrip_comments”NŒstrip_elements_with_classes”NŒ strip_classes”NŒ report_level”KŒ halt_level”KŒexit_status_level”KŒdebug”NŒwarning_stream”NŒ traceback”ˆŒinput_encoding”Œ utf-8-sig”Œinput_encoding_error_handler”Œstrict”Œoutput_encoding”Œutf-8”Œoutput_encoding_error_handler”j…Œerror_encoding”Œutf-8”Œerror_encoding_error_handler”Œbackslashreplace”Œ language_code”Œen”Œrecord_dependencies”NŒconfig”NŒ id_prefix”hŒauto_id_prefix”Œid”Œ dump_settings”NŒdump_internals”NŒdump_transforms”NŒdump_pseudo_xml”NŒexpose_internals”NŒstrict_visitor”NŒ_disable_config”NŒ_source”hÊŒ _destination”NŒ _config_files”]”Œ7/var/lib/git/docbuild/linux/Documentation/docutils.conf”aŒfile_insertion_enabled”ˆŒ raw_enabled”KŒline_length_limit”M'Œpep_references”NŒ pep_base_url”Œhttps://peps.python.org/”Œpep_file_url_template”Œpep-%04d”Œrfc_references”NŒ rfc_base_url”Œ&https://datatracker.ietf.org/doc/html/”Œ tab_width”KŒtrim_footnote_reference_space”‰Œsyntax_highlight”Œlong”Œ smart_quotes”ˆŒsmartquotes_locales”]”Œcharacter_level_inline_markup”‰Œdoctitle_xform”‰Œ docinfo_xform”KŒsectsubtitle_xform”‰Œ image_loading”Œlink”Œembed_stylesheet”‰Œcloak_email_addresses”ˆŒsection_self_link”‰Œenv”NubŒreporter”NŒindirect_targets”]”Œsubstitution_defs”}”Œsubstitution_names”}”Œrefnames”}”Œrefids”}”Œnameids”}”(j_j\jWjTjtjqjÅjÂjïjìjOjLuŒ nametypes”}”(j_‰jW‰jt‰jʼnjï‰jO‰uh}”(j\h·jThÛjqjljÂjwjìjÈjLjòuŒ footnote_refs”}”Œ citation_refs”}”Œ autofootnotes”]”Œautofootnote_refs”]”Œsymbol_footnotes”]”Œsymbol_footnote_refs”]”Œ footnotes”]”Œ citations”]”Œautofootnote_start”KŒsymbol_footnote_start”KŒ id_counter”Œ collections”ŒCounter”“”}”…”R”Œparse_messages”]”Œtransform_messages”]”Œ transformer”NŒ include_log”]”Œ decoration”Nh²hub.