root/include/linux/fsnotify.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. fsnotify_dirent
  2. fsnotify_parent
  3. fsnotify_path
  4. fsnotify_perm
  5. fsnotify_link_count
  6. fsnotify_move
  7. fsnotify_inode_delete
  8. fsnotify_vfsmount_delete
  9. fsnotify_inoderemove
  10. fsnotify_create
  11. fsnotify_link
  12. fsnotify_unlink
  13. fsnotify_mkdir
  14. fsnotify_rmdir
  15. fsnotify_access
  16. fsnotify_modify
  17. fsnotify_open
  18. fsnotify_close
  19. fsnotify_xattr
  20. fsnotify_change

   1 /* SPDX-License-Identifier: GPL-2.0 */
   2 #ifndef _LINUX_FS_NOTIFY_H
   3 #define _LINUX_FS_NOTIFY_H
   4 
   5 /*
   6  * include/linux/fsnotify.h - generic hooks for filesystem notification, to
   7  * reduce in-source duplication from both dnotify and inotify.
   8  *
   9  * We don't compile any of this away in some complicated menagerie of ifdefs.
  10  * Instead, we rely on the code inside to optimize away as needed.
  11  *
  12  * (C) Copyright 2005 Robert Love
  13  */
  14 
  15 #include <linux/fsnotify_backend.h>
  16 #include <linux/audit.h>
  17 #include <linux/slab.h>
  18 #include <linux/bug.h>
  19 
  20 /*
  21  * Notify this @dir inode about a change in the directory entry @dentry.
  22  *
  23  * Unlike fsnotify_parent(), the event will be reported regardless of the
  24  * FS_EVENT_ON_CHILD mask on the parent inode.
  25  */
  26 static inline int fsnotify_dirent(struct inode *dir, struct dentry *dentry,
  27                                   __u32 mask)
  28 {
  29         return fsnotify(dir, mask, d_inode(dentry), FSNOTIFY_EVENT_INODE,
  30                         &dentry->d_name, 0);
  31 }
  32 
  33 /* Notify this dentry's parent about a child's events. */
  34 static inline int fsnotify_parent(const struct path *path,
  35                                   struct dentry *dentry, __u32 mask)
  36 {
  37         if (!dentry)
  38                 dentry = path->dentry;
  39 
  40         return __fsnotify_parent(path, dentry, mask);
  41 }
  42 
  43 /*
  44  * Simple wrapper to consolidate calls fsnotify_parent()/fsnotify() when
  45  * an event is on a path.
  46  */
  47 static inline int fsnotify_path(struct inode *inode, const struct path *path,
  48                                 __u32 mask)
  49 {
  50         int ret = fsnotify_parent(path, NULL, mask);
  51 
  52         if (ret)
  53                 return ret;
  54         return fsnotify(inode, mask, path, FSNOTIFY_EVENT_PATH, NULL, 0);
  55 }
  56 
  57 /* Simple call site for access decisions */
  58 static inline int fsnotify_perm(struct file *file, int mask)
  59 {
  60         int ret;
  61         const struct path *path = &file->f_path;
  62         struct inode *inode = file_inode(file);
  63         __u32 fsnotify_mask = 0;
  64 
  65         if (file->f_mode & FMODE_NONOTIFY)
  66                 return 0;
  67         if (!(mask & (MAY_READ | MAY_OPEN)))
  68                 return 0;
  69         if (mask & MAY_OPEN) {
  70                 fsnotify_mask = FS_OPEN_PERM;
  71 
  72                 if (file->f_flags & __FMODE_EXEC) {
  73                         ret = fsnotify_path(inode, path, FS_OPEN_EXEC_PERM);
  74 
  75                         if (ret)
  76                                 return ret;
  77                 }
  78         } else if (mask & MAY_READ) {
  79                 fsnotify_mask = FS_ACCESS_PERM;
  80         }
  81 
  82         if (S_ISDIR(inode->i_mode))
  83                 fsnotify_mask |= FS_ISDIR;
  84 
  85         return fsnotify_path(inode, path, fsnotify_mask);
  86 }
  87 
  88 /*
  89  * fsnotify_link_count - inode's link count changed
  90  */
  91 static inline void fsnotify_link_count(struct inode *inode)
  92 {
  93         __u32 mask = FS_ATTRIB;
  94 
  95         if (S_ISDIR(inode->i_mode))
  96                 mask |= FS_ISDIR;
  97 
  98         fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
  99 }
 100 
 101 /*
 102  * fsnotify_move - file old_name at old_dir was moved to new_name at new_dir
 103  */
 104 static inline void fsnotify_move(struct inode *old_dir, struct inode *new_dir,
 105                                  const struct qstr *old_name,
 106                                  int isdir, struct inode *target,
 107                                  struct dentry *moved)
 108 {
 109         struct inode *source = moved->d_inode;
 110         u32 fs_cookie = fsnotify_get_cookie();
 111         __u32 old_dir_mask = FS_MOVED_FROM;
 112         __u32 new_dir_mask = FS_MOVED_TO;
 113         __u32 mask = FS_MOVE_SELF;
 114         const struct qstr *new_name = &moved->d_name;
 115 
 116         if (old_dir == new_dir)
 117                 old_dir_mask |= FS_DN_RENAME;
 118 
 119         if (isdir) {
 120                 old_dir_mask |= FS_ISDIR;
 121                 new_dir_mask |= FS_ISDIR;
 122                 mask |= FS_ISDIR;
 123         }
 124 
 125         fsnotify(old_dir, old_dir_mask, source, FSNOTIFY_EVENT_INODE, old_name,
 126                  fs_cookie);
 127         fsnotify(new_dir, new_dir_mask, source, FSNOTIFY_EVENT_INODE, new_name,
 128                  fs_cookie);
 129 
 130         if (target)
 131                 fsnotify_link_count(target);
 132 
 133         if (source)
 134                 fsnotify(source, mask, source, FSNOTIFY_EVENT_INODE, NULL, 0);
 135         audit_inode_child(new_dir, moved, AUDIT_TYPE_CHILD_CREATE);
 136 }
 137 
 138 /*
 139  * fsnotify_inode_delete - and inode is being evicted from cache, clean up is needed
 140  */
 141 static inline void fsnotify_inode_delete(struct inode *inode)
 142 {
 143         __fsnotify_inode_delete(inode);
 144 }
 145 
 146 /*
 147  * fsnotify_vfsmount_delete - a vfsmount is being destroyed, clean up is needed
 148  */
 149 static inline void fsnotify_vfsmount_delete(struct vfsmount *mnt)
 150 {
 151         __fsnotify_vfsmount_delete(mnt);
 152 }
 153 
 154 /*
 155  * fsnotify_inoderemove - an inode is going away
 156  */
 157 static inline void fsnotify_inoderemove(struct inode *inode)
 158 {
 159         __u32 mask = FS_DELETE_SELF;
 160 
 161         if (S_ISDIR(inode->i_mode))
 162                 mask |= FS_ISDIR;
 163 
 164         fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
 165         __fsnotify_inode_delete(inode);
 166 }
 167 
 168 /*
 169  * fsnotify_create - 'name' was linked in
 170  */
 171 static inline void fsnotify_create(struct inode *inode, struct dentry *dentry)
 172 {
 173         audit_inode_child(inode, dentry, AUDIT_TYPE_CHILD_CREATE);
 174 
 175         fsnotify_dirent(inode, dentry, FS_CREATE);
 176 }
 177 
 178 /*
 179  * fsnotify_link - new hardlink in 'inode' directory
 180  * Note: We have to pass also the linked inode ptr as some filesystems leave
 181  *   new_dentry->d_inode NULL and instantiate inode pointer later
 182  */
 183 static inline void fsnotify_link(struct inode *dir, struct inode *inode, struct dentry *new_dentry)
 184 {
 185         fsnotify_link_count(inode);
 186         audit_inode_child(dir, new_dentry, AUDIT_TYPE_CHILD_CREATE);
 187 
 188         fsnotify(dir, FS_CREATE, inode, FSNOTIFY_EVENT_INODE, &new_dentry->d_name, 0);
 189 }
 190 
 191 /*
 192  * fsnotify_unlink - 'name' was unlinked
 193  *
 194  * Caller must make sure that dentry->d_name is stable.
 195  */
 196 static inline void fsnotify_unlink(struct inode *dir, struct dentry *dentry)
 197 {
 198         /* Expected to be called before d_delete() */
 199         WARN_ON_ONCE(d_is_negative(dentry));
 200 
 201         fsnotify_dirent(dir, dentry, FS_DELETE);
 202 }
 203 
 204 /*
 205  * fsnotify_mkdir - directory 'name' was created
 206  */
 207 static inline void fsnotify_mkdir(struct inode *inode, struct dentry *dentry)
 208 {
 209         audit_inode_child(inode, dentry, AUDIT_TYPE_CHILD_CREATE);
 210 
 211         fsnotify_dirent(inode, dentry, FS_CREATE | FS_ISDIR);
 212 }
 213 
 214 /*
 215  * fsnotify_rmdir - directory 'name' was removed
 216  *
 217  * Caller must make sure that dentry->d_name is stable.
 218  */
 219 static inline void fsnotify_rmdir(struct inode *dir, struct dentry *dentry)
 220 {
 221         /* Expected to be called before d_delete() */
 222         WARN_ON_ONCE(d_is_negative(dentry));
 223 
 224         fsnotify_dirent(dir, dentry, FS_DELETE | FS_ISDIR);
 225 }
 226 
 227 /*
 228  * fsnotify_access - file was read
 229  */
 230 static inline void fsnotify_access(struct file *file)
 231 {
 232         const struct path *path = &file->f_path;
 233         struct inode *inode = file_inode(file);
 234         __u32 mask = FS_ACCESS;
 235 
 236         if (S_ISDIR(inode->i_mode))
 237                 mask |= FS_ISDIR;
 238 
 239         if (!(file->f_mode & FMODE_NONOTIFY))
 240                 fsnotify_path(inode, path, mask);
 241 }
 242 
 243 /*
 244  * fsnotify_modify - file was modified
 245  */
 246 static inline void fsnotify_modify(struct file *file)
 247 {
 248         const struct path *path = &file->f_path;
 249         struct inode *inode = file_inode(file);
 250         __u32 mask = FS_MODIFY;
 251 
 252         if (S_ISDIR(inode->i_mode))
 253                 mask |= FS_ISDIR;
 254 
 255         if (!(file->f_mode & FMODE_NONOTIFY))
 256                 fsnotify_path(inode, path, mask);
 257 }
 258 
 259 /*
 260  * fsnotify_open - file was opened
 261  */
 262 static inline void fsnotify_open(struct file *file)
 263 {
 264         const struct path *path = &file->f_path;
 265         struct inode *inode = file_inode(file);
 266         __u32 mask = FS_OPEN;
 267 
 268         if (S_ISDIR(inode->i_mode))
 269                 mask |= FS_ISDIR;
 270         if (file->f_flags & __FMODE_EXEC)
 271                 mask |= FS_OPEN_EXEC;
 272 
 273         fsnotify_path(inode, path, mask);
 274 }
 275 
 276 /*
 277  * fsnotify_close - file was closed
 278  */
 279 static inline void fsnotify_close(struct file *file)
 280 {
 281         const struct path *path = &file->f_path;
 282         struct inode *inode = file_inode(file);
 283         fmode_t mode = file->f_mode;
 284         __u32 mask = (mode & FMODE_WRITE) ? FS_CLOSE_WRITE : FS_CLOSE_NOWRITE;
 285 
 286         if (S_ISDIR(inode->i_mode))
 287                 mask |= FS_ISDIR;
 288 
 289         if (!(file->f_mode & FMODE_NONOTIFY))
 290                 fsnotify_path(inode, path, mask);
 291 }
 292 
 293 /*
 294  * fsnotify_xattr - extended attributes were changed
 295  */
 296 static inline void fsnotify_xattr(struct dentry *dentry)
 297 {
 298         struct inode *inode = dentry->d_inode;
 299         __u32 mask = FS_ATTRIB;
 300 
 301         if (S_ISDIR(inode->i_mode))
 302                 mask |= FS_ISDIR;
 303 
 304         fsnotify_parent(NULL, dentry, mask);
 305         fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
 306 }
 307 
 308 /*
 309  * fsnotify_change - notify_change event.  file was modified and/or metadata
 310  * was changed.
 311  */
 312 static inline void fsnotify_change(struct dentry *dentry, unsigned int ia_valid)
 313 {
 314         struct inode *inode = dentry->d_inode;
 315         __u32 mask = 0;
 316 
 317         if (ia_valid & ATTR_UID)
 318                 mask |= FS_ATTRIB;
 319         if (ia_valid & ATTR_GID)
 320                 mask |= FS_ATTRIB;
 321         if (ia_valid & ATTR_SIZE)
 322                 mask |= FS_MODIFY;
 323 
 324         /* both times implies a utime(s) call */
 325         if ((ia_valid & (ATTR_ATIME | ATTR_MTIME)) == (ATTR_ATIME | ATTR_MTIME))
 326                 mask |= FS_ATTRIB;
 327         else if (ia_valid & ATTR_ATIME)
 328                 mask |= FS_ACCESS;
 329         else if (ia_valid & ATTR_MTIME)
 330                 mask |= FS_MODIFY;
 331 
 332         if (ia_valid & ATTR_MODE)
 333                 mask |= FS_ATTRIB;
 334 
 335         if (mask) {
 336                 if (S_ISDIR(inode->i_mode))
 337                         mask |= FS_ISDIR;
 338 
 339                 fsnotify_parent(NULL, dentry, mask);
 340                 fsnotify(inode, mask, inode, FSNOTIFY_EVENT_INODE, NULL, 0);
 341         }
 342 }
 343 
 344 #endif  /* _LINUX_FS_NOTIFY_H */

/* [<][>][^][v][top][bottom][index][help] */