--- m/kernel/watch_queue.c +++ n/kernel/watch_queue.c @@ -470,6 +470,7 @@ int add_watch_to_object(struct watch *wa { struct watch_queue *wqueue = rcu_access_pointer(watch->queue); struct watch *w; + int err; hlist_for_each_entry(w, &wlist->watchers, list_node) { struct watch_queue *wq = rcu_access_pointer(w->queue); @@ -482,9 +483,8 @@ int add_watch_to_object(struct watch *wa if (atomic_inc_return(&watch->cred->user->nr_watches) > task_rlimit(current, RLIMIT_NOFILE)) { - atomic_dec(&watch->cred->user->nr_watches); - put_cred(watch->cred); - return -EAGAIN; + err = -EAGAIN; + goto out; } if (lock_wqueue(wqueue)) { @@ -492,10 +492,16 @@ int add_watch_to_object(struct watch *wa kref_get(&watch->usage); hlist_add_head(&watch->queue_node, &wqueue->watches); unlock_wqueue(wqueue); + + hlist_add_head(&watch->list_node, &wlist->watchers); + return 0; } - hlist_add_head(&watch->list_node, &wlist->watchers); - return 0; + err = -ENXIO; +out: + atomic_dec(&watch->cred->user->nr_watches); + put_cred(watch->cred); + return err; } EXPORT_SYMBOL(add_watch_to_object);