fs/nfs/dir.c
Source file repositories/reference/linux-study-clean/fs/nfs/dir.c
File Facts
- System
- Linux kernel
- Corpus path
fs/nfs/dir.c- Extension
.c- Size
- 91026 bytes
- Lines
- 3432
- Domain
- Core OS
- Bucket
- VFS And Filesystem Core
- Inferred role
- Core OS: operation-table or driver-model contract
- Status
- pattern 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.
- Defines an operation table; this is where Linux turns generic core objects into subsystem-specific behavior.
- 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/compat.hlinux/module.hlinux/time.hlinux/errno.hlinux/stat.hlinux/fcntl.hlinux/string.hlinux/kernel.hlinux/slab.hlinux/mm.hlinux/sunrpc/clnt.hlinux/nfs_fs.hlinux/nfs_mount.hlinux/pagemap.hlinux/namei.hlinux/mount.hlinux/swap.hlinux/sched.hlinux/kmemleak.hlinux/xattr.hlinux/hash.hdelegation.hiostat.hinternal.hfscache.hnfstrace.h
Detected Declarations
struct nfs_cache_array_entrystruct nfs_cache_arraystruct nfs_readdir_descriptorfunction alloc_nfs_open_dir_contextfunction put_nfs_open_dir_contextfunction nfs_opendirfunction nfs_closedirfunction nfs_set_dtsizefunction nfs_shrink_dtsizefunction nfs_grow_dtsizefunction nfs_readdir_folio_init_arrayfunction nfs_add_to_readdir_arrayfunction nfs_readdir_folio_reinit_arrayfunction nfs_readdir_folio_array_allocfunction nfs_readdir_folio_array_freefunction nfs_readdir_array_index_cookiefunction nfs_readdir_array_set_eoffunction nfs_readdir_array_is_fullfunction nfs_clear_readdir_arrayfunction nfs_readdir_array_maxentriesfunction nfs_readdir_array_can_expandfunction nfs_readdir_folio_array_appendfunction nfs_readdir_folio_cookie_hashfunction nfs_readdir_folio_validatefunction nfs_readdir_folio_unlock_and_putfunction nfs_readdir_folio_init_and_validatefunction nfs_readdir_folio_last_cookiefunction nfs_readdir_folio_needs_fillingfunction nfs_readdir_folio_set_eoffunction is_32bit_apifunction nfs_readdir_use_cookiefunction nfs_readdir_seek_next_arrayfunction nfs_readdir_rewind_searchfunction nfs_readdir_search_for_posfunction nfs_readdir_array_cookie_in_rangefunction nfs_readdir_search_for_cookiefunction nfs_readdir_search_arrayfunction nfs_readdir_xdr_fillerfunction xdr_decodefunction nfs_same_filefunction nfs_use_readdirplusfunction nfs_readdir_record_entry_cache_hitfunction nfs_getattrfunction nfs_lookup_advise_force_readdirplusfunction nfs_prime_dcachefunction nfs_readdir_entry_decodefunction nfs_readdir_folio_fillerfunction nfs_readdir_free_pages
Annotated Snippet
const struct file_operations nfs_dir_operations = {
.llseek = nfs_llseek_dir,
.read = generic_read_dir,
.iterate_shared = nfs_readdir,
.open = nfs_opendir,
.release = nfs_closedir,
.fsync = nfs_fsync_dir,
};
const struct address_space_operations nfs_dir_aops = {
.free_folio = nfs_readdir_clear_array,
};
#define NFS_INIT_DTSIZE SZ_64K
static struct nfs_open_dir_context *
alloc_nfs_open_dir_context(struct inode *dir)
{
struct nfs_inode *nfsi = NFS_I(dir);
struct nfs_open_dir_context *ctx;
ctx = kzalloc_obj(*ctx, GFP_KERNEL_ACCOUNT);
if (ctx != NULL) {
ctx->attr_gencount = nfsi->attr_gencount;
ctx->dtsize = min(NFS_SERVER(dir)->dtsize, NFS_INIT_DTSIZE);
spin_lock(&dir->i_lock);
if (list_empty(&nfsi->open_files) &&
(nfsi->cache_validity & NFS_INO_DATA_INVAL_DEFER))
nfs_set_cache_invalid(dir,
NFS_INO_INVALID_DATA |
NFS_INO_REVAL_FORCED);
list_add_tail_rcu(&ctx->list, &nfsi->open_files);
memcpy(ctx->verf, nfsi->cookieverf, sizeof(ctx->verf));
spin_unlock(&dir->i_lock);
return ctx;
}
return ERR_PTR(-ENOMEM);
}
static void put_nfs_open_dir_context(struct inode *dir, struct nfs_open_dir_context *ctx)
{
spin_lock(&dir->i_lock);
list_del_rcu(&ctx->list);
spin_unlock(&dir->i_lock);
kfree_rcu(ctx, rcu_head);
}
/*
* Open file
*/
static int
nfs_opendir(struct inode *inode, struct file *filp)
{
int res = 0;
struct nfs_open_dir_context *ctx;
dfprintk(FILE, "NFS: open dir(%pD2)\n", filp);
nfs_inc_stats(inode, NFSIOS_VFSOPEN);
ctx = alloc_nfs_open_dir_context(inode);
if (IS_ERR(ctx)) {
res = PTR_ERR(ctx);
goto out;
}
filp->private_data = ctx;
out:
return res;
}
static int
nfs_closedir(struct inode *inode, struct file *filp)
{
put_nfs_open_dir_context(file_inode(filp), filp->private_data);
return 0;
}
struct nfs_cache_array_entry {
u64 cookie;
u64 ino;
const char *name;
unsigned int name_len;
unsigned char d_type;
};
struct nfs_cache_array {
u64 change_attr;
u64 last_cookie;
unsigned int size;
unsigned char folio_full : 1,
Annotation
- Immediate include surface: `linux/compat.h`, `linux/module.h`, `linux/time.h`, `linux/errno.h`, `linux/stat.h`, `linux/fcntl.h`, `linux/string.h`, `linux/kernel.h`.
- Detected declarations: `struct nfs_cache_array_entry`, `struct nfs_cache_array`, `struct nfs_readdir_descriptor`, `function alloc_nfs_open_dir_context`, `function put_nfs_open_dir_context`, `function nfs_opendir`, `function nfs_closedir`, `function nfs_set_dtsize`, `function nfs_shrink_dtsize`, `function nfs_grow_dtsize`.
- Atlas domain: Core OS / VFS And Filesystem Core.
- Implementation status: pattern 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.