inotify.c 19.2 KB
Newer Older
R
Robert Love 已提交
1 2 3 4 5 6 7
/*
 * fs/inotify.c - inode-based file event notifications
 *
 * Authors:
 *	John McCutchan	<ttb@tentacle.dhs.org>
 *	Robert Love	<rml@novell.com>
 *
8 9
 * Kernel API added by: Amy Griffis <amy.griffis@hp.com>
 *
R
Robert Love 已提交
10
 * Copyright (C) 2005 John McCutchan
11
 * Copyright 2006 Hewlett-Packard Development Company, L.P.
R
Robert Love 已提交
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2, or (at your option) any
 * later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 */

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/spinlock.h>
#include <linux/idr.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/list.h>
#include <linux/writeback.h>
#include <linux/inotify.h>

static atomic_t inotify_cookie;

/*
 * Lock ordering:
 *
 * dentry->d_lock (used to keep d_move() away from dentry->d_parent)
I
Ingo Molnar 已提交
41
 * iprune_mutex (synchronize shrink_icache_memory())
R
Robert Love 已提交
42
 * 	inode_lock (protects the super_block->s_inodes list)
I
Ingo Molnar 已提交
43
 * 	inode->inotify_mutex (protects inode->inotify_watches and watches->i_list)
44 45 46 47 48 49
 * 		inotify_handle->mutex (protects inotify_handle and watches->h_list)
 *
 * The inode->inotify_mutex and inotify_handle->mutex and held during execution
 * of a caller's event handler.  Thus, the caller must not hold any locks
 * taken in their event handler while calling any of the published inotify
 * interfaces.
R
Robert Love 已提交
50 51 52
 */

/*
53
 * Lifetimes of the three main data structures--inotify_handle, inode, and
R
Robert Love 已提交
54 55
 * inotify_watch--are managed by reference count.
 *
56 57 58
 * inotify_handle: Lifetime is from inotify_init() to inotify_destroy().
 * Additional references can bump the count via get_inotify_handle() and drop
 * the count via put_inotify_handle().
R
Robert Love 已提交
59
 *
60 61 62 63 64 65
 * inotify_watch: for inotify's purposes, lifetime is from inotify_add_watch()
 * to remove_watch_no_event().  Additional references can bump the count via
 * get_inotify_watch() and drop the count via put_inotify_watch().  The caller
 * is reponsible for the final put after receiving IN_IGNORED, or when using
 * IN_ONESHOT after receiving the first event.  Inotify does the final put if
 * inotify_destroy() is called.
R
Robert Love 已提交
66 67
 *
 * inode: Pinned so long as the inode is associated with a watch, from
68
 * inotify_add_watch() to the final put_inotify_watch().
R
Robert Love 已提交
69 70 71
 */

/*
72
 * struct inotify_handle - represents an inotify instance
R
Robert Love 已提交
73
 *
I
Ingo Molnar 已提交
74
 * This structure is protected by the mutex 'mutex'.
R
Robert Love 已提交
75
 */
76
struct inotify_handle {
R
Robert Love 已提交
77
	struct idr		idr;		/* idr mapping wd -> watch */
I
Ingo Molnar 已提交
78
	struct mutex		mutex;		/* protects this bad boy */
R
Robert Love 已提交
79 80
	struct list_head	watches;	/* list of watches */
	atomic_t		count;		/* reference count */
81
	u32			last_wd;	/* the last wd allocated */
82
	const struct inotify_operations *in_ops; /* inotify caller operations */
R
Robert Love 已提交
83 84
};

85
static inline void get_inotify_handle(struct inotify_handle *ih)
R
Robert Love 已提交
86
{
87
	atomic_inc(&ih->count);
R
Robert Love 已提交
88 89
}

90
static inline void put_inotify_handle(struct inotify_handle *ih)
R
Robert Love 已提交
91
{
92 93 94
	if (atomic_dec_and_test(&ih->count)) {
		idr_destroy(&ih->idr);
		kfree(ih);
R
Robert Love 已提交
95 96 97
	}
}

98 99 100 101 102
/**
 * get_inotify_watch - grab a reference to an inotify_watch
 * @watch: watch to grab
 */
void get_inotify_watch(struct inotify_watch *watch)
R
Robert Love 已提交
103 104 105
{
	atomic_inc(&watch->count);
}
106
EXPORT_SYMBOL_GPL(get_inotify_watch);
R
Robert Love 已提交
107

