aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/inotify.c64
-rw-r--r--fs/inotify_user.c1
-rw-r--r--include/linux/inotify.h20
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)
468EXPORT_SYMBOL_GPL(inotify_init); 468EXPORT_SYMBOL_GPL(inotify_init);
469 469
470/** 470/**
471 * inotify_init_watch - initialize an inotify watch
472 * @watch: watch to initialize
473 */
474void 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}
481EXPORT_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)
515EXPORT_SYMBOL_GPL(inotify_destroy); 528EXPORT_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 */
538s32 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}
559EXPORT_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}
660EXPORT_SYMBOL_GPL(inotify_rm_wd); 698EXPORT_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 */
707int inotify_rm_watch(struct inotify_handle *ih,
708 struct inotify_watch *watch)
709{
710 return inotify_rm_wd(ih, watch->wd);
711}
712EXPORT_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
114extern struct inotify_handle *inotify_init(const struct inotify_operations *); 114extern struct inotify_handle *inotify_init(const struct inotify_operations *);
115extern void inotify_init_watch(struct inotify_watch *);
115extern void inotify_destroy(struct inotify_handle *); 116extern void inotify_destroy(struct inotify_handle *);
117extern __s32 inotify_find_watch(struct inotify_handle *, struct inode *,
118 struct inotify_watch **);
116extern __s32 inotify_find_update_watch(struct inotify_handle *, struct inode *, 119extern __s32 inotify_find_update_watch(struct inotify_handle *, struct inode *,
117 u32); 120 u32);
118extern __s32 inotify_add_watch(struct inotify_handle *, struct inotify_watch *, 121extern __s32 inotify_add_watch(struct inotify_handle *, struct inotify_watch *,
119 struct inode *, __u32); 122 struct inode *, __u32);
123extern int inotify_rm_watch(struct inotify_handle *, struct inotify_watch *);
120extern int inotify_rm_wd(struct inotify_handle *, __u32); 124extern int inotify_rm_wd(struct inotify_handle *, __u32);
121extern void get_inotify_watch(struct inotify_watch *); 125extern void get_inotify_watch(struct inotify_watch *);
122extern void put_inotify_watch(struct inotify_watch *); 126extern 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
170static inline void inotify_init_watch(struct inotify_watch *watch)
171{
172}
173
166static inline void inotify_destroy(struct inotify_handle *ih) 174static inline void inotify_destroy(struct inotify_handle *ih)
167{ 175{
168} 176}
169 177
178static inline __s32 inotify_find_watch(struct inotify_handle *ih, struct inode *inode,
179 struct inotify_watch **watchp)
180{
181 return -EOPNOTSUPP;
182}
183
170static inline __s32 inotify_find_update_watch(struct inotify_handle *ih, 184static 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
197static inline int inotify_rm_watch(struct inotify_handle *ih,
198 struct inotify_watch *watch)
199{
200 return -EOPNOTSUPP;
201}
202
183static inline int inotify_rm_wd(struct inotify_handle *ih, __u32 wd) 203static inline int inotify_rm_wd(struct inotify_handle *ih, __u32 wd)
184{ 204{
185 return -EOPNOTSUPP; 205 return -EOPNOTSUPP;