[CIFS] fix memory leak in cifs session info struct on reconnect
[sfrench/cifs-2.6.git] / fs / inotify.c
index f48a3dae07120f14e8f20c0514e2f8b00986c278..732ec4bd5774507f8c06c6e05cc90d4d2004a84b 100644 (file)
@@ -538,7 +538,7 @@ void inotify_d_instantiate(struct dentry *entry, struct inode *inode)
        WARN_ON(entry->d_flags & DCACHE_INOTIFY_PARENT_WATCHED);
        spin_lock(&entry->d_lock);
        parent = entry->d_parent;
-       if (inotify_inode_watched(parent->d_inode))
+       if (parent->d_inode && inotify_inode_watched(parent->d_inode))
                entry->d_flags |= DCACHE_INOTIFY_PARENT_WATCHED;
        spin_unlock(&entry->d_lock);
 }
@@ -848,7 +848,11 @@ static int inotify_release(struct inode *ignored, struct file *file)
                inode = watch->inode;
                mutex_lock(&inode->inotify_mutex);
                mutex_lock(&dev->mutex);
-               remove_watch_no_event(watch, dev);
+
+               /* make sure we didn't race with another list removal */
+               if (likely(idr_find(&dev->idr, watch->wd)))
+                       remove_watch_no_event(watch, dev);
+
                mutex_unlock(&dev->mutex);
                mutex_unlock(&inode->inotify_mutex);
                put_inotify_watch(watch);
@@ -890,8 +894,7 @@ static int inotify_ignore(struct inotify_device *dev, s32 wd)
        mutex_lock(&dev->mutex);
 
        /* make sure that we did not race */
-       watch = idr_find(&dev->idr, wd);
-       if (likely(watch))
+       if (likely(idr_find(&dev->idr, wd) == watch))
                remove_watch(watch, dev);
 
        mutex_unlock(&dev->mutex);
@@ -920,7 +923,7 @@ static long inotify_ioctl(struct file *file, unsigned int cmd,
        return ret;
 }
 
-static struct file_operations inotify_fops = {
+static const struct file_operations inotify_fops = {
        .poll           = inotify_poll,
        .read           = inotify_read,
        .release        = inotify_release,