108
/**
R
Robert Love 已提交
109
 * put_inotify_watch - decrements the ref count on a given watch.  cleans up
110 111 112
 * watch references if the count reaches zero.  inotify_watch is freed by
 * inotify callers via the destroy_watch() op.
 * @watch: watch to release
R
Robert Love 已提交
113
 */
114
void put_inotify_watch(struct inotify_watch *watch)
R
Robert Love 已提交
115 116
{
	if (atomic_dec_and_test(&watch->count)) {
117
		struct inotify_handle *ih = watch->ih;
R
Robert Love 已提交
118

119 120 121
		iput(watch->inode);
		ih->in_ops->destroy_watch(watch);
		put_inotify_handle(ih);
R
Robert Love 已提交
122 123
	}
}
124
EXPORT_SYMBOL_GPL(put_inotify_watch);
R
Robert Love 已提交
125 126

/*
127
 * inotify_handle_get_wd - returns the next WD for use by the given handle
R
Robert Love 已提交
128
 *
129
 * Callers must hold ih->mutex.  This function can sleep.
R
Robert Love 已提交
130
 */
131 132
static int inotify_handle_get_wd(struct inotify_handle *ih,
				 struct inotify_watch *watch)
R
Robert Love 已提交
133 134 135 136
{
	int ret;

	do {
137
		if (unlikely(!idr_pre_get(&ih->idr, GFP_KERNEL)))
R
Robert Love 已提交
138
			return -ENOSPC;
139
		ret = idr_get_new_above(&ih->idr, watch, ih->last_wd+1, &watch->wd);
R
Robert Love 已提交
140 141
	} while (ret == -EAGAIN);

142 143
	if (likely(!ret))
		ih->last_wd = watch->wd;
R
Robert Love 已提交
144

145
	return ret;
R
Robert Love 已提交
146 147
}

148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
/*
 * inotify_inode_watched - returns nonzero if there are watches on this inode
 * and zero otherwise.  We call this lockless, we do not care if we race.
 */
static inline int inotify_inode_watched(struct inode *inode)
{
	return !list_empty(&inode->inotify_watches);
}

/*
 * Get child dentry flag into synch with parent inode.
 * Flag should always be clear for negative dentrys.
 */
static void set_dentry_child_flags(struct inode *inode, int watched)
{
	struct dentry *alias;

	spin_lock(&dcache_lock);
	list_for_each_entry(alias, &inode->i_dentry, d_alias) {
		struct dentry *child;

		list_for_each_entry(child, &alias->d_subdirs, d_u.d_child) {
			if (!child->d_inode) {
				WARN_ON(child->d_flags & DCACHE_INOTIFY_PARENT_WATCHED);
				continue;
			}
			spin_lock(&child->d_lock);
			if (watched) {
				WARN_ON(child->d_flags &
						DCACHE_INOTIFY_PARENT_WATCHED);
				child->d_flags |= DCACHE_INOTIFY_PARENT_WATCHED;
			} else {
				WARN_ON(!(child->d_flags &
					DCACHE_INOTIFY_PARENT_WATCHED));
				child->d_flags&=~DCACHE_INOTIFY_PARENT_WATCHED;
			}
			spin_unlock(&child->d_lock);
		}
	}
	spin_unlock(&dcache_lock);
}

R
Robert Love 已提交
190
/*
191 192
 * inotify_find_handle - find the watch associated with the given inode and
 * handle
R
Robert Love 已提交
193
 *
I
Ingo Molnar 已提交
194
 * Callers must hold inode->inotify_mutex.
R
Robert Love 已提交
195
 */
196 197
static struct inotify_watch *inode_find_handle(struct inode *inode,
					       struct inotify_handle *ih)
R
Robert Love 已提交
198 199 200 201
{
	struct inotify_watch *watch;

	list_for_each_entry(watch, &inode->inotify_watches, i_list) {
202
		if (watch->ih == ih)
R
Robert Love 已提交
203 204 205 206 207 208 209
			return watch;
	}

	return NULL;
}

/*
210
 * remove_watch_no_event - remove watch without the IN_IGNORED event.
211 212
 *
 * Callers must hold both inode->inotify_mutex and ih->mutex.
R
Robert Love 已提交
213 214
 */
