0001
0002 #ifndef _LINUX_FS_NOTIFY_H
0003 #define _LINUX_FS_NOTIFY_H
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/fsnotify_backend.h>
0016 #include <linux/audit.h>
0017 #include <linux/slab.h>
0018 #include <linux/bug.h>
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029 static inline int fsnotify_name(__u32 mask, const void *data, int data_type,
0030 struct inode *dir, const struct qstr *name,
0031 u32 cookie)
0032 {
0033 if (atomic_long_read(&dir->i_sb->s_fsnotify_connectors) == 0)
0034 return 0;
0035
0036 return fsnotify(mask, data, data_type, dir, name, NULL, cookie);
0037 }
0038
0039 static inline void fsnotify_dirent(struct inode *dir, struct dentry *dentry,
0040 __u32 mask)
0041 {
0042 fsnotify_name(mask, dentry, FSNOTIFY_EVENT_DENTRY, dir, &dentry->d_name, 0);
0043 }
0044
0045 static inline void fsnotify_inode(struct inode *inode, __u32 mask)
0046 {
0047 if (atomic_long_read(&inode->i_sb->s_fsnotify_connectors) == 0)
0048 return;
0049
0050 if (S_ISDIR(inode->i_mode))
0051 mask |= FS_ISDIR;
0052
0053 fsnotify(mask, inode, FSNOTIFY_EVENT_INODE, NULL, NULL, inode, 0);
0054 }
0055
0056
0057 static inline int fsnotify_parent(struct dentry *dentry, __u32 mask,
0058 const void *data, int data_type)
0059 {
0060 struct inode *inode = d_inode(dentry);
0061
0062 if (atomic_long_read(&inode->i_sb->s_fsnotify_connectors) == 0)
0063 return 0;
0064
0065 if (S_ISDIR(inode->i_mode)) {
0066 mask |= FS_ISDIR;
0067
0068
0069 if (!(dentry->d_flags & DCACHE_FSNOTIFY_PARENT_WATCHED))
0070 goto notify_child;
0071 }
0072
0073
0074 if (IS_ROOT(dentry))
0075 goto notify_child;
0076
0077 return __fsnotify_parent(dentry, mask, data, data_type);
0078
0079 notify_child:
0080 return fsnotify(mask, data, data_type, NULL, NULL, inode, 0);
0081 }
0082
0083
0084
0085
0086
0087 static inline void fsnotify_dentry(struct dentry *dentry, __u32 mask)
0088 {
0089 fsnotify_parent(dentry, mask, dentry, FSNOTIFY_EVENT_DENTRY);
0090 }
0091
0092 static inline int fsnotify_file(struct file *file, __u32 mask)
0093 {
0094 const struct path *path = &file->f_path;
0095
0096 if (file->f_mode & FMODE_NONOTIFY)
0097 return 0;
0098
0099 return fsnotify_parent(path->dentry, mask, path, FSNOTIFY_EVENT_PATH);
0100 }
0101
0102
0103 static inline int fsnotify_perm(struct file *file, int mask)
0104 {
0105 int ret;
0106 __u32 fsnotify_mask = 0;
0107
0108 if (!(mask & (MAY_READ | MAY_OPEN)))
0109 return 0;
0110
0111 if (mask & MAY_OPEN) {
0112 fsnotify_mask = FS_OPEN_PERM;
0113
0114 if (file->f_flags & __FMODE_EXEC) {
0115 ret = fsnotify_file(file, FS_OPEN_EXEC_PERM);
0116
0117 if (ret)
0118 return ret;
0119 }
0120 } else if (mask & MAY_READ) {
0121 fsnotify_mask = FS_ACCESS_PERM;
0122 }
0123
0124 return fsnotify_file(file, fsnotify_mask);
0125 }
0126
0127
0128
0129
0130 static inline void fsnotify_link_count(struct inode *inode)
0131 {
0132 fsnotify_inode(inode, FS_ATTRIB);
0133 }
0134
0135
0136
0137
0138 static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir,
0139 const struct qstr *old_name,
0140 int isdir, struct inode *target,
0141 struct dentry *moved)
0142 {
0143 struct inode *source = moved->d_inode;
0144 u32 fs_cookie = fsnotify_get_cookie();
0145 __u32 old_dir_mask = FS_MOVED_FROM;
0146 __u32 new_dir_mask = FS_MOVED_TO;
0147 __u32 rename_mask = FS_RENAME;
0148 const struct qstr *new_name = &moved->d_name;
0149
0150 if (isdir) {
0151 old_dir_mask |= FS_ISDIR;
0152 new_dir_mask |= FS_ISDIR;
0153 rename_mask |= FS_ISDIR;
0154 }
0155
0156
0157 fsnotify_name(rename_mask, moved, FSNOTIFY_EVENT_DENTRY,
0158 old_dir, old_name, 0);
0159
0160 fsnotify_name(old_dir_mask, source, FSNOTIFY_EVENT_INODE,
0161 old_dir, old_name, fs_cookie);
0162 fsnotify_name(new_dir_mask, source, FSNOTIFY_EVENT_INODE,
0163 new_dir, new_name, fs_cookie);
0164
0165 if (target)
0166 fsnotify_link_count(target);
0167 fsnotify_inode(source, FS_MOVE_SELF);
0168 audit_inode_child(new_dir, moved, AUDIT_TYPE_CHILD_CREATE);
0169 }
0170
0171
0172
0173
0174 static inline void fsnotify_inode_delete(struct inode *inode)
0175 {
0176 __fsnotify_inode_delete(inode);
0177 }
0178
0179
0180
0181
0182 static inline void fsnotify_vfsmount_delete(struct vfsmount *mnt)
0183 {
0184 __fsnotify_vfsmount_delete(mnt);
0185 }
0186
0187
0188
0189
0190 static inline void fsnotify_inoderemove(struct inode *inode)
0191 {
0192 fsnotify_inode(inode, FS_DELETE_SELF);
0193 __fsnotify_inode_delete(inode);
0194 }
0195
0196
0197
0198
0199
0200
0201
0202
0203 static inline void fsnotify_create(struct inode *dir, struct dentry *dentry)
0204 {
0205 audit_inode_child(dir, dentry, AUDIT_TYPE_CHILD_CREATE);
0206
0207 fsnotify_dirent(dir, dentry, FS_CREATE);
0208 }
0209
0210
0211
0212
0213
0214
0215
0216
0217 static inline void fsnotify_link(struct inode *dir, struct inode *inode,
0218 struct dentry *new_dentry)
0219 {
0220 fsnotify_link_count(inode);
0221 audit_inode_child(dir, new_dentry, AUDIT_TYPE_CHILD_CREATE);
0222
0223 fsnotify_name(FS_CREATE, inode, FSNOTIFY_EVENT_INODE,
0224 dir, &new_dentry->d_name, 0);
0225 }
0226
0227
0228
0229
0230
0231
0232
0233
0234
0235 static inline void fsnotify_delete(struct inode *dir, struct inode *inode,
0236 struct dentry *dentry)
0237 {
0238 __u32 mask = FS_DELETE;
0239
0240 if (S_ISDIR(inode->i_mode))
0241 mask |= FS_ISDIR;
0242
0243 fsnotify_name(mask, inode, FSNOTIFY_EVENT_INODE, dir, &dentry->d_name,
0244 0);
0245 }
0246
0247
0248
0249
0250
0251
0252
0253
0254 static inline void d_delete_notify(struct inode *dir, struct dentry *dentry)
0255 {
0256 struct inode *inode = d_inode(dentry);
0257
0258 ihold(inode);
0259 d_delete(dentry);
0260 fsnotify_delete(dir, inode, dentry);
0261 iput(inode);
0262 }
0263
0264
0265
0266
0267
0268
0269 static inline void fsnotify_unlink(struct inode *dir, struct dentry *dentry)
0270 {
0271 if (WARN_ON_ONCE(d_is_negative(dentry)))
0272 return;
0273
0274 fsnotify_delete(dir, d_inode(dentry), dentry);
0275 }
0276
0277
0278
0279
0280
0281
0282
0283
0284 static inline void fsnotify_mkdir(struct inode *dir, struct dentry *dentry)
0285 {
0286 audit_inode_child(dir, dentry, AUDIT_TYPE_CHILD_CREATE);
0287
0288 fsnotify_dirent(dir, dentry, FS_CREATE | FS_ISDIR);
0289 }
0290
0291
0292
0293
0294
0295
0296 static inline void fsnotify_rmdir(struct inode *dir, struct dentry *dentry)
0297 {
0298 if (WARN_ON_ONCE(d_is_negative(dentry)))
0299 return;
0300
0301 fsnotify_delete(dir, d_inode(dentry), dentry);
0302 }
0303
0304
0305
0306
0307 static inline void fsnotify_access(struct file *file)
0308 {
0309 fsnotify_file(file, FS_ACCESS);
0310 }
0311
0312
0313
0314
0315 static inline void fsnotify_modify(struct file *file)
0316 {
0317 fsnotify_file(file, FS_MODIFY);
0318 }
0319
0320
0321
0322
0323 static inline void fsnotify_open(struct file *file)
0324 {
0325 __u32 mask = FS_OPEN;
0326
0327 if (file->f_flags & __FMODE_EXEC)
0328 mask |= FS_OPEN_EXEC;
0329
0330 fsnotify_file(file, mask);
0331 }
0332
0333
0334
0335
0336 static inline void fsnotify_close(struct file *file)
0337 {
0338 __u32 mask = (file->f_mode & FMODE_WRITE) ? FS_CLOSE_WRITE :
0339 FS_CLOSE_NOWRITE;
0340
0341 fsnotify_file(file, mask);
0342 }
0343
0344
0345
0346
0347 static inline void fsnotify_xattr(struct dentry *dentry)
0348 {
0349 fsnotify_dentry(dentry, FS_ATTRIB);
0350 }
0351
0352
0353
0354
0355
0356 static inline void fsnotify_change(struct dentry *dentry, unsigned int ia_valid)
0357 {
0358 __u32 mask = 0;
0359
0360 if (ia_valid & ATTR_UID)
0361 mask |= FS_ATTRIB;
0362 if (ia_valid & ATTR_GID)
0363 mask |= FS_ATTRIB;
0364 if (ia_valid & ATTR_SIZE)
0365 mask |= FS_MODIFY;
0366
0367
0368 if ((ia_valid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME))
0369 mask |= FS_ATTRIB;
0370 else if (ia_valid & ATTR_ATIME)
0371 mask |= FS_ACCESS;
0372 else if (ia_valid & ATTR_MTIME)
0373 mask |= FS_MODIFY;
0374
0375 if (ia_valid & ATTR_MODE)
0376 mask |= FS_ATTRIB;
0377
0378 if (mask)
0379 fsnotify_dentry(dentry, mask);
0380 }
0381
0382 static inline int fsnotify_sb_error(struct super_block *sb, struct inode *inode,
0383 int error)
0384 {
0385 struct fs_error_report report = {
0386 .error = error,
0387 .inode = inode,
0388 .sb = sb,
0389 };
0390
0391 return fsnotify(FS_ERROR, &report, FSNOTIFY_EVENT_ERROR,
0392 NULL, NULL, NULL, 0);
0393 }
0394
0395 #endif