diff options
author | Amy Griffis <amy.griffis@hp.com> | 2006-06-01 16:11:05 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2006-06-20 05:25:19 -0400 |
commit | 3ca10067f7f4bfa62a1b0edc84f590261fa02d75 (patch) | |
tree | 456e1b555cd4af838bd4e833aa7589ab2bab6766 /fs | |
parent | a9dc971d3fdb857a2bcd6d53238125a2cd31d5f4 (diff) |
[PATCH] inotify (4/5): allow watch removal from event handler
Allow callers to remove watches from their event handler via
inotify_remove_watch_locked(). This functionality can be used to
achieve IN_ONESHOT-like functionality for a subset of events in the
mask.
Signed-off-by: Amy Griffis <amy.griffis@hp.com>
Acked-by: Robert Love <rml@novell.com>
Acked-by: John McCutchan <john@johnmccutchan.com>
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/inotify.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/fs/inotify.c b/fs/inotify.c index 8477c4fbecb4..723836a1f718 100644 --- a/fs/inotify.c +++ b/fs/inotify.c | |||
@@ -207,7 +207,7 @@ static struct inotify_watch *inode_find_handle(struct inode *inode, | |||
207 | } | 207 | } |
208 | 208 | ||
209 | /* | 209 | /* |
210 | * remove_watch_no_event - remove_watch() without the IN_IGNORED event. | 210 | * remove_watch_no_event - remove watch without the IN_IGNORED event. |
211 | * | 211 | * |
212 | * Callers must hold both inode->inotify_mutex and ih->mutex. | 212 | * Callers must hold both inode->inotify_mutex and ih->mutex. |
213 | */ | 213 | */ |
@@ -223,17 +223,22 @@ static void remove_watch_no_event(struct inotify_watch *watch, | |||
223 | idr_remove(&ih->idr, watch->wd); | 223 | idr_remove(&ih->idr, watch->wd); |
224 | } | 224 | } |
225 | 225 | ||
226 | /* | 226 | /** |
227 | * remove_watch - Remove a watch from both the handle and the inode. Sends | 227 | * inotify_remove_watch_locked - Remove a watch from both the handle and the |
228 | * the IN_IGNORED event signifying that the inode is no longer watched. | 228 | * inode. Sends the IN_IGNORED event signifying that the inode is no longer |
229 | * watched. May be invoked from a caller's event handler. | ||
230 | * @ih: inotify handle associated with watch | ||
231 | * @watch: watch to remove | ||
229 | * | 232 | * |
230 | * Callers must hold both inode->inotify_mutex and ih->mutex. | 233 | * Callers must hold both inode->inotify_mutex and ih->mutex. |
231 | */ | 234 | */ |
232 | static void remove_watch(struct inotify_watch *watch, struct inotify_handle *ih) | 235 | void inotify_remove_watch_locked(struct inotify_handle *ih, |
236 | struct inotify_watch *watch) | ||
233 | { | 237 | { |
234 | remove_watch_no_event(watch, ih); | 238 | remove_watch_no_event(watch, ih); |
235 | ih->in_ops->handle_event(watch, watch->wd, IN_IGNORED, 0, NULL, NULL); | 239 | ih->in_ops->handle_event(watch, watch->wd, IN_IGNORED, 0, NULL, NULL); |
236 | } | 240 | } |
241 | EXPORT_SYMBOL_GPL(inotify_remove_watch_locked); | ||
237 | 242 | ||
238 | /* Kernel API for producing events */ | 243 | /* Kernel API for producing events */ |
239 | 244 | ||
@@ -378,7 +383,7 @@ void inotify_unmount_inodes(struct list_head *list) | |||
378 | 383 | ||
379 | need_iput_tmp = need_iput; | 384 | need_iput_tmp = need_iput; |
380 | need_iput = NULL; | 385 | need_iput = NULL; |
381 | /* In case the remove_watch() drops a reference. */ | 386 | /* In case inotify_remove_watch_locked() drops a reference. */ |
382 | if (inode != need_iput_tmp) | 387 | if (inode != need_iput_tmp) |
383 | __iget(inode); | 388 | __iget(inode); |
384 | else | 389 | else |
@@ -411,7 +416,7 @@ void inotify_unmount_inodes(struct list_head *list) | |||
411 | mutex_lock(&ih->mutex); | 416 | mutex_lock(&ih->mutex); |
412 | ih->in_ops->handle_event(watch, watch->wd, IN_UNMOUNT, 0, | 417 | ih->in_ops->handle_event(watch, watch->wd, IN_UNMOUNT, 0, |
413 | NULL, NULL); | 418 | NULL, NULL); |
414 | remove_watch(watch, ih); | 419 | inotify_remove_watch_locked(ih, watch); |
415 | mutex_unlock(&ih->mutex); | 420 | mutex_unlock(&ih->mutex); |
416 | } | 421 | } |
417 | mutex_unlock(&inode->inotify_mutex); | 422 | mutex_unlock(&inode->inotify_mutex); |
@@ -434,7 +439,7 @@ void inotify_inode_is_dead(struct inode *inode) | |||
434 | list_for_each_entry_safe(watch, next, &inode->inotify_watches, i_list) { | 439 | list_for_each_entry_safe(watch, next, &inode->inotify_watches, i_list) { |
435 | struct inotify_handle *ih = watch->ih; | 440 | struct inotify_handle *ih = watch->ih; |
436 | mutex_lock(&ih->mutex); | 441 | mutex_lock(&ih->mutex); |
437 | remove_watch(watch, ih); | 442 | inotify_remove_watch_locked(ih, watch); |
438 | mutex_unlock(&ih->mutex); | 443 | mutex_unlock(&ih->mutex); |
439 | } | 444 | } |
440 | mutex_unlock(&inode->inotify_mutex); | 445 | mutex_unlock(&inode->inotify_mutex); |
@@ -687,7 +692,7 @@ int inotify_rm_wd(struct inotify_handle *ih, u32 wd) | |||
687 | 692 | ||
688 | /* make sure that we did not race */ | 693 | /* make sure that we did not race */ |
689 | if (likely(idr_find(&ih->idr, wd) == watch)) | 694 | if (likely(idr_find(&ih->idr, wd) == watch)) |
690 | remove_watch(watch, ih); | 695 | inotify_remove_watch_locked(ih, watch); |
691 | 696 | ||
692 | mutex_unlock(&ih->mutex); | 697 | mutex_unlock(&ih->mutex); |
693 | mutex_unlock(&inode->inotify_mutex); | 698 | mutex_unlock(&inode->inotify_mutex); |