static void remove_watch_no_event(struct inotify_watch *watch,
215
				  struct inotify_handle *ih)
R
Robert Love 已提交
216 217
{
	list_del(&watch->i_list);
218
	list_del(&watch->h_list);
R
Robert Love 已提交
219

220 221 222
	if (!inotify_inode_watched(watch->inode))
		set_dentry_child_flags(watch->inode, 0);

223
	idr_remove(&ih->idr, watch->wd);
R
Robert Love 已提交
224 225
}

226 227 228 229 230 231
/**
 * inotify_remove_watch_locked - Remove a watch from both the handle and the
 * inode.  Sends the IN_IGNORED event signifying that the inode is no longer
 * watched.  May be invoked from a caller's event handler.
 * @ih: inotify handle associated with watch
 * @watch: watch to remove
R
Robert Love 已提交
232
 *
233
 * Callers must hold both inode->inotify_mutex and ih->mutex.
R
Robert Love 已提交
234
 */
235 236
void inotify_remove_watch_locked(struct inotify_handle *ih,
				 struct inotify_watch *watch)
R
Robert Love 已提交
237
{
238
	remove_watch_no_event(watch, ih);
239
	ih->in_ops->handle_event(watch, watch->wd, IN_IGNORED, 0, NULL, NULL);
R
Robert Love 已提交
240
}
241
EXPORT_SYMBOL_GPL(inotify_remove_watch_locked);
R
Robert Love 已提交
242

243
/* Kernel API for producing events */
244

R
Robert Love 已提交
245
/*
246
 * inotify_d_instantiate - instantiate dcache entry for inode
R
Robert Love 已提交
247
 */
248
void inotify_d_instantiate(struct dentry *entry, struct inode *inode)
R
Robert Love 已提交
249
{
250 251 252 253 254 255 256 257
	struct dentry *parent;

	if (!inode)
		return;

	WARN_ON(entry->d_flags & DCACHE_INOTIFY_PARENT_WATCHED);
	spin_lock(&entry->d_lock);
	parent = entry->d_parent;
258
	if (parent->d_inode && inotify_inode_watched(parent->d_inode))
259 260
		entry->d_flags |= DCACHE_INOTIFY_PARENT_WATCHED;
	spin_unlock(&entry->d_lock);
R
Robert Love 已提交
261 262
}

263 264 265 266 267 268 269 270 271 272 273 274 275
/*
 * inotify_d_move - dcache entry has been moved
 */
void inotify_d_move(struct dentry *entry)
{
	struct dentry *parent;

	parent = entry->d_parent;
	if (inotify_inode_watched(parent->d_inode))
		entry->d_flags |= DCACHE_INOTIFY_PARENT_WATCHED;
	else
		entry->d_flags &= ~DCACHE_INOTIFY_PARENT_WATCHED;
}
R
Robert Love 已提交
276 277 278 279 280 281 282

/**
 * inotify_inode_queue_event - queue an event to all watches on this inode
 * @inode: inode event is originating from
 * @mask: event mask describing this event
 * @cookie: cookie for synchronization, or zero
 * @name: filename, if any
283
 * @n_inode: inode associated with name
R
Robert Love 已提交
284 285
 */
void inotify_inode_queue_event(struct inode *inode, u32 mask, u32 cookie,
286
			       const char *name, struct inode *n_inode)
R
Robert Love 已提交
287 288 289 290 291 292
{
	struct inotify_watch *watch, *next;

	if (!inotify_inode_watched(inode))
		return;

I
Ingo Molnar 已提交
293
	mutex_lock(&inode->inotify_mutex);
R
Robert Love 已提交
294 295 296
	list_for_each_entry_safe(watch, next, &inode->inotify_watches, i_list) {
		u32 watch_mask = watch->mask;
		if (watch_mask & mask) {
297 298
			struct inotify_handle *ih= watch->ih;
			mutex_lock(&ih->mutex);
R
Robert Love 已提交
299
			if (watch_mask & IN_ONESHOT)
300
				remove_watch_no_event(watch, ih);
301 302
			ih->in_ops->handle_event(watch, watch->wd, mask, cookie,
						 name, n_inode);
303
			mutex_unlock(&ih->mutex);
R
Robert Love 已提交
304 305
		}
	}
I
Ingo Molnar 已提交
306
	mutex_unlock(&inode->inotify_mutex);
R
Robert Love 已提交
307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322
}
EXPORT_SYMBOL_GPL(inotify_inode_queue_event);

