162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci#ifndef __LINUX_DCACHE_H
362306a36Sopenharmony_ci#define __LINUX_DCACHE_H
462306a36Sopenharmony_ci
562306a36Sopenharmony_ci#include <linux/atomic.h>
662306a36Sopenharmony_ci#include <linux/list.h>
762306a36Sopenharmony_ci#include <linux/math.h>
862306a36Sopenharmony_ci#include <linux/rculist.h>
962306a36Sopenharmony_ci#include <linux/rculist_bl.h>
1062306a36Sopenharmony_ci#include <linux/spinlock.h>
1162306a36Sopenharmony_ci#include <linux/seqlock.h>
1262306a36Sopenharmony_ci#include <linux/cache.h>
1362306a36Sopenharmony_ci#include <linux/rcupdate.h>
1462306a36Sopenharmony_ci#include <linux/lockref.h>
1562306a36Sopenharmony_ci#include <linux/stringhash.h>
1662306a36Sopenharmony_ci#include <linux/wait.h>
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_cistruct path;
1962306a36Sopenharmony_cistruct file;
2062306a36Sopenharmony_cistruct vfsmount;
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci/*
2362306a36Sopenharmony_ci * linux/include/linux/dcache.h
2462306a36Sopenharmony_ci *
2562306a36Sopenharmony_ci * Dirent cache data structures
2662306a36Sopenharmony_ci *
2762306a36Sopenharmony_ci * (C) Copyright 1997 Thomas Schoebel-Theuer,
2862306a36Sopenharmony_ci * with heavy changes by Linus Torvalds
2962306a36Sopenharmony_ci */
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_ci#define IS_ROOT(x) ((x) == (x)->d_parent)
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci/* The hash is always the low bits of hash_len */
3462306a36Sopenharmony_ci#ifdef __LITTLE_ENDIAN
3562306a36Sopenharmony_ci #define HASH_LEN_DECLARE u32 hash; u32 len
3662306a36Sopenharmony_ci #define bytemask_from_count(cnt)	(~(~0ul << (cnt)*8))
3762306a36Sopenharmony_ci#else
3862306a36Sopenharmony_ci #define HASH_LEN_DECLARE u32 len; u32 hash
3962306a36Sopenharmony_ci #define bytemask_from_count(cnt)	(~(~0ul >> (cnt)*8))
4062306a36Sopenharmony_ci#endif
4162306a36Sopenharmony_ci
4262306a36Sopenharmony_ci/*
4362306a36Sopenharmony_ci * "quick string" -- eases parameter passing, but more importantly
4462306a36Sopenharmony_ci * saves "metadata" about the string (ie length and the hash).
4562306a36Sopenharmony_ci *
4662306a36Sopenharmony_ci * hash comes first so it snuggles against d_parent in the
4762306a36Sopenharmony_ci * dentry.
4862306a36Sopenharmony_ci */
4962306a36Sopenharmony_cistruct qstr {
5062306a36Sopenharmony_ci	union {
5162306a36Sopenharmony_ci		struct {
5262306a36Sopenharmony_ci			HASH_LEN_DECLARE;
5362306a36Sopenharmony_ci		};
5462306a36Sopenharmony_ci		u64 hash_len;
5562306a36Sopenharmony_ci	};
5662306a36Sopenharmony_ci	const unsigned char *name;
5762306a36Sopenharmony_ci};
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci#define QSTR_INIT(n,l) { { { .len = l } }, .name = n }
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ciextern const struct qstr empty_name;
6262306a36Sopenharmony_ciextern const struct qstr slash_name;
6362306a36Sopenharmony_ciextern const struct qstr dotdot_name;
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci/*
6662306a36Sopenharmony_ci * Try to keep struct dentry aligned on 64 byte cachelines (this will
6762306a36Sopenharmony_ci * give reasonable cacheline footprint with larger lines without the
6862306a36Sopenharmony_ci * large memory footprint increase).
6962306a36Sopenharmony_ci */
7062306a36Sopenharmony_ci#ifdef CONFIG_64BIT
7162306a36Sopenharmony_ci# define DNAME_INLINE_LEN 32 /* 192 bytes */
7262306a36Sopenharmony_ci#else
7362306a36Sopenharmony_ci# ifdef CONFIG_SMP
7462306a36Sopenharmony_ci#  define DNAME_INLINE_LEN 36 /* 128 bytes */
7562306a36Sopenharmony_ci# else
7662306a36Sopenharmony_ci#  define DNAME_INLINE_LEN 40 /* 128 bytes */
7762306a36Sopenharmony_ci# endif
7862306a36Sopenharmony_ci#endif
7962306a36Sopenharmony_ci
8062306a36Sopenharmony_ci#define d_lock	d_lockref.lock
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_cistruct dentry {
8362306a36Sopenharmony_ci	/* RCU lookup touched fields */
8462306a36Sopenharmony_ci	unsigned int d_flags;		/* protected by d_lock */
8562306a36Sopenharmony_ci	seqcount_spinlock_t d_seq;	/* per dentry seqlock */
8662306a36Sopenharmony_ci	struct hlist_bl_node d_hash;	/* lookup hash list */
8762306a36Sopenharmony_ci	struct dentry *d_parent;	/* parent directory */
8862306a36Sopenharmony_ci	struct qstr d_name;
8962306a36Sopenharmony_ci	struct inode *d_inode;		/* Where the name belongs to - NULL is
9062306a36Sopenharmony_ci					 * negative */
9162306a36Sopenharmony_ci	unsigned char d_iname[DNAME_INLINE_LEN];	/* small names */
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci	/* Ref lookup also touches following */
9462306a36Sopenharmony_ci	struct lockref d_lockref;	/* per-dentry lock and refcount */
9562306a36Sopenharmony_ci	const struct dentry_operations *d_op;
9662306a36Sopenharmony_ci	struct super_block *d_sb;	/* The root of the dentry tree */
9762306a36Sopenharmony_ci	unsigned long d_time;		/* used by d_revalidate */
9862306a36Sopenharmony_ci	void *d_fsdata;			/* fs-specific data */
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ci	union {
10162306a36Sopenharmony_ci		struct list_head d_lru;		/* LRU list */
10262306a36Sopenharmony_ci		wait_queue_head_t *d_wait;	/* in-lookup ones only */
10362306a36Sopenharmony_ci	};
10462306a36Sopenharmony_ci	struct list_head d_child;	/* child of parent list */
10562306a36Sopenharmony_ci	struct list_head d_subdirs;	/* our children */
10662306a36Sopenharmony_ci	/*
10762306a36Sopenharmony_ci	 * d_alias and d_rcu can share memory
10862306a36Sopenharmony_ci	 */
10962306a36Sopenharmony_ci	union {
11062306a36Sopenharmony_ci		struct hlist_node d_alias;	/* inode alias list */
11162306a36Sopenharmony_ci		struct hlist_bl_node d_in_lookup_hash;	/* only for in-lookup ones */
11262306a36Sopenharmony_ci	 	struct rcu_head d_rcu;
11362306a36Sopenharmony_ci	} d_u;
11462306a36Sopenharmony_ci} __randomize_layout;
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci/*
11762306a36Sopenharmony_ci * dentry->d_lock spinlock nesting subclasses:
11862306a36Sopenharmony_ci *
11962306a36Sopenharmony_ci * 0: normal
12062306a36Sopenharmony_ci * 1: nested
12162306a36Sopenharmony_ci */
12262306a36Sopenharmony_cienum dentry_d_lock_class
12362306a36Sopenharmony_ci{
12462306a36Sopenharmony_ci	DENTRY_D_LOCK_NORMAL, /* implicitly used by plain spin_lock() APIs. */
12562306a36Sopenharmony_ci	DENTRY_D_LOCK_NESTED
12662306a36Sopenharmony_ci};
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_cistruct dentry_operations {
12962306a36Sopenharmony_ci	int (*d_revalidate)(struct dentry *, unsigned int);
13062306a36Sopenharmony_ci	int (*d_weak_revalidate)(struct dentry *, unsigned int);
13162306a36Sopenharmony_ci	int (*d_hash)(const struct dentry *, struct qstr *);
13262306a36Sopenharmony_ci	int (*d_compare)(const struct dentry *,
13362306a36Sopenharmony_ci			unsigned int, const char *, const struct qstr *);
13462306a36Sopenharmony_ci	int (*d_delete)(const struct dentry *);
13562306a36Sopenharmony_ci	int (*d_init)(struct dentry *);
13662306a36Sopenharmony_ci	void (*d_release)(struct dentry *);
13762306a36Sopenharmony_ci	void (*d_prune)(struct dentry *);
13862306a36Sopenharmony_ci	void (*d_iput)(struct dentry *, struct inode *);
13962306a36Sopenharmony_ci	char *(*d_dname)(struct dentry *, char *, int);
14062306a36Sopenharmony_ci	struct vfsmount *(*d_automount)(struct path *);
14162306a36Sopenharmony_ci	int (*d_manage)(const struct path *, bool);
14262306a36Sopenharmony_ci	struct dentry *(*d_real)(struct dentry *, const struct inode *);
14362306a36Sopenharmony_ci} ____cacheline_aligned;
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci/*
14662306a36Sopenharmony_ci * Locking rules for dentry_operations callbacks are to be found in
14762306a36Sopenharmony_ci * Documentation/filesystems/locking.rst. Keep it updated!
14862306a36Sopenharmony_ci *
14962306a36Sopenharmony_ci * FUrther descriptions are found in Documentation/filesystems/vfs.rst.
15062306a36Sopenharmony_ci * Keep it updated too!
15162306a36Sopenharmony_ci */
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci/* d_flags entries */
15462306a36Sopenharmony_ci#define DCACHE_OP_HASH			0x00000001
15562306a36Sopenharmony_ci#define DCACHE_OP_COMPARE		0x00000002
15662306a36Sopenharmony_ci#define DCACHE_OP_REVALIDATE		0x00000004
15762306a36Sopenharmony_ci#define DCACHE_OP_DELETE		0x00000008
15862306a36Sopenharmony_ci#define DCACHE_OP_PRUNE			0x00000010
15962306a36Sopenharmony_ci
16062306a36Sopenharmony_ci#define	DCACHE_DISCONNECTED		0x00000020
16162306a36Sopenharmony_ci     /* This dentry is possibly not currently connected to the dcache tree, in
16262306a36Sopenharmony_ci      * which case its parent will either be itself, or will have this flag as
16362306a36Sopenharmony_ci      * well.  nfsd will not use a dentry with this bit set, but will first
16462306a36Sopenharmony_ci      * endeavour to clear the bit either by discovering that it is connected,
16562306a36Sopenharmony_ci      * or by performing lookup operations.   Any filesystem which supports
16662306a36Sopenharmony_ci      * nfsd_operations MUST have a lookup function which, if it finds a
16762306a36Sopenharmony_ci      * directory inode with a DCACHE_DISCONNECTED dentry, will d_move that
16862306a36Sopenharmony_ci      * dentry into place and return that dentry rather than the passed one,
16962306a36Sopenharmony_ci      * typically using d_splice_alias. */
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci#define DCACHE_REFERENCED		0x00000040 /* Recently used, don't discard. */
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci#define DCACHE_DONTCACHE		0x00000080 /* Purge from memory on final dput() */
17462306a36Sopenharmony_ci
17562306a36Sopenharmony_ci#define DCACHE_CANT_MOUNT		0x00000100
17662306a36Sopenharmony_ci#define DCACHE_GENOCIDE			0x00000200
17762306a36Sopenharmony_ci#define DCACHE_SHRINK_LIST		0x00000400
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci#define DCACHE_OP_WEAK_REVALIDATE	0x00000800
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci#define DCACHE_NFSFS_RENAMED		0x00001000
18262306a36Sopenharmony_ci     /* this dentry has been "silly renamed" and has to be deleted on the last
18362306a36Sopenharmony_ci      * dput() */
18462306a36Sopenharmony_ci#define DCACHE_COOKIE			0x00002000 /* For use by dcookie subsystem */
18562306a36Sopenharmony_ci#define DCACHE_FSNOTIFY_PARENT_WATCHED	0x00004000
18662306a36Sopenharmony_ci     /* Parent inode is watched by some fsnotify listener */
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci#define DCACHE_DENTRY_KILLED		0x00008000
18962306a36Sopenharmony_ci
19062306a36Sopenharmony_ci#define DCACHE_MOUNTED			0x00010000 /* is a mountpoint */
19162306a36Sopenharmony_ci#define DCACHE_NEED_AUTOMOUNT		0x00020000 /* handle automount on this dir */
19262306a36Sopenharmony_ci#define DCACHE_MANAGE_TRANSIT		0x00040000 /* manage transit from this dirent */
19362306a36Sopenharmony_ci#define DCACHE_MANAGED_DENTRY \
19462306a36Sopenharmony_ci	(DCACHE_MOUNTED|DCACHE_NEED_AUTOMOUNT|DCACHE_MANAGE_TRANSIT)
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci#define DCACHE_LRU_LIST			0x00080000
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci#define DCACHE_ENTRY_TYPE		0x00700000
19962306a36Sopenharmony_ci#define DCACHE_MISS_TYPE		0x00000000 /* Negative dentry (maybe fallthru to nowhere) */
20062306a36Sopenharmony_ci#define DCACHE_WHITEOUT_TYPE		0x00100000 /* Whiteout dentry (stop pathwalk) */
20162306a36Sopenharmony_ci#define DCACHE_DIRECTORY_TYPE		0x00200000 /* Normal directory */
20262306a36Sopenharmony_ci#define DCACHE_AUTODIR_TYPE		0x00300000 /* Lookupless directory (presumed automount) */
20362306a36Sopenharmony_ci#define DCACHE_REGULAR_TYPE		0x00400000 /* Regular file type (or fallthru to such) */
20462306a36Sopenharmony_ci#define DCACHE_SPECIAL_TYPE		0x00500000 /* Other file type (or fallthru to such) */
20562306a36Sopenharmony_ci#define DCACHE_SYMLINK_TYPE		0x00600000 /* Symlink (or fallthru to such) */
20662306a36Sopenharmony_ci
20762306a36Sopenharmony_ci#define DCACHE_MAY_FREE			0x00800000
20862306a36Sopenharmony_ci#define DCACHE_FALLTHRU			0x01000000 /* Fall through to lower layer */
20962306a36Sopenharmony_ci#define DCACHE_NOKEY_NAME		0x02000000 /* Encrypted name encoded without key */
21062306a36Sopenharmony_ci#define DCACHE_OP_REAL			0x04000000
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci#define DCACHE_PAR_LOOKUP		0x10000000 /* being looked up (with parent locked shared) */
21362306a36Sopenharmony_ci#define DCACHE_DENTRY_CURSOR		0x20000000
21462306a36Sopenharmony_ci#define DCACHE_NORCU			0x40000000 /* No RCU delay for freeing */
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ciextern seqlock_t rename_lock;
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci/*
21962306a36Sopenharmony_ci * These are the low-level FS interfaces to the dcache..
22062306a36Sopenharmony_ci */
22162306a36Sopenharmony_ciextern void d_instantiate(struct dentry *, struct inode *);
22262306a36Sopenharmony_ciextern void d_instantiate_new(struct dentry *, struct inode *);
22362306a36Sopenharmony_ciextern struct dentry * d_instantiate_unique(struct dentry *, struct inode *);
22462306a36Sopenharmony_ciextern struct dentry * d_instantiate_anon(struct dentry *, struct inode *);
22562306a36Sopenharmony_ciextern void __d_drop(struct dentry *dentry);
22662306a36Sopenharmony_ciextern void d_drop(struct dentry *dentry);
22762306a36Sopenharmony_ciextern void d_delete(struct dentry *);
22862306a36Sopenharmony_ciextern void d_set_d_op(struct dentry *dentry, const struct dentry_operations *op);
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci/* allocate/de-allocate */
23162306a36Sopenharmony_ciextern struct dentry * d_alloc(struct dentry *, const struct qstr *);
23262306a36Sopenharmony_ciextern struct dentry * d_alloc_anon(struct super_block *);
23362306a36Sopenharmony_ciextern struct dentry * d_alloc_parallel(struct dentry *, const struct qstr *,
23462306a36Sopenharmony_ci					wait_queue_head_t *);
23562306a36Sopenharmony_ciextern struct dentry * d_splice_alias(struct inode *, struct dentry *);
23662306a36Sopenharmony_ciextern struct dentry * d_add_ci(struct dentry *, struct inode *, struct qstr *);
23762306a36Sopenharmony_ciextern bool d_same_name(const struct dentry *dentry, const struct dentry *parent,
23862306a36Sopenharmony_ci			const struct qstr *name);
23962306a36Sopenharmony_ciextern struct dentry * d_exact_alias(struct dentry *, struct inode *);
24062306a36Sopenharmony_ciextern struct dentry *d_find_any_alias(struct inode *inode);
24162306a36Sopenharmony_ciextern struct dentry * d_obtain_alias(struct inode *);
24262306a36Sopenharmony_ciextern struct dentry * d_obtain_root(struct inode *);
24362306a36Sopenharmony_ciextern void shrink_dcache_sb(struct super_block *);
24462306a36Sopenharmony_ciextern void shrink_dcache_parent(struct dentry *);
24562306a36Sopenharmony_ciextern void shrink_dcache_for_umount(struct super_block *);
24662306a36Sopenharmony_ciextern void d_invalidate(struct dentry *);
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci/* only used at mount-time */
24962306a36Sopenharmony_ciextern struct dentry * d_make_root(struct inode *);
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_ci/* <clickety>-<click> the ramfs-type tree */
25262306a36Sopenharmony_ciextern void d_genocide(struct dentry *);
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_ciextern void d_tmpfile(struct file *, struct inode *);
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_ciextern struct dentry *d_find_alias(struct inode *);
25762306a36Sopenharmony_ciextern void d_prune_aliases(struct inode *);
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ciextern struct dentry *d_find_alias_rcu(struct inode *);
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci/* test whether we have any submounts in a subdir tree */
26262306a36Sopenharmony_ciextern int path_has_submounts(const struct path *);
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_ci/*
26562306a36Sopenharmony_ci * This adds the entry to the hash queues.
26662306a36Sopenharmony_ci */
26762306a36Sopenharmony_ciextern void d_rehash(struct dentry *);
26862306a36Sopenharmony_ci
26962306a36Sopenharmony_ciextern void d_add(struct dentry *, struct inode *);
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_ci/* used for rename() and baskets */
27262306a36Sopenharmony_ciextern void d_move(struct dentry *, struct dentry *);
27362306a36Sopenharmony_ciextern void d_exchange(struct dentry *, struct dentry *);
27462306a36Sopenharmony_ciextern struct dentry *d_ancestor(struct dentry *, struct dentry *);
27562306a36Sopenharmony_ci
27662306a36Sopenharmony_ci/* appendix may either be NULL or be used for transname suffixes */
27762306a36Sopenharmony_ciextern struct dentry *d_lookup(const struct dentry *, const struct qstr *);
27862306a36Sopenharmony_ciextern struct dentry *d_hash_and_lookup(struct dentry *, struct qstr *);
27962306a36Sopenharmony_ciextern struct dentry *__d_lookup(const struct dentry *, const struct qstr *);
28062306a36Sopenharmony_ciextern struct dentry *__d_lookup_rcu(const struct dentry *parent,
28162306a36Sopenharmony_ci				const struct qstr *name, unsigned *seq);
28262306a36Sopenharmony_ci
28362306a36Sopenharmony_cistatic inline unsigned d_count(const struct dentry *dentry)
28462306a36Sopenharmony_ci{
28562306a36Sopenharmony_ci	return dentry->d_lockref.count;
28662306a36Sopenharmony_ci}
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci/*
28962306a36Sopenharmony_ci * helper function for dentry_operations.d_dname() members
29062306a36Sopenharmony_ci */
29162306a36Sopenharmony_ciextern __printf(3, 4)
29262306a36Sopenharmony_cichar *dynamic_dname(char *, int, const char *, ...);
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_ciextern char *__d_path(const struct path *, const struct path *, char *, int);
29562306a36Sopenharmony_ciextern char *d_absolute_path(const struct path *, char *, int);
29662306a36Sopenharmony_ciextern char *d_path(const struct path *, char *, int);
29762306a36Sopenharmony_ciextern char *dentry_path_raw(const struct dentry *, char *, int);
29862306a36Sopenharmony_ciextern char *dentry_path(const struct dentry *, char *, int);
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci/* Allocation counts.. */
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci/**
30362306a36Sopenharmony_ci *	dget, dget_dlock -	get a reference to a dentry
30462306a36Sopenharmony_ci *	@dentry: dentry to get a reference to
30562306a36Sopenharmony_ci *
30662306a36Sopenharmony_ci *	Given a dentry or %NULL pointer increment the reference count
30762306a36Sopenharmony_ci *	if appropriate and return the dentry. A dentry will not be
30862306a36Sopenharmony_ci *	destroyed when it has references.
30962306a36Sopenharmony_ci */
31062306a36Sopenharmony_cistatic inline struct dentry *dget_dlock(struct dentry *dentry)
31162306a36Sopenharmony_ci{
31262306a36Sopenharmony_ci	if (dentry)
31362306a36Sopenharmony_ci		dentry->d_lockref.count++;
31462306a36Sopenharmony_ci	return dentry;
31562306a36Sopenharmony_ci}
31662306a36Sopenharmony_ci
31762306a36Sopenharmony_cistatic inline struct dentry *dget(struct dentry *dentry)
31862306a36Sopenharmony_ci{
31962306a36Sopenharmony_ci	if (dentry)
32062306a36Sopenharmony_ci		lockref_get(&dentry->d_lockref);
32162306a36Sopenharmony_ci	return dentry;
32262306a36Sopenharmony_ci}
32362306a36Sopenharmony_ci
32462306a36Sopenharmony_ciextern struct dentry *dget_parent(struct dentry *dentry);
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_ci/**
32762306a36Sopenharmony_ci *	d_unhashed -	is dentry hashed
32862306a36Sopenharmony_ci *	@dentry: entry to check
32962306a36Sopenharmony_ci *
33062306a36Sopenharmony_ci *	Returns true if the dentry passed is not currently hashed.
33162306a36Sopenharmony_ci */
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_cistatic inline int d_unhashed(const struct dentry *dentry)
33462306a36Sopenharmony_ci{
33562306a36Sopenharmony_ci	return hlist_bl_unhashed(&dentry->d_hash);
33662306a36Sopenharmony_ci}
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_cistatic inline int d_unlinked(const struct dentry *dentry)
33962306a36Sopenharmony_ci{
34062306a36Sopenharmony_ci	return d_unhashed(dentry) && !IS_ROOT(dentry);
34162306a36Sopenharmony_ci}
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_cistatic inline int cant_mount(const struct dentry *dentry)
34462306a36Sopenharmony_ci{
34562306a36Sopenharmony_ci	return (dentry->d_flags & DCACHE_CANT_MOUNT);
34662306a36Sopenharmony_ci}
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_cistatic inline void dont_mount(struct dentry *dentry)
34962306a36Sopenharmony_ci{
35062306a36Sopenharmony_ci	spin_lock(&dentry->d_lock);
35162306a36Sopenharmony_ci	dentry->d_flags |= DCACHE_CANT_MOUNT;
35262306a36Sopenharmony_ci	spin_unlock(&dentry->d_lock);
35362306a36Sopenharmony_ci}
35462306a36Sopenharmony_ci
35562306a36Sopenharmony_ciextern void __d_lookup_unhash_wake(struct dentry *dentry);
35662306a36Sopenharmony_ci
35762306a36Sopenharmony_cistatic inline int d_in_lookup(const struct dentry *dentry)
35862306a36Sopenharmony_ci{
35962306a36Sopenharmony_ci	return dentry->d_flags & DCACHE_PAR_LOOKUP;
36062306a36Sopenharmony_ci}
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_cistatic inline void d_lookup_done(struct dentry *dentry)
36362306a36Sopenharmony_ci{
36462306a36Sopenharmony_ci	if (unlikely(d_in_lookup(dentry)))
36562306a36Sopenharmony_ci		__d_lookup_unhash_wake(dentry);
36662306a36Sopenharmony_ci}
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_ciextern void dput(struct dentry *);
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_cistatic inline bool d_managed(const struct dentry *dentry)
37162306a36Sopenharmony_ci{
37262306a36Sopenharmony_ci	return dentry->d_flags & DCACHE_MANAGED_DENTRY;
37362306a36Sopenharmony_ci}
37462306a36Sopenharmony_ci
37562306a36Sopenharmony_cistatic inline bool d_mountpoint(const struct dentry *dentry)
37662306a36Sopenharmony_ci{
37762306a36Sopenharmony_ci	return dentry->d_flags & DCACHE_MOUNTED;
37862306a36Sopenharmony_ci}
37962306a36Sopenharmony_ci
38062306a36Sopenharmony_ci/*
38162306a36Sopenharmony_ci * Directory cache entry type accessor functions.
38262306a36Sopenharmony_ci */
38362306a36Sopenharmony_cistatic inline unsigned __d_entry_type(const struct dentry *dentry)
38462306a36Sopenharmony_ci{
38562306a36Sopenharmony_ci	return dentry->d_flags & DCACHE_ENTRY_TYPE;
38662306a36Sopenharmony_ci}
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_cistatic inline bool d_is_miss(const struct dentry *dentry)
38962306a36Sopenharmony_ci{
39062306a36Sopenharmony_ci	return __d_entry_type(dentry) == DCACHE_MISS_TYPE;
39162306a36Sopenharmony_ci}
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_cistatic inline bool d_is_whiteout(const struct dentry *dentry)
39462306a36Sopenharmony_ci{
39562306a36Sopenharmony_ci	return __d_entry_type(dentry) == DCACHE_WHITEOUT_TYPE;
39662306a36Sopenharmony_ci}
39762306a36Sopenharmony_ci
39862306a36Sopenharmony_cistatic inline bool d_can_lookup(const struct dentry *dentry)
39962306a36Sopenharmony_ci{
40062306a36Sopenharmony_ci	return __d_entry_type(dentry) == DCACHE_DIRECTORY_TYPE;
40162306a36Sopenharmony_ci}
40262306a36Sopenharmony_ci
40362306a36Sopenharmony_cistatic inline bool d_is_autodir(const struct dentry *dentry)
40462306a36Sopenharmony_ci{
40562306a36Sopenharmony_ci	return __d_entry_type(dentry) == DCACHE_AUTODIR_TYPE;
40662306a36Sopenharmony_ci}
40762306a36Sopenharmony_ci
40862306a36Sopenharmony_cistatic inline bool d_is_dir(const struct dentry *dentry)
40962306a36Sopenharmony_ci{
41062306a36Sopenharmony_ci	return d_can_lookup(dentry) || d_is_autodir(dentry);
41162306a36Sopenharmony_ci}
41262306a36Sopenharmony_ci
41362306a36Sopenharmony_cistatic inline bool d_is_symlink(const struct dentry *dentry)
41462306a36Sopenharmony_ci{
41562306a36Sopenharmony_ci	return __d_entry_type(dentry) == DCACHE_SYMLINK_TYPE;
41662306a36Sopenharmony_ci}
41762306a36Sopenharmony_ci
41862306a36Sopenharmony_cistatic inline bool d_is_reg(const struct dentry *dentry)
41962306a36Sopenharmony_ci{
42062306a36Sopenharmony_ci	return __d_entry_type(dentry) == DCACHE_REGULAR_TYPE;
42162306a36Sopenharmony_ci}
42262306a36Sopenharmony_ci
42362306a36Sopenharmony_cistatic inline bool d_is_special(const struct dentry *dentry)
42462306a36Sopenharmony_ci{
42562306a36Sopenharmony_ci	return __d_entry_type(dentry) == DCACHE_SPECIAL_TYPE;
42662306a36Sopenharmony_ci}
42762306a36Sopenharmony_ci
42862306a36Sopenharmony_cistatic inline bool d_is_file(const struct dentry *dentry)
42962306a36Sopenharmony_ci{
43062306a36Sopenharmony_ci	return d_is_reg(dentry) || d_is_special(dentry);
43162306a36Sopenharmony_ci}
43262306a36Sopenharmony_ci
43362306a36Sopenharmony_cistatic inline bool d_is_negative(const struct dentry *dentry)
43462306a36Sopenharmony_ci{
43562306a36Sopenharmony_ci	// TODO: check d_is_whiteout(dentry) also.
43662306a36Sopenharmony_ci	return d_is_miss(dentry);
43762306a36Sopenharmony_ci}
43862306a36Sopenharmony_ci
43962306a36Sopenharmony_cistatic inline bool d_flags_negative(unsigned flags)
44062306a36Sopenharmony_ci{
44162306a36Sopenharmony_ci	return (flags & DCACHE_ENTRY_TYPE) == DCACHE_MISS_TYPE;
44262306a36Sopenharmony_ci}
44362306a36Sopenharmony_ci
44462306a36Sopenharmony_cistatic inline bool d_is_positive(const struct dentry *dentry)
44562306a36Sopenharmony_ci{
44662306a36Sopenharmony_ci	return !d_is_negative(dentry);
44762306a36Sopenharmony_ci}
44862306a36Sopenharmony_ci
44962306a36Sopenharmony_ci/**
45062306a36Sopenharmony_ci * d_really_is_negative - Determine if a dentry is really negative (ignoring fallthroughs)
45162306a36Sopenharmony_ci * @dentry: The dentry in question
45262306a36Sopenharmony_ci *
45362306a36Sopenharmony_ci * Returns true if the dentry represents either an absent name or a name that
45462306a36Sopenharmony_ci * doesn't map to an inode (ie. ->d_inode is NULL).  The dentry could represent
45562306a36Sopenharmony_ci * a true miss, a whiteout that isn't represented by a 0,0 chardev or a
45662306a36Sopenharmony_ci * fallthrough marker in an opaque directory.
45762306a36Sopenharmony_ci *
45862306a36Sopenharmony_ci * Note!  (1) This should be used *only* by a filesystem to examine its own
45962306a36Sopenharmony_ci * dentries.  It should not be used to look at some other filesystem's
46062306a36Sopenharmony_ci * dentries.  (2) It should also be used in combination with d_inode() to get
46162306a36Sopenharmony_ci * the inode.  (3) The dentry may have something attached to ->d_lower and the
46262306a36Sopenharmony_ci * type field of the flags may be set to something other than miss or whiteout.
46362306a36Sopenharmony_ci */
46462306a36Sopenharmony_cistatic inline bool d_really_is_negative(const struct dentry *dentry)
46562306a36Sopenharmony_ci{
46662306a36Sopenharmony_ci	return dentry->d_inode == NULL;
46762306a36Sopenharmony_ci}
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_ci/**
47062306a36Sopenharmony_ci * d_really_is_positive - Determine if a dentry is really positive (ignoring fallthroughs)
47162306a36Sopenharmony_ci * @dentry: The dentry in question
47262306a36Sopenharmony_ci *
47362306a36Sopenharmony_ci * Returns true if the dentry represents a name that maps to an inode
47462306a36Sopenharmony_ci * (ie. ->d_inode is not NULL).  The dentry might still represent a whiteout if
47562306a36Sopenharmony_ci * that is represented on medium as a 0,0 chardev.
47662306a36Sopenharmony_ci *
47762306a36Sopenharmony_ci * Note!  (1) This should be used *only* by a filesystem to examine its own
47862306a36Sopenharmony_ci * dentries.  It should not be used to look at some other filesystem's
47962306a36Sopenharmony_ci * dentries.  (2) It should also be used in combination with d_inode() to get
48062306a36Sopenharmony_ci * the inode.
48162306a36Sopenharmony_ci */
48262306a36Sopenharmony_cistatic inline bool d_really_is_positive(const struct dentry *dentry)
48362306a36Sopenharmony_ci{
48462306a36Sopenharmony_ci	return dentry->d_inode != NULL;
48562306a36Sopenharmony_ci}
48662306a36Sopenharmony_ci
48762306a36Sopenharmony_cistatic inline int simple_positive(const struct dentry *dentry)
48862306a36Sopenharmony_ci{
48962306a36Sopenharmony_ci	return d_really_is_positive(dentry) && !d_unhashed(dentry);
49062306a36Sopenharmony_ci}
49162306a36Sopenharmony_ci
49262306a36Sopenharmony_ciextern void d_set_fallthru(struct dentry *dentry);
49362306a36Sopenharmony_ci
49462306a36Sopenharmony_cistatic inline bool d_is_fallthru(const struct dentry *dentry)
49562306a36Sopenharmony_ci{
49662306a36Sopenharmony_ci	return dentry->d_flags & DCACHE_FALLTHRU;
49762306a36Sopenharmony_ci}
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_ci
50062306a36Sopenharmony_ciextern int sysctl_vfs_cache_pressure;
50162306a36Sopenharmony_ci
50262306a36Sopenharmony_cistatic inline unsigned long vfs_pressure_ratio(unsigned long val)
50362306a36Sopenharmony_ci{
50462306a36Sopenharmony_ci	return mult_frac(val, sysctl_vfs_cache_pressure, 100);
50562306a36Sopenharmony_ci}
50662306a36Sopenharmony_ci
50762306a36Sopenharmony_ci/**
50862306a36Sopenharmony_ci * d_inode - Get the actual inode of this dentry
50962306a36Sopenharmony_ci * @dentry: The dentry to query
51062306a36Sopenharmony_ci *
51162306a36Sopenharmony_ci * This is the helper normal filesystems should use to get at their own inodes
51262306a36Sopenharmony_ci * in their own dentries and ignore the layering superimposed upon them.
51362306a36Sopenharmony_ci */
51462306a36Sopenharmony_cistatic inline struct inode *d_inode(const struct dentry *dentry)
51562306a36Sopenharmony_ci{
51662306a36Sopenharmony_ci	return dentry->d_inode;
51762306a36Sopenharmony_ci}
51862306a36Sopenharmony_ci
51962306a36Sopenharmony_ci/**
52062306a36Sopenharmony_ci * d_inode_rcu - Get the actual inode of this dentry with READ_ONCE()
52162306a36Sopenharmony_ci * @dentry: The dentry to query
52262306a36Sopenharmony_ci *
52362306a36Sopenharmony_ci * This is the helper normal filesystems should use to get at their own inodes
52462306a36Sopenharmony_ci * in their own dentries and ignore the layering superimposed upon them.
52562306a36Sopenharmony_ci */
52662306a36Sopenharmony_cistatic inline struct inode *d_inode_rcu(const struct dentry *dentry)
52762306a36Sopenharmony_ci{
52862306a36Sopenharmony_ci	return READ_ONCE(dentry->d_inode);
52962306a36Sopenharmony_ci}
53062306a36Sopenharmony_ci
53162306a36Sopenharmony_ci/**
53262306a36Sopenharmony_ci * d_backing_inode - Get upper or lower inode we should be using
53362306a36Sopenharmony_ci * @upper: The upper layer
53462306a36Sopenharmony_ci *
53562306a36Sopenharmony_ci * This is the helper that should be used to get at the inode that will be used
53662306a36Sopenharmony_ci * if this dentry were to be opened as a file.  The inode may be on the upper
53762306a36Sopenharmony_ci * dentry or it may be on a lower dentry pinned by the upper.
53862306a36Sopenharmony_ci *
53962306a36Sopenharmony_ci * Normal filesystems should not use this to access their own inodes.
54062306a36Sopenharmony_ci */
54162306a36Sopenharmony_cistatic inline struct inode *d_backing_inode(const struct dentry *upper)
54262306a36Sopenharmony_ci{
54362306a36Sopenharmony_ci	struct inode *inode = upper->d_inode;
54462306a36Sopenharmony_ci
54562306a36Sopenharmony_ci	return inode;
54662306a36Sopenharmony_ci}
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci/**
54962306a36Sopenharmony_ci * d_backing_dentry - Get upper or lower dentry we should be using
55062306a36Sopenharmony_ci * @upper: The upper layer
55162306a36Sopenharmony_ci *
55262306a36Sopenharmony_ci * This is the helper that should be used to get the dentry of the inode that
55362306a36Sopenharmony_ci * will be used if this dentry were opened as a file.  It may be the upper
55462306a36Sopenharmony_ci * dentry or it may be a lower dentry pinned by the upper.
55562306a36Sopenharmony_ci *
55662306a36Sopenharmony_ci * Normal filesystems should not use this to access their own dentries.
55762306a36Sopenharmony_ci */
55862306a36Sopenharmony_cistatic inline struct dentry *d_backing_dentry(struct dentry *upper)
55962306a36Sopenharmony_ci{
56062306a36Sopenharmony_ci	return upper;
56162306a36Sopenharmony_ci}
56262306a36Sopenharmony_ci
56362306a36Sopenharmony_ci/**
56462306a36Sopenharmony_ci * d_real - Return the real dentry
56562306a36Sopenharmony_ci * @dentry: the dentry to query
56662306a36Sopenharmony_ci * @inode: inode to select the dentry from multiple layers (can be NULL)
56762306a36Sopenharmony_ci *
56862306a36Sopenharmony_ci * If dentry is on a union/overlay, then return the underlying, real dentry.
56962306a36Sopenharmony_ci * Otherwise return the dentry itself.
57062306a36Sopenharmony_ci *
57162306a36Sopenharmony_ci * See also: Documentation/filesystems/vfs.rst
57262306a36Sopenharmony_ci */
57362306a36Sopenharmony_cistatic inline struct dentry *d_real(struct dentry *dentry,
57462306a36Sopenharmony_ci				    const struct inode *inode)
57562306a36Sopenharmony_ci{
57662306a36Sopenharmony_ci	if (unlikely(dentry->d_flags & DCACHE_OP_REAL))
57762306a36Sopenharmony_ci		return dentry->d_op->d_real(dentry, inode);
57862306a36Sopenharmony_ci	else
57962306a36Sopenharmony_ci		return dentry;
58062306a36Sopenharmony_ci}
58162306a36Sopenharmony_ci
58262306a36Sopenharmony_ci/**
58362306a36Sopenharmony_ci * d_real_inode - Return the real inode
58462306a36Sopenharmony_ci * @dentry: The dentry to query
58562306a36Sopenharmony_ci *
58662306a36Sopenharmony_ci * If dentry is on a union/overlay, then return the underlying, real inode.
58762306a36Sopenharmony_ci * Otherwise return d_inode().
58862306a36Sopenharmony_ci */
58962306a36Sopenharmony_cistatic inline struct inode *d_real_inode(const struct dentry *dentry)
59062306a36Sopenharmony_ci{
59162306a36Sopenharmony_ci	/* This usage of d_real() results in const dentry */
59262306a36Sopenharmony_ci	return d_backing_inode(d_real((struct dentry *) dentry, NULL));
59362306a36Sopenharmony_ci}
59462306a36Sopenharmony_ci
59562306a36Sopenharmony_cistruct name_snapshot {
59662306a36Sopenharmony_ci	struct qstr name;
59762306a36Sopenharmony_ci	unsigned char inline_name[DNAME_INLINE_LEN];
59862306a36Sopenharmony_ci};
59962306a36Sopenharmony_civoid take_dentry_name_snapshot(struct name_snapshot *, struct dentry *);
60062306a36Sopenharmony_civoid release_dentry_name_snapshot(struct name_snapshot *);
60162306a36Sopenharmony_ci
60262306a36Sopenharmony_ci#endif	/* __LINUX_DCACHE_H */
603