aboutsummaryrefslogtreecommitdiffstats
path: root/fs/notify
diff options
context:
space:
mode:
Diffstat (limited to 'fs/notify')
-rw-r--r--fs/notify/Makefile2
-rw-r--r--fs/notify/fanotify/Kconfig2
-rw-r--r--fs/notify/fanotify/fanotify.c1
-rw-r--r--fs/notify/fanotify/fanotify_user.c90
-rw-r--r--fs/notify/fdinfo.c179
-rw-r--r--fs/notify/fdinfo.h27
-rw-r--r--fs/notify/inode_mark.c5
-rw-r--r--fs/notify/inotify/inotify_user.c30
-rw-r--r--fs/notify/notification.c2
9 files changed, 265 insertions, 73 deletions
diff --git a/fs/notify/Makefile b/fs/notify/Makefile
index ae5f33a6d868..96d3420d0242 100644
--- a/fs/notify/Makefile
+++ b/fs/notify/Makefile
@@ -1,5 +1,5 @@
1obj-$(CONFIG_FSNOTIFY) += fsnotify.o notification.o group.o inode_mark.o \ 1obj-$(CONFIG_FSNOTIFY) += fsnotify.o notification.o group.o inode_mark.o \
2 mark.o vfsmount_mark.o 2 mark.o vfsmount_mark.o fdinfo.o
3 3
4obj-y += dnotify/ 4obj-y += dnotify/
5obj-y += inotify/ 5obj-y += inotify/
diff --git a/fs/notify/fanotify/Kconfig b/fs/notify/fanotify/Kconfig
index 7dceff005a67..e5f911bd80d2 100644
--- a/fs/notify/fanotify/Kconfig
+++ b/fs/notify/fanotify/Kconfig
@@ -4,7 +4,7 @@ config FANOTIFY
4 select ANON_INODES 4 select ANON_INODES
5 default n 5 default n
6 ---help--- 6 ---help---
7 Say Y here to enable fanotify suport. fanotify is a file access 7 Say Y here to enable fanotify support. fanotify is a file access
8 notification system which differs from inotify in that it sends 8 notification system which differs from inotify in that it sends
9 an open file descriptor to the userspace listener along with 9 an open file descriptor to the userspace listener along with
10 the event. 10 the event.
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c
index aeb5b5abbd4f..0c2f9122b262 100644
--- a/fs/notify/fanotify/fanotify.c
+++ b/fs/notify/fanotify/fanotify.c
@@ -27,6 +27,7 @@ static bool should_merge(struct fsnotify_event *old, struct fsnotify_event *new)
27 if ((old->path.mnt == new->path.mnt) && 27 if ((old->path.mnt == new->path.mnt) &&
28 (old->path.dentry == new->path.dentry)) 28 (old->path.dentry == new->path.dentry))
29 return true; 29 return true;
30 break;
30 case (FSNOTIFY_EVENT_NONE): 31 case (FSNOTIFY_EVENT_NONE):
31 return true; 32 return true;
32 default: 33 default:
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c
index f0e7a57bc899..9ff4a5ee6e20 100644
--- a/fs/notify/fanotify/fanotify_user.c
+++ b/fs/notify/fanotify/fanotify_user.c
@@ -17,6 +17,7 @@
17#include <asm/ioctls.h> 17#include <asm/ioctls.h>
18 18
19#include "../../mount.h" 19#include "../../mount.h"
20#include "../fdinfo.h"
20 21
21#define FANOTIFY_DEFAULT_MAX_EVENTS 16384 22#define FANOTIFY_DEFAULT_MAX_EVENTS 16384
22#define FANOTIFY_DEFAULT_MAX_MARKS 8192 23#define FANOTIFY_DEFAULT_MAX_MARKS 8192
@@ -58,7 +59,9 @@ static struct fsnotify_event *get_one_event(struct fsnotify_group *group,
58 return fsnotify_remove_notify_event(group); 59 return fsnotify_remove_notify_event(group);
59} 60}
60 61
61static int create_fd(struct fsnotify_group *group, struct fsnotify_event *event) 62static int create_fd(struct fsnotify_group *group,
63 struct fsnotify_event *event,
64 struct file **file)
62{ 65{
63 int client_fd; 66 int client_fd;
64 struct file *new_file; 67 struct file *new_file;
@@ -98,7 +101,7 @@ static int create_fd(struct fsnotify_group *group, struct fsnotify_event *event)
98 put_unused_fd(client_fd); 101 put_unused_fd(client_fd);
99 client_fd = PTR_ERR(new_file); 102 client_fd = PTR_ERR(new_file);
100 } else { 103 } else {
101 fd_install(client_fd, new_file); 104 *file = new_file;
102 } 105 }
103 106
104 return client_fd; 107 return client_fd;
@@ -106,13 +109,15 @@ static int create_fd(struct fsnotify_group *group, struct fsnotify_event *event)
106 109
107static int fill_event_metadata(struct fsnotify_group *group, 110static int fill_event_metadata(struct fsnotify_group *group,
108 struct fanotify_event_metadata *metadata, 111 struct fanotify_event_metadata *metadata,
109 struct fsnotify_event *event) 112 struct fsnotify_event *event,
113 struct file **file)
110{ 114{
111 int ret = 0; 115 int ret = 0;
112 116
113 pr_debug("%s: group=%p metadata=%p event=%p\n", __func__, 117 pr_debug("%s: group=%p metadata=%p event=%p\n", __func__,
114 group, metadata, event); 118 group, metadata, event);
115 119
120 *file = NULL;
116 metadata->event_len = FAN_EVENT_METADATA_LEN; 121 metadata->event_len = FAN_EVENT_METADATA_LEN;
117 metadata->metadata_len = FAN_EVENT_METADATA_LEN; 122 metadata->metadata_len = FAN_EVENT_METADATA_LEN;
118 metadata->vers = FANOTIFY_METADATA_VERSION; 123 metadata->vers = FANOTIFY_METADATA_VERSION;
@@ -121,7 +126,7 @@ static int fill_event_metadata(struct fsnotify_group *group,
121 if (unlikely(event->mask & FAN_Q_OVERFLOW)) 126 if (unlikely(event->mask & FAN_Q_OVERFLOW))
122 metadata->fd = FAN_NOFD; 127 metadata->fd = FAN_NOFD;
123 else { 128 else {
124 metadata->fd = create_fd(group, event); 129 metadata->fd = create_fd(group, event, file);
125 if (metadata->fd < 0) 130 if (metadata->fd < 0)
126 ret = metadata->fd; 131 ret = metadata->fd;
127 } 132 }
@@ -220,25 +225,6 @@ static int prepare_for_access_response(struct fsnotify_group *group,
220 return 0; 225 return 0;
221} 226}
222 227
223static void remove_access_response(struct fsnotify_group *group,
224 struct fsnotify_event *event,
225 __s32 fd)
226{
227 struct fanotify_response_event *re;
228
229 if (!(event->mask & FAN_ALL_PERM_EVENTS))
230 return;
231
232 re = dequeue_re(group, fd);
233 if (!re)
234 return;
235
236 BUG_ON(re->event != event);
237
238 kmem_cache_free(fanotify_response_event_cache, re);
239
240 return;
241}
242#else 228#else
243static int prepare_for_access_response(struct fsnotify_group *group, 229static int prepare_for_access_response(struct fsnotify_group *group,
244 struct fsnotify_event *event, 230 struct fsnotify_event *event,
@@ -247,12 +233,6 @@ static int prepare_for_access_response(struct fsnotify_group *group,
247 return 0; 233 return 0;
248} 234}
249 235
250static void remove_access_response(struct fsnotify_group *group,
251 struct fsnotify_event *event,
252 __s32 fd)
253{
254 return;
255}
256#endif 236#endif
257 237
258static ssize_t copy_event_to_user(struct fsnotify_group *group, 238static ssize_t copy_event_to_user(struct fsnotify_group *group,
@@ -260,31 +240,34 @@ static ssize_t copy_event_to_user(struct fsnotify_group *group,
260 char __user *buf) 240 char __user *buf)
261{ 241{
262 struct fanotify_event_metadata fanotify_event_metadata; 242 struct fanotify_event_metadata fanotify_event_metadata;
243 struct file *f;
263 int fd, ret; 244 int fd, ret;
264 245
265 pr_debug("%s: group=%p event=%p\n", __func__, group, event); 246 pr_debug("%s: group=%p event=%p\n", __func__, group, event);
266 247
267 ret = fill_event_metadata(group, &fanotify_event_metadata, event); 248 ret = fill_event_metadata(group, &fanotify_event_metadata, event, &f);
268 if (ret < 0) 249 if (ret < 0)
269 goto out; 250 goto out;
270 251
271 fd = fanotify_event_metadata.fd; 252 fd = fanotify_event_metadata.fd;
272 ret = prepare_for_access_response(group, event, fd);
273 if (ret)
274 goto out_close_fd;
275
276 ret = -EFAULT; 253 ret = -EFAULT;
277 if (copy_to_user(buf, &fanotify_event_metadata, 254 if (copy_to_user(buf, &fanotify_event_metadata,
278 fanotify_event_metadata.event_len)) 255 fanotify_event_metadata.event_len))
279 goto out_kill_access_response; 256 goto out_close_fd;
280 257
258 ret = prepare_for_access_response(group, event, fd);
259 if (ret)
260 goto out_close_fd;
261
262 if (fd != FAN_NOFD)
263 fd_install(fd, f);
281 return fanotify_event_metadata.event_len; 264 return fanotify_event_metadata.event_len;
282 265
283out_kill_access_response:
284 remove_access_response(group, event, fd);
285out_close_fd: 266out_close_fd:
286 if (fd != FAN_NOFD) 267 if (fd != FAN_NOFD) {
287 sys_close(fd); 268 put_unused_fd(fd);
269 fput(f);
270 }
288out: 271out:
289#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS 272#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
290 if (event->mask & FAN_ALL_PERM_EVENTS) { 273 if (event->mask & FAN_ALL_PERM_EVENTS) {
@@ -450,6 +433,7 @@ static long fanotify_ioctl(struct file *file, unsigned int cmd, unsigned long ar
450} 433}
451 434
452static const struct file_operations fanotify_fops = { 435static const struct file_operations fanotify_fops = {
436 .show_fdinfo = fanotify_show_fdinfo,
453 .poll = fanotify_poll, 437 .poll = fanotify_poll,
454 .read = fanotify_read, 438 .read = fanotify_read,
455 .write = fanotify_write, 439 .write = fanotify_write,
@@ -474,24 +458,22 @@ static int fanotify_find_path(int dfd, const char __user *filename,
474 dfd, filename, flags); 458 dfd, filename, flags);
475 459
476 if (filename == NULL) { 460 if (filename == NULL) {
477 struct file *file; 461 struct fd f = fdget(dfd);
478 int fput_needed;
479 462
480 ret = -EBADF; 463 ret = -EBADF;
481 file = fget_light(dfd, &fput_needed); 464 if (!f.file)
482 if (!file)
483 goto out; 465 goto out;
484 466
485 ret = -ENOTDIR; 467 ret = -ENOTDIR;
486 if ((flags & FAN_MARK_ONLYDIR) && 468 if ((flags & FAN_MARK_ONLYDIR) &&
487 !(S_ISDIR(file->f_path.dentry->d_inode->i_mode))) { 469 !(S_ISDIR(f.file->f_path.dentry->d_inode->i_mode))) {
488 fput_light(file, fput_needed); 470 fdput(f);
489 goto out; 471 goto out;
490 } 472 }
491 473
492 *path = file->f_path; 474 *path = f.file->f_path;
493 path_get(path); 475 path_get(path);
494 fput_light(file, fput_needed); 476 fdput(f);
495 } else { 477 } else {
496 unsigned int lookup_flags = 0; 478 unsigned int lookup_flags = 0;
497 479
@@ -780,9 +762,9 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags,
780 struct inode *inode = NULL; 762 struct inode *inode = NULL;
781 struct vfsmount *mnt = NULL; 763 struct vfsmount *mnt = NULL;
782 struct fsnotify_group *group; 764 struct fsnotify_group *group;
783 struct file *filp; 765 struct fd f;
784 struct path path; 766 struct path path;
785 int ret, fput_needed; 767 int ret;
786 768
787 pr_debug("%s: fanotify_fd=%d flags=%x dfd=%d pathname=%p mask=%llx\n", 769 pr_debug("%s: fanotify_fd=%d flags=%x dfd=%d pathname=%p mask=%llx\n",
788 __func__, fanotify_fd, flags, dfd, pathname, mask); 770 __func__, fanotify_fd, flags, dfd, pathname, mask);
@@ -816,15 +798,15 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags,
816#endif 798#endif
817 return -EINVAL; 799 return -EINVAL;
818 800
819 filp = fget_light(fanotify_fd, &fput_needed); 801 f = fdget(fanotify_fd);
820 if (unlikely(!filp)) 802 if (unlikely(!f.file))
821 return -EBADF; 803 return -EBADF;
822 804
823 /* verify that this is indeed an fanotify instance */ 805 /* verify that this is indeed an fanotify instance */
824 ret = -EINVAL; 806 ret = -EINVAL;
825 if (unlikely(filp->f_op != &fanotify_fops)) 807 if (unlikely(f.file->f_op != &fanotify_fops))
826 goto fput_and_out; 808 goto fput_and_out;
827 group = filp->private_data; 809 group = f.file->private_data;
828 810
829 /* 811 /*
830 * group->priority == FS_PRIO_0 == FAN_CLASS_NOTIF. These are not 812 * group->priority == FS_PRIO_0 == FAN_CLASS_NOTIF. These are not
@@ -871,7 +853,7 @@ SYSCALL_DEFINE(fanotify_mark)(int fanotify_fd, unsigned int flags,
871 853
872 path_put(&path); 854 path_put(&path);
873fput_and_out: 855fput_and_out:
874 fput_light(filp, fput_needed); 856 fdput(f);
875 return ret; 857 return ret;
876} 858}
877 859
diff --git a/fs/notify/fdinfo.c b/fs/notify/fdinfo.c
new file mode 100644
index 000000000000..238a5930cb3c
--- /dev/null
+++ b/fs/notify/fdinfo.c
@@ -0,0 +1,179 @@
1#include <linux/file.h>
2#include <linux/fs.h>
3#include <linux/fsnotify_backend.h>
4#include <linux/idr.h>
5#include <linux/init.h>
6#include <linux/inotify.h>
7#include <linux/fanotify.h>
8#include <linux/kernel.h>
9#include <linux/namei.h>
10#include <linux/sched.h>
11#include <linux/types.h>
12#include <linux/seq_file.h>
13#include <linux/proc_fs.h>
14#include <linux/exportfs.h>
15
16#include "inotify/inotify.h"
17#include "../fs/mount.h"
18
19#if defined(CONFIG_PROC_FS)
20
21#if defined(CONFIG_INOTIFY_USER) || defined(CONFIG_FANOTIFY)
22
23static int show_fdinfo(struct seq_file *m, struct file *f,
24 int (*show)(struct seq_file *m, struct fsnotify_mark *mark))
25{
26 struct fsnotify_group *group = f->private_data;
27 struct fsnotify_mark *mark;
28 int ret = 0;
29
30 mutex_lock(&group->mark_mutex);
31 list_for_each_entry(mark, &group->marks_list, g_list) {
32 ret = show(m, mark);
33 if (ret)
34 break;
35 }
36 mutex_unlock(&group->mark_mutex);
37 return ret;
38}
39
40#if defined(CONFIG_EXPORTFS)
41static int show_mark_fhandle(struct seq_file *m, struct inode *inode)
42{
43 struct {
44 struct file_handle handle;
45 u8 pad[64];
46 } f;
47 int size, ret, i;
48
49 f.handle.handle_bytes = sizeof(f.pad);
50 size = f.handle.handle_bytes >> 2;
51
52 ret = exportfs_encode_inode_fh(inode, (struct fid *)f.handle.f_handle, &size, 0);
53 if ((ret == 255) || (ret == -ENOSPC)) {
54 WARN_ONCE(1, "Can't encode file handler for inotify: %d\n", ret);
55 return 0;
56 }
57
58 f.handle.handle_type = ret;
59 f.handle.handle_bytes = size * sizeof(u32);
60
61 ret = seq_printf(m, "fhandle-bytes:%x fhandle-type:%x f_handle:",
62 f.handle.handle_bytes, f.handle.handle_type);
63
64 for (i = 0; i < f.handle.handle_bytes; i++)
65 ret |= seq_printf(m, "%02x", (int)f.handle.f_handle[i]);
66
67 return ret;
68}
69#else
70static int show_mark_fhandle(struct seq_file *m, struct inode *inode)
71{
72 return 0;
73}
74#endif
75
76#ifdef CONFIG_INOTIFY_USER
77
78static int inotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
79{
80 struct inotify_inode_mark *inode_mark;
81 struct inode *inode;
82 int ret = 0;
83
84 if (!(mark->flags & (FSNOTIFY_MARK_FLAG_ALIVE | FSNOTIFY_MARK_FLAG_INODE)))
85 return 0;
86
87 inode_mark = container_of(mark, struct inotify_inode_mark, fsn_mark);
88 inode = igrab(mark->i.inode);
89 if (inode) {
90 ret = seq_printf(m, "inotify wd:%x ino:%lx sdev:%x "
91 "mask:%x ignored_mask:%x ",
92 inode_mark->wd, inode->i_ino,
93 inode->i_sb->s_dev,
94 mark->mask, mark->ignored_mask);
95 ret |= show_mark_fhandle(m, inode);
96 ret |= seq_putc(m, '\n');
97 iput(inode);
98 }
99
100 return ret;
101}
102
103int inotify_show_fdinfo(struct seq_file *m, struct file *f)
104{
105 return show_fdinfo(m, f, inotify_fdinfo);
106}
107
108#endif /* CONFIG_INOTIFY_USER */
109
110#ifdef CONFIG_FANOTIFY
111
112static int fanotify_fdinfo(struct seq_file *m, struct fsnotify_mark *mark)
113{
114 unsigned int mflags = 0;
115 struct inode *inode;
116 int ret = 0;
117
118 if (!(mark->flags & FSNOTIFY_MARK_FLAG_ALIVE))
119 return 0;
120
121 if (mark->flags & FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY)
122 mflags |= FAN_MARK_IGNORED_SURV_MODIFY;
123
124 if (mark->flags & FSNOTIFY_MARK_FLAG_INODE) {
125 inode = igrab(mark->i.inode);
126 if (!inode)
127 goto out;
128 ret = seq_printf(m, "fanotify ino:%lx sdev:%x "
129 "mflags:%x mask:%x ignored_mask:%x ",
130 inode->i_ino, inode->i_sb->s_dev,
131 mflags, mark->mask, mark->ignored_mask);
132 ret |= show_mark_fhandle(m, inode);
133 ret |= seq_putc(m, '\n');
134 iput(inode);
135 } else if (mark->flags & FSNOTIFY_MARK_FLAG_VFSMOUNT) {
136 struct mount *mnt = real_mount(mark->m.mnt);
137
138 ret = seq_printf(m, "fanotify mnt_id:%x mflags:%x mask:%x "
139 "ignored_mask:%x\n", mnt->mnt_id, mflags,
140 mark->mask, mark->ignored_mask);
141 }
142out:
143 return ret;
144}
145
146int fanotify_show_fdinfo(struct seq_file *m, struct file *f)
147{
148 struct fsnotify_group *group = f->private_data;
149 unsigned int flags = 0;
150
151 switch (group->priority) {
152 case FS_PRIO_0:
153 flags |= FAN_CLASS_NOTIF;
154 break;
155 case FS_PRIO_1:
156 flags |= FAN_CLASS_CONTENT;
157 break;
158 case FS_PRIO_2:
159 flags |= FAN_CLASS_PRE_CONTENT;
160 break;
161 }
162
163 if (group->max_events == UINT_MAX)
164 flags |= FAN_UNLIMITED_QUEUE;
165
166 if (group->fanotify_data.max_marks == UINT_MAX)
167 flags |= FAN_UNLIMITED_MARKS;
168
169 seq_printf(m, "fanotify flags:%x event-flags:%x\n",
170 flags, group->fanotify_data.f_flags);
171
172 return show_fdinfo(m, f, fanotify_fdinfo);
173}
174
175#endif /* CONFIG_FANOTIFY */
176
177#endif /* CONFIG_INOTIFY_USER || CONFIG_FANOTIFY */
178
179#endif /* CONFIG_PROC_FS */
diff --git a/fs/notify/fdinfo.h b/fs/notify/fdinfo.h
new file mode 100644
index 000000000000..556afda990e9
--- /dev/null
+++ b/fs/notify/fdinfo.h
@@ -0,0 +1,27 @@
1#ifndef __FSNOTIFY_FDINFO_H__
2#define __FSNOTIFY_FDINFO_H__
3
4#include <linux/errno.h>
5#include <linux/proc_fs.h>
6
7struct seq_file;
8struct file;
9
10#ifdef CONFIG_PROC_FS
11
12#ifdef CONFIG_INOTIFY_USER
13extern int inotify_show_fdinfo(struct seq_file *m, struct file *f);
14#endif
15
16#ifdef CONFIG_FANOTIFY
17extern int fanotify_show_fdinfo(struct seq_file *m, struct file *f);
18#endif
19
20#else /* CONFIG_PROC_FS */
21
22#define inotify_show_fdinfo NULL
23#define fanotify_show_fdinfo NULL
24
25#endif /* CONFIG_PROC_FS */
26
27#endif /* __FSNOTIFY_FDINFO_H__ */
diff --git a/fs/notify/inode_mark.c b/fs/notify/inode_mark.c
index 21230209c957..f31e90fc050d 100644
--- a/fs/notify/inode_mark.c
+++ b/fs/notify/inode_mark.c
@@ -124,8 +124,9 @@ void fsnotify_clear_inode_marks_by_group(struct fsnotify_group *group)
124 * given a group and inode, find the mark associated with that combination. 124 * given a group and inode, find the mark associated with that combination.
125 * if found take a reference to that mark and return it, else return NULL 125 * if found take a reference to that mark and return it, else return NULL
126 */ 126 */
127struct fsnotify_mark *fsnotify_find_inode_mark_locked(struct fsnotify_group *group, 127static struct fsnotify_mark *fsnotify_find_inode_mark_locked(
128 struct inode *inode) 128 struct fsnotify_group *group,
129 struct inode *inode)
129{ 130{
130 struct fsnotify_mark *mark; 131 struct fsnotify_mark *mark;
131 struct hlist_node *pos; 132 struct hlist_node *pos;
diff --git a/fs/notify/inotify/inotify_user.c b/fs/notify/inotify/inotify_user.c
index 463e828f1f31..228a2c2ad8d7 100644
--- a/fs/notify/inotify/inotify_user.c
+++ b/fs/notify/inotify/inotify_user.c
@@ -40,6 +40,7 @@
40#include <linux/wait.h> 40#include <linux/wait.h>
41 41
42#include "inotify.h" 42#include "inotify.h"
43#include "../fdinfo.h"
43 44
44#include <asm/ioctls.h> 45#include <asm/ioctls.h>
45 46
@@ -329,6 +330,7 @@ static long inotify_ioctl(struct file *file, unsigned int cmd,
329} 330}
330 331
331static const struct file_operations inotify_fops = { 332static const struct file_operations inotify_fops = {
333 .show_fdinfo = inotify_show_fdinfo,
332 .poll = inotify_poll, 334 .poll = inotify_poll,
333 .read = inotify_read, 335 .read = inotify_read,
334 .fasync = fsnotify_fasync, 336 .fasync = fsnotify_fasync,
@@ -751,16 +753,16 @@ SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname,
751 struct fsnotify_group *group; 753 struct fsnotify_group *group;
752 struct inode *inode; 754 struct inode *inode;
753 struct path path; 755 struct path path;
754 struct file *filp; 756 struct fd f;
755 int ret, fput_needed; 757 int ret;
756 unsigned flags = 0; 758 unsigned flags = 0;
757 759
758 filp = fget_light(fd, &fput_needed); 760 f = fdget(fd);
759 if (unlikely(!filp)) 761 if (unlikely(!f.file))
760 return -EBADF; 762 return -EBADF;
761 763
762 /* verify that this is indeed an inotify instance */ 764 /* verify that this is indeed an inotify instance */
763 if (unlikely(filp->f_op != &inotify_fops)) { 765 if (unlikely(f.file->f_op != &inotify_fops)) {
764 ret = -EINVAL; 766 ret = -EINVAL;
765 goto fput_and_out; 767 goto fput_and_out;
766 } 768 }
@@ -776,13 +778,13 @@ SYSCALL_DEFINE3(inotify_add_watch, int, fd, const char __user *, pathname,
776 778
777 /* inode held in place by reference to path; group by fget on fd */ 779 /* inode held in place by reference to path; group by fget on fd */
778 inode = path.dentry->d_inode; 780 inode = path.dentry->d_inode;
779 group = filp->private_data; 781 group = f.file->private_data;
780 782
781 /* create/update an inode mark */ 783 /* create/update an inode mark */
782 ret = inotify_update_watch(group, inode, mask); 784 ret = inotify_update_watch(group, inode, mask);
783 path_put(&path); 785 path_put(&path);
784fput_and_out: 786fput_and_out:
785 fput_light(filp, fput_needed); 787 fdput(f);
786 return ret; 788 return ret;
787} 789}
788 790
@@ -790,19 +792,19 @@ SYSCALL_DEFINE2(inotify_rm_watch, int, fd, __s32, wd)
790{ 792{
791 struct fsnotify_group *group; 793 struct fsnotify_group *group;
792 struct inotify_inode_mark *i_mark; 794 struct inotify_inode_mark *i_mark;
793 struct file *filp; 795 struct fd f;
794 int ret = 0, fput_needed; 796 int ret = 0;
795 797
796 filp = fget_light(fd, &fput_needed); 798 f = fdget(fd);
797 if (unlikely(!filp)) 799 if (unlikely(!f.file))
798 return -EBADF; 800 return -EBADF;
799 801
800 /* verify that this is indeed an inotify instance */ 802 /* verify that this is indeed an inotify instance */
801 ret = -EINVAL; 803 ret = -EINVAL;
802 if (unlikely(filp->f_op != &inotify_fops)) 804 if (unlikely(f.file->f_op != &inotify_fops))
803 goto out; 805 goto out;
804 806
805 group = filp->private_data; 807 group = f.file->private_data;
806 808
807 ret = -EINVAL; 809 ret = -EINVAL;
808 i_mark = inotify_idr_find(group, wd); 810 i_mark = inotify_idr_find(group, wd);
@@ -817,7 +819,7 @@ SYSCALL_DEFINE2(inotify_rm_watch, int, fd, __s32, wd)
817 fsnotify_put_mark(&i_mark->fsn_mark); 819 fsnotify_put_mark(&i_mark->fsn_mark);
818 820
819out: 821out:
820 fput_light(filp, fput_needed); 822 fdput(f);
821 return ret; 823 return ret;
822} 824}
823 825
diff --git a/fs/notify/notification.c b/fs/notify/notification.c
index b3963d8c9988..7b51b05f160c 100644
--- a/fs/notify/notification.c
+++ b/fs/notify/notification.c
@@ -18,7 +18,7 @@
18 18
19/* 19/*
20 * Basic idea behind the notification queue: An fsnotify group (like inotify) 20 * Basic idea behind the notification queue: An fsnotify group (like inotify)
21 * sends the userspace notification about events asyncronously some time after 21 * sends the userspace notification about events asynchronously some time after
22 * the event happened. When inotify gets an event it will need to add that 22 * the event happened. When inotify gets an event it will need to add that
23 * event to the group notify queue. Since a single event might need to be on 23 * event to the group notify queue. Since a single event might need to be on
24 * multiple group's notification queues we can't add the event directly to each 24 * multiple group's notification queues we can't add the event directly to each