/**
 * inotify_dentry_parent_queue_event - queue an event to a dentry's parent
 * @dentry: the dentry in question, we queue against this dentry's parent
 * @mask: event mask describing this event
 * @cookie: cookie for synchronization, or zero
 * @name: filename, if any
 */
void inotify_dentry_parent_queue_event(struct dentry *dentry, u32 mask,
				       u32 cookie, const char *name)
{
	struct dentry *parent;
	struct inode *inode;

323
	if (!(dentry->d_flags & DCACHE_INOTIFY_PARENT_WATCHED))
J
John McCutchan 已提交
324 325
		return;

R
Robert Love 已提交
326 327 328 329 330 331 332
	spin_lock(&dentry->d_lock);
	parent = dentry->d_parent;
	inode = parent->d_inode;

	if (inotify_inode_watched(inode)) {
		dget(parent);
		spin_unlock(&dentry->d_lock);
333 334
		inotify_inode_queue_event(inode, mask, cookie, name,
					  dentry->d_inode);
R
Robert Love 已提交
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354
		dput(parent);
	} else
		spin_unlock(&dentry->d_lock);
}
EXPORT_SYMBOL_GPL(inotify_dentry_parent_queue_event);

/**
 * inotify_get_cookie - return a unique cookie for use in synchronizing events.
 */
u32 inotify_get_cookie(void)
{
	return atomic_inc_return(&inotify_cookie);
}
EXPORT_SYMBOL_GPL(inotify_get_cookie);

/**
 * inotify_unmount_inodes - an sb is unmounting.  handle any watched inodes.
 * @list: list of inodes being unmounted (sb->s_inodes)
 *
 * Called with inode_lock held, protecting the unmounting super block's list
I
Ingo Molnar 已提交
355
 * of inodes, and with iprune_mutex held, keeping shrink_icache_memory() at bay.
R
Robert Love 已提交
356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385
 * We temporarily drop inode_lock, however, and CAN block.
 */
void inotify_unmount_inodes(struct list_head *list)
{
	struct inode *inode, *next_i, *need_iput = NULL;

	list_for_each_entry_safe(inode, next_i, list, i_sb_list) {
		struct inotify_watch *watch, *next_w;
		struct inode *need_iput_tmp;
		struct list_head *watches;

		/*
		 * If i_count is zero, the inode cannot have any watches and
		 * doing an __iget/iput with MS_ACTIVE clear would actually
		 * evict all inodes with zero i_count from icache which is
		 * unnecessarily violent and may in fact be illegal to do.
		 */
		if (!atomic_read(&inode->i_count))
			continue;

		/*
		 * We cannot __iget() an inode in state I_CLEAR, I_FREEING, or
		 * I_WILL_FREE which is fine because by that point the inode
		 * cannot have any associated watches.
		 */
		if (inode->i_state & (I_CLEAR | I_FREEING | I_WILL_FREE))
			continue;

		need_iput_tmp = need_iput;
		need_iput = NULL;
386
		/* In case inotify_remove_watch_locked() drops a reference. */
R
Robert Love 已提交
387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403
		if (inode != need_iput_tmp)
			__iget(inode);
		else
			need_iput_tmp = NULL;
		/* In case the dropping of a reference would nuke next_i. */
		if ((&next_i->i_sb_list != list) &&
				atomic_read(&next_i->i_count) &&
				!(next_i->i_state & (I_CLEAR | I_FREEING |
					I_WILL_FREE))) {
			__iget(next_i);
			need_iput = next_i;
		}

		/*
		 * We can safely drop inode_lock here because we hold
		 * references on both inode and next_i.  Also no new inodes
		 * will be added since the umount has begun.  Finally,
I
Ingo Molnar 已提交
404
		 * iprune_mutex keeps shrink_icache_memory() away.
R
Robert Love 已提交
405 406 407 408 409 410 411
		 */
		spin_unlock(&inode_lock);

		if (need_iput_tmp)
			iput(need_iput_tmp);

		/* for each watch, send IN_UNMOUNT and then remove it */
I
Ingo Molnar 已提交
412
		mutex_lock(&inode->inotify_mutex);
R
Robert Love 已提交
413 414
		watches = &inode->inotify_watches;
		list_for_each_entry_safe(watch, next_w, watches, i_list) {
415 416 417
			struct inotify_handle *ih= watch->ih;
			mutex_lock(&ih->mutex);
			ih->in_ops->handle_event(watch, watch->wd, IN_UNMOUNT, 0,
418
						 NULL, NULL);
419
			inotify_remove_watch_locked(ih, watch);
420
			mutex_unlock(&ih->mutex);
R
Robert Love 已提交
421
		}
I
Ingo Molnar 已提交
422
		mutex_unlock(&inode->inotify_mutex);
R
Robert Love 已提交
423 424 425 426 427 428 429 430 431 432 433 434 435 436 437
		iput(inode);		

		spin_lock(&inode_lock);
	}
}
EXPORT_SYMBOL_GPL(inotify_unmount_inodes);

