コード例 #1
0
static int inotify_handle_event(struct fsnotify_group *group, struct fsnotify_event *event)
{
	struct fsnotify_mark_entry *entry;
	struct inotify_inode_mark_entry *ientry;
	struct inode *to_tell;
	struct inotify_event_private_data *event_priv;
	struct fsnotify_event_private_data *fsn_event_priv;
	int wd, ret;

	to_tell = event->to_tell;

	spin_lock(&to_tell->i_lock);
	entry = fsnotify_find_mark_entry(group, to_tell);
	spin_unlock(&to_tell->i_lock);
	/* race with watch removal?  We already passes should_send */
	if (unlikely(!entry))
		return 0;
	ientry = container_of(entry, struct inotify_inode_mark_entry,
			      fsn_entry);
	wd = ientry->wd;

	event_priv = kmem_cache_alloc(event_priv_cachep, GFP_KERNEL);
	if (unlikely(!event_priv))
		return -ENOMEM;

	fsn_event_priv = &event_priv->fsnotify_event_priv_data;

	fsn_event_priv->group = group;
	event_priv->wd = wd;

	ret = fsnotify_add_notify_event(group, event, fsn_event_priv);
	if (ret) {
		inotify_free_event_priv(fsn_event_priv);
		/* EEXIST says we tail matched, EOVERFLOW isn't something
		 * to report up the stack. */
		if ((ret == -EEXIST) ||
		    (ret == -EOVERFLOW))
			ret = 0;
	}
	
	if (entry->mask & IN_ONESHOT)
                fsnotify_destroy_mark_by_entry(entry);

	/*
	 * If we hold the entry until after the event is on the queue
	 * IN_IGNORED won't be able to pass this event in the queue
	 */
	fsnotify_put_mark(entry);

	return ret;
}
コード例 #2
0
static bool inotify_should_send_event(struct fsnotify_group *group, struct inode *inode, __u32 mask)
{
	struct fsnotify_mark_entry *entry;
	bool send;

	spin_lock(&inode->i_lock);
	entry = fsnotify_find_mark_entry(group, inode);
	spin_unlock(&inode->i_lock);
	if (!entry)
		return false;

	mask = (mask & ~FS_EVENT_ON_CHILD);
	send = (entry->mask & mask);

	/* find took a reference */
	fsnotify_put_mark(entry);

	return send;
}