aboutsummaryrefslogtreecommitdiffstats
path: root/fs/notify/notification.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-08-12 17:23:04 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-08-12 17:23:04 -0400
commit2069601b3f0ea38170d4b509b89f3ca0a373bdc1 (patch)
tree647002d4c3814bd3d95d16ef7edef1757de8554f /fs/notify/notification.c
parentad41a1e0cab07c5125456e8d38e5b1ab148d04aa (diff)
Revert "fsnotify: store struct file not struct path"
This reverts commit 3bcf3860a4ff9bbc522820b4b765e65e4deceb3e (and the accompanying commit c1e5c954020e "vfs/fsnotify: fsnotify_close can delay the final work in fput" that was a horribly ugly hack to make it work at all). The 'struct file' approach not only causes that disgusting hack, it somehow breaks pulseaudio, probably due to some other subtlety with f_count handling. Fix up various conflicts due to later fsnotify work. Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/notify/notification.c')
-rw-r--r--fs/notify/notification.c33
1 files changed, 11 insertions, 22 deletions
diff --git a/fs/notify/notification.c b/fs/notify/notification.c
index d6c435adc7a2..f39260f8f865 100644
--- a/fs/notify/notification.c
+++ b/fs/notify/notification.c
@@ -31,7 +31,6 @@
31 * allocated and used. 31 * allocated and used.
32 */ 32 */
33 33
34#include <linux/file.h>
35#include <linux/fs.h> 34#include <linux/fs.h>
36#include <linux/init.h> 35#include <linux/init.h>
37#include <linux/kernel.h> 36#include <linux/kernel.h>
@@ -90,8 +89,8 @@ void fsnotify_put_event(struct fsnotify_event *event)
90 if (atomic_dec_and_test(&event->refcnt)) { 89 if (atomic_dec_and_test(&event->refcnt)) {
91 pr_debug("%s: event=%p\n", __func__, event); 90 pr_debug("%s: event=%p\n", __func__, event);
92 91
93 if (event->data_type == FSNOTIFY_EVENT_FILE) 92 if (event->data_type == FSNOTIFY_EVENT_PATH)
94 fput(event->file); 93 path_put(&event->path);
95 94
96 BUG_ON(!list_empty(&event->private_data_list)); 95 BUG_ON(!list_empty(&event->private_data_list));
97 96
@@ -376,8 +375,8 @@ struct fsnotify_event *fsnotify_clone_event(struct fsnotify_event *old_event)
376 } 375 }
377 } 376 }
378 event->tgid = get_pid(old_event->tgid); 377 event->tgid = get_pid(old_event->tgid);
379 if (event->data_type == FSNOTIFY_EVENT_FILE) 378 if (event->data_type == FSNOTIFY_EVENT_PATH)
380 get_file(event->file); 379 path_get(&event->path);
381 380
382 return event; 381 return event;
383} 382}
@@ -424,22 +423,11 @@ struct fsnotify_event *fsnotify_create_event(struct inode *to_tell, __u32 mask,
424 event->data_type = data_type; 423 event->data_type = data_type;
425 424
426 switch (data_type) { 425 switch (data_type) {
427 case FSNOTIFY_EVENT_FILE: { 426 case FSNOTIFY_EVENT_PATH: {
428 event->file = data; 427 struct path *path = data;
429 /* 428 event->path.dentry = path->dentry;
430 * if this file is about to disappear hold an extra reference 429 event->path.mnt = path->mnt;
431 * until we return to __fput so we don't have to worry about 430 path_get(&event->path);
432 * future get/put destroying the file under us or generating
433 * additional events. Notice that we change f_mode without
434 * holding f_lock. This is safe since this is the only possible
435 * reference to this object in the kernel (it was about to be
436 * freed, remember?)
437 */
438 if (!atomic_long_read(&event->file->f_count)) {
439 event->file->f_mode |= FMODE_NONOTIFY;
440 get_file(event->file);
441 }
442 get_file(event->file);
443 break; 431 break;
444 } 432 }
445 case FSNOTIFY_EVENT_INODE: 433 case FSNOTIFY_EVENT_INODE:
@@ -447,7 +435,8 @@ struct fsnotify_event *fsnotify_create_event(struct inode *to_tell, __u32 mask,
447 break; 435 break;
448 case FSNOTIFY_EVENT_NONE: 436 case FSNOTIFY_EVENT_NONE:
449 event->inode = NULL; 437 event->inode = NULL;
450 event->file = NULL; 438 event->path.dentry = NULL;
439 event->path.mnt = NULL;
451 break; 440 break;
452 default: 441 default:
453 BUG(); 442 BUG();