/* * include/linux/fsnotify.h - generic hooks for filesystem notification, to * reduce in-source duplication from both dnotify and inotify. * * We don't compile any of this away in some complicated menagerie of ifdefs. * Instead, we rely on the code inside to optimize away as needed. * * (C) Copyright 2005 Robert Love
*/
/* Are there any inode/mount/sb objects watched with priority prio or above? */ staticinlinebool fsnotify_sb_has_priority_watchers(struct super_block *sb, int prio)
{ struct fsnotify_sb_info *sbinfo = fsnotify_sb_info(sb);
/* Were any marks ever added to any object on this sb? */ if (!sbinfo) returnfalse;
/* Are there any inode/mount/sb objects that are being watched at all? */ staticinlinebool fsnotify_sb_has_watchers(struct super_block *sb)
{ return fsnotify_sb_has_priority_watchers(sb, 0);
}
/* * Notify this @dir inode about a change in a child directory entry. * The directory entry may have turned positive or negative or its inode may * have changed (i.e. renamed over). * * Unlike fsnotify_parent(), the event will be reported regardless of the * FS_EVENT_ON_CHILD mask on the parent inode and will not be reported if only * the child is interested and not the parent.
*/ staticinlineint fsnotify_name(__u32 mask, constvoid *data, int data_type, struct inode *dir, conststruct qstr *name,
u32 cookie)
{ if (!fsnotify_sb_has_watchers(dir->i_sb)) return 0;
/* * Simple wrappers to consolidate calls to fsnotify_parent() when an event * is on a file/dentry.
*/ staticinlinevoid fsnotify_dentry(struct dentry *dentry, __u32 mask)
{
fsnotify_parent(dentry, mask, dentry, FSNOTIFY_EVENT_DENTRY);
}
staticinlineint fsnotify_file(struct file *file, __u32 mask)
{ /* * FMODE_NONOTIFY are fds generated by fanotify itself which should not * generate new events. We also don't want to generate events for * FMODE_PATH fds (involves open & close events) as they are just * handle creation / destruction events and not "real" file events.
*/ if (FMODE_FSNOTIFY_NONE(file->f_mode)) return 0;
return fsnotify_path(&file->f_path, mask);
}
#ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS
int fsnotify_open_perm_and_set_mode(struct file *file);
/* * fsnotify_file_area_perm - permission hook before access to file range
*/ staticinlineint fsnotify_file_area_perm(struct file *file, int perm_mask, const loff_t *ppos, size_t count)
{ /* * filesystem may be modified in the context of permission events * (e.g. by HSM filling a file on access), so sb freeze protection * must not be held.
*/
lockdep_assert_once(file_write_not_started(file));
if (!(perm_mask & (MAY_READ | MAY_WRITE | MAY_ACCESS))) return 0;
/* * read()/write() and other types of access generate pre-content events.
*/ if (unlikely(FMODE_FSNOTIFY_HSM(file->f_mode))) { int ret = fsnotify_pre_content(&file->f_path, ppos, count);
if (ret) return ret;
}
if (!(perm_mask & MAY_READ) ||
likely(!FMODE_FSNOTIFY_ACCESS_PERM(file->f_mode))) return 0;
/* * read() also generates the legacy FS_ACCESS_PERM event, so content * scanners can inspect the content filled by pre-content event.
*/ return fsnotify_path(&file->f_path, FS_ACCESS_PERM);
}
/* * fsnotify_mmap_perm - permission hook before mmap of file range
*/ staticinlineint fsnotify_mmap_perm(struct file *file, int prot, const loff_t off, size_t len)
{ /* * mmap() generates only pre-content events.
*/ if (!file || likely(!FMODE_FSNOTIFY_HSM(file->f_mode))) return 0;
if (target)
fsnotify_link_count(target);
fsnotify_inode(source, FS_MOVE_SELF);
audit_inode_child(new_dir, moved, AUDIT_TYPE_CHILD_CREATE);
}
/* * fsnotify_inode_delete - and inode is being evicted from cache, clean up is needed
*/ staticinlinevoid fsnotify_inode_delete(struct inode *inode)
{
__fsnotify_inode_delete(inode);
}
/* * fsnotify_vfsmount_delete - a vfsmount is being destroyed, clean up is needed
*/ staticinlinevoid fsnotify_vfsmount_delete(struct vfsmount *mnt)
{
__fsnotify_vfsmount_delete(mnt);
}
/* * fsnotify_inoderemove - an inode is going away
*/ staticinlinevoid fsnotify_inoderemove(struct inode *inode)
{
fsnotify_inode(inode, FS_DELETE_SELF);
__fsnotify_inode_delete(inode);
}
/* * fsnotify_create - 'name' was linked in * * Caller must make sure that dentry->d_name is stable. * Note: some filesystems (e.g. kernfs) leave @dentry negative and instantiate * ->d_inode later
*/ staticinlinevoid fsnotify_create(struct inode *dir, struct dentry *dentry)
{
audit_inode_child(dir, dentry, AUDIT_TYPE_CHILD_CREATE);
fsnotify_dirent(dir, dentry, FS_CREATE);
}
/* * fsnotify_link - new hardlink in 'inode' directory * * Caller must make sure that new_dentry->d_name is stable. * Note: We have to pass also the linked inode ptr as some filesystems leave * new_dentry->d_inode NULL and instantiate inode pointer later
*/ staticinlinevoid fsnotify_link(struct inode *dir, struct inode *inode, struct dentry *new_dentry)
{
fsnotify_link_count(inode);
audit_inode_child(dir, new_dentry, AUDIT_TYPE_CHILD_CREATE);
/* * fsnotify_delete - @dentry was unlinked and unhashed * * Caller must make sure that dentry->d_name is stable. * * Note: unlike fsnotify_unlink(), we have to pass also the unlinked inode * as this may be called after d_delete() and old_dentry may be negative.
*/ staticinlinevoid fsnotify_delete(struct inode *dir, struct inode *inode, struct dentry *dentry)
{
__u32 mask = FS_DELETE;
/** * d_delete_notify - delete a dentry and call fsnotify_delete() * @dentry: The dentry to delete * * This helper is used to guaranty that the unlinked inode cannot be found * by lookup of this name after fsnotify_delete() event has been delivered.
*/ staticinlinevoid d_delete_notify(struct inode *dir, struct dentry *dentry)
{ struct inode *inode = d_inode(dentry);
/* * fsnotify_unlink - 'name' was unlinked * * Caller must make sure that dentry->d_name is stable.
*/ staticinlinevoid fsnotify_unlink(struct inode *dir, struct dentry *dentry)
{ if (WARN_ON_ONCE(d_is_negative(dentry))) return;
fsnotify_delete(dir, d_inode(dentry), dentry);
}
/* * fsnotify_mkdir - directory 'name' was created * * Caller must make sure that dentry->d_name is stable. * Note: some filesystems (e.g. kernfs) leave @dentry negative and instantiate * ->d_inode later
*/ staticinlinevoid fsnotify_mkdir(struct inode *dir, struct dentry *dentry)
{
audit_inode_child(dir, dentry, AUDIT_TYPE_CHILD_CREATE);
/* * fsnotify_rmdir - directory 'name' was removed * * Caller must make sure that dentry->d_name is stable.
*/ staticinlinevoid fsnotify_rmdir(struct inode *dir, struct dentry *dentry)
{ if (WARN_ON_ONCE(d_is_negative(dentry))) return;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.