diff options
| -rw-r--r-- | fs/notify/fsnotify.c | 13 | ||||
| -rw-r--r-- | include/linux/fsnotify.h | 40 | ||||
| -rw-r--r-- | include/linux/fsnotify_backend.h | 4 |
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. */ |
| 81 | void __fsnotify_parent(struct dentry *dentry, __u32 mask) | 81 | void __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. */ |
| 29 | static inline void fsnotify_parent(struct dentry *dentry, __u32 mask) | 29 | static 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 | */ |
| 156 | static inline void fsnotify_access(struct file *file) | 161 | static 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 | */ |
| 172 | static inline void fsnotify_modify(struct file *file) | 176 | static 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 | */ |
| 188 | static inline void fsnotify_open(struct file *file) | 191 | static 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 | */ |
| 204 | static inline void fsnotify_close(struct file *file) | 206 | static 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 | ||
| 288 | static inline const char *fsnotify_oldname_init(const char *name) | 290 | static 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 */ |
| 260 | extern void fsnotify(struct inode *to_tell, __u32 mask, void *data, int data_is, | 260 | extern 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); |
| 262 | extern void __fsnotify_parent(struct dentry *dentry, __u32 mask); | 262 | extern void __fsnotify_parent(struct file *file, struct dentry *dentry, __u32 mask); |
| 263 | extern void __fsnotify_inode_delete(struct inode *inode); | 263 | extern void __fsnotify_inode_delete(struct inode *inode); |
| 264 | extern u32 fsnotify_get_cookie(void); | 264 | extern 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 | ||
| 370 | static inline void __fsnotify_parent(struct dentry *dentry, __u32 mask) | 370 | static inline void __fsnotify_parent(struct file *file, struct dentry *dentry, __u32 mask) |
| 371 | {} | 371 | {} |
| 372 | 372 | ||
| 373 | static inline void __fsnotify_inode_delete(struct inode *inode) | 373 | static inline void __fsnotify_inode_delete(struct inode *inode) |
