xref: /openbmc/linux/fs/notify/dnotify/dnotify.c (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
13e0a4e85SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2272eb014SEric Paris /*
3272eb014SEric Paris  * Directory notifications for Linux.
4272eb014SEric Paris  *
5272eb014SEric Paris  * Copyright (C) 2000,2001,2002 Stephen Rothwell
6272eb014SEric Paris  *
73c5119c0SEric Paris  * Copyright (C) 2009 Eric Paris <Red Hat Inc>
83c5119c0SEric Paris  * dnotify was largly rewritten to use the new fsnotify infrastructure
9272eb014SEric Paris  */
10272eb014SEric Paris #include <linux/fs.h>
11272eb014SEric Paris #include <linux/module.h>
12272eb014SEric Paris #include <linux/sched.h>
1301919134SEric W. Biederman #include <linux/sched/signal.h>
14272eb014SEric Paris #include <linux/dnotify.h>
15272eb014SEric Paris #include <linux/init.h>
16ac5656d8SAaron Goidel #include <linux/security.h>
17272eb014SEric Paris #include <linux/spinlock.h>
18272eb014SEric Paris #include <linux/slab.h>
19272eb014SEric Paris #include <linux/fdtable.h>
203c5119c0SEric Paris #include <linux/fsnotify_backend.h>
21272eb014SEric Paris 
2249a4de75SXiaoming Ni static int dir_notify_enable __read_mostly = 1;
2349a4de75SXiaoming Ni #ifdef CONFIG_SYSCTL
2449a4de75SXiaoming Ni static struct ctl_table dnotify_sysctls[] = {
2549a4de75SXiaoming Ni 	{
2649a4de75SXiaoming Ni 		.procname	= "dir-notify-enable",
2749a4de75SXiaoming Ni 		.data		= &dir_notify_enable,
2849a4de75SXiaoming Ni 		.maxlen		= sizeof(int),
2949a4de75SXiaoming Ni 		.mode		= 0644,
3049a4de75SXiaoming Ni 		.proc_handler	= proc_dointvec,
3149a4de75SXiaoming Ni 	},
3249a4de75SXiaoming Ni 	{}
3349a4de75SXiaoming Ni };
dnotify_sysctl_init(void)3449a4de75SXiaoming Ni static void __init dnotify_sysctl_init(void)
3549a4de75SXiaoming Ni {
3649a4de75SXiaoming Ni 	register_sysctl_init("fs", dnotify_sysctls);
3749a4de75SXiaoming Ni }
3849a4de75SXiaoming Ni #else
3949a4de75SXiaoming Ni #define dnotify_sysctl_init() do { } while (0)
4049a4de75SXiaoming Ni #endif
41272eb014SEric Paris 
423c5119c0SEric Paris static struct kmem_cache *dnotify_struct_cache __read_mostly;
43ef5e2b78SEric Paris static struct kmem_cache *dnotify_mark_cache __read_mostly;
443c5119c0SEric Paris static struct fsnotify_group *dnotify_group __read_mostly;
45272eb014SEric Paris 
463c5119c0SEric Paris /*
47e61ce867SEric Paris  * dnotify will attach one of these to each inode (i_fsnotify_marks) which
483c5119c0SEric Paris  * is being watched by dnotify.  If multiple userspace applications are watching
493c5119c0SEric Paris  * the same directory with dnotify their information is chained in dn
503c5119c0SEric Paris  */
51ef5e2b78SEric Paris struct dnotify_mark {
52ef5e2b78SEric Paris 	struct fsnotify_mark fsn_mark;
53272eb014SEric Paris 	struct dnotify_struct *dn;
543c5119c0SEric Paris };
55272eb014SEric Paris 
563c5119c0SEric Paris /*
573c5119c0SEric Paris  * When a process starts or stops watching an inode the set of events which
583c5119c0SEric Paris  * dnotify cares about for that inode may change.  This function runs the
593c5119c0SEric Paris  * list of everything receiving dnotify events about this directory and calculates
603c5119c0SEric Paris  * the set of all those events.  After it updates what dnotify is interested in
613c5119c0SEric Paris  * it calls the fsnotify function so it can update the set of all events relevant
623c5119c0SEric Paris  * to this inode.
633c5119c0SEric Paris  */
dnotify_recalc_inode_mask(struct fsnotify_mark * fsn_mark)64ef5e2b78SEric Paris static void dnotify_recalc_inode_mask(struct fsnotify_mark *fsn_mark)
653c5119c0SEric Paris {
6666d2b81bSJan Kara 	__u32 new_mask = 0;
673c5119c0SEric Paris 	struct dnotify_struct *dn;
68ef5e2b78SEric Paris 	struct dnotify_mark *dn_mark  = container_of(fsn_mark,
69ef5e2b78SEric Paris 						     struct dnotify_mark,
70ef5e2b78SEric Paris 						     fsn_mark);
713c5119c0SEric Paris 
72ef5e2b78SEric Paris 	assert_spin_locked(&fsn_mark->lock);
733c5119c0SEric Paris 
74ef5e2b78SEric Paris 	for (dn = dn_mark->dn; dn != NULL; dn = dn->dn_next)
753c5119c0SEric Paris 		new_mask |= (dn->dn_mask & ~FS_DN_MULTISHOT);
7666d2b81bSJan Kara 	if (fsn_mark->mask == new_mask)
77272eb014SEric Paris 		return;
7866d2b81bSJan Kara 	fsn_mark->mask = new_mask;
793c5119c0SEric Paris 
80a242677bSJan Kara 	fsnotify_recalc_mask(fsn_mark->connector);
81272eb014SEric Paris }
82272eb014SEric Paris 
833c5119c0SEric Paris /*
843c5119c0SEric Paris  * Mains fsnotify call where events are delivered to dnotify.
853c5119c0SEric Paris  * Find the dnotify mark on the relevant inode, run the list of dnotify structs
863c5119c0SEric Paris  * on that mark and determine which of them has expressed interest in receiving
873c5119c0SEric Paris  * events of this type.  When found send the correct process and signal and
883c5119c0SEric Paris  * destroy the dnotify struct if it was not registered to receive multiple
893c5119c0SEric Paris  * events.
903c5119c0SEric Paris  */
dnotify_handle_event(struct fsnotify_mark * inode_mark,u32 mask,struct inode * inode,struct inode * dir,const struct qstr * name,u32 cookie)91b9a1b977SAmir Goldstein static int dnotify_handle_event(struct fsnotify_mark *inode_mark, u32 mask,
92b9a1b977SAmir Goldstein 				struct inode *inode, struct inode *dir,
93950cc0d2SAmir Goldstein 				const struct qstr *name, u32 cookie)
94272eb014SEric Paris {
95ef5e2b78SEric Paris 	struct dnotify_mark *dn_mark;
96272eb014SEric Paris 	struct dnotify_struct *dn;
97272eb014SEric Paris 	struct dnotify_struct **prev;
98272eb014SEric Paris 	struct fown_struct *fown;
997053aee2SJan Kara 	__u32 test_mask = mask & ~FS_EVENT_ON_CHILD;
100272eb014SEric Paris 
101b9a1b977SAmir Goldstein 	/* not a dir, dnotify doesn't care */
102b9a1b977SAmir Goldstein 	if (!dir && !(mask & FS_ISDIR))
103b9a1b977SAmir Goldstein 		return 0;
104b9a1b977SAmir Goldstein 
105ce8f76fbSEric Paris 	dn_mark = container_of(inode_mark, struct dnotify_mark, fsn_mark);
1063c5119c0SEric Paris 
107ce8f76fbSEric Paris 	spin_lock(&inode_mark->lock);
108ef5e2b78SEric Paris 	prev = &dn_mark->dn;
109272eb014SEric Paris 	while ((dn = *prev) != NULL) {
11094552684SAndreas Gruenbacher 		if ((dn->dn_mask & test_mask) == 0) {
111272eb014SEric Paris 			prev = &dn->dn_next;
112272eb014SEric Paris 			continue;
113272eb014SEric Paris 		}
114272eb014SEric Paris 		fown = &dn->dn_filp->f_owner;
115272eb014SEric Paris 		send_sigio(fown, dn->dn_fd, POLL_MSG);
1163c5119c0SEric Paris 		if (dn->dn_mask & FS_DN_MULTISHOT)
117272eb014SEric Paris 			prev = &dn->dn_next;
118272eb014SEric Paris 		else {
119272eb014SEric Paris 			*prev = dn->dn_next;
1203c5119c0SEric Paris 			kmem_cache_free(dnotify_struct_cache, dn);
121ce8f76fbSEric Paris 			dnotify_recalc_inode_mask(inode_mark);
122272eb014SEric Paris 		}
123272eb014SEric Paris 	}
124272eb014SEric Paris 
125ce8f76fbSEric Paris 	spin_unlock(&inode_mark->lock);
1263c5119c0SEric Paris 
1273c5119c0SEric Paris 	return 0;
1283c5119c0SEric Paris }
129272eb014SEric Paris 
dnotify_free_mark(struct fsnotify_mark * fsn_mark)130ef5e2b78SEric Paris static void dnotify_free_mark(struct fsnotify_mark *fsn_mark)
1313c5119c0SEric Paris {
132ef5e2b78SEric Paris 	struct dnotify_mark *dn_mark = container_of(fsn_mark,
133ef5e2b78SEric Paris 						    struct dnotify_mark,
134ef5e2b78SEric Paris 						    fsn_mark);
1353c5119c0SEric Paris 
136ef5e2b78SEric Paris 	BUG_ON(dn_mark->dn);
1373c5119c0SEric Paris 
138ef5e2b78SEric Paris 	kmem_cache_free(dnotify_mark_cache, dn_mark);
1393c5119c0SEric Paris }
1403c5119c0SEric Paris 
141c9ea9df3SBhumika Goyal static const struct fsnotify_ops dnotify_fsnotify_ops = {
142b9a1b977SAmir Goldstein 	.handle_inode_event = dnotify_handle_event,
143054c636eSJan Kara 	.free_mark = dnotify_free_mark,
1443c5119c0SEric Paris };
1453c5119c0SEric Paris 
1463c5119c0SEric Paris /*
1473c5119c0SEric Paris  * Called every time a file is closed.  Looks first for a dnotify mark on the
148e61ce867SEric Paris  * inode.  If one is found run all of the ->dn structures attached to that
1493c5119c0SEric Paris  * mark for one relevant to this process closing the file and remove that
1503c5119c0SEric Paris  * dnotify_struct.  If that was the last dnotify_struct also remove the
151e61ce867SEric Paris  * fsnotify_mark.
1523c5119c0SEric Paris  */
dnotify_flush(struct file * filp,fl_owner_t id)1533c5119c0SEric Paris void dnotify_flush(struct file *filp, fl_owner_t id)
1543c5119c0SEric Paris {
155ef5e2b78SEric Paris 	struct fsnotify_mark *fsn_mark;
156ef5e2b78SEric Paris 	struct dnotify_mark *dn_mark;
1573c5119c0SEric Paris 	struct dnotify_struct *dn;
1583c5119c0SEric Paris 	struct dnotify_struct **prev;
1593c5119c0SEric Paris 	struct inode *inode;
1604712e722SJan Kara 	bool free = false;
1613c5119c0SEric Paris 
162496ad9aaSAl Viro 	inode = file_inode(filp);
1633c5119c0SEric Paris 	if (!S_ISDIR(inode->i_mode))
164272eb014SEric Paris 		return;
165272eb014SEric Paris 
166b1362edfSJan Kara 	fsn_mark = fsnotify_find_mark(&inode->i_fsnotify_marks, dnotify_group);
167ef5e2b78SEric Paris 	if (!fsn_mark)
1683c5119c0SEric Paris 		return;
169ef5e2b78SEric Paris 	dn_mark = container_of(fsn_mark, struct dnotify_mark, fsn_mark);
1703c5119c0SEric Paris 
171aabb45fdSAmir Goldstein 	fsnotify_group_lock(dnotify_group);
1723c5119c0SEric Paris 
173ef5e2b78SEric Paris 	spin_lock(&fsn_mark->lock);
174ef5e2b78SEric Paris 	prev = &dn_mark->dn;
1753c5119c0SEric Paris 	while ((dn = *prev) != NULL) {
1763c5119c0SEric Paris 		if ((dn->dn_owner == id) && (dn->dn_filp == filp)) {
1773c5119c0SEric Paris 			*prev = dn->dn_next;
1783c5119c0SEric Paris 			kmem_cache_free(dnotify_struct_cache, dn);
179ef5e2b78SEric Paris 			dnotify_recalc_inode_mask(fsn_mark);
1803c5119c0SEric Paris 			break;
1813c5119c0SEric Paris 		}
1823c5119c0SEric Paris 		prev = &dn->dn_next;
1833c5119c0SEric Paris 	}
1843c5119c0SEric Paris 
185ef5e2b78SEric Paris 	spin_unlock(&fsn_mark->lock);
1863c5119c0SEric Paris 
18752f85729SLino Sanfilippo 	/* nothing else could have found us thanks to the dnotify_groups
18852f85729SLino Sanfilippo 	   mark_mutex */
1894712e722SJan Kara 	if (dn_mark->dn == NULL) {
1904712e722SJan Kara 		fsnotify_detach_mark(fsn_mark);
1914712e722SJan Kara 		free = true;
1924712e722SJan Kara 	}
1933c5119c0SEric Paris 
194aabb45fdSAmir Goldstein 	fsnotify_group_unlock(dnotify_group);
1953c5119c0SEric Paris 
1964712e722SJan Kara 	if (free)
1974712e722SJan Kara 		fsnotify_free_mark(fsn_mark);
198ef5e2b78SEric Paris 	fsnotify_put_mark(fsn_mark);
1993c5119c0SEric Paris }
2003c5119c0SEric Paris 
2013c5119c0SEric Paris /* this conversion is done only at watch creation */
convert_arg(unsigned int arg)202*f4ae4081SLuca Vizzarro static __u32 convert_arg(unsigned int arg)
2033c5119c0SEric Paris {
2043c5119c0SEric Paris 	__u32 new_mask = FS_EVENT_ON_CHILD;
2053c5119c0SEric Paris 
2063c5119c0SEric Paris 	if (arg & DN_MULTISHOT)
2073c5119c0SEric Paris 		new_mask |= FS_DN_MULTISHOT;
2083c5119c0SEric Paris 	if (arg & DN_DELETE)
2093c5119c0SEric Paris 		new_mask |= (FS_DELETE | FS_MOVED_FROM);
2103c5119c0SEric Paris 	if (arg & DN_MODIFY)
2113c5119c0SEric Paris 		new_mask |= FS_MODIFY;
2123c5119c0SEric Paris 	if (arg & DN_ACCESS)
2133c5119c0SEric Paris 		new_mask |= FS_ACCESS;
2143c5119c0SEric Paris 	if (arg & DN_ATTRIB)
2153c5119c0SEric Paris 		new_mask |= FS_ATTRIB;
2163c5119c0SEric Paris 	if (arg & DN_RENAME)
217e54183faSAmir Goldstein 		new_mask |= FS_RENAME;
2183c5119c0SEric Paris 	if (arg & DN_CREATE)
2193c5119c0SEric Paris 		new_mask |= (FS_CREATE | FS_MOVED_TO);
2203c5119c0SEric Paris 
2213c5119c0SEric Paris 	return new_mask;
2223c5119c0SEric Paris }
2233c5119c0SEric Paris 
2243c5119c0SEric Paris /*
2253c5119c0SEric Paris  * If multiple processes watch the same inode with dnotify there is only one
226e61ce867SEric Paris  * dnotify mark in inode->i_fsnotify_marks but we chain a dnotify_struct
2273c5119c0SEric Paris  * onto that mark.  This function either attaches the new dnotify_struct onto
2283c5119c0SEric Paris  * that list, or it |= the mask onto an existing dnofiy_struct.
2293c5119c0SEric Paris  */
attach_dn(struct dnotify_struct * dn,struct dnotify_mark * dn_mark,fl_owner_t id,int fd,struct file * filp,__u32 mask)230ef5e2b78SEric Paris static int attach_dn(struct dnotify_struct *dn, struct dnotify_mark *dn_mark,
2313c5119c0SEric Paris 		     fl_owner_t id, int fd, struct file *filp, __u32 mask)
2323c5119c0SEric Paris {
2333c5119c0SEric Paris 	struct dnotify_struct *odn;
2343c5119c0SEric Paris 
235ef5e2b78SEric Paris 	odn = dn_mark->dn;
2363c5119c0SEric Paris 	while (odn != NULL) {
2373c5119c0SEric Paris 		/* adding more events to existing dnofiy_struct? */
2383c5119c0SEric Paris 		if ((odn->dn_owner == id) && (odn->dn_filp == filp)) {
2393c5119c0SEric Paris 			odn->dn_fd = fd;
2403c5119c0SEric Paris 			odn->dn_mask |= mask;
2413c5119c0SEric Paris 			return -EEXIST;
2423c5119c0SEric Paris 		}
2433c5119c0SEric Paris 		odn = odn->dn_next;
2443c5119c0SEric Paris 	}
2453c5119c0SEric Paris 
2463c5119c0SEric Paris 	dn->dn_mask = mask;
2473c5119c0SEric Paris 	dn->dn_fd = fd;
2483c5119c0SEric Paris 	dn->dn_filp = filp;
2493c5119c0SEric Paris 	dn->dn_owner = id;
250ef5e2b78SEric Paris 	dn->dn_next = dn_mark->dn;
251ef5e2b78SEric Paris 	dn_mark->dn = dn;
2523c5119c0SEric Paris 
2533c5119c0SEric Paris 	return 0;
2543c5119c0SEric Paris }
2553c5119c0SEric Paris 
2563c5119c0SEric Paris /*
2573c5119c0SEric Paris  * When a process calls fcntl to attach a dnotify watch to a directory it ends
2583c5119c0SEric Paris  * up here.  Allocate both a mark for fsnotify to add and a dnotify_struct to be
2593c5119c0SEric Paris  * attached to the fsnotify_mark.
2603c5119c0SEric Paris  */
fcntl_dirnotify(int fd,struct file * filp,unsigned int arg)261*f4ae4081SLuca Vizzarro int fcntl_dirnotify(int fd, struct file *filp, unsigned int arg)
2623c5119c0SEric Paris {
263ef5e2b78SEric Paris 	struct dnotify_mark *new_dn_mark, *dn_mark;
264ef5e2b78SEric Paris 	struct fsnotify_mark *new_fsn_mark, *fsn_mark;
2653c5119c0SEric Paris 	struct dnotify_struct *dn;
2663c5119c0SEric Paris 	struct inode *inode;
2673c5119c0SEric Paris 	fl_owner_t id = current->files;
2683c5119c0SEric Paris 	struct file *f;
2693c5119c0SEric Paris 	int destroy = 0, error = 0;
2703c5119c0SEric Paris 	__u32 mask;
2713c5119c0SEric Paris 
2723c5119c0SEric Paris 	/* we use these to tell if we need to kfree */
273ef5e2b78SEric Paris 	new_fsn_mark = NULL;
2743c5119c0SEric Paris 	dn = NULL;
2753c5119c0SEric Paris 
2763c5119c0SEric Paris 	if (!dir_notify_enable) {
2773c5119c0SEric Paris 		error = -EINVAL;
2783c5119c0SEric Paris 		goto out_err;
2793c5119c0SEric Paris 	}
2803c5119c0SEric Paris 
2813c5119c0SEric Paris 	/* a 0 mask means we are explicitly removing the watch */
2823c5119c0SEric Paris 	if ((arg & ~DN_MULTISHOT) == 0) {
2833c5119c0SEric Paris 		dnotify_flush(filp, id);
2843c5119c0SEric Paris 		error = 0;
2853c5119c0SEric Paris 		goto out_err;
2863c5119c0SEric Paris 	}
2873c5119c0SEric Paris 
2883c5119c0SEric Paris 	/* dnotify only works on directories */
289496ad9aaSAl Viro 	inode = file_inode(filp);
2903c5119c0SEric Paris 	if (!S_ISDIR(inode->i_mode)) {
2913c5119c0SEric Paris 		error = -ENOTDIR;
2923c5119c0SEric Paris 		goto out_err;
2933c5119c0SEric Paris 	}
2943c5119c0SEric Paris 
295ac5656d8SAaron Goidel 	/*
296ac5656d8SAaron Goidel 	 * convert the userspace DN_* "arg" to the internal FS_*
297ac5656d8SAaron Goidel 	 * defined in fsnotify
298ac5656d8SAaron Goidel 	 */
299ac5656d8SAaron Goidel 	mask = convert_arg(arg);
300ac5656d8SAaron Goidel 
301ac5656d8SAaron Goidel 	error = security_path_notify(&filp->f_path, mask,
302ac5656d8SAaron Goidel 			FSNOTIFY_OBJ_TYPE_INODE);
303ac5656d8SAaron Goidel 	if (error)
304ac5656d8SAaron Goidel 		goto out_err;
305ac5656d8SAaron Goidel 
3063c5119c0SEric Paris 	/* expect most fcntl to add new rather than augment old */
3073c5119c0SEric Paris 	dn = kmem_cache_alloc(dnotify_struct_cache, GFP_KERNEL);
3083c5119c0SEric Paris 	if (!dn) {
3093c5119c0SEric Paris 		error = -ENOMEM;
3103c5119c0SEric Paris 		goto out_err;
3113c5119c0SEric Paris 	}
3123c5119c0SEric Paris 
3133c5119c0SEric Paris 	/* new fsnotify mark, we expect most fcntl calls to add a new mark */
314ef5e2b78SEric Paris 	new_dn_mark = kmem_cache_alloc(dnotify_mark_cache, GFP_KERNEL);
315ef5e2b78SEric Paris 	if (!new_dn_mark) {
3163c5119c0SEric Paris 		error = -ENOMEM;
3173c5119c0SEric Paris 		goto out_err;
3183c5119c0SEric Paris 	}
3193c5119c0SEric Paris 
320ef5e2b78SEric Paris 	/* set up the new_fsn_mark and new_dn_mark */
321ef5e2b78SEric Paris 	new_fsn_mark = &new_dn_mark->fsn_mark;
322054c636eSJan Kara 	fsnotify_init_mark(new_fsn_mark, dnotify_group);
323ef5e2b78SEric Paris 	new_fsn_mark->mask = mask;
324ef5e2b78SEric Paris 	new_dn_mark->dn = NULL;
3253c5119c0SEric Paris 
3263c5119c0SEric Paris 	/* this is needed to prevent the fcntl/close race described below */
327aabb45fdSAmir Goldstein 	fsnotify_group_lock(dnotify_group);
3283c5119c0SEric Paris 
329ef5e2b78SEric Paris 	/* add the new_fsn_mark or find an old one. */
330b1362edfSJan Kara 	fsn_mark = fsnotify_find_mark(&inode->i_fsnotify_marks, dnotify_group);
331ef5e2b78SEric Paris 	if (fsn_mark) {
332ef5e2b78SEric Paris 		dn_mark = container_of(fsn_mark, struct dnotify_mark, fsn_mark);
333ef5e2b78SEric Paris 		spin_lock(&fsn_mark->lock);
334272eb014SEric Paris 	} else {
335b249f5beSAmir Goldstein 		error = fsnotify_add_inode_mark_locked(new_fsn_mark, inode, 0);
336b3a00660SJan Kara 		if (error) {
337aabb45fdSAmir Goldstein 			fsnotify_group_unlock(dnotify_group);
338b3a00660SJan Kara 			goto out_err;
339b3a00660SJan Kara 		}
340ef5e2b78SEric Paris 		spin_lock(&new_fsn_mark->lock);
341ef5e2b78SEric Paris 		fsn_mark = new_fsn_mark;
342ef5e2b78SEric Paris 		dn_mark = new_dn_mark;
343ef5e2b78SEric Paris 		/* we used new_fsn_mark, so don't free it */
344ef5e2b78SEric Paris 		new_fsn_mark = NULL;
345272eb014SEric Paris 	}
3463c5119c0SEric Paris 
3473c5119c0SEric Paris 	rcu_read_lock();
348460b4f81SEric W. Biederman 	f = lookup_fd_rcu(fd);
3493c5119c0SEric Paris 	rcu_read_unlock();
3503c5119c0SEric Paris 
3513c5119c0SEric Paris 	/* if (f != filp) means that we lost a race and another task/thread
3523c5119c0SEric Paris 	 * actually closed the fd we are still playing with before we grabbed
35352f85729SLino Sanfilippo 	 * the dnotify_groups mark_mutex and fsn_mark->lock.  Since closing the
35452f85729SLino Sanfilippo 	 * fd is the only time we clean up the marks we need to get our mark
35552f85729SLino Sanfilippo 	 * off the list. */
3563c5119c0SEric Paris 	if (f != filp) {
3573c5119c0SEric Paris 		/* if we added ourselves, shoot ourselves, it's possible that
358ef5e2b78SEric Paris 		 * the flush actually did shoot this fsn_mark.  That's fine too
3593c5119c0SEric Paris 		 * since multiple calls to destroy_mark is perfectly safe, if
360ef5e2b78SEric Paris 		 * we found a dn_mark already attached to the inode, just sod
3613c5119c0SEric Paris 		 * off silently as the flush at close time dealt with it.
3623c5119c0SEric Paris 		 */
363ef5e2b78SEric Paris 		if (dn_mark == new_dn_mark)
3643c5119c0SEric Paris 			destroy = 1;
365b3a00660SJan Kara 		error = 0;
3663c5119c0SEric Paris 		goto out;
367272eb014SEric Paris 	}
3683c5119c0SEric Paris 
36901919134SEric W. Biederman 	__f_setown(filp, task_pid(current), PIDTYPE_TGID, 0);
3703c5119c0SEric Paris 
371ef5e2b78SEric Paris 	error = attach_dn(dn, dn_mark, id, fd, filp, mask);
372ef5e2b78SEric Paris 	/* !error means that we attached the dn to the dn_mark, so don't free it */
3733c5119c0SEric Paris 	if (!error)
3743c5119c0SEric Paris 		dn = NULL;
3753c5119c0SEric Paris 	/* -EEXIST means that we didn't add this new dn and used an old one.
3763c5119c0SEric Paris 	 * that isn't an error (and the unused dn should be freed) */
3773c5119c0SEric Paris 	else if (error == -EEXIST)
3783c5119c0SEric Paris 		error = 0;
3793c5119c0SEric Paris 
380ef5e2b78SEric Paris 	dnotify_recalc_inode_mask(fsn_mark);
3813c5119c0SEric Paris out:
382ef5e2b78SEric Paris 	spin_unlock(&fsn_mark->lock);
3833c5119c0SEric Paris 
3843c5119c0SEric Paris 	if (destroy)
3854712e722SJan Kara 		fsnotify_detach_mark(fsn_mark);
386aabb45fdSAmir Goldstein 	fsnotify_group_unlock(dnotify_group);
3874712e722SJan Kara 	if (destroy)
3884712e722SJan Kara 		fsnotify_free_mark(fsn_mark);
389ef5e2b78SEric Paris 	fsnotify_put_mark(fsn_mark);
3903c5119c0SEric Paris out_err:
391ef5e2b78SEric Paris 	if (new_fsn_mark)
392ef5e2b78SEric Paris 		fsnotify_put_mark(new_fsn_mark);
3933c5119c0SEric Paris 	if (dn)
3943c5119c0SEric Paris 		kmem_cache_free(dnotify_struct_cache, dn);
3953c5119c0SEric Paris 	return error;
3963c5119c0SEric Paris }
397272eb014SEric Paris 
dnotify_init(void)398272eb014SEric Paris static int __init dnotify_init(void)
399272eb014SEric Paris {
400d46eb14bSShakeel Butt 	dnotify_struct_cache = KMEM_CACHE(dnotify_struct,
401d46eb14bSShakeel Butt 					  SLAB_PANIC|SLAB_ACCOUNT);
402d46eb14bSShakeel Butt 	dnotify_mark_cache = KMEM_CACHE(dnotify_mark, SLAB_PANIC|SLAB_ACCOUNT);
4033c5119c0SEric Paris 
404aabb45fdSAmir Goldstein 	dnotify_group = fsnotify_alloc_group(&dnotify_fsnotify_ops,
405aabb45fdSAmir Goldstein 					     FSNOTIFY_GROUP_NOFS);
4063c5119c0SEric Paris 	if (IS_ERR(dnotify_group))
4073c5119c0SEric Paris 		panic("unable to allocate fsnotify group for dnotify\n");
40849a4de75SXiaoming Ni 	dnotify_sysctl_init();
409272eb014SEric Paris 	return 0;
410272eb014SEric Paris }
411272eb014SEric Paris 
412272eb014SEric Paris module_init(dnotify_init)
413