]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
inotify fixes queued for 2.6.24-stable
authorChris Wright <chrisw@sous-sol.org>
Wed, 26 Mar 2008 16:09:06 +0000 (09:09 -0700)
committerChris Wright <chrisw@sous-sol.org>
Wed, 26 Mar 2008 16:09:06 +0000 (09:09 -0700)
queue-2.6.24/inotify-fix-race.patch [new file with mode: 0644]
queue-2.6.24/inotify-remove-debug-code.patch [new file with mode: 0644]
queue-2.6.24/series

diff --git a/queue-2.6.24/inotify-fix-race.patch b/queue-2.6.24/inotify-fix-race.patch
new file mode 100644 (file)
index 0000000..05cddb8
--- /dev/null
@@ -0,0 +1,67 @@
+From stable-bounces@linux.kernel.org  Wed Mar 26 09:02:24 2008
+To: stable@kernel.org
+Message-Id: <E1Je8Zb-0003Vs-Nl@debian64.daheim>
+From: Christian Lamparter <chunkeey@web.de>
+Date: Tue, 25 Mar 2008 13:48:15 +0100
+Cc: nickpiggin@yahoo.com.au
+Subject: inotify: fix race
+
+From: Nick Piggin <npiggin@suse.de>
+
+upstream commit: d599e36a9ea85432587f4550acc113cd7549d12a
+
+There is a race between setting an inode's children's "parent watched" flag
+when placing the first watch on a parent, and instantiating new children of
+that parent: a child could miss having its flags set by
+set_dentry_child_flags, but then inotify_d_instantiate might still see
+!inotify_inode_watched.
+
+The solution is to set_dentry_child_flags after adding the watch.  Locking is
+taken care of, because both set_dentry_child_flags and inotify_d_instantiate
+hold dcache_lock and child->d_locks.
+
+Signed-off-by: Nick Piggin <npiggin@suse.de>
+Cc: Robert Love <rlove@google.com>
+Cc: John McCutchan <ttb@tentacle.dhs.org>
+Cc: Jan Kara <jack@ucw.cz>
+Cc: Yan Zheng <yanzheng@21cn.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Christian Lamparter <chunkeey@web.de>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ fs/inotify.c |   13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+--- a/fs/inotify.c
++++ b/fs/inotify.c
+@@ -627,6 +627,7 @@ s32 inotify_add_watch(struct inotify_han
+                     struct inode *inode, u32 mask)
+ {
+       int ret = 0;
++      int newly_watched;
+       /* don't allow invalid bits: we don't want flags set */
+       mask &= IN_ALL_EVENTS | IN_ONESHOT;
+@@ -653,12 +654,18 @@ s32 inotify_add_watch(struct inotify_han
+        */
+       watch->inode = igrab(inode);
+-      if (!inotify_inode_watched(inode))
+-              set_dentry_child_flags(inode, 1);
+-
+       /* Add the watch to the handle's and the inode's list */
++      newly_watched = !inotify_inode_watched(inode);
+       list_add(&watch->h_list, &ih->watches);
+       list_add(&watch->i_list, &inode->inotify_watches);
++      /*
++       * Set child flags _after_ adding the watch, so there is no race
++       * windows where newly instantiated children could miss their parent's
++       * watched flag.
++       */
++      if (newly_watched)
++              set_dentry_child_flags(inode, 1);
++
+ out:
+       mutex_unlock(&ih->mutex);
+       mutex_unlock(&inode->inotify_mutex);
diff --git a/queue-2.6.24/inotify-remove-debug-code.patch b/queue-2.6.24/inotify-remove-debug-code.patch
new file mode 100644 (file)
index 0000000..f792028
--- /dev/null
@@ -0,0 +1,81 @@
+From stable-bounces@linux.kernel.org  Wed Mar 26 09:04:06 2008
+To: stable@kernel.org
+Message-Id: <E1Je8Ze-0003Vx-2Z@debian64.daheim>
+From: Christian Lamparter <chunkeey@web.de>
+Date: Tue, 25 Mar 2008 13:48:18 +0100
+Cc: nickpiggin@yahoo.com.au
+Subject: inotify: remove debug code
+
+From: Nick Piggin <npiggin@suse.de>
+
+upstream commit: 0d71bd5993b630a989d15adc2562a9ffe41cd26d
+
+The inotify debugging code is supposed to verify that the
+DCACHE_INOTIFY_PARENT_WATCHED scalability optimisation does not result in
+notifications getting lost nor extra needless locking generated.
+
+Unfortunately there are also some races in the debugging code.  And it isn't
+very good at finding problems anyway.  So remove it for now.
+
+Signed-off-by: Nick Piggin <npiggin@suse.de>
+Cc: Robert Love <rlove@google.com>
+Cc: John McCutchan <ttb@tentacle.dhs.org>
+Cc: Jan Kara <jack@ucw.cz>
+Cc: Yan Zheng <yanzheng@21cn.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Christian Lamparter <chunkeey@web.de>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ fs/dcache.c  |    3 ---
+ fs/inotify.c |   17 +++++------------
+ 2 files changed, 5 insertions(+), 15 deletions(-)
+
+--- a/fs/dcache.c
++++ b/fs/dcache.c
+@@ -1408,9 +1408,6 @@ void d_delete(struct dentry * dentry)
+       if (atomic_read(&dentry->d_count) == 1) {
+               dentry_iput(dentry);
+               fsnotify_nameremove(dentry, isdir);
+-
+-              /* remove this and other inotify debug checks after 2.6.18 */
+-              dentry->d_flags &= ~DCACHE_INOTIFY_PARENT_WATCHED;
+               return;
+       }
+--- a/fs/inotify.c
++++ b/fs/inotify.c
+@@ -168,20 +168,14 @@ static void set_dentry_child_flags(struc
+               struct dentry *child;
+               list_for_each_entry(child, &alias->d_subdirs, d_u.d_child) {
+-                      if (!child->d_inode) {
+-                              WARN_ON(child->d_flags & DCACHE_INOTIFY_PARENT_WATCHED);
++                      if (!child->d_inode)
+                               continue;
+-                      }
++
+                       spin_lock(&child->d_lock);
+-                      if (watched) {
+-                              WARN_ON(child->d_flags &
+-                                              DCACHE_INOTIFY_PARENT_WATCHED);
++                      if (watched)
+                               child->d_flags |= DCACHE_INOTIFY_PARENT_WATCHED;
+-                      } else {
+-                              WARN_ON(!(child->d_flags &
+-                                      DCACHE_INOTIFY_PARENT_WATCHED));
+-                              child->d_flags&=~DCACHE_INOTIFY_PARENT_WATCHED;
+-                      }
++                      else
++                              child->d_flags &=~DCACHE_INOTIFY_PARENT_WATCHED;
+                       spin_unlock(&child->d_lock);
+               }
+       }
+@@ -253,7 +247,6 @@ void inotify_d_instantiate(struct dentry
+       if (!inode)
+               return;
+-      WARN_ON(entry->d_flags & DCACHE_INOTIFY_PARENT_WATCHED);
+       spin_lock(&entry->d_lock);
+       parent = entry->d_parent;
+       if (parent->d_inode && inotify_inode_watched(parent->d_inode))
index 6ec465708ee66b09fc30e8488a9b793508271c5c..dfee4f3cc18525e6281aa6ecf94ce2befb2c4813 100644 (file)
@@ -6,3 +6,5 @@ v4l-ivtv-add-missing-sg_init_table.patch
 uio-add-pgprot_noncached-to-uio-mmap-code.patch
 usb-add-support-for-motorola-rokr-z6-cellphone-in-mass-storage-mode.patch
 usb-new-quirk-flag-to-avoid-set-interface.patch
+inotify-fix-race.patch
+inotify-remove-debug-code.patch