/**
 * inotify_inode_is_dead - an inode has been deleted, cleanup any watches
 * @inode: inode that is about to be removed
 */
void inotify_inode_is_dead(struct inode *inode)
{
	struct inotify_watch *watch, *next;

I
Ingo Molnar 已提交
438
	mutex_lock(&inode->inotify_mutex);
R
Robert Love 已提交
439
	list_for_each_entry_safe(watch, next, &inode->inotify_watches, i_list) {
440 441
		struct inotify_handle *ih = watch->ih;
		mutex_lock(&ih->mutex);
442
		inotify_remove_watch_locked(ih, watch);
443
		mutex_unlock(&ih->mutex);
R
Robert Love 已提交
444
	}
I
Ingo Molnar 已提交
445
	mutex_unlock(&inode->inotify_mutex);
R
Robert Love 已提交
446 447 448
}
EXPORT_SYMBOL_GPL(inotify_inode_is_dead);

449
/* Kernel Consumer API */
R
Robert Love 已提交
450

451 452 453 454 455
/**
 * inotify_init - allocate and initialize an inotify instance
 * @ops: caller's inotify operations
 */
struct inotify_handle *inotify_init(const struct inotify_operations *ops)
R
Robert Love 已提交
456
{
457
	struct inotify_handle *ih;
R
Robert Love 已提交
458

459 460 461
	ih = kmalloc(sizeof(struct inotify_handle), GFP_KERNEL);
	if (unlikely(!ih))
		return ERR_PTR(-ENOMEM);
R
Robert Love 已提交
462

463 464 465 466 467 468 469
	idr_init(&ih->idr);
	INIT_LIST_HEAD(&ih->watches);
	mutex_init(&ih->mutex);
	ih->last_wd = 0;
	ih->in_ops = ops;
	atomic_set(&ih->count, 0);
	get_inotify_handle(ih);
R
Robert Love 已提交
470

471
	return ih;
R
Robert Love 已提交
472
}
473
EXPORT_SYMBOL_GPL(inotify_init);
R
Robert Love 已提交
474

475 476 477 478 479 480 481 482 483 484 485 486 487
/**
 * inotify_init_watch - initialize an inotify watch
 * @watch: watch to initialize
 */
void inotify_init_watch(struct inotify_watch *watch)
{
	INIT_LIST_HEAD(&watch->h_list);
	INIT_LIST_HEAD(&watch->i_list);
	atomic_set(&watch->count, 0);
	get_inotify_watch(watch); /* initial get */
}
EXPORT_SYMBOL_GPL(inotify_init_watch);

488 489 490 491 492
/**
 * inotify_destroy - clean up and destroy an inotify instance
 * @ih: inotify handle
 */
