示例#1
0
文件: vfsub.c 项目: wosigh/patches
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;
}
示例#2
0
static struct dentry *lkup_hash(const char *name, struct dentry *parent,
				int len, struct lkup_args *lkup)
{
	struct dentry *dentry;
	char *p;
	unsigned long hash;
	struct qstr this;
	unsigned int c;
	struct nameidata tmp_nd;

	dentry = ERR_PTR(-EACCES);
	this.name = name;
	this.len = len;
	if (unlikely(!len))
		goto out;

	p = (void*)name;
	hash = init_name_hash();
	while (len--) {
		c = *p++;
		if (unlikely(c == '/' || c == '\0'))
			goto out;
		hash = partial_name_hash(c, hash);
	}
	this.hash = end_name_hash(hash);

	memset(&tmp_nd, 0, sizeof(tmp_nd));
	tmp_nd.dentry = dget(parent);
	tmp_nd.mnt = mntget(lkup->nfsmnt);
#ifndef CONFIG_AUFS_DLGT
	dentry = __lookup_hash(&this, parent, &tmp_nd);
#else
	if (!lkup->dlgt)
		dentry = __lookup_hash(&this, parent, &tmp_nd);
	else {
		int wkq_err;
		struct lookup_hash_args args = {
			.errp	= &dentry,
			.name	= &this,
			.base	= parent,
			.nd	= &tmp_nd
		};
		wkq_err = au_wkq_wait(call_lookup_hash, &args, /*dlgt*/1);
		if (unlikely(wkq_err))
			dentry = ERR_PTR(wkq_err);
	}
#endif
	path_release(&tmp_nd);

 out:
	TraceErrPtr(dentry);
	return dentry;
}
#elif defined(CONFIG_AUFS_DLGT)
static struct dentry *lkup_hash(const char *name, struct dentry *parent,
				int len, struct lkup_args *lkup)
{
	return ERR_PTR(-ENOSYS);
}
#endif

#ifdef CONFIG_AUFS_DLGT
struct lookup_one_len_args {
	struct dentry **errp;
	const char *name;
	struct dentry *parent;
	int len;
};

static void call_lookup_one_len(void *args)
{
	struct lookup_one_len_args *a = args;
	*a->errp = lookup_one_len(a->name, a->parent, a->len);
}
#endif /* CONFIG_AUFS_DLGT */

#if defined(CONFIG_AUFS_LHASH_PATCH) || defined(CONFIG_AUFS_DLGT)
/* cf. lookup_one_len() in linux/fs/namei.c */
struct dentry *lkup_one(const char *name, struct dentry *parent, int len,
			struct lkup_args *lkup)
{
	struct dentry *dentry;

	LKTRTrace("%.*s/%.*s, lkup{%p, %d}\n",
		  DLNPair(parent), len, name, lkup->nfsmnt, lkup->dlgt);

	if (!lkup->nfsmnt) {
#ifndef CONFIG_AUFS_DLGT
		dentry = lookup_one_len(name, parent, len);
#else
		if (!lkup->dlgt)
			dentry = lookup_one_len(name, parent, len);
		else {
			int wkq_err;
			struct lookup_one_len_args args = {
				.errp	= &dentry,
				.name	= name,
				.parent	= parent,
				.len	= len
			};
			wkq_err = au_wkq_wait(call_lookup_one_len, &args,
					      /*dlgt*/1);
			if (unlikely(wkq_err))
				dentry = ERR_PTR(wkq_err);
		}
#endif
	} else
示例#3
0
static void call_lookup_hash(void *args)
{
	struct lookup_hash_args *a = args;
	*a->errp = __lookup_hash(a->name, a->base, a->nd);
}