/* Mount namespace events */ #define FSNOTIFY_MNT_EVENTS (FS_MNT_ATTACH | FS_MNT_DETACH)
/* Content events can be used to inspect file content */ #define FSNOTIFY_CONTENT_PERM_EVENTS (FS_OPEN_PERM | FS_OPEN_EXEC_PERM | \
FS_ACCESS_PERM) /* Pre-content events can be used to fill file content */ #define FSNOTIFY_PRE_CONTENT_EVENTS (FS_PRE_ACCESS)
/* Events that can be reported to backends */ #define ALL_FSNOTIFY_EVENTS (ALL_FSNOTIFY_DIRENT_EVENTS | \
FSNOTIFY_MNT_EVENTS | \
FS_EVENTS_POSS_ON_CHILD | \
FS_DELETE_SELF | FS_MOVE_SELF | \
FS_UNMOUNT | FS_Q_OVERFLOW | FS_IN_IGNORED | \
FS_ERROR)
/* Extra flags that may be reported with event or control handling of events */ #define ALL_FSNOTIFY_FLAGS (FS_ISDIR | FS_EVENT_ON_CHILD | FS_DN_MULTISHOT)
/* *Agroupisa"thing"thatwantstoreceivenotificationaboutfilesystem *events.Themaskholdsthesubsetofeventtypesthisgroupcaresabout. *refcntonagroupisuptotheimplementorandatanymomentifitgoes0 *everythingwillbecleanedup.
*/ struct fsnotify_group { conststruct fsnotify_ops *ops; /* how this group handles things */
/* *Howtherefcntisusedisuptoeachgroup.Whentherefcnthits0 *fsnotifywillcleanupalloftheresourcesassociatedwiththisgroup. *Asanexample,thednotifygroupwillalwayshavearefcnt=1andthat *willneverchange.Inotify,ontheotherhand,hasagroupper *inotify_init()andtherefcntwillhit0onlywhenthatfdhasbeen *closed.
*/
refcount_t refcnt; /* things with interest in this group */
/* needed to send notification to userspace */
spinlock_t notification_lock; /* protect the notification_list */ struct list_head notification_list; /* list of event_holder this group needs to send to userspace */
wait_queue_head_t notification_waitq; /* read() on the notification file blocks on this waitq */ unsignedint q_len; /* events on the queue */ unsignedint max_events; /* maximum events allowed on the list */ enum fsnotify_group_prio priority; /* priority for sending events */ bool shutdown; /* group is being shut down, don't queue more events */
#define FSNOTIFY_GROUP_USER 0x01 /* user allocated group */ #define FSNOTIFY_GROUP_DUPS 0x02 /* allow multiple marks per object */ int flags; unsignedint owner_flags; /* stored flags of mark_mutex owner */
/* stores all fastpath marks assoc with this group so they can be cleaned on unregister */ struct mutex mark_mutex; /* protect marks_list */
atomic_t user_waits; /* Number of tasks waiting for user
* response */ struct list_head marks_list; /* all inode marks for this group */
/* When calling fsnotify tell it if the data is a path or inode */ enum fsnotify_data_type {
FSNOTIFY_EVENT_NONE,
FSNOTIFY_EVENT_FILE_RANGE,
FSNOTIFY_EVENT_PATH,
FSNOTIFY_EVENT_INODE,
FSNOTIFY_EVENT_DENTRY,
FSNOTIFY_EVENT_MNT,
FSNOTIFY_EVENT_ERROR,
};
/* The type of object that a mark is attached to */ enum fsnotify_obj_type {
FSNOTIFY_OBJ_TYPE_ANY = -1,
FSNOTIFY_OBJ_TYPE_INODE,
FSNOTIFY_OBJ_TYPE_VFSMOUNT,
FSNOTIFY_OBJ_TYPE_SB,
FSNOTIFY_OBJ_TYPE_MNTNS,
FSNOTIFY_OBJ_TYPE_COUNT,
FSNOTIFY_OBJ_TYPE_DETACHED = FSNOTIFY_OBJ_TYPE_COUNT
};
/* *Amarkissimplyanobjectattachedtoanincoreinodewhichallowsan *fsnotifylistenertoindicatetheyareeithernolongerinterestedinevents *ofatypematchingmaskoronlyinterestedinthoseevents. * *Theseareflushedwhenaninodeisevictedfromcoreandmaybeflushed *whentheinodeismodified(asseenbyfsnotify_access).Somefsnotify *users(suchasdnotify)willflushthesewhentheopenfdisclosedandnot *atinodeevictionormodification. * *Textinbracketsisshowingthelock(s)protectingmodificationsofa *particularentry.obj_lockmeanseitherinode->i_lockor *mnt->mnt_root->d_lockdependingonthemarktype.
*/ struct fsnotify_mark { /* Mask this mark is for [mark->lock, group->mark_mutex] */
__u32 mask; /* We hold one for presence in g_list. Also one ref for each 'thing'
* in kernel that found and may be using this mark. */
refcount_t refcnt; /* Group this mark is for. Set on mark creation, stable until last ref
* is dropped */ struct fsnotify_group *group; /* List of marks by group->marks_list. Also reused for queueing *markintodestroy_listwhenit'swaitingfortheendofSRCUperiod
* before it can be freed. [group->mark_mutex] */ struct list_head g_list; /* Protects inode / mnt pointers, flags, masks */
spinlock_t lock; /* List of marks for inode / vfsmount [connector->lock, mark ref] */ struct hlist_node obj_list; /* Head of list of marks for an object [mark ref] */ struct fsnotify_mark_connector *connector; /* Events types and flags to ignore [mark->lock, group->mark_mutex] */
__u32 ignore_mask; /* General fsnotify mark flags */ #define FSNOTIFY_MARK_FLAG_ALIVE 0x0001 #define FSNOTIFY_MARK_FLAG_ATTACHED 0x0002 /* inotify mark flags */ #define FSNOTIFY_MARK_FLAG_EXCL_UNLINK 0x0010 #define FSNOTIFY_MARK_FLAG_IN_ONESHOT 0x0020 /* fanotify mark flags */ #define FSNOTIFY_MARK_FLAG_IGNORED_SURV_MODIFY 0x0100 #define FSNOTIFY_MARK_FLAG_NO_IREF 0x0200 #define FSNOTIFY_MARK_FLAG_HAS_IGNORE_FLAGS 0x0400 #define FSNOTIFY_MARK_FLAG_HAS_FSID 0x0800 #define FSNOTIFY_MARK_FLAG_WEAK_FSID 0x1000 unsignedint flags; /* flags [mark->lock] */
};
staticinline __u32 fsnotify_parent_needed_mask(__u32 mask)
{ /* FS_EVENT_ON_CHILD is set on marks that want parent/name info */ if (!(mask & FS_EVENT_ON_CHILD)) return0; /* *Thisobjectmightbewatchedbyamarkthatcaresaboutparent/name *info,doesitcareaboutthespecificsetofeventsthatcanbe *reportedwithparent/nameinfo?
*/ return mask & FS_EVENTS_POSS_TO_PARENT;
}
/* FS_EVENT_ON_CHILD is set if the inode may care */ if (!(parent_mask & FS_EVENT_ON_CHILD)) return0; /* this inode might care about child events, does it care about the
* specific set of events that can happen on a child? */ return parent_mask & FS_EVENTS_POSS_ON_CHILD;
}
/* called from fsnotify listeners, such as fanotify or dnotify */
/* create a new group */ externstruct fsnotify_group *fsnotify_alloc_group( conststruct fsnotify_ops *ops, int flags); /* get reference to a group */ externvoid fsnotify_get_group(struct fsnotify_group *group); /* drop reference on a group from fsnotify_alloc_group */ externvoid fsnotify_put_group(struct fsnotify_group *group); /* group destruction begins, stop queuing new events */ externvoid fsnotify_group_stop_queueing(struct fsnotify_group *group); /* destroy group */ externvoid fsnotify_destroy_group(struct fsnotify_group *group); /* fasync handler function */ externint fsnotify_fasync(int fd, struct file *file, int on); /* Free event from memory */ externvoid fsnotify_destroy_event(struct fsnotify_group *group, struct fsnotify_event *event); /* attach the event to the group notification queue */ externint fsnotify_insert_event(struct fsnotify_group *group, struct fsnotify_event *event, int (*merge)(struct fsnotify_group *, struct fsnotify_event *), void (*insert)(struct fsnotify_group *, struct fsnotify_event *));
externbool fsnotify_notify_queue_is_empty(struct fsnotify_group *group); /* return, but do not dequeue the first event on the notification queue */ externstruct fsnotify_event *fsnotify_peek_first_event(struct fsnotify_group *group); /* return AND dequeue the first event on the notification queue */ externstruct fsnotify_event *fsnotify_remove_first_event(struct fsnotify_group *group); /* Remove event queued in the notification list */ externvoid fsnotify_remove_queued_event(struct fsnotify_group *group, struct fsnotify_event *event);
/* functions used to manipulate the marks attached to inodes */
/* *Checkifmask(orignoremask)shouldbeapplieddependingifvictimisa *directoryandwhetheritisreportedtoawatchingparent.
*/ staticinlinebool fsnotify_mask_applicable(__u32 mask, bool is_dir, int iter_type)
{ /* Should mask be applied to a directory? */ if (is_dir && !(mask & FS_ISDIR)) returnfalse;
/* Should mask be applied to a child? */ if (iter_type == FSNOTIFY_ITER_TYPE_PARENT &&
!(mask & FS_EVENT_ON_CHILD)) returnfalse;
/* Get mask of events for a list of marks */ extern __u32 fsnotify_conn_mask(struct fsnotify_mark_connector *conn); /* Calculate mask of events for a list of marks */ externvoid fsnotify_recalc_mask(struct fsnotify_mark_connector *conn); externvoid fsnotify_init_mark(struct fsnotify_mark *mark, struct fsnotify_group *group); /* Find mark belonging to given group in the list of marks */ struct fsnotify_mark *fsnotify_find_mark(void *obj, unsignedint obj_type, struct fsnotify_group *group); /* attach the mark to the object */ int fsnotify_add_mark(struct fsnotify_mark *mark, void *obj, unsignedint obj_type, int add_flags); int fsnotify_add_mark_locked(struct fsnotify_mark *mark, void *obj, unsignedint obj_type, int add_flags);
/* attach the mark to the inode */ staticinlineint fsnotify_add_inode_mark(struct fsnotify_mark *mark, struct inode *inode, int add_flags)
{ return fsnotify_add_mark(mark, inode, FSNOTIFY_OBJ_TYPE_INODE,
add_flags);
} staticinlineint fsnotify_add_inode_mark_locked(struct fsnotify_mark *mark, struct inode *inode, int add_flags)
{ return fsnotify_add_mark_locked(mark, inode, FSNOTIFY_OBJ_TYPE_INODE,
add_flags);
}
/* given a group and a mark, flag mark to be freed when all references are dropped */ externvoid fsnotify_destroy_mark(struct fsnotify_mark *mark, struct fsnotify_group *group); /* detach mark from inode / mount list, group list, drop inode reference */ externvoid fsnotify_detach_mark(struct fsnotify_mark *mark); /* free mark */ externvoid fsnotify_free_mark(struct fsnotify_mark *mark); /* Wait until all marks queued for destruction are destroyed */ externvoid fsnotify_wait_marks_destroyed(void); /* Clear all of the marks of a group attached to a given object type */ externvoid fsnotify_clear_marks_by_group(struct fsnotify_group *group, unsignedint obj_type); externvoid fsnotify_get_mark(struct fsnotify_mark *mark); externvoid fsnotify_put_mark(struct fsnotify_mark *mark); externvoid fsnotify_finish_user_wait(struct fsnotify_iter_info *iter_info); externbool fsnotify_prepare_user_wait(struct fsnotify_iter_info *iter_info);
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 und die Messung sind noch experimentell.