void inotify_destroy(struct inotify_handle *ih)
R
Robert Love 已提交
493 494
{
	/*
495
	 * Destroy all of the watches for this handle. Unfortunately, not very
R
Robert Love 已提交
496 497
	 * pretty.  We cannot do a simple iteration over the list, because we
	 * do not know the inode until we iterate to the watch.  But we need to
498
	 * hold inode->inotify_mutex before ih->mutex.  The following works.
R
Robert Love 已提交
499 500 501 502 503 504
	 */
	while (1) {
		struct inotify_watch *watch;
		struct list_head *watches;
		struct inode *inode;

505 506
		mutex_lock(&ih->mutex);
		watches = &ih->watches;
R
Robert Love 已提交
507
		if (list_empty(watches)) {
508
			mutex_unlock(&ih->mutex);
R
Robert Love 已提交
509 510
			break;
		}
511
		watch = list_entry(watches->next, struct inotify_watch, h_list);
R
Robert Love 已提交
512
		get_inotify_watch(watch);
513
		mutex_unlock(&ih->mutex);
R
Robert Love 已提交
514 515

		inode = watch->inode;
I
Ingo Molnar 已提交
516
		mutex_lock(&inode->inotify_mutex);
517
		mutex_lock(&ih->mutex);
518 519

		/* make sure we didn't race with another list removal */
520 521 522 523
		if (likely(idr_find(&ih->idr, watch->wd))) {
			remove_watch_no_event(watch, ih);
			put_inotify_watch(watch);
		}
524

525
		mutex_unlock(&ih->mutex);
I
Ingo Molnar 已提交
526
		mutex_unlock(&inode->inotify_mutex);
R
Robert Love 已提交
527 528 529
		put_inotify_watch(watch);
	}

530 531
	/* free this handle: the put matching the get in inotify_init() */
	put_inotify_handle(ih);
R
Robert Love 已提交
532
}
533
EXPORT_SYMBOL_GPL(inotify_destroy);
R
Robert Love 已提交
534

535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565
/**
 * inotify_find_watch - find an existing watch for an (ih,inode) pair
 * @ih: inotify handle
 * @inode: inode to watch
 * @watchp: pointer to existing inotify_watch
 *
 * Caller must pin given inode (via nameidata).
 */
s32 inotify_find_watch(struct inotify_handle *ih, struct inode *inode,
		       struct inotify_watch **watchp)
{
	struct inotify_watch *old;
	int ret = -ENOENT;

	mutex_lock(&inode->inotify_mutex);
	mutex_lock(&ih->mutex);

	old = inode_find_handle(inode, ih);
	if (unlikely(old)) {
		get_inotify_watch(old); /* caller must put watch */
		*watchp = old;
		ret = old->wd;
	}

	mutex_unlock(&ih->mutex);
	mutex_unlock(&inode->inotify_mutex);

	return ret;
}
EXPORT_SYMBOL_GPL(inotify_find_watch);

566 567 568 569 570
/**
 * inotify_find_update_watch - find and update the mask of an existing watch
 * @ih: inotify handle
 * @inode: inode's watch to update
 * @mask: mask of events to watch
R
Robert Love 已提交
571
 *
572
 * Caller must pin given inode (via nameidata).
R
Robert Love 已提交
573
 */
574 575
s32 inotify_find_update_watch(struct inotify_handle *ih, struct inode *inode,
			      u32 mask)
R
Robert Love 已提交
576
{
577 578 579
	struct inotify_watch *old;
	int mask_add = 0;
	int ret;
R
Robert Love 已提交
580

581 582 583 584 585 586
	if (mask & IN_MASK_ADD)
		mask_add = 1;

	/* don't allow invalid bits: we don't want flags set */
	mask &= IN_ALL_EVENTS | IN_ONESHOT;
	if (unlikely(!mask))
R
Robert Love 已提交
587 588
		return -EINVAL;

I
Ingo Molnar 已提交
589
	mutex_lock(&inode->inotify_mutex);
590
	mutex_lock(&ih->mutex);
R
Robert Love 已提交
591

592 593 594 595 596 597 598 599
	/*
	 * Handle the case of re-adding a watch on an (inode,ih) pair that we
	 * are already watching.  We just update the mask and return its wd.
	 */
	old = inode_find_handle(inode, ih);
	if (unlikely(!old)) {
		ret = -ENOENT;
		goto out;
R
Robert Love 已提交
600 601
	}

602 603 604 605 606 607 608 609
	if (mask_add)
		old->mask |= mask;
	else
		old->mask = mask;
	ret = old->wd;
out:
	mutex_unlock(&ih->mutex);
	mutex_unlock(&inode->inotify_mutex);
R
Robert Love 已提交
610 611
	return ret;
}
612
EXPORT_SYMBOL_GPL(inotify_find_update_watch);
R
Robert Love 已提交
613

614 615 616 617 618 619 620 621 622 623 624 625 626
/**
 * inotify_add_watch - add a watch to an inotify instance
 * @ih: inotify handle
 * @watch: caller allocated watch structure
 * @inode: inode to watch
 * @mask: mask of events to watch
 *
 * Caller must pin given inode (via nameidata).
 * Caller must ensure it only calls inotify_add_watch() once per watch.
 * Calls inotify_handle_get_wd() so may sleep.
 */
