162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * fs/kernfs/kernfs-internal.h - kernfs internal header file
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (c) 2001-3 Patrick Mochel
662306a36Sopenharmony_ci * Copyright (c) 2007 SUSE Linux Products GmbH
762306a36Sopenharmony_ci * Copyright (c) 2007, 2013 Tejun Heo <teheo@suse.de>
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#ifndef __KERNFS_INTERNAL_H
1162306a36Sopenharmony_ci#define __KERNFS_INTERNAL_H
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include <linux/lockdep.h>
1462306a36Sopenharmony_ci#include <linux/fs.h>
1562306a36Sopenharmony_ci#include <linux/mutex.h>
1662306a36Sopenharmony_ci#include <linux/rwsem.h>
1762306a36Sopenharmony_ci#include <linux/xattr.h>
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci#include <linux/kernfs.h>
2062306a36Sopenharmony_ci#include <linux/fs_context.h>
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_cistruct kernfs_iattrs {
2362306a36Sopenharmony_ci	kuid_t			ia_uid;
2462306a36Sopenharmony_ci	kgid_t			ia_gid;
2562306a36Sopenharmony_ci	struct timespec64	ia_atime;
2662306a36Sopenharmony_ci	struct timespec64	ia_mtime;
2762306a36Sopenharmony_ci	struct timespec64	ia_ctime;
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci	struct simple_xattrs	xattrs;
3062306a36Sopenharmony_ci	atomic_t		nr_user_xattrs;
3162306a36Sopenharmony_ci	atomic_t		user_xattr_size;
3262306a36Sopenharmony_ci};
3362306a36Sopenharmony_ci
3462306a36Sopenharmony_cistruct kernfs_root {
3562306a36Sopenharmony_ci	/* published fields */
3662306a36Sopenharmony_ci	struct kernfs_node	*kn;
3762306a36Sopenharmony_ci	unsigned int		flags;	/* KERNFS_ROOT_* flags */
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci	/* private fields, do not use outside kernfs proper */
4062306a36Sopenharmony_ci	struct idr		ino_idr;
4162306a36Sopenharmony_ci	u32			last_id_lowbits;
4262306a36Sopenharmony_ci	u32			id_highbits;
4362306a36Sopenharmony_ci	struct kernfs_syscall_ops *syscall_ops;
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci	/* list of kernfs_super_info of this root, protected by kernfs_rwsem */
4662306a36Sopenharmony_ci	struct list_head	supers;
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	wait_queue_head_t	deactivate_waitq;
4962306a36Sopenharmony_ci	struct rw_semaphore	kernfs_rwsem;
5062306a36Sopenharmony_ci	struct rw_semaphore	kernfs_iattr_rwsem;
5162306a36Sopenharmony_ci	struct rw_semaphore	kernfs_supers_rwsem;
5262306a36Sopenharmony_ci};
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci/* +1 to avoid triggering overflow warning when negating it */
5562306a36Sopenharmony_ci#define KN_DEACTIVATED_BIAS		(INT_MIN + 1)
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci/* KERNFS_TYPE_MASK and types are defined in include/linux/kernfs.h */
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci/**
6062306a36Sopenharmony_ci * kernfs_root - find out the kernfs_root a kernfs_node belongs to
6162306a36Sopenharmony_ci * @kn: kernfs_node of interest
6262306a36Sopenharmony_ci *
6362306a36Sopenharmony_ci * Return: the kernfs_root @kn belongs to.
6462306a36Sopenharmony_ci */
6562306a36Sopenharmony_cistatic inline struct kernfs_root *kernfs_root(struct kernfs_node *kn)
6662306a36Sopenharmony_ci{
6762306a36Sopenharmony_ci	/* if parent exists, it's always a dir; otherwise, @sd is a dir */
6862306a36Sopenharmony_ci	if (kn->parent)
6962306a36Sopenharmony_ci		kn = kn->parent;
7062306a36Sopenharmony_ci	return kn->dir.root;
7162306a36Sopenharmony_ci}
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci/*
7462306a36Sopenharmony_ci * mount.c
7562306a36Sopenharmony_ci */
7662306a36Sopenharmony_cistruct kernfs_super_info {
7762306a36Sopenharmony_ci	struct super_block	*sb;
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci	/*
8062306a36Sopenharmony_ci	 * The root associated with this super_block.  Each super_block is
8162306a36Sopenharmony_ci	 * identified by the root and ns it's associated with.
8262306a36Sopenharmony_ci	 */
8362306a36Sopenharmony_ci	struct kernfs_root	*root;
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci	/*
8662306a36Sopenharmony_ci	 * Each sb is associated with one namespace tag, currently the
8762306a36Sopenharmony_ci	 * network namespace of the task which mounted this kernfs
8862306a36Sopenharmony_ci	 * instance.  If multiple tags become necessary, make the following
8962306a36Sopenharmony_ci	 * an array and compare kernfs_node tag against every entry.
9062306a36Sopenharmony_ci	 */
9162306a36Sopenharmony_ci	const void		*ns;
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci	/* anchored at kernfs_root->supers, protected by kernfs_rwsem */
9462306a36Sopenharmony_ci	struct list_head	node;
9562306a36Sopenharmony_ci};
9662306a36Sopenharmony_ci#define kernfs_info(SB) ((struct kernfs_super_info *)(SB->s_fs_info))
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_cistatic inline struct kernfs_node *kernfs_dentry_node(struct dentry *dentry)
9962306a36Sopenharmony_ci{
10062306a36Sopenharmony_ci	if (d_really_is_negative(dentry))
10162306a36Sopenharmony_ci		return NULL;
10262306a36Sopenharmony_ci	return d_inode(dentry)->i_private;
10362306a36Sopenharmony_ci}
10462306a36Sopenharmony_ci
10562306a36Sopenharmony_cistatic inline void kernfs_set_rev(struct kernfs_node *parent,
10662306a36Sopenharmony_ci				  struct dentry *dentry)
10762306a36Sopenharmony_ci{
10862306a36Sopenharmony_ci	dentry->d_time = parent->dir.rev;
10962306a36Sopenharmony_ci}
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_cistatic inline void kernfs_inc_rev(struct kernfs_node *parent)
11262306a36Sopenharmony_ci{
11362306a36Sopenharmony_ci	parent->dir.rev++;
11462306a36Sopenharmony_ci}
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_cistatic inline bool kernfs_dir_changed(struct kernfs_node *parent,
11762306a36Sopenharmony_ci				      struct dentry *dentry)
11862306a36Sopenharmony_ci{
11962306a36Sopenharmony_ci	if (parent->dir.rev != dentry->d_time)
12062306a36Sopenharmony_ci		return true;
12162306a36Sopenharmony_ci	return false;
12262306a36Sopenharmony_ci}
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ciextern const struct super_operations kernfs_sops;
12562306a36Sopenharmony_ciextern struct kmem_cache *kernfs_node_cache, *kernfs_iattrs_cache;
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci/*
12862306a36Sopenharmony_ci * inode.c
12962306a36Sopenharmony_ci */
13062306a36Sopenharmony_ciextern const struct xattr_handler *kernfs_xattr_handlers[];
13162306a36Sopenharmony_civoid kernfs_evict_inode(struct inode *inode);
13262306a36Sopenharmony_ciint kernfs_iop_permission(struct mnt_idmap *idmap,
13362306a36Sopenharmony_ci			  struct inode *inode, int mask);
13462306a36Sopenharmony_ciint kernfs_iop_setattr(struct mnt_idmap *idmap, struct dentry *dentry,
13562306a36Sopenharmony_ci		       struct iattr *iattr);
13662306a36Sopenharmony_ciint kernfs_iop_getattr(struct mnt_idmap *idmap,
13762306a36Sopenharmony_ci		       const struct path *path, struct kstat *stat,
13862306a36Sopenharmony_ci		       u32 request_mask, unsigned int query_flags);
13962306a36Sopenharmony_cissize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size);
14062306a36Sopenharmony_ciint __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr);
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci/*
14362306a36Sopenharmony_ci * dir.c
14462306a36Sopenharmony_ci */
14562306a36Sopenharmony_ciextern const struct dentry_operations kernfs_dops;
14662306a36Sopenharmony_ciextern const struct file_operations kernfs_dir_fops;
14762306a36Sopenharmony_ciextern const struct inode_operations kernfs_dir_iops;
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_cistruct kernfs_node *kernfs_get_active(struct kernfs_node *kn);
15062306a36Sopenharmony_civoid kernfs_put_active(struct kernfs_node *kn);
15162306a36Sopenharmony_ciint kernfs_add_one(struct kernfs_node *kn);
15262306a36Sopenharmony_cistruct kernfs_node *kernfs_new_node(struct kernfs_node *parent,
15362306a36Sopenharmony_ci				    const char *name, umode_t mode,
15462306a36Sopenharmony_ci				    kuid_t uid, kgid_t gid,
15562306a36Sopenharmony_ci				    unsigned flags);
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci/*
15862306a36Sopenharmony_ci * file.c
15962306a36Sopenharmony_ci */
16062306a36Sopenharmony_ciextern const struct file_operations kernfs_file_fops;
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_cibool kernfs_should_drain_open_files(struct kernfs_node *kn);
16362306a36Sopenharmony_civoid kernfs_drain_open_files(struct kernfs_node *kn);
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ci/*
16662306a36Sopenharmony_ci * symlink.c
16762306a36Sopenharmony_ci */
16862306a36Sopenharmony_ciextern const struct inode_operations kernfs_symlink_iops;
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci/*
17162306a36Sopenharmony_ci * kernfs locks
17262306a36Sopenharmony_ci */
17362306a36Sopenharmony_ciextern struct kernfs_global_locks *kernfs_locks;
17462306a36Sopenharmony_ci#endif	/* __KERNFS_INTERNAL_H */
175