inotify: remove inotify in kernel interface
[linux-2.6.git] / include / linux / fsnotify.h
1 #ifndef _LINUX_FS_NOTIFY_H
2 #define _LINUX_FS_NOTIFY_H
3
4 /*
5  * include/linux/fsnotify.h - generic hooks for filesystem notification, to
6  * reduce in-source duplication from both dnotify and inotify.
7  *
8  * We don't compile any of this away in some complicated menagerie of ifdefs.
9  * Instead, we rely on the code inside to optimize away as needed.
10  *
11  * (C) Copyright 2005 Robert Love
12  */
13
14 #include <linux/fsnotify_backend.h>
15 #include <linux/audit.h>
16 #include <linux/slab.h>
17
18 /*
19  * fsnotify_d_instantiate - instantiate a dentry for inode
20  * Called with dcache_lock held.
21  */
22 static inline void fsnotify_d_instantiate(struct dentry *entry,
23                                                 struct inode *inode)
24 {
25         __fsnotify_d_instantiate(entry, inode);
26 }
27
28 /* Notify this dentry's parent about a child's events. */
29 static inline void fsnotify_parent(struct dentry *dentry, __u32 mask)
30 {
31         __fsnotify_parent(dentry, mask);
32 }
33
34 /*
35  * fsnotify_d_move - entry has been moved
36  * Called with dcache_lock and entry->d_lock held.
37  */
38 static inline void fsnotify_d_move(struct dentry *entry)
39 {
40         /*
41          * On move we need to update entry->d_flags to indicate if the new parent
42          * cares about events from this entry.
43          */
44         __fsnotify_update_dcache_flags(entry);
45 }
46
47 /*
48  * fsnotify_link_count - inode's link count changed
49  */
50 static inline void fsnotify_link_count(struct inode *inode)
51 {
52         fsnotify(inode, FS_ATTRIB, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
53 }
54
55 /*
56  * fsnotify_move - file old_name at old_dir was moved to new_name at new_dir
57  */
58 static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir,
59                                  const char *old_name,
60                                  int isdir, struct inode *target, struct dentry *moved)
61 {
62         struct inode *source = moved->d_inode;
63         u32 fs_cookie = fsnotify_get_cookie();
64         __u32 old_dir_mask = (FS_EVENT_ON_CHILD | FS_MOVED_FROM);
65         __u32 new_dir_mask = (FS_EVENT_ON_CHILD | FS_MOVED_TO);
66         const char *new_name = moved->d_name.name;
67
68         if (old_dir == new_dir)
69                 old_dir_mask |= FS_DN_RENAME;
70
71         if (isdir) {
72                 old_dir_mask |= FS_IN_ISDIR;
73                 new_dir_mask |= FS_IN_ISDIR;
74         }
75
76         fsnotify(old_dir, old_dir_mask, old_dir, FSNOTIFY_EVENT_INODE, old_name, fs_cookie);
77         fsnotify(new_dir, new_dir_mask, new_dir, FSNOTIFY_EVENT_INODE, new_name, fs_cookie);
78
79         if (target)
80                 fsnotify_link_count(target);
81
82         if (source)
83                 fsnotify(source, FS_MOVE_SELF, moved->d_inode, FSNOTIFY_EVENT_INODE, NULL, 0);
84         audit_inode_child(moved, new_dir);
85 }
86
87 /*
88  * fsnotify_inode_delete - and inode is being evicted from cache, clean up is needed
89  */
90 static inline void fsnotify_inode_delete(struct inode *inode)
91 {
92         __fsnotify_inode_delete(inode);
93 }
94
95 /*
96  * fsnotify_nameremove - a filename was removed from a directory
97  */
98 static inline void fsnotify_nameremove(struct dentry *dentry, int isdir)
99 {
100         __u32 mask = FS_DELETE;
101
102         if (isdir)
103                 mask |= FS_IN_ISDIR;
104
105         fsnotify_parent(dentry, mask);
106 }
107
108 /*
109  * fsnotify_inoderemove - an inode is going away
110  */
111 static inline void fsnotify_inoderemove(struct inode *inode)
112 {
113         fsnotify(inode, FS_DELETE_SELF, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
114         __fsnotify_inode_delete(inode);
115 }
116
117 /*
118  * fsnotify_create - 'name' was linked in
119  */
120 static inline void fsnotify_create(struct inode *inode, struct dentry *dentry)
121 {
122         audit_inode_child(dentry, inode);
123
124         fsnotify(inode, FS_CREATE, dentry->d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0);
125 }
126
127 /*
128  * fsnotify_link - new hardlink in 'inode' directory
129  * Note: We have to pass also the linked inode ptr as some filesystems leave
130  *   new_dentry->d_inode NULL and instantiate inode pointer later
131  */
132 static inline void fsnotify_link(struct inode *dir, struct inode *inode, struct dentry *new_dentry)
133 {
134         fsnotify_link_count(inode);
135         audit_inode_child(new_dentry, dir);
136
137         fsnotify(dir, FS_CREATE, inode, FSNOTIFY_EVENT_INODE, new_dentry->d_name.name, 0);
138 }
139
140 /*
141  * fsnotify_mkdir - directory 'name' was created
142  */
143 static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry)
144 {
145         __u32 mask = (FS_CREATE | FS_IN_ISDIR);
146         struct inode *d_inode = dentry->d_inode;
147
148         audit_inode_child(dentry, inode);
149
150         fsnotify(inode, mask, d_inode, FSNOTIFY_EVENT_INODE, dentry->d_name.name, 0);
151 }
152
153 /*
154  * fsnotify_access - file was read
155  */
156 static inline void fsnotify_access(struct dentry *dentry)
157 {
158         struct inode *inode = dentry->d_inode;
159         __u32 mask = FS_ACCESS;
160
161         if (S_ISDIR(inode->i_mode))
162                 mask |= FS_IN_ISDIR;
163
164         fsnotify_parent(dentry, mask);
165         fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
166 }
167
168 /*
169  * fsnotify_modify - file was modified
170  */
171 static inline void fsnotify_modify(struct dentry *dentry)
172 {
173         struct inode *inode = dentry->d_inode;
174         __u32 mask = FS_MODIFY;
175
176         if (S_ISDIR(inode->i_mode))
177                 mask |= FS_IN_ISDIR;
178
179         fsnotify_parent(dentry, mask);
180         fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
181 }
182
183 /*
184  * fsnotify_open - file was opened
185  */
186 static inline void fsnotify_open(struct dentry *dentry)
187 {
188         struct inode *inode = dentry->d_inode;
189         __u32 mask = FS_OPEN;
190
191         if (S_ISDIR(inode->i_mode))
192                 mask |= FS_IN_ISDIR;
193
194         fsnotify_parent(dentry, mask);
195         fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
196 }
197
198 /*
199  * fsnotify_close - file was closed
200  */
201 static inline void fsnotify_close(struct file *file)
202 {
203         struct dentry *dentry = file->f_path.dentry;
204         struct inode *inode = dentry->d_inode;
205         fmode_t mode = file->f_mode;
206         __u32 mask = (mode & FMODE_WRITE) ? FS_CLOSE_WRITE : FS_CLOSE_NOWRITE;
207
208         if (S_ISDIR(inode->i_mode))
209                 mask |= FS_IN_ISDIR;
210
211         fsnotify_parent(dentry, mask);
212         fsnotify(inode, mask, file, FSNOTIFY_EVENT_FILE, NULL, 0);
213 }
214
215 /*
216  * fsnotify_xattr - extended attributes were changed
217  */
218 static inline void fsnotify_xattr(struct dentry *dentry)
219 {
220         struct inode *inode = dentry->d_inode;
221         __u32 mask = FS_ATTRIB;
222
223         if (S_ISDIR(inode->i_mode))
224                 mask |= FS_IN_ISDIR;
225
226         fsnotify_parent(dentry, mask);
227         fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
228 }
229
230 /*
231  * fsnotify_change - notify_change event.  file was modified and/or metadata
232  * was changed.
233  */
234 static inline void fsnotify_change(struct dentry *dentry, unsigned int ia_valid)
235 {
236         struct inode *inode = dentry->d_inode;
237         __u32 mask = 0;
238
239         if (ia_valid & ATTR_UID)
240                 mask |= FS_ATTRIB;
241         if (ia_valid & ATTR_GID)
242                 mask |= FS_ATTRIB;
243         if (ia_valid & ATTR_SIZE)
244                 mask |= FS_MODIFY;
245
246         /* both times implies a utime(s) call */
247         if ((ia_valid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME))
248                 mask |= FS_ATTRIB;
249         else if (ia_valid & ATTR_ATIME)
250                 mask |= FS_ACCESS;
251         else if (ia_valid & ATTR_MTIME)
252                 mask |= FS_MODIFY;
253
254         if (ia_valid & ATTR_MODE)
255                 mask |= FS_ATTRIB;
256
257         if (mask) {
258                 if (S_ISDIR(inode->i_mode))
259                         mask |= FS_IN_ISDIR;
260                 fsnotify_parent(dentry, mask);
261                 fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
262         }
263 }
264
265 #if defined(CONFIG_FSNOTIFY)    /* notify helpers */
266
267 /*
268  * fsnotify_oldname_init - save off the old filename before we change it
269  */
270 static inline const char *fsnotify_oldname_init(const char *name)
271 {
272         return kstrdup(name, GFP_KERNEL);
273 }
274
275 /*
276  * fsnotify_oldname_free - free the name we got from fsnotify_oldname_init
277  */
278 static inline void fsnotify_oldname_free(const char *old_name)
279 {
280         kfree(old_name);
281 }
282
283 #else   /* CONFIG_INOTIFY || CONFIG_FSNOTIFY */
284
285 static inline const char *fsnotify_oldname_init(const char *name)
286 {
287         return NULL;
288 }
289
290 static inline void fsnotify_oldname_free(const char *old_name)
291 {
292 }
293
294 #endif  /* ! CONFIG_INOTIFY */
295
296 #endif  /* _LINUX_FS_NOTIFY_H */