aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/notify/fsnotify.c13
-rw-r--r--include/linux/fsnotify.h40
-rw-r--r--include/linux/fsnotify_backend.h4
3 files changed, 33 insertions, 24 deletions
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c
index 523337b600a0..806beede24a3 100644
--- a/fs/notify/fsnotify.c
+++ b/fs/notify/fsnotify.c
@@ -78,13 +78,16 @@ void __fsnotify_update_child_dentry_flags(struct inode *inode)
78} 78}
79 79
80/* Notify this dentry's parent about a child's events. */ 80/* Notify this dentry's parent about a child's events. */
81void __fsnotify_parent(struct dentry *dentry, __u32 mask) 81void __fsnotify_parent(struct file *file, struct dentry *dentry, __u32 mask)
82{ 82{
83 struct dentry *parent; 83 struct dentry *parent;
84 struct inode *p_inode; 84 struct inode *p_inode;
85 bool send = false; 85 bool send = false;
86 bool should_update_children = false; 86 bool should_update_children = false;
87 87
88 if (file)
89 dentry = file->f_path.dentry;
90
88 if (!(dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED)) 91 if (!(dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED))
89 return; 92 return;
90 93
@@ -115,8 +118,12 @@ void __fsnotify_parent(struct dentry *dentry, __u32 mask)
115 * specifies these are events which came from a child. */ 118 * specifies these are events which came from a child. */
116 mask |= FS_EVENT_ON_CHILD; 119 mask |= FS_EVENT_ON_CHILD;
117 120
118 fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE, 121 if (file)
119 dentry->d_name.name, 0); 122 fsnotify(p_inode, mask, file, FSNOTIFY_EVENT_FILE,
123 dentry->d_name.name, 0);
124 else
125 fsnotify(p_inode, mask, dentry->d_inode, FSNOTIFY_EVENT_INODE,
126 dentry->d_name.name, 0);
120 dput(parent); 127 dput(parent);
121 } 128 }
122 129
diff --git a/include/linux/fsnotify.h b/include/linux/fsnotify.h
index 845e57abfb86..04ea03ea8090 100644
--- a/include/linux/fsnotify.h
+++ b/include/linux/fsnotify.h
@@ -26,9 +26,14 @@ static inline void fsnotify_d_instantiate(struct dentry *entry,
26} 26}
27 27
28/* Notify this dentry's parent about a child's events. */ 28/* Notify this dentry's parent about a child's events. */
29static inline void fsnotify_parent(struct dentry *dentry, __u32 mask) 29static inline void fsnotify_parent(struct file *file, struct dentry *dentry, __u32 mask)
30{ 30{
31 __fsnotify_parent(dentry, mask); 31 BUG_ON(file && dentry);
32
33 if (file)
34 dentry = file->f_path.dentry;
35
36 __fsnotify_parent(file, dentry, mask);
32} 37}
33 38
34/* 39/*
@@ -102,7 +107,7 @@ static inline void fsnotify_nameremove(struct dentry *dentry, int isdir)
102 if (isdir) 107 if (isdir)
103 mask |= FS_IN_ISDIR; 108 mask |= FS_IN_ISDIR;
104 109
105 fsnotify_parent(dentry, mask); 110 fsnotify_parent(NULL, dentry, mask);
106} 111}
107 112
108/* 113/*
@@ -155,14 +160,13 @@ static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry)
155 */ 160 */
156static inline void fsnotify_access(struct file *file) 161static inline void fsnotify_access(struct file *file)
157{ 162{
158 struct dentry *dentry = file->f_path.dentry; 163 struct inode *inode = file->f_path.dentry->d_inode;
159 struct inode *inode = dentry->d_inode;
160 __u32 mask = FS_ACCESS; 164 __u32 mask = FS_ACCESS;
161 165
162 if (S_ISDIR(inode->i_mode)) 166 if (S_ISDIR(inode->i_mode))
163 mask |= FS_IN_ISDIR; 167 mask |= FS_IN_ISDIR;
164 168
165 fsnotify_parent(dentry, mask); 169 fsnotify_parent(file, NULL, mask);
166 fsnotify(inode, mask, file, FSNOTIFY_EVENT_FILE, NULL, 0); 170 fsnotify(inode, mask, file, FSNOTIFY_EVENT_FILE, NULL, 0);
167} 171}
168 172
@@ -171,14 +175,13 @@ static inline void fsnotify_access(struct file *file)
171 */ 175 */
172static inline void fsnotify_modify(struct file *file) 176static inline void fsnotify_modify(struct file *file)
173{ 177{
174 struct dentry *dentry = file->f_path.dentry; 178 struct inode *inode = file->f_path.dentry->d_inode;
175 struct inode *inode = dentry->d_inode;
176 __u32 mask = FS_MODIFY; 179 __u32 mask = FS_MODIFY;
177 180
178 if (S_ISDIR(inode->i_mode)) 181 if (S_ISDIR(inode->i_mode))
179 mask |= FS_IN_ISDIR; 182 mask |= FS_IN_ISDIR;
180 183
181 fsnotify_parent(dentry, mask); 184 fsnotify_parent(file, NULL, mask);
182 fsnotify(inode, mask, file, FSNOTIFY_EVENT_FILE, NULL, 0); 185 fsnotify(inode, mask, file, FSNOTIFY_EVENT_FILE, NULL, 0);
183} 186}
184 187
@@ -187,14 +190,13 @@ static inline void fsnotify_modify(struct file *file)
187 */ 190 */
188static inline void fsnotify_open(struct file *file) 191static inline void fsnotify_open(struct file *file)
189{ 192{
190 struct dentry *dentry = file->f_path.dentry; 193 struct inode *inode = file->f_path.dentry->d_inode;
191 struct inode *inode = dentry->d_inode;
192 __u32 mask = FS_OPEN; 194 __u32 mask = FS_OPEN;
193 195
194 if (S_ISDIR(inode->i_mode)) 196 if (S_ISDIR(inode->i_mode))
195 mask |= FS_IN_ISDIR; 197 mask |= FS_IN_ISDIR;
196 198
197 fsnotify_parent(dentry, mask); 199 fsnotify_parent(file, NULL, mask);
198 fsnotify(inode, mask, file, FSNOTIFY_EVENT_FILE, NULL, 0); 200 fsnotify(inode, mask, file, FSNOTIFY_EVENT_FILE, NULL, 0);
199} 201}
200 202
@@ -203,15 +205,14 @@ static inline void fsnotify_open(struct file *file)
203 */ 205 */
204static inline void fsnotify_close(struct file *file) 206static inline void fsnotify_close(struct file *file)
205{ 207{
206 struct dentry *dentry = file->f_path.dentry; 208 struct inode *inode = file->f_path.dentry->d_inode;
207 struct inode *inode = dentry->d_inode;
208 fmode_t mode = file->f_mode; 209 fmode_t mode = file->f_mode;
209 __u32 mask = (mode & FMODE_WRITE) ? FS_CLOSE_WRITE : FS_CLOSE_NOWRITE; 210 __u32 mask = (mode & FMODE_WRITE) ? FS_CLOSE_WRITE : FS_CLOSE_NOWRITE;
210 211
211 if (S_ISDIR(inode->i_mode)) 212 if (S_ISDIR(inode->i_mode))
212 mask |= FS_IN_ISDIR; 213 mask |= FS_IN_ISDIR;
213 214
214 fsnotify_parent(dentry, mask); 215 fsnotify_parent(file, NULL, mask);
215 fsnotify(inode, mask, file, FSNOTIFY_EVENT_FILE, NULL, 0); 216 fsnotify(inode, mask, file, FSNOTIFY_EVENT_FILE, NULL, 0);
216} 217}
217 218
@@ -226,7 +227,7 @@ static inline void fsnotify_xattr(struct dentry *dentry)
226 if (S_ISDIR(inode->i_mode)) 227 if (S_ISDIR(inode->i_mode))
227 mask |= FS_IN_ISDIR; 228 mask |= FS_IN_ISDIR;
228 229
229 fsnotify_parent(dentry, mask); 230 fsnotify_parent(NULL, dentry, mask);
230 fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0); 231 fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
231} 232}
232 233
@@ -260,7 +261,8 @@ static inline void fsnotify_change(struct dentry *dentry, unsigned int ia_valid)
260 if (mask) { 261 if (mask) {
261 if (S_ISDIR(inode->i_mode)) 262 if (S_ISDIR(inode->i_mode))
262 mask |= FS_IN_ISDIR; 263 mask |= FS_IN_ISDIR;
263 fsnotify_parent(dentry, mask); 264
265 fsnotify_parent(NULL, dentry, mask);
264 fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0); 266 fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
265 } 267 }
266} 268}
@@ -283,7 +285,7 @@ static inline void fsnotify_oldname_free(const char *old_name)
283 kfree(old_name); 285 kfree(old_name);
284} 286}
285 287
286#else /* CONFIG_INOTIFY || CONFIG_FSNOTIFY */ 288#else /* CONFIG_FSNOTIFY */
287 289
288static inline const char *fsnotify_oldname_init(const char *name) 290static inline const char *fsnotify_oldname_init(const char *name)
289{ 291{
@@ -294,6 +296,6 @@ static inline void fsnotify_oldname_free(const char *old_name)
294{ 296{
295} 297}
296 298
297#endif /* ! CONFIG_INOTIFY */ 299#endif /* CONFIG_FSNOTIFY */
298 300
299#endif /* _LINUX_FS_NOTIFY_H */ 301#endif /* _LINUX_FS_NOTIFY_H */
diff --git a/include/linux/fsnotify_backend.h b/include/linux/fsnotify_backend.h
index 2766df67f1ec..0e0c2b76b067 100644
--- a/include/linux/fsnotify_backend.h
+++ b/include/linux/fsnotify_backend.h
@@ -259,7 +259,7 @@ struct fsnotify_mark_entry {
259/* main fsnotify call to send events */ 259/* main fsnotify call to send events */
260extern void fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, 260extern void fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is,
261 const char *name, u32 cookie); 261 const char *name, u32 cookie);
262extern void __fsnotify_parent(struct dentry *dentry, __u32 mask); 262extern void __fsnotify_parent(struct file *file, struct dentry *dentry, __u32 mask);
263extern void __fsnotify_inode_delete(struct inode *inode); 263extern void __fsnotify_inode_delete(struct inode *inode);
264extern u32 fsnotify_get_cookie(void); 264extern u32 fsnotify_get_cookie(void);
265 265
@@ -367,7 +367,7 @@ static inline void fsnotify(struct inode *to_tell, __u32 mask, void *data, int d
367 const char *name, u32 cookie) 367 const char *name, u32 cookie)
368{} 368{}
369 369
370static inline void __fsnotify_parent(struct dentry *dentry, __u32 mask) 370static inline void __fsnotify_parent(struct file *file, struct dentry *dentry, __u32 mask)
371{} 371{}
372 372
373static inline void __fsnotify_inode_delete(struct inode *inode) 373static inline void __fsnotify_inode_delete(struct inode *inode)