fs/overlayfs/readdir.c
Source file repositories/reference/linux-study-clean/fs/overlayfs/readdir.c
File Facts
- System
- Linux kernel
- Corpus path
fs/overlayfs/readdir.c- Extension
.c- Size
- 30619 bytes
- Lines
- 1327
- 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.
- 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/fs.hlinux/slab.hlinux/namei.hlinux/file.hlinux/filelock.hlinux/xattr.hlinux/rbtree.hlinux/security.hlinux/cred.hlinux/ratelimit.hlinux/overflow.hoverlayfs.h
Detected Declarations
struct ovl_cache_entrystruct ovl_dir_cachestruct ovl_readdir_datastruct ovl_dir_filestruct ovl_readdir_translatefunction ovl_casefoldfunction ovl_cache_entry_find_linkfunction ovl_calc_d_inofunction ovl_cache_entry_add_rbfunction ovl_fill_lowestfunction ovl_cache_entry_freefunction ovl_cache_freefunction ovl_dir_cache_freefunction ovl_cache_putfunction ovl_fill_mergefunction ovl_check_whiteoutsfunction ovl_dir_readfunction ovl_dir_resetfunction ovl_dir_read_mergedfunction ovl_seek_cursorfunction list_for_eachfunction ovl_remap_lower_inofunction statfunction ovl_fill_plainfunction ovl_dir_read_impurefunction list_for_each_entry_safefunction ovl_fill_realfunction ovl_is_impure_dirfunction ovl_iterate_realfunction ovl_iterate_mergedfunction ovl_need_adjust_d_inofunction ovl_iteratefunction with_ovl_credsfunction ovl_dir_llseekfunction ovl_real_fdgetfunction ovl_dir_fsyncfunction ovl_dir_releasefunction ovl_dir_openfunction ovl_check_empty_dirfunction list_for_each_entry_safefunction ovl_cleanup_whiteoutsfunction list_for_each_entryfunction ovl_check_d_typefunction ovl_check_d_type_supportedfunction ovl_workdir_cleanup_recursefunction list_for_each_entryfunction ovl_workdir_cleanupfunction ovl_indexdir_cleanup
Annotated Snippet
const struct file_operations ovl_dir_operations = {
.read = generic_read_dir,
.open = ovl_dir_open,
.iterate_shared = shared_ovl_iterate,
.llseek = ovl_dir_llseek,
.fsync = ovl_dir_fsync,
.release = ovl_dir_release,
.setlease = generic_setlease,
};
int ovl_check_empty_dir(struct dentry *dentry, struct list_head *list)
{
int err;
struct ovl_cache_entry *p, *n;
struct rb_root root = RB_ROOT;
with_ovl_creds(dentry->d_sb)
err = ovl_dir_read_merged(dentry, list, &root);
if (err)
return err;
err = 0;
list_for_each_entry_safe(p, n, list, l_node) {
/*
* Select whiteouts in upperdir, they should
* be cleared when deleting this directory.
*/
if (p->is_whiteout) {
if (p->is_upper)
continue;
goto del_entry;
}
if (name_is_dot_dotdot(p->name, p->len))
goto del_entry;
err = -ENOTEMPTY;
break;
del_entry:
list_del(&p->l_node);
ovl_cache_entry_free(p);
}
return err;
}
void ovl_cleanup_whiteouts(struct ovl_fs *ofs, struct dentry *upper,
struct list_head *list)
{
struct ovl_cache_entry *p;
list_for_each_entry(p, list, l_node) {
struct dentry *dentry;
if (WARN_ON(!p->is_whiteout || !p->is_upper))
continue;
dentry = ovl_lookup_upper_unlocked(ofs, p->name, upper, p->len);
if (IS_ERR(dentry)) {
pr_err("lookup '%s/%.*s' failed (%i)\n",
upper->d_name.name, p->len, p->name,
(int) PTR_ERR(dentry));
continue;
}
if (dentry->d_inode)
ovl_cleanup(ofs, upper, dentry);
dput(dentry);
}
}
static bool ovl_check_d_type(struct dir_context *ctx, const char *name,
int namelen, loff_t offset, u64 ino,
unsigned int d_type)
{
struct ovl_readdir_data *rdd =
container_of(ctx, struct ovl_readdir_data, ctx);
/* Even if d_type is not supported, DT_DIR is returned for . and .. */
if (name_is_dot_dotdot(name, namelen))
return true;
if (d_type != DT_UNKNOWN)
rdd->d_type_supported = true;
return true;
}
/*
* Returns 1 if d_type is supported, 0 not supported/unknown. Negative values
Annotation
- Immediate include surface: `linux/fs.h`, `linux/slab.h`, `linux/namei.h`, `linux/file.h`, `linux/filelock.h`, `linux/xattr.h`, `linux/rbtree.h`, `linux/security.h`.
- Detected declarations: `struct ovl_cache_entry`, `struct ovl_dir_cache`, `struct ovl_readdir_data`, `struct ovl_dir_file`, `struct ovl_readdir_translate`, `function ovl_casefold`, `function ovl_cache_entry_find_link`, `function ovl_calc_d_ino`, `function ovl_cache_entry_add_rb`, `function ovl_fill_lowest`.
- Atlas domain: Core OS / VFS And Filesystem Core.
- Implementation status: pattern implementation candidate.
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.