diff options
-rw-r--r-- | fs/inotify.c | 64 | ||||
-rw-r--r-- | fs/inotify_user.c | 1 | ||||
-rw-r--r-- | include/linux/inotify.h | 20 |
3 files changed, 79 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); |
diff --git a/include/linux/inotify.h b/include/linux/inotify.h index e7899e7d83ad..e7e7fb7fc778 100644 --- a/include/linux/inotify.h +++ b/include/linux/inotify.h | |||
@@ -112,11 +112,15 @@ extern u32 inotify_get_cookie(void); | |||
112 | /* Kernel Consumer API */ | 112 | /* Kernel Consumer API */ |
113 | 113 | ||
114 | extern struct inotify_handle *inotify_init(const struct inotify_operations *); | 114 | extern struct inotify_handle *inotify_init(const struct inotify_operations *); |
115 | extern void inotify_init_watch(struct inotify_watch *); | ||
115 | extern void inotify_destroy(struct inotify_handle *); | 116 | extern void inotify_destroy(struct inotify_handle *); |
117 | extern __s32 inotify_find_watch(struct inotify_handle *, struct inode *, | ||
118 | struct inotify_watch **); | ||
116 | extern __s32 inotify_find_update_watch(struct inotify_handle *, struct inode *, | 119 | extern __s32 inotify_find_update_watch(struct inotify_handle *, struct inode *, |
117 | u32); | 120 | u32); |
118 | extern __s32 inotify_add_watch(struct inotify_handle *, struct inotify_watch *, | 121 | extern __s32 inotify_add_watch(struct inotify_handle *, struct inotify_watch *, |
119 | struct inode *, __u32); | 122 | struct inode *, __u32); |
123 | extern int inotify_rm_watch(struct inotify_handle *, struct inotify_watch *); | ||
120 | extern int inotify_rm_wd(struct inotify_handle *, __u32); | 124 | extern int inotify_rm_wd(struct inotify_handle *, __u32); |
121 | extern void get_inotify_watch(struct inotify_watch *); | 125 | extern void get_inotify_watch(struct inotify_watch *); |
122 | extern void put_inotify_watch(struct inotify_watch *); | 126 | extern void put_inotify_watch(struct inotify_watch *); |
@@ -163,10 +167,20 @@ static inline struct inotify_handle *inotify_init(const struct inotify_operation | |||
163 | return ERR_PTR(-EOPNOTSUPP); | 167 | return ERR_PTR(-EOPNOTSUPP); |
164 | } | 168 | } |
165 | 169 | ||
170 | static inline void inotify_init_watch(struct inotify_watch *watch) | ||
171 | { | ||
172 | } | ||
173 | |||
166 | static inline void inotify_destroy(struct inotify_handle *ih) | 174 | static inline void inotify_destroy(struct inotify_handle *ih) |
167 | { | 175 | { |
168 | } | 176 | } |
169 | 177 | ||
178 | static inline __s32 inotify_find_watch(struct inotify_handle *ih, struct inode *inode, | ||
179 | struct inotify_watch **watchp) | ||
180 | { | ||
181 | return -EOPNOTSUPP; | ||
182 | } | ||
183 | |||
170 | static inline __s32 inotify_find_update_watch(struct inotify_handle *ih, | 184 | static inline __s32 inotify_find_update_watch(struct inotify_handle *ih, |
171 | struct inode *inode, u32 mask) | 185 | struct inode *inode, u32 mask) |
172 | { | 186 | { |
@@ -180,6 +194,12 @@ static inline __s32 inotify_add_watch(struct inotify_handle *ih, | |||
180 | return -EOPNOTSUPP; | 194 | return -EOPNOTSUPP; |
181 | } | 195 | } |
182 | 196 | ||
197 | static inline int inotify_rm_watch(struct inotify_handle *ih, | ||
198 | struct inotify_watch *watch) | ||
199 | { | ||
200 | return -EOPNOTSUPP; | ||
201 | } | ||
202 | |||
183 | static inline int inotify_rm_wd(struct inotify_handle *ih, __u32 wd) | 203 | static inline int inotify_rm_wd(struct inotify_handle *ih, __u32 wd) |
184 | { | 204 | { |
185 | return -EOPNOTSUPP; | 205 | return -EOPNOTSUPP; |