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