fs/nfsd/nfscache.c
Source file repositories/reference/linux-study-clean/fs/nfsd/nfscache.c
File Facts
- System
- Linux kernel
- Corpus path
fs/nfsd/nfscache.c- Extension
.c- Size
- 18784 bytes
- Lines
- 668
- Domain
- Core OS
- Bucket
- VFS And Filesystem Core
- Inferred role
- Core OS: implementation source
- Status
- source implementation candidate
Why This File Exists
Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.
- Uses kernel synchronization; read lock ordering, sleepability, and interrupt context assumptions before translating.
- Allocates kernel memory; connect allocation flags and lifetime to context constraints.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
linux/sunrpc/svc_xprt.hlinux/slab.hlinux/vmalloc.hlinux/sunrpc/addr.hlinux/highmem.hlinux/log2.hlinux/hash.hnet/checksum.hnfsd.hcache.htrace.h
Detected Declarations
struct nfsd_drc_bucketfunction nfsd_cache_size_limitfunction nfsd_hashsizefunction nfsd_cacherep_allocfunction nfsd_cacherep_freefunction nfsd_cacherep_disposefunction nfsd_cacherep_unlink_lockedfunction nfsd_reply_cache_free_lockedfunction nfsd_reply_cache_freefunction nfsd_drc_slab_createfunction nfsd_drc_slab_freefunction nfsd_reply_cache_initfunction nfsd_reply_cache_shutdownfunction lru_put_endfunction nfsd_cache_bucket_findfunction nfsd_prune_bucket_lockedfunction cachefunction nfsd_reply_cache_scanfunction nfsd_cache_csumfunction nfsd_cache_key_cmpfunction nfsd_cache_insertfunction nfsd_cache_lookupfunction bytesfunction nfsd_cache_appendfunction nfsd_reply_cache_stats_show
Annotated Snippet
struct nfsd_drc_bucket {
struct rb_root rb_head;
struct list_head lru_head;
spinlock_t cache_lock;
};
static struct kmem_cache *drc_slab;
static int nfsd_cache_append(struct svc_rqst *rqstp, struct kvec *vec);
static unsigned long nfsd_reply_cache_count(struct shrinker *shrink,
struct shrink_control *sc);
static unsigned long nfsd_reply_cache_scan(struct shrinker *shrink,
struct shrink_control *sc);
/*
* Put a cap on the size of the DRC based on the amount of available
* low memory in the machine.
*
* 64MB: 8192
* 128MB: 11585
* 256MB: 16384
* 512MB: 23170
* 1GB: 32768
* 2GB: 46340
* 4GB: 65536
* 8GB: 92681
* 16GB: 131072
*
* ...with a hard cap of 256k entries. In the worst case, each entry will be
* ~1k, so the above numbers should give a rough max of the amount of memory
* used in k.
*
* XXX: these limits are per-container, so memory used will increase
* linearly with number of containers. Maybe that's OK.
*/
static unsigned int
nfsd_cache_size_limit(void)
{
unsigned int limit;
unsigned long low_pages = totalram_pages() - totalhigh_pages();
limit = (16 * int_sqrt(low_pages)) << (PAGE_SHIFT-10);
return min_t(unsigned int, limit, 256*1024);
}
/*
* Compute the number of hash buckets we need. Divide the max cachesize by
* the "target" max bucket size, and round up to next power of two.
*/
static unsigned int
nfsd_hashsize(unsigned int limit)
{
return roundup_pow_of_two(limit / TARGET_BUCKET_SIZE);
}
static struct nfsd_cacherep *
nfsd_cacherep_alloc(struct svc_rqst *rqstp, __wsum csum,
struct nfsd_net *nn)
{
struct nfsd_cacherep *rp;
rp = kmem_cache_alloc(drc_slab, GFP_KERNEL);
if (rp) {
rp->c_state = RC_UNUSED;
rp->c_type = RC_NOCACHE;
RB_CLEAR_NODE(&rp->c_node);
INIT_LIST_HEAD(&rp->c_lru);
memset(&rp->c_key, 0, sizeof(rp->c_key));
rp->c_key.k_xid = rqstp->rq_xid;
rp->c_key.k_proc = rqstp->rq_proc;
rpc_copy_addr((struct sockaddr *)&rp->c_key.k_addr, svc_addr(rqstp));
rpc_set_port((struct sockaddr *)&rp->c_key.k_addr, rpc_get_port(svc_addr(rqstp)));
rp->c_key.k_prot = rqstp->rq_prot;
rp->c_key.k_vers = rqstp->rq_vers;
rp->c_key.k_len = rqstp->rq_arg.len;
rp->c_key.k_csum = csum;
}
return rp;
}
static void nfsd_cacherep_free(struct nfsd_cacherep *rp)
{
if (rp->c_type == RC_REPLBUFF)
kfree(rp->c_replvec.iov_base);
kmem_cache_free(drc_slab, rp);
}
static unsigned long
nfsd_cacherep_dispose(struct list_head *dispose)
Annotation
- Immediate include surface: `linux/sunrpc/svc_xprt.h`, `linux/slab.h`, `linux/vmalloc.h`, `linux/sunrpc/addr.h`, `linux/highmem.h`, `linux/log2.h`, `linux/hash.h`, `net/checksum.h`.
- Detected declarations: `struct nfsd_drc_bucket`, `function nfsd_cache_size_limit`, `function nfsd_hashsize`, `function nfsd_cacherep_alloc`, `function nfsd_cacherep_free`, `function nfsd_cacherep_dispose`, `function nfsd_cacherep_unlink_locked`, `function nfsd_reply_cache_free_locked`, `function nfsd_reply_cache_free`, `function nfsd_drc_slab_create`.
- Atlas domain: Core OS / VFS And Filesystem Core.
- Implementation status: source implementation candidate.
- Synchronization appears in or near this file; preserve lock ordering, sleepability, and interrupt-context constraints.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.