brintos

brintos / linux-shallow public Read only

0
0
Text · 23.3 KiB · 8705c77 Raw
914 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 *  event_inode.c - part of tracefs, a pseudo file system for activating tracing4 *5 *  Copyright (C) 2020-23 VMware Inc, author: Steven Rostedt <rostedt@goodmis.org>6 *  Copyright (C) 2020-23 VMware Inc, author: Ajay Kaher <akaher@vmware.com>7 *  Copyright (C) 2023 Google, author: Steven Rostedt <rostedt@goodmis.org>8 *9 *  eventfs is used to dynamically create inodes and dentries based on the10 *  meta data provided by the tracing system.11 *12 *  eventfs stores the meta-data of files/dirs and holds off on creating13 *  inodes/dentries of the files. When accessed, the eventfs will create the14 *  inodes/dentries in a just-in-time (JIT) manner. The eventfs will clean up15 *  and delete the inodes/dentries when they are no longer referenced.16 */17#include <linux/fsnotify.h>18#include <linux/fs.h>19#include <linux/namei.h>20#include <linux/workqueue.h>21#include <linux/security.h>22#include <linux/tracefs.h>23#include <linux/kref.h>24#include <linux/delay.h>25#include "internal.h"26 27/*28 * eventfs_mutex protects the eventfs_inode (ei) dentry. Any access29 * to the ei->dentry must be done under this mutex and after checking30 * if ei->is_freed is not set. When ei->is_freed is set, the dentry31 * is on its way to being freed after the last dput() is made on it.32 */33static DEFINE_MUTEX(eventfs_mutex);34 35/* Choose something "unique" ;-) */36#define EVENTFS_FILE_INODE_INO		0x12c4e3737 38struct eventfs_root_inode {39	struct eventfs_inode		ei;40	struct dentry			*events_dir;41};42 43static struct eventfs_root_inode *get_root_inode(struct eventfs_inode *ei)44{45	WARN_ON_ONCE(!ei->is_events);46	return container_of(ei, struct eventfs_root_inode, ei);47}48 49/* Just try to make something consistent and unique */50static int eventfs_dir_ino(struct eventfs_inode *ei)51{52	if (!ei->ino) {53		ei->ino = get_next_ino();54		/* Must not have the file inode number */55		if (ei->ino == EVENTFS_FILE_INODE_INO)56			ei->ino = get_next_ino();57	}58 59	return ei->ino;60}61 62/*63 * The eventfs_inode (ei) itself is protected by SRCU. It is released from64 * its parent's list and will have is_freed set (under eventfs_mutex).65 * After the SRCU grace period is over and the last dput() is called66 * the ei is freed.67 */68DEFINE_STATIC_SRCU(eventfs_srcu);69 70/* Mode is unsigned short, use the upper bits for flags */71enum {72	EVENTFS_SAVE_MODE	= BIT(16),73	EVENTFS_SAVE_UID	= BIT(17),74	EVENTFS_SAVE_GID	= BIT(18),75};76 77#define EVENTFS_MODE_MASK	(EVENTFS_SAVE_MODE - 1)78 79static void free_ei_rcu(struct rcu_head *rcu)80{81	struct eventfs_inode *ei = container_of(rcu, struct eventfs_inode, rcu);82	struct eventfs_root_inode *rei;83 84	kfree(ei->entry_attrs);85	kfree_const(ei->name);86	if (ei->is_events) {87		rei = get_root_inode(ei);88		kfree(rei);89	} else {90		kfree(ei);91	}92}93 94/*95 * eventfs_inode reference count management.96 *97 * NOTE! We count only references from dentries, in the98 * form 'dentry->d_fsdata'. There are also references from99 * directory inodes ('ti->private'), but the dentry reference100 * count is always a superset of the inode reference count.101 */102static void release_ei(struct kref *ref)103{104	struct eventfs_inode *ei = container_of(ref, struct eventfs_inode, kref);105	const struct eventfs_entry *entry;106 107	WARN_ON_ONCE(!ei->is_freed);108 109	for (int i = 0; i < ei->nr_entries; i++) {110		entry = &ei->entries[i];111		if (entry->release)112			entry->release(entry->name, ei->data);113	}114 115	call_srcu(&eventfs_srcu, &ei->rcu, free_ei_rcu);116}117 118static inline void put_ei(struct eventfs_inode *ei)119{120	if (ei)121		kref_put(&ei->kref, release_ei);122}123 124static inline void free_ei(struct eventfs_inode *ei)125{126	if (ei) {127		ei->is_freed = 1;128		put_ei(ei);129	}130}131 132/*133 * Called when creation of an ei fails, do not call release() functions.134 */135static inline void cleanup_ei(struct eventfs_inode *ei)136{137	if (ei) {138		/* Set nr_entries to 0 to prevent release() function being called */139		ei->nr_entries = 0;140		free_ei(ei);141	}142}143 144static inline struct eventfs_inode *get_ei(struct eventfs_inode *ei)145{146	if (ei)147		kref_get(&ei->kref);148	return ei;149}150 151static struct dentry *eventfs_root_lookup(struct inode *dir,152					  struct dentry *dentry,153					  unsigned int flags);154static int eventfs_iterate(struct file *file, struct dir_context *ctx);155 156static void update_attr(struct eventfs_attr *attr, struct iattr *iattr)157{158	unsigned int ia_valid = iattr->ia_valid;159 160	if (ia_valid & ATTR_MODE) {161		attr->mode = (attr->mode & ~EVENTFS_MODE_MASK) |162			(iattr->ia_mode & EVENTFS_MODE_MASK) |163			EVENTFS_SAVE_MODE;164	}165	if (ia_valid & ATTR_UID) {166		attr->mode |= EVENTFS_SAVE_UID;167		attr->uid = iattr->ia_uid;168	}169	if (ia_valid & ATTR_GID) {170		attr->mode |= EVENTFS_SAVE_GID;171		attr->gid = iattr->ia_gid;172	}173}174 175static int eventfs_set_attr(struct mnt_idmap *idmap, struct dentry *dentry,176			    struct iattr *iattr)177{178	const struct eventfs_entry *entry;179	struct eventfs_inode *ei;180	const char *name;181	int ret;182 183	mutex_lock(&eventfs_mutex);184	ei = dentry->d_fsdata;185	if (ei->is_freed) {186		/* Do not allow changes if the event is about to be removed. */187		mutex_unlock(&eventfs_mutex);188		return -ENODEV;189	}190 191	/* Preallocate the children mode array if necessary */192	if (!(dentry->d_inode->i_mode & S_IFDIR)) {193		if (!ei->entry_attrs) {194			ei->entry_attrs = kcalloc(ei->nr_entries, sizeof(*ei->entry_attrs),195						  GFP_NOFS);196			if (!ei->entry_attrs) {197				ret = -ENOMEM;198				goto out;199			}200		}201	}202 203	ret = simple_setattr(idmap, dentry, iattr);204	if (ret < 0)205		goto out;206 207	/*208	 * If this is a dir, then update the ei cache, only the file209	 * mode is saved in the ei->m_children, and the ownership is210	 * determined by the parent directory.211	 */212	if (dentry->d_inode->i_mode & S_IFDIR) {213		/* Just use the inode permissions for the events directory */214		if (!ei->is_events)215			update_attr(&ei->attr, iattr);216 217	} else {218		name = dentry->d_name.name;219 220		for (int i = 0; i < ei->nr_entries; i++) {221			entry = &ei->entries[i];222			if (strcmp(name, entry->name) == 0) {223				update_attr(&ei->entry_attrs[i], iattr);224				break;225			}226		}227	}228 out:229	mutex_unlock(&eventfs_mutex);230	return ret;231}232 233static const struct inode_operations eventfs_dir_inode_operations = {234	.lookup		= eventfs_root_lookup,235	.setattr	= eventfs_set_attr,236};237 238static const struct inode_operations eventfs_file_inode_operations = {239	.setattr	= eventfs_set_attr,240};241 242static const struct file_operations eventfs_file_operations = {243	.read		= generic_read_dir,244	.iterate_shared	= eventfs_iterate,245	.llseek		= generic_file_llseek,246};247 248static void eventfs_set_attrs(struct eventfs_inode *ei, bool update_uid, kuid_t uid,249			      bool update_gid, kgid_t gid, int level)250{251	struct eventfs_inode *ei_child;252 253	/* Update events/<system>/<event> */254	if (WARN_ON_ONCE(level > 3))255		return;256 257	if (update_uid) {258		ei->attr.mode &= ~EVENTFS_SAVE_UID;259		ei->attr.uid = uid;260	}261 262	if (update_gid) {263		ei->attr.mode &= ~EVENTFS_SAVE_GID;264		ei->attr.gid = gid;265	}266 267	list_for_each_entry(ei_child, &ei->children, list) {268		eventfs_set_attrs(ei_child, update_uid, uid, update_gid, gid, level + 1);269	}270 271	if (!ei->entry_attrs)272		return;273 274	for (int i = 0; i < ei->nr_entries; i++) {275		if (update_uid) {276			ei->entry_attrs[i].mode &= ~EVENTFS_SAVE_UID;277			ei->entry_attrs[i].uid = uid;278		}279		if (update_gid) {280			ei->entry_attrs[i].mode &= ~EVENTFS_SAVE_GID;281			ei->entry_attrs[i].gid = gid;282		}283	}284 285}286 287/*288 * On a remount of tracefs, if UID or GID options are set, then289 * the mount point inode permissions should be used.290 * Reset the saved permission flags appropriately.291 */292void eventfs_remount(struct tracefs_inode *ti, bool update_uid, bool update_gid)293{294	struct eventfs_inode *ei = ti->private;295 296	/* Only the events directory does the updates */297	if (!ei || !ei->is_events || ei->is_freed)298		return;299 300	eventfs_set_attrs(ei, update_uid, ti->vfs_inode.i_uid,301			  update_gid, ti->vfs_inode.i_gid, 0);302}303 304static void update_inode_attr(struct inode *inode, umode_t mode,305			      struct eventfs_attr *attr, struct eventfs_root_inode *rei)306{307	if (attr && attr->mode & EVENTFS_SAVE_MODE)308		inode->i_mode = attr->mode & EVENTFS_MODE_MASK;309	else310		inode->i_mode = mode;311 312	if (attr && attr->mode & EVENTFS_SAVE_UID)313		inode->i_uid = attr->uid;314	else315		inode->i_uid = rei->ei.attr.uid;316 317	if (attr && attr->mode & EVENTFS_SAVE_GID)318		inode->i_gid = attr->gid;319	else320		inode->i_gid = rei->ei.attr.gid;321}322 323static struct inode *eventfs_get_inode(struct dentry *dentry, struct eventfs_attr *attr,324				       umode_t mode,  struct eventfs_inode *ei)325{326	struct eventfs_root_inode *rei;327	struct eventfs_inode *pei;328	struct tracefs_inode *ti;329	struct inode *inode;330 331	inode = tracefs_get_inode(dentry->d_sb);332	if (!inode)333		return NULL;334 335	ti = get_tracefs(inode);336	ti->private = ei;337	ti->flags |= TRACEFS_EVENT_INODE;338 339	/* Find the top dentry that holds the "events" directory */340	do {341		dentry = dentry->d_parent;342		/* Directories always have d_fsdata */343		pei = dentry->d_fsdata;344	} while (!pei->is_events);345 346	rei = get_root_inode(pei);347 348	update_inode_attr(inode, mode, attr, rei);349 350	return inode;351}352 353/**354 * lookup_file - look up a file in the tracefs filesystem355 * @parent_ei: Pointer to the eventfs_inode that represents parent of the file356 * @dentry: the dentry to look up357 * @mode: the permission that the file should have.358 * @attr: saved attributes changed by user359 * @data: something that the caller will want to get to later on.360 * @fop: struct file_operations that should be used for this file.361 *362 * This function creates a dentry that represents a file in the eventsfs_inode363 * directory. The inode.i_private pointer will point to @data in the open()364 * call.365 */366static struct dentry *lookup_file(struct eventfs_inode *parent_ei,367				  struct dentry *dentry,368				  umode_t mode,369				  struct eventfs_attr *attr,370				  void *data,371				  const struct file_operations *fop)372{373	struct inode *inode;374 375	if (!(mode & S_IFMT))376		mode |= S_IFREG;377 378	if (WARN_ON_ONCE(!S_ISREG(mode)))379		return ERR_PTR(-EIO);380 381	/* Only directories have ti->private set to an ei, not files */382	inode = eventfs_get_inode(dentry, attr, mode, NULL);383	if (unlikely(!inode))384		return ERR_PTR(-ENOMEM);385 386	inode->i_op = &eventfs_file_inode_operations;387	inode->i_fop = fop;388	inode->i_private = data;389 390	/* All files will have the same inode number */391	inode->i_ino = EVENTFS_FILE_INODE_INO;392 393	// Files have their parent's ei as their fsdata394	dentry->d_fsdata = get_ei(parent_ei);395 396	d_add(dentry, inode);397	return NULL;398};399 400/**401 * lookup_dir_entry - look up a dir in the tracefs filesystem402 * @dentry: the directory to look up403 * @pei: Pointer to the parent eventfs_inode if available404 * @ei: the eventfs_inode that represents the directory to create405 *406 * This function will look up a dentry for a directory represented by407 * a eventfs_inode.408 */409static struct dentry *lookup_dir_entry(struct dentry *dentry,410	struct eventfs_inode *pei, struct eventfs_inode *ei)411{412	struct inode *inode;413	umode_t mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;414 415	inode = eventfs_get_inode(dentry, &ei->attr, mode, ei);416	if (unlikely(!inode))417		return ERR_PTR(-ENOMEM);418 419	inode->i_op = &eventfs_dir_inode_operations;420	inode->i_fop = &eventfs_file_operations;421 422	/* All directories will have the same inode number */423	inode->i_ino = eventfs_dir_ino(ei);424 425	dentry->d_fsdata = get_ei(ei);426 427	d_add(dentry, inode);428	return NULL;429}430 431static inline struct eventfs_inode *init_ei(struct eventfs_inode *ei, const char *name)432{433	ei->name = kstrdup_const(name, GFP_KERNEL);434	if (!ei->name)435		return NULL;436	kref_init(&ei->kref);437	return ei;438}439 440static inline struct eventfs_inode *alloc_ei(const char *name)441{442	struct eventfs_inode *ei = kzalloc(sizeof(*ei), GFP_KERNEL);443	struct eventfs_inode *result;444 445	if (!ei)446		return NULL;447 448	result = init_ei(ei, name);449	if (!result)450		kfree(ei);451 452	return result;453}454 455static inline struct eventfs_inode *alloc_root_ei(const char *name)456{457	struct eventfs_root_inode *rei = kzalloc(sizeof(*rei), GFP_KERNEL);458	struct eventfs_inode *ei;459 460	if (!rei)461		return NULL;462 463	rei->ei.is_events = 1;464	ei = init_ei(&rei->ei, name);465	if (!ei)466		kfree(rei);467 468	return ei;469}470 471/**472 * eventfs_d_release - dentry is going away473 * @dentry: dentry which has the reference to remove.474 *475 * Remove the association between a dentry from an eventfs_inode.476 */477void eventfs_d_release(struct dentry *dentry)478{479	put_ei(dentry->d_fsdata);480}481 482/**483 * lookup_file_dentry - create a dentry for a file of an eventfs_inode484 * @dentry: The parent dentry under which the new file's dentry will be created485 * @ei: the eventfs_inode that the file will be created under486 * @idx: the index into the entry_attrs[] of the @ei487 * @mode: The mode of the file.488 * @data: The data to use to set the inode of the file with on open()489 * @fops: The fops of the file to be created.490 *491 * This function creates a dentry for a file associated with an492 * eventfs_inode @ei. It uses the entry attributes specified by @idx,493 * if available. The file will have the specified @mode and its inode will be494 * set up with @data upon open. The file operations will be set to @fops.495 *496 * Return: Returns a pointer to the newly created file's dentry or an error497 * pointer.498 */499static struct dentry *500lookup_file_dentry(struct dentry *dentry,501		   struct eventfs_inode *ei, int idx,502		   umode_t mode, void *data,503		   const struct file_operations *fops)504{505	struct eventfs_attr *attr = NULL;506 507	if (ei->entry_attrs)508		attr = &ei->entry_attrs[idx];509 510	return lookup_file(ei, dentry, mode, attr, data, fops);511}512 513/**514 * eventfs_root_lookup - lookup routine to create file/dir515 * @dir: in which a lookup is being done516 * @dentry: file/dir dentry517 * @flags: Just passed to simple_lookup()518 *519 * Used to create dynamic file/dir with-in @dir, search with-in @ei520 * list, if @dentry found go ahead and create the file/dir521 */522 523static struct dentry *eventfs_root_lookup(struct inode *dir,524					  struct dentry *dentry,525					  unsigned int flags)526{527	struct eventfs_inode *ei_child;528	struct tracefs_inode *ti;529	struct eventfs_inode *ei;530	const char *name = dentry->d_name.name;531	struct dentry *result = NULL;532 533	ti = get_tracefs(dir);534	if (WARN_ON_ONCE(!(ti->flags & TRACEFS_EVENT_INODE)))535		return ERR_PTR(-EIO);536 537	mutex_lock(&eventfs_mutex);538 539	ei = ti->private;540	if (!ei || ei->is_freed)541		goto out;542 543	list_for_each_entry(ei_child, &ei->children, list) {544		if (strcmp(ei_child->name, name) != 0)545			continue;546		/* A child is freed and removed from the list at the same time */547		if (WARN_ON_ONCE(ei_child->is_freed))548			goto out;549		result = lookup_dir_entry(dentry, ei, ei_child);550		goto out;551	}552 553	for (int i = 0; i < ei->nr_entries; i++) {554		void *data;555		umode_t mode;556		const struct file_operations *fops;557		const struct eventfs_entry *entry = &ei->entries[i];558 559		if (strcmp(name, entry->name) != 0)560			continue;561 562		data = ei->data;563		if (entry->callback(name, &mode, &data, &fops) <= 0)564			goto out;565 566		result = lookup_file_dentry(dentry, ei, i, mode, data, fops);567		goto out;568	}569 out:570	mutex_unlock(&eventfs_mutex);571	return result;572}573 574/*575 * Walk the children of a eventfs_inode to fill in getdents().576 */577static int eventfs_iterate(struct file *file, struct dir_context *ctx)578{579	const struct file_operations *fops;580	struct inode *f_inode = file_inode(file);581	const struct eventfs_entry *entry;582	struct eventfs_inode *ei_child;583	struct tracefs_inode *ti;584	struct eventfs_inode *ei;585	const char *name;586	umode_t mode;587	int idx;588	int ret = -EINVAL;589	int ino;590	int i, r, c;591 592	if (!dir_emit_dots(file, ctx))593		return 0;594 595	ti = get_tracefs(f_inode);596	if (!(ti->flags & TRACEFS_EVENT_INODE))597		return -EINVAL;598 599	c = ctx->pos - 2;600 601	idx = srcu_read_lock(&eventfs_srcu);602 603	mutex_lock(&eventfs_mutex);604	ei = READ_ONCE(ti->private);605	if (ei && ei->is_freed)606		ei = NULL;607	mutex_unlock(&eventfs_mutex);608 609	if (!ei)610		goto out;611 612	/*613	 * Need to create the dentries and inodes to have a consistent614	 * inode number.615	 */616	ret = 0;617 618	/* Start at 'c' to jump over already read entries */619	for (i = c; i < ei->nr_entries; i++, ctx->pos++) {620		void *cdata = ei->data;621 622		entry = &ei->entries[i];623		name = entry->name;624 625		mutex_lock(&eventfs_mutex);626		/* If ei->is_freed then just bail here, nothing more to do */627		if (ei->is_freed) {628			mutex_unlock(&eventfs_mutex);629			goto out;630		}631		r = entry->callback(name, &mode, &cdata, &fops);632		mutex_unlock(&eventfs_mutex);633		if (r <= 0)634			continue;635 636		ino = EVENTFS_FILE_INODE_INO;637 638		if (!dir_emit(ctx, name, strlen(name), ino, DT_REG))639			goto out;640	}641 642	/* Subtract the skipped entries above */643	c -= min((unsigned int)c, (unsigned int)ei->nr_entries);644 645	list_for_each_entry_srcu(ei_child, &ei->children, list,646				 srcu_read_lock_held(&eventfs_srcu)) {647 648		if (c > 0) {649			c--;650			continue;651		}652 653		ctx->pos++;654 655		if (ei_child->is_freed)656			continue;657 658		name = ei_child->name;659 660		ino = eventfs_dir_ino(ei_child);661 662		if (!dir_emit(ctx, name, strlen(name), ino, DT_DIR))663			goto out_dec;664	}665	ret = 1;666 out:667	srcu_read_unlock(&eventfs_srcu, idx);668 669	return ret;670 671 out_dec:672	/* Incremented ctx->pos without adding something, reset it */673	ctx->pos--;674	goto out;675}676 677/**678 * eventfs_create_dir - Create the eventfs_inode for this directory679 * @name: The name of the directory to create.680 * @parent: The eventfs_inode of the parent directory.681 * @entries: A list of entries that represent the files under this directory682 * @size: The number of @entries683 * @data: The default data to pass to the files (an entry may override it).684 *685 * This function creates the descriptor to represent a directory in the686 * eventfs. This descriptor is an eventfs_inode, and it is returned to be687 * used to create other children underneath.688 *689 * The @entries is an array of eventfs_entry structures which has:690 *	const char		 *name691 *	eventfs_callback	callback;692 *693 * The name is the name of the file, and the callback is a pointer to a function694 * that will be called when the file is reference (either by lookup or by695 * reading a directory). The callback is of the prototype:696 *697 *    int callback(const char *name, umode_t *mode, void **data,698 *		   const struct file_operations **fops);699 *700 * When a file needs to be created, this callback will be called with701 *   name = the name of the file being created (so that the same callback702 *          may be used for multiple files).703 *   mode = a place to set the file's mode704 *   data = A pointer to @data, and the callback may replace it, which will705 *         cause the file created to pass the new data to the open() call.706 *   fops = the fops to use for the created file.707 *708 * NB. @callback is called while holding internal locks of the eventfs709 *     system. The callback must not call any code that might also call into710 *     the tracefs or eventfs system or it will risk creating a deadlock.711 */712struct eventfs_inode *eventfs_create_dir(const char *name, struct eventfs_inode *parent,713					 const struct eventfs_entry *entries,714					 int size, void *data)715{716	struct eventfs_inode *ei;717 718	if (!parent)719		return ERR_PTR(-EINVAL);720 721	ei = alloc_ei(name);722	if (!ei)723		return ERR_PTR(-ENOMEM);724 725	ei->entries = entries;726	ei->nr_entries = size;727	ei->data = data;728	INIT_LIST_HEAD(&ei->children);729	INIT_LIST_HEAD(&ei->list);730 731	mutex_lock(&eventfs_mutex);732	if (!parent->is_freed)733		list_add_tail(&ei->list, &parent->children);734	mutex_unlock(&eventfs_mutex);735 736	/* Was the parent freed? */737	if (list_empty(&ei->list)) {738		cleanup_ei(ei);739		ei = ERR_PTR(-EBUSY);740	}741	return ei;742}743 744/**745 * eventfs_create_events_dir - create the top level events directory746 * @name: The name of the top level directory to create.747 * @parent: Parent dentry for this file in the tracefs directory.748 * @entries: A list of entries that represent the files under this directory749 * @size: The number of @entries750 * @data: The default data to pass to the files (an entry may override it).751 *752 * This function creates the top of the trace event directory.753 *754 * See eventfs_create_dir() for use of @entries.755 */756struct eventfs_inode *eventfs_create_events_dir(const char *name, struct dentry *parent,757						const struct eventfs_entry *entries,758						int size, void *data)759{760	struct dentry *dentry = tracefs_start_creating(name, parent);761	struct eventfs_root_inode *rei;762	struct eventfs_inode *ei;763	struct tracefs_inode *ti;764	struct inode *inode;765	kuid_t uid;766	kgid_t gid;767 768	if (security_locked_down(LOCKDOWN_TRACEFS))769		return NULL;770 771	if (IS_ERR(dentry))772		return ERR_CAST(dentry);773 774	ei = alloc_root_ei(name);775	if (!ei)776		goto fail;777 778	inode = tracefs_get_inode(dentry->d_sb);779	if (unlikely(!inode))780		goto fail;781 782	// Note: we have a ref to the dentry from tracefs_start_creating()783	rei = get_root_inode(ei);784	rei->events_dir = dentry;785 786	ei->entries = entries;787	ei->nr_entries = size;788	ei->data = data;789 790	/* Save the ownership of this directory */791	uid = d_inode(dentry->d_parent)->i_uid;792	gid = d_inode(dentry->d_parent)->i_gid;793 794	/*795	 * The ei->attr will be used as the default values for the796	 * files beneath this directory.797	 */798	ei->attr.uid = uid;799	ei->attr.gid = gid;800 801	INIT_LIST_HEAD(&ei->children);802	INIT_LIST_HEAD(&ei->list);803 804	ti = get_tracefs(inode);805	ti->flags |= TRACEFS_EVENT_INODE;806	ti->private = ei;807 808	inode->i_mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO;809	inode->i_uid = uid;810	inode->i_gid = gid;811	inode->i_op = &eventfs_dir_inode_operations;812	inode->i_fop = &eventfs_file_operations;813 814	dentry->d_fsdata = get_ei(ei);815 816	/*817	 * Keep all eventfs directories with i_nlink == 1.818	 * Due to the dynamic nature of the dentry creations and not819	 * wanting to add a pointer to the parent eventfs_inode in the820	 * eventfs_inode structure, keeping the i_nlink in sync with the821	 * number of directories would cause too much complexity for822	 * something not worth much. Keeping directory links at 1823	 * tells userspace not to trust the link number.824	 */825	d_instantiate(dentry, inode);826	/* The dentry of the "events" parent does keep track though */827	inc_nlink(dentry->d_parent->d_inode);828	fsnotify_mkdir(dentry->d_parent->d_inode, dentry);829	tracefs_end_creating(dentry);830 831	return ei;832 833 fail:834	cleanup_ei(ei);835	tracefs_failed_creating(dentry);836	return ERR_PTR(-ENOMEM);837}838 839/**840 * eventfs_remove_rec - remove eventfs dir or file from list841 * @ei: eventfs_inode to be removed.842 * @level: prevent recursion from going more than 3 levels deep.843 *844 * This function recursively removes eventfs_inodes which845 * contains info of files and/or directories.846 */847static void eventfs_remove_rec(struct eventfs_inode *ei, int level)848{849	struct eventfs_inode *ei_child;850 851	/*852	 * Check recursion depth. It should never be greater than 3:853	 * 0 - events/854	 * 1 - events/group/855	 * 2 - events/group/event/856	 * 3 - events/group/event/file857	 */858	if (WARN_ON_ONCE(level > 3))859		return;860 861	/* search for nested folders or files */862	list_for_each_entry(ei_child, &ei->children, list)863		eventfs_remove_rec(ei_child, level + 1);864 865	list_del_rcu(&ei->list);866	free_ei(ei);867}868 869/**870 * eventfs_remove_dir - remove eventfs dir or file from list871 * @ei: eventfs_inode to be removed.872 *873 * This function acquire the eventfs_mutex lock and call eventfs_remove_rec()874 */875void eventfs_remove_dir(struct eventfs_inode *ei)876{877	if (!ei)878		return;879 880	mutex_lock(&eventfs_mutex);881	eventfs_remove_rec(ei, 0);882	mutex_unlock(&eventfs_mutex);883}884 885/**886 * eventfs_remove_events_dir - remove the top level eventfs directory887 * @ei: the event_inode returned by eventfs_create_events_dir().888 *889 * This function removes the events main directory890 */891void eventfs_remove_events_dir(struct eventfs_inode *ei)892{893	struct eventfs_root_inode *rei;894	struct dentry *dentry;895 896	rei = get_root_inode(ei);897	dentry = rei->events_dir;898	if (!dentry)899		return;900 901	rei->events_dir = NULL;902	eventfs_remove_dir(ei);903 904	/*905	 * Matches the dget() done by tracefs_start_creating()906	 * in eventfs_create_events_dir() when it the dentry was907	 * created. In other words, it's a normal dentry that908	 * sticks around while the other ei->dentry are created909	 * and destroyed dynamically.910	 */911	d_invalidate(dentry);912	dput(dentry);913}914