Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/aoe-2.6
[linux-2.6] / 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 #ifdef __KERNEL__
15
16 #include <linux/dnotify.h>
17 #include <linux/inotify.h>
18
19 /*
20  * fsnotify_d_instantiate - instantiate a dentry for inode
21  * Called with dcache_lock held.
22  */
23 static inline void fsnotify_d_instantiate(struct dentry *entry,
24                                                 struct inode *inode)
25 {
26         inotify_d_instantiate(entry, inode);
27 }
28
29 /*
30  * fsnotify_d_move - entry has been moved
31  * Called with dcache_lock and entry->d_lock held.
32  */
33 static inline void fsnotify_d_move(struct dentry *entry)
34 {
35         inotify_d_move(entry);
36 }
37
38 /*
39  * fsnotify_move - file old_name at old_dir was moved to new_name at new_dir
40  */
41 static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir,
42                                  const char *old_name, const char *new_name,
43                                  int isdir, struct inode *target, struct inode *source)
44 {
45         u32 cookie = inotify_get_cookie();
46
47         if (old_dir == new_dir)
48                 inode_dir_notify(old_dir, DN_RENAME);
49         else {
50                 inode_dir_notify(old_dir, DN_DELETE);
51                 inode_dir_notify(new_dir, DN_CREATE);
52         }
53
54         if (isdir)
55                 isdir = IN_ISDIR;
56         inotify_inode_queue_event(old_dir, IN_MOVED_FROM|isdir,cookie,old_name);
57         inotify_inode_queue_event(new_dir, IN_MOVED_TO|isdir, cookie, new_name);
58
59         if (target) {
60                 inotify_inode_queue_event(target, IN_DELETE_SELF, 0, NULL);
61                 inotify_inode_is_dead(target);
62         }
63
64         if (source) {
65                 inotify_inode_queue_event(source, IN_MOVE_SELF, 0, NULL);
66         }
67 }
68
69 /*
70  * fsnotify_nameremove - a filename was removed from a directory
71  */
72 static inline void fsnotify_nameremove(struct dentry *dentry, int isdir)
73 {
74         if (isdir)
75                 isdir = IN_ISDIR;
76         dnotify_parent(dentry, DN_DELETE);
77         inotify_dentry_parent_queue_event(dentry, IN_DELETE|isdir, 0, dentry->d_name.name);
78 }
79
80 /*
81  * fsnotify_inoderemove - an inode is going away
82  */
83 static inline void fsnotify_inoderemove(struct inode *inode)
84 {
85         inotify_inode_queue_event(inode, IN_DELETE_SELF, 0, NULL);
86         inotify_inode_is_dead(inode);
87 }
88
89 /*
90  * fsnotify_create - 'name' was linked in
91  */
92 static inline void fsnotify_create(struct inode *inode, const char *name)
93 {
94         inode_dir_notify(inode, DN_CREATE);
95         inotify_inode_queue_event(inode, IN_CREATE, 0, name);
96 }
97
98 /*
99  * fsnotify_mkdir - directory 'name' was created
100  */
101 static inline void fsnotify_mkdir(struct inode *inode, const char *name)
102 {
103         inode_dir_notify(inode, DN_CREATE);
104         inotify_inode_queue_event(inode, IN_CREATE | IN_ISDIR, 0, name);
105 }
106
107 /*
108  * fsnotify_access - file was read
109  */
110 static inline void fsnotify_access(struct dentry *dentry)
111 {
112         struct inode *inode = dentry->d_inode;
113         u32 mask = IN_ACCESS;
114
115         if (S_ISDIR(inode->i_mode))
116                 mask |= IN_ISDIR;
117
118         dnotify_parent(dentry, DN_ACCESS);
119         inotify_dentry_parent_queue_event(dentry, mask, 0, dentry->d_name.name);
120         inotify_inode_queue_event(inode, mask, 0, NULL);
121 }
122
123 /*
124  * fsnotify_modify - file was modified
125  */
126 static inline void fsnotify_modify(struct dentry *dentry)
127 {
128         struct inode *inode = dentry->d_inode;
129         u32 mask = IN_MODIFY;
130
131         if (S_ISDIR(inode->i_mode))
132                 mask |= IN_ISDIR;
133
134         dnotify_parent(dentry, DN_MODIFY);
135         inotify_dentry_parent_queue_event(dentry, mask, 0, dentry->d_name.name);
136         inotify_inode_queue_event(inode, mask, 0, NULL);
137 }
138
139 /*
140  * fsnotify_open - file was opened
141  */
142 static inline void fsnotify_open(struct dentry *dentry)
143 {
144         struct inode *inode = dentry->d_inode;
145         u32 mask = IN_OPEN;
146
147         if (S_ISDIR(inode->i_mode))
148                 mask |= IN_ISDIR;
149
150         inotify_dentry_parent_queue_event(dentry, mask, 0, dentry->d_name.name);
151         inotify_inode_queue_event(inode, mask, 0, NULL);        
152 }
153
154 /*
155  * fsnotify_close - file was closed
156  */
157 static inline void fsnotify_close(struct file *file)
158 {
159         struct dentry *dentry = file->f_dentry;
160         struct inode *inode = dentry->d_inode;
161         const char *name = dentry->d_name.name;
162         mode_t mode = file->f_mode;
163         u32 mask = (mode & FMODE_WRITE) ? IN_CLOSE_WRITE : IN_CLOSE_NOWRITE;
164
165         if (S_ISDIR(inode->i_mode))
166                 mask |= IN_ISDIR;
167
168         inotify_dentry_parent_queue_event(dentry, mask, 0, name);
169         inotify_inode_queue_event(inode, mask, 0, NULL);
170 }
171
172 /*
173  * fsnotify_xattr - extended attributes were changed
174  */
175 static inline void fsnotify_xattr(struct dentry *dentry)
176 {
177         struct inode *inode = dentry->d_inode;
178         u32 mask = IN_ATTRIB;
179
180         if (S_ISDIR(inode->i_mode))
181                 mask |= IN_ISDIR;
182
183         inotify_dentry_parent_queue_event(dentry, mask, 0, dentry->d_name.name);
184         inotify_inode_queue_event(inode, mask, 0, NULL);
185 }
186
187 /*
188  * fsnotify_change - notify_change event.  file was modified and/or metadata
189  * was changed.
190  */
191 static inline void fsnotify_change(struct dentry *dentry, unsigned int ia_valid)
192 {
193         struct inode *inode = dentry->d_inode;
194         int dn_mask = 0;
195         u32 in_mask = 0;
196
197         if (ia_valid & ATTR_UID) {
198                 in_mask |= IN_ATTRIB;
199                 dn_mask |= DN_ATTRIB;
200         }
201         if (ia_valid & ATTR_GID) {
202                 in_mask |= IN_ATTRIB;
203                 dn_mask |= DN_ATTRIB;
204         }
205         if (ia_valid & ATTR_SIZE) {
206                 in_mask |= IN_MODIFY;
207                 dn_mask |= DN_MODIFY;
208         }
209         /* both times implies a utime(s) call */
210         if ((ia_valid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME))
211         {
212                 in_mask |= IN_ATTRIB;
213                 dn_mask |= DN_ATTRIB;
214         } else if (ia_valid & ATTR_ATIME) {
215                 in_mask |= IN_ACCESS;
216                 dn_mask |= DN_ACCESS;
217         } else if (ia_valid & ATTR_MTIME) {
218                 in_mask |= IN_MODIFY;
219                 dn_mask |= DN_MODIFY;
220         }
221         if (ia_valid & ATTR_MODE) {
222                 in_mask |= IN_ATTRIB;
223                 dn_mask |= DN_ATTRIB;
224         }
225
226         if (dn_mask)
227                 dnotify_parent(dentry, dn_mask);
228         if (in_mask) {
229                 if (S_ISDIR(inode->i_mode))
230                         in_mask |= IN_ISDIR;
231                 inotify_inode_queue_event(inode, in_mask, 0, NULL);
232                 inotify_dentry_parent_queue_event(dentry, in_mask, 0,
233                                                   dentry->d_name.name);
234         }
235 }
236
237 #ifdef CONFIG_INOTIFY   /* inotify helpers */
238
239 /*
240  * fsnotify_oldname_init - save off the old filename before we change it
241  */
242 static inline const char *fsnotify_oldname_init(const char *name)
243 {
244         return kstrdup(name, GFP_KERNEL);
245 }
246
247 /*
248  * fsnotify_oldname_free - free the name we got from fsnotify_oldname_init
249  */
250 static inline void fsnotify_oldname_free(const char *old_name)
251 {
252         kfree(old_name);
253 }
254
255 #else   /* CONFIG_INOTIFY */
256
257 static inline const char *fsnotify_oldname_init(const char *name)
258 {
259         return NULL;
260 }
261
262 static inline void fsnotify_oldname_free(const char *old_name)
263 {
264 }
265
266 #endif  /* ! CONFIG_INOTIFY */
267
268 #endif  /* __KERNEL__ */
269
270 #endif  /* _LINUX_FS_NOTIFY_H */