LCOV - code coverage report
Current view: top level - lkbce/include/linux - fsnotify.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 27 27 100.0 %
Date: 2017-01-25 Functions: 2 2 100.0 %

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

Generated by: LCOV version 1.10