diff options
Diffstat (limited to 'fs')
-rw-r--r-- | fs/inotify.c | 64 | ||||
-rw-r--r-- | fs/inotify_user.c | 1 |
2 files changed, 59 insertions, 6 deletions
diff --git a/fs/inotify.c b/fs/inotify.c index f25c21801fdc..8477c4fbecb4 100644 --- a/fs/inotify.c +++ b/fs/inotify.c | |||
@@ -468,6 +468,19 @@ struct inotify_handle *inotify_init(const struct inotify_operations *ops) | |||
468 | EXPORT_SYMBOL_GPL(inotify_init); | 468 | EXPORT_SYMBOL_GPL(inotify_init); |
469 | 469 | ||
470 | /** | 470 | /** |
471 | * inotify_init_watch - initialize an inotify watch | ||
472 | * @watch: watch to initialize | ||
473 | */ | ||
474 | void inotify_init_watch(struct inotify_watch *watch) | ||
475 | { | ||
476 | INIT_LIST_HEAD(&watch->h_list); | ||
477 | INIT_LIST_HEAD(&watch->i_list); | ||
478 | atomic_set(&watch->count, 0); | ||
479 | get_inotify_watch(watch); /* initial get */ | ||
480 | } | ||
481 | EXPORT_SYMBOL_GPL(inotify_init_watch); | ||
482 | |||
483 | /** | ||
471 | * inotify_destroy - clean up and destroy an inotify instance | 484 | * inotify_destroy - clean up and destroy an inotify instance |
472 | * @ih: inotify handle | 485 | * @ih: inotify handle |
473 | */ | 486 | */ |
@@ -515,6 +528,37 @@ void inotify_destroy(struct inotify_handle *ih) | |||
515 | EXPORT_SYMBOL_GPL(inotify_destroy); | 528 | EXPORT_SYMBOL_GPL(inotify_destroy); |
516 | 529 | ||
517 | /** | 530 | /** |
531 | * inotify_find_watch - find an existing watch for an (ih,inode) pair | ||
532 | * @ih: inotify handle | ||
533 | * @inode: inode to watch | ||
534 | * @watchp: pointer to existing inotify_watch | ||
535 | * | ||
536 | * Caller must pin given inode (via nameidata). | ||
537 | */ | ||
538 | s32 inotify_find_watch(struct inotify_handle *ih, struct inode *inode, | ||
539 | struct inotify_watch **watchp) | ||
540 | { | ||
541 | struct inotify_watch *old; | ||
542 | int ret = -ENOENT; | ||
543 | |||
544 | mutex_lock(&inode->inotify_mutex); | ||
545 | mutex_lock(&ih->mutex); | ||
546 | |||
547 | old = inode_find_handle(inode, ih); | ||
548 | if (unlikely(old)) { | ||
549 | get_inotify_watch(old); /* caller must put watch */ | ||
550 | *watchp = old; | ||
551 | ret = old->wd; | ||
552 | } | ||
553 | |||
554 | mutex_unlock(&ih->mutex); | ||
555 | mutex_unlock(&inode->inotify_mutex); | ||
556 | |||
557 | return ret; | ||
558 | } | ||
559 | EXPORT_SYMBOL_GPL(inotify_find_watch); | ||
560 | |||
561 | /** | ||
518 | * inotify_find_update_watch - find and update the mask of an existing watch | 562 | * inotify_find_update_watch - find and update the mask of an existing watch |
519 | * @ih: inotify handle | 563 | * @ih: inotify handle |
520 | * @inode: inode's watch to update | 564 | * @inode: inode's watch to update |
@@ -593,10 +637,6 @@ s32 inotify_add_watch(struct inotify_handle *ih, struct inotify_watch *watch, | |||
593 | goto out; | 637 | goto out; |
594 | ret = watch->wd; | 638 | ret = watch->wd; |
595 | 639 | ||
596 | atomic_set(&watch->count, 0); | ||
597 | INIT_LIST_HEAD(&watch->h_list); | ||
598 | INIT_LIST_HEAD(&watch->i_list); | ||
599 | |||
600 | /* save a reference to handle and bump the count to make it official */ | 640 | /* save a reference to handle and bump the count to make it official */ |
601 | get_inotify_handle(ih); | 641 | get_inotify_handle(ih); |
602 | watch->ih = ih; | 642 | watch->ih = ih; |
@@ -607,8 +647,6 @@ s32 inotify_add_watch(struct inotify_handle *ih, struct inotify_watch *watch, | |||
607 | */ | 647 | */ |
608 | watch->inode = igrab(inode); | 648 | watch->inode = igrab(inode); |
609 | 649 | ||
610 | get_inotify_watch(watch); /* initial get */ | ||
611 | |||
612 | if (!inotify_inode_watched(inode)) | 650 | if (!inotify_inode_watched(inode)) |
613 | set_dentry_child_flags(inode, 1); | 651 | set_dentry_child_flags(inode, 1); |
614 | 652 | ||
@@ -659,6 +697,20 @@ int inotify_rm_wd(struct inotify_handle *ih, u32 wd) | |||
659 | } | 697 | } |
660 | EXPORT_SYMBOL_GPL(inotify_rm_wd); | 698 | EXPORT_SYMBOL_GPL(inotify_rm_wd); |
661 | 699 | ||
700 | /** | ||
701 | * inotify_rm_watch - remove a watch from an inotify instance | ||
702 | * @ih: inotify handle | ||
703 | * @watch: watch to remove | ||
704 | * | ||
705 | * Can sleep. | ||
706 | */ | ||
707 | int inotify_rm_watch(struct inotify_handle *ih, | ||
708 | struct inotify_watch *watch) | ||
709 | { | ||
710 | return inotify_rm_wd(ih, watch->wd); | ||
711 | } | ||
712 | EXPORT_SYMBOL_GPL(inotify_rm_watch); | ||
713 | |||
662 | /* | 714 | /* |
663 | * inotify_setup - core initialization function | 715 | * inotify_setup - core initialization function |
664 | */ | 716 | */ |
diff --git a/fs/inotify_user.c b/fs/inotify_user.c index 8b83c7190067..9e9931e2badd 100644 --- a/fs/inotify_user.c +++ b/fs/inotify_user.c | |||
@@ -380,6 +380,7 @@ static int create_watch(struct inotify_device *dev, struct inode *inode, | |||
380 | 380 | ||
381 | atomic_inc(&dev->user->inotify_watches); | 381 | atomic_inc(&dev->user->inotify_watches); |
382 | 382 | ||
383 | inotify_init_watch(&watch->wdata); | ||
383 | ret = inotify_add_watch(dev->ih, &watch->wdata, inode, mask); | 384 | ret = inotify_add_watch(dev->ih, &watch->wdata, inode, mask); |
384 | if (ret < 0) | 385 | if (ret < 0) |
385 | free_inotify_user_watch(&watch->wdata); | 386 | free_inotify_user_watch(&watch->wdata); |