diff options
Diffstat (limited to 'fs/inotify.c')
-rw-r--r-- | fs/inotify.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/fs/inotify.c b/fs/inotify.c index 2c5b92152876..b2b109bf29d6 100644 --- a/fs/inotify.c +++ b/fs/inotify.c | |||
@@ -627,6 +627,7 @@ s32 inotify_add_watch(struct inotify_handle *ih, struct inotify_watch *watch, | |||
627 | struct inode *inode, u32 mask) | 627 | struct inode *inode, u32 mask) |
628 | { | 628 | { |
629 | int ret = 0; | 629 | int ret = 0; |
630 | int newly_watched; | ||
630 | 631 | ||
631 | /* don't allow invalid bits: we don't want flags set */ | 632 | /* don't allow invalid bits: we don't want flags set */ |
632 | mask &= IN_ALL_EVENTS | IN_ONESHOT; | 633 | mask &= IN_ALL_EVENTS | IN_ONESHOT; |
@@ -653,12 +654,18 @@ s32 inotify_add_watch(struct inotify_handle *ih, struct inotify_watch *watch, | |||
653 | */ | 654 | */ |
654 | watch->inode = igrab(inode); | 655 | watch->inode = igrab(inode); |
655 | 656 | ||
656 | if (!inotify_inode_watched(inode)) | ||
657 | set_dentry_child_flags(inode, 1); | ||
658 | |||
659 | /* Add the watch to the handle's and the inode's list */ | 657 | /* Add the watch to the handle's and the inode's list */ |
658 | newly_watched = !inotify_inode_watched(inode); | ||
660 | list_add(&watch->h_list, &ih->watches); | 659 | list_add(&watch->h_list, &ih->watches); |
661 | list_add(&watch->i_list, &inode->inotify_watches); | 660 | list_add(&watch->i_list, &inode->inotify_watches); |
661 | /* | ||
662 | * Set child flags _after_ adding the watch, so there is no race | ||
663 | * windows where newly instantiated children could miss their parent's | ||
664 | * watched flag. | ||
665 | */ | ||
666 | if (newly_watched) | ||
667 | set_dentry_child_flags(inode, 1); | ||
668 | |||
662 | out: | 669 | out: |
663 | mutex_unlock(&ih->mutex); | 670 | mutex_unlock(&ih->mutex); |
664 | mutex_unlock(&inode->inotify_mutex); | 671 | mutex_unlock(&inode->inotify_mutex); |