X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=fs%2Fdnotify.c;h=676073b8dda57659202b123dde8adb90e0fb416b;hb=ec38fa2b35f13e7fa1d676a5bc997d0df1b02574;hp=936409fcd9397a9909e74fd7547d609ee1e57986;hpb=706b75ddbe36d20d071424f9867385c319b67f8d;p=linux-2.6-omap-h63xx.git diff --git a/fs/dnotify.c b/fs/dnotify.c index 936409fcd93..676073b8dda 100644 --- a/fs/dnotify.c +++ b/fs/dnotify.c @@ -20,6 +20,7 @@ #include #include #include +#include int dir_notify_enable __read_mostly = 1; @@ -66,6 +67,7 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg) struct dnotify_struct **prev; struct inode *inode; fl_owner_t id = current->files; + struct file *f; int error = 0; if ((arg & ~DN_MULTISHOT) == 0) { @@ -92,6 +94,15 @@ int fcntl_dirnotify(int fd, struct file *filp, unsigned long arg) prev = &odn->dn_next; } + rcu_read_lock(); + f = fcheck(fd); + rcu_read_unlock(); + /* we'd lost the race with close(), sod off silently */ + /* note that inode->i_lock prevents reordering problems + * between accesses to descriptor table and ->i_dnotify */ + if (f != filp) + goto out_free; + error = __f_setown(filp, task_pid(current), PIDTYPE_PID, 0); if (error) goto out_free; @@ -176,7 +187,7 @@ EXPORT_SYMBOL_GPL(dnotify_parent); static int __init dnotify_init(void) { dn_cache = kmem_cache_create("dnotify_cache", - sizeof(struct dnotify_struct), 0, SLAB_PANIC, NULL, NULL); + sizeof(struct dnotify_struct), 0, SLAB_PANIC, NULL); return 0; }