fs/overlayfs/util.c

Source file repositories/reference/linux-study-clean/fs/overlayfs/util.c

File Facts

System
Linux kernel
Corpus path
fs/overlayfs/util.c
Extension
.c
Size
38587 bytes
Lines
1519
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.

Dependency Surface

Detected Declarations

Annotated Snippet

if (ovl_numlower(oe)) {
			if (ovl_test_flag(OVL_CONST_INO, d_inode(dentry)))
				type |= __OVL_PATH_ORIGIN;
			if (d_is_dir(dentry) ||
			    !ovl_has_upperdata(d_inode(dentry)))
				type |= __OVL_PATH_MERGE;
		}
	} else {
		if (ovl_numlower(oe) > 1)
			type |= __OVL_PATH_MERGE;
	}
	return type;
}

void ovl_path_upper(struct dentry *dentry, struct path *path)
{
	struct ovl_fs *ofs = OVL_FS(dentry->d_sb);

	path->mnt = ovl_upper_mnt(ofs);
	path->dentry = ovl_dentry_upper(dentry);
}

void ovl_path_lower(struct dentry *dentry, struct path *path)
{
	struct ovl_entry *oe = OVL_E(dentry);
	struct ovl_path *lowerpath = ovl_lowerstack(oe);

	if (ovl_numlower(oe)) {
		path->mnt = lowerpath->layer->mnt;
		path->dentry = lowerpath->dentry;
	} else {
		*path = (struct path) { };
	}
}

void ovl_path_lowerdata(struct dentry *dentry, struct path *path)
{
	struct ovl_entry *oe = OVL_E(dentry);
	struct ovl_path *lowerdata = ovl_lowerdata(oe);
	struct dentry *lowerdata_dentry = ovl_lowerdata_dentry(oe);

	if (lowerdata_dentry) {
		path->dentry = lowerdata_dentry;
		/*
		 * Pairs with smp_wmb() in ovl_dentry_set_lowerdata().
		 * Make sure that if lowerdata->dentry is visible, then
		 * datapath->layer is visible as well.
		 */
		smp_rmb();
		path->mnt = READ_ONCE(lowerdata->layer)->mnt;
	} else {
		*path = (struct path) { };
	}
}

enum ovl_path_type ovl_path_real(struct dentry *dentry, struct path *path)
{
	enum ovl_path_type type = ovl_path_type(dentry);

	if (!OVL_TYPE_UPPER(type))
		ovl_path_lower(dentry, path);
	else
		ovl_path_upper(dentry, path);

	return type;
}

enum ovl_path_type ovl_path_realdata(struct dentry *dentry, struct path *path)
{
	enum ovl_path_type type = ovl_path_type(dentry);

	WARN_ON_ONCE(d_is_dir(dentry));

	if (!OVL_TYPE_UPPER(type) || OVL_TYPE_MERGE(type))
		ovl_path_lowerdata(dentry, path);
	else
		ovl_path_upper(dentry, path);

	return type;
}

struct dentry *ovl_dentry_upper(struct dentry *dentry)
{
	struct inode *inode = d_inode(dentry);

	return inode ? ovl_upperdentry_dereference(OVL_I(inode)) : NULL;
}

struct dentry *ovl_dentry_lower(struct dentry *dentry)
{

Annotation

Implementation Notes