s32 inotify_add_watch(struct inotify_handle *ih, struct inotify_watch *watch,
		      struct inode *inode, u32 mask)
R
Robert Love 已提交
627
{
628
	int ret = 0;
R
Robert Love 已提交
629

630 631 632 633 634
	/* don't allow invalid bits: we don't want flags set */
	mask &= IN_ALL_EVENTS | IN_ONESHOT;
	if (unlikely(!mask))
		return -EINVAL;
	watch->mask = mask;
R
Robert Love 已提交
635

636 637
	mutex_lock(&inode->inotify_mutex);
	mutex_lock(&ih->mutex);
638

639 640
	/* Initialize a new watch */
	ret = inotify_handle_get_wd(ih, watch);
641
	if (unlikely(ret))
642 643
		goto out;
	ret = watch->wd;
R
Robert Love 已提交
644

645 646 647
	/* save a reference to handle and bump the count to make it official */
	get_inotify_handle(ih);
	watch->ih = ih;
R
Robert Love 已提交
648 649

	/*
650 651
	 * Save a reference to the inode and bump the ref count to make it
	 * official.  We hold a reference to nameidata, which makes this safe.
R
Robert Love 已提交
652
	 */
653
	watch->inode = igrab(inode);
R
Robert Love 已提交
654

655 656 657
	if (!inotify_inode_watched(inode))
		set_dentry_child_flags(inode, 1);

658 659
	/* Add the watch to the handle's and the inode's list */
	list_add(&watch->h_list, &ih->watches);
R
Robert Love 已提交
660 661
	list_add(&watch->i_list, &inode->inotify_watches);
out:
662
	mutex_unlock(&ih->mutex);
I
Ingo Molnar 已提交
663
	mutex_unlock(&inode->inotify_mutex);
R
Robert Love 已提交
664 665
	return ret;
}
666
EXPORT_SYMBOL_GPL(inotify_add_watch);
R
Robert Love 已提交
667

668 669 670 671 672 673 674 675
/**
 * inotify_rm_wd - remove a watch from an inotify instance
 * @ih: inotify handle
 * @wd: watch descriptor to remove
 *
 * Can sleep.
 */
int inotify_rm_wd(struct inotify_handle *ih, u32 wd)
R
Robert Love 已提交
676
{
677 678
	struct inotify_watch *watch;
	struct inode *inode;
R
Robert Love 已提交
679

680 681 682 683 684
	mutex_lock(&ih->mutex);
	watch = idr_find(&ih->idr, wd);
	if (unlikely(!watch)) {
		mutex_unlock(&ih->mutex);
		return -EINVAL;
R
Robert Love 已提交
685
	}
686 687 688
	get_inotify_watch(watch);
	inode = watch->inode;
	mutex_unlock(&ih->mutex);
R
Robert Love 已提交
689

690 691
	mutex_lock(&inode->inotify_mutex);
	mutex_lock(&ih->mutex);
692

693 694
	/* make sure that we did not race */
	if (likely(idr_find(&ih->idr, wd) == watch))
695
		inotify_remove_watch_locked(ih, watch);
R
Robert Love 已提交
696

697 698 699
	mutex_unlock(&ih->mutex);
	mutex_unlock(&inode->inotify_mutex);
	put_inotify_watch(watch);
R
Robert Love 已提交
700

701 702 703
	return 0;
}
EXPORT_SYMBOL_GPL(inotify_rm_wd);
R
Robert Love 已提交
704

705 706 707 708 709 710 711 712 713 714 715 716 717 718
/**
 * inotify_rm_watch - remove a watch from an inotify instance
 * @ih: inotify handle
 * @watch: watch to remove
 *
 * Can sleep.
 */
int inotify_rm_watch(struct inotify_handle *ih,
		     struct inotify_watch *watch)
{
	return inotify_rm_wd(ih, watch->wd);
}
EXPORT_SYMBOL_GPL(inotify_rm_watch);

R
Robert Love 已提交
719
/*
720
 * inotify_setup - core initialization function
R
Robert Love 已提交
721
 */
722
static int __init inotify_setup(void)
R
Robert Love 已提交
723 724 725 726 727 728
{
	atomic_set(&inotify_cookie, 0);

	return 0;
}

729
module_init(inotify_setup);
新手
引导
客服 返回
顶部