Exemplo n.º 1
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;
}
Exemplo n.º 2
0
/*
 * returns a negative dentry whose name is unique and temporary.
 */
struct dentry *au_whtmp_lkup(struct dentry *h_parent, struct au_branch *br,
			     struct qstr *prefix)
{
	struct dentry *dentry;
	int i;
	char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN + 1],
		*name, *p;
	/* strict atomic_t is unnecessary here */
	static unsigned short cnt;
	struct qstr qs;

	BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN);

	name = defname;
	qs.len = sizeof(defname) - DNAME_INLINE_LEN + prefix->len - 1;
	if (unlikely(prefix->len > DNAME_INLINE_LEN)) {
		dentry = ERR_PTR(-ENAMETOOLONG);
		if (unlikely(qs.len > NAME_MAX))
			goto out;
		dentry = ERR_PTR(-ENOMEM);
		name = kmalloc(qs.len + 1, GFP_NOFS);
		if (unlikely(!name))
			goto out;
	}

	/* doubly whiteout-ed */
	memcpy(name, AUFS_WH_PFX AUFS_WH_PFX, AUFS_WH_PFX_LEN * 2);
	p = name + AUFS_WH_PFX_LEN * 2;
	memcpy(p, prefix->name, prefix->len);
	p += prefix->len;
	*p++ = '.';
	AuDebugOn(name + qs.len + 1 - p <= AUFS_WH_TMP_LEN);

	qs.name = name;
	for (i = 0; i < 3; i++) {
		sprintf(p, "%.*x", AUFS_WH_TMP_LEN, cnt++);
		dentry = au_sio_lkup_one(&qs, h_parent, br);
		if (IS_ERR(dentry) || !dentry->d_inode)
			goto out_name;
		dput(dentry);
	}
	/* pr_warn("could not get random name\n"); */
	dentry = ERR_PTR(-EEXIST);
	AuDbg("%.*s\n", AuLNPair(&qs));
	BUG();

out_name:
	if (name != defname)
		kfree(name);
out:
	AuTraceErrPtr(dentry);
	return dentry;
}
Exemplo n.º 3
0
struct dentry *vfsub__lookup_hash(struct qstr *name, struct dentry *parent,
				  struct nameidata *nd)
{
	struct dentry *d;

	LKTRTrace("%.*s/%.*s, nd %d\n",
		  AuDLNPair(parent), AuLNPair(name), !!nd);
	if (nd)
		LKTRTrace("nd{0x%x}\n", nd->flags);
	IMustLock(parent->d_inode);

	d = __lookup_hash(name, parent, nd);
	if (!IS_ERR(d))
		au_update_fuse_h_inode(NULL, d); /*ignore*/
	return d;
}