static void aufs_inotify(struct inotify_watch *watch, u32 wd __maybe_unused,
			 u32 mask, u32 cookie __maybe_unused,
			 const char *h_child_name, struct inode *h_child_inode)
{
	struct au_hnotify *hnotify;
	struct qstr h_child_qstr = {
		.name = h_child_name
	};

	/* if IN_UNMOUNT happens, there must be another bug */
	AuDebugOn(mask & IN_UNMOUNT);
	if (mask & (IN_IGNORED | IN_UNMOUNT)) {
		put_inotify_watch(watch);
		return;
	}

#ifdef AuDbgHnotify
	au_debug(1);
	if (1 || !h_child_name || strcmp(h_child_name, AUFS_XINO_FNAME)) {
		AuDbg("i%lu, wd %d, mask 0x%x %s, cookie 0x%x, hcname %s,"
		      " hi%lu\n",
		      watch->inode->i_ino, wd, mask, in_name(mask), cookie,
		      h_child_name ? h_child_name : "",
		      h_child_inode ? h_child_inode->i_ino : 0);
		WARN_ON(1);
	}
	au_debug(0);
#endif

	if (h_child_name)
		h_child_qstr.len = strlen(h_child_name);
	hnotify = container_of(watch, struct au_hnotify, hn_watch);
	au_hnotify(watch->inode, hnotify, mask, &h_child_qstr, h_child_inode);
}
Example #2
0
static int au_hfsn_handle_event(struct fsnotify_group *group,
				struct fsnotify_mark *inode_mark,
				struct fsnotify_mark *vfsmount_mark,
				struct fsnotify_event *event)
{
	int err;
	struct au_hnotify *hnotify;
	struct inode *h_dir, *h_inode;
	__u32 mask;
	struct qstr h_child_qstr = {
		.name	= event->file_name,
		.len	= event->name_len
	};

	AuDebugOn(event->data_type != FSNOTIFY_EVENT_INODE);

	err = 0;
	/* if FS_UNMOUNT happens, there must be another bug */
	mask = event->mask;
	AuDebugOn(mask & FS_UNMOUNT);
	if (mask & (FS_IN_IGNORED | FS_UNMOUNT))
		goto out;

	h_dir = event->to_tell;
	h_inode = event->inode;
#ifdef AuDbgHnotify
	au_debug(1);
	if (1 || h_child_qstr.len != sizeof(AUFS_XINO_FNAME) - 1
	    || strncmp(h_child_qstr.name, AUFS_XINO_FNAME, h_child_qstr.len)) {
		AuDbg("i%lu, mask 0x%x %s, hcname %.*s, hi%lu\n",
		      h_dir->i_ino, mask, au_hfsn_name(mask),
		      AuLNPair(&h_child_qstr), h_inode ? h_inode->i_ino : 0);
		/* WARN_ON(1); */
	}
	au_debug(0);
#endif

	AuDebugOn(!inode_mark);
	hnotify = container_of(inode_mark, struct au_hnotify, hn_mark);
	err = au_hnotify(h_dir, hnotify, mask, &h_child_qstr, h_inode);

out:
	return err;
}

/* isn't it waste to ask every registered 'group'? */
/* copied from linux/fs/notify/inotify/inotify_fsnotiry.c */
/* it should be exported to modules */
static bool au_hfsn_should_send_event(struct fsnotify_group *group,
				      struct inode *h_inode,
				      struct fsnotify_mark *inode_mark,
				      struct fsnotify_mark *vfsmount_mark,
				      __u32 mask, void *data, int data_type)
{
	mask = (mask & ~FS_EVENT_ON_CHILD);
	return inode_mark->mask & mask;
}