Ejemplo n.º 1
0
static int noinline_for_stack
au_opts_parse_mod(struct au_opt_mod *mod, substring_t args[])
{
	int err;
	struct path path;
	char *p;

	err = -EINVAL;
	mod->path = args[0].from;
	p = strchr(mod->path, '=');
	if (unlikely(!p)) {
		pr_err("no permssion %s\n", args[0].from);
		goto out;
	}

	*p++ = 0;
	err = vfsub_kern_path(mod->path, lkup_dirflags, &path);
	if (unlikely(err)) {
		pr_err("lookup failed %s (%d)\n", mod->path, err);
		goto out;
	}

	mod->perm = br_perm_val(p);
	AuDbg("mod path %s, perm 0x%x, %s\n", mod->path, mod->perm, p);
	mod->h_root = dget(path.dentry);
	path_put(&path);

out:
	return err;
}
Ejemplo n.º 2
0
static int opt_add(struct au_opt *opt, char *opt_str, unsigned long sb_flags,
		   aufs_bindex_t bindex)
{
	int err;
	struct au_opt_add *add = &opt->add;
	char *p;

	add->bindex = bindex;
	add->perm = AuBrPerm_RO;
	add->pathname = opt_str;
	p = strchr(opt_str, '=');
	if (p) {
		*p++ = 0;
		if (*p)
			add->perm = br_perm_val(p);
	}

	err = vfsub_kern_path(add->pathname, lkup_dirflags, &add->path);
	if (!err) {
		if (!p) {
			add->perm = AuBrPerm_RO;
			if (au_test_fs_rr(add->path.dentry->d_sb))
				add->perm = AuBrPerm_RR;
			else if (!bindex && !(sb_flags & MS_RDONLY))
				add->perm = AuBrPerm_RW;
		}
		opt->type = Opt_add;
		goto out;
	}
	pr_err("lookup failed %s (%d)\n", add->pathname, err);
	err = -EINVAL;

out:
	return err;
}
Ejemplo n.º 3
0
static int au_opts_parse_del(struct au_opt_del *del, substring_t args[])
{
	int err;

	del->pathname = args[0].from;
	AuDbg("del path %s\n", del->pathname);

	err = vfsub_kern_path(del->pathname, lkup_dirflags, &del->h_path);
	if (unlikely(err))
		pr_err("lookup failed %s (%d)\n", del->pathname, err);

	return err;
}
Ejemplo n.º 4
0
static int noinline_for_stack
au_opts_parse_xino_itrunc_path(struct super_block *sb,
			       struct au_opt_xino_itrunc *xino_itrunc,
			       substring_t args[])
{
	int err;
	aufs_bindex_t bend, bindex;
	struct path path;
	struct dentry *root;

	err = vfsub_kern_path(args[0].from, lkup_dirflags, &path);
	if (unlikely(err)) {
		pr_err("lookup failed %s (%d)\n", args[0].from, err);
		goto out;
	}

	xino_itrunc->bindex = -1;
	root = sb->s_root;
	aufs_read_lock(root, AuLock_FLUSH);
	bend = au_sbend(sb);
	for (bindex = 0; bindex <= bend; bindex++) {
		if (au_h_dptr(root, bindex) == path.dentry) {
			xino_itrunc->bindex = bindex;
			break;
		}
	}
	aufs_read_unlock(root, !AuLock_IR);
	path_put(&path);

	if (unlikely(xino_itrunc->bindex < 0)) {
		pr_err("no such branch %s\n", args[0].from);
		err = -EINVAL;
	}

out:
	return err;
}
Ejemplo n.º 5
0
static
struct dentry *decode_by_path(struct super_block *sb, aufs_bindex_t bindex,
			      ino_t ino, __u32 *fh, int fh_len,
			      struct au_nfsd_si_lock *nsi_lock)
{
	struct dentry *dentry, *h_parent, *root;
	struct super_block *h_sb;
	char *pathname, *p;
	struct vfsmount *h_mnt;
	struct au_branch *br;
	int err;
	struct path path;

	br = au_sbr(sb, bindex);
	/* au_br_get(br); */
	h_mnt = br->br_mnt;
	h_sb = h_mnt->mnt_sb;
	/* todo: call lower fh_to_dentry()? fh_to_parent()? */
	h_parent = exportfs_decode_fh(h_mnt, (void *)(fh + Fh_tail),
				      fh_len - Fh_tail, fh[Fh_h_type],
				      h_acceptable, /*context*/NULL);
	dentry = h_parent;
	if (unlikely(!h_parent || IS_ERR(h_parent))) {
		AuWarn1("%s decode_fh failed, %ld\n",
			au_sbtype(h_sb), PTR_ERR(h_parent));
		goto out;
	}
	dentry = NULL;
	if (unlikely(au_test_anon(h_parent))) {
		AuWarn1("%s decode_fh returned a disconnected dentry\n",
			au_sbtype(h_sb));
		goto out_h_parent;
	}

	dentry = ERR_PTR(-ENOMEM);
	pathname = (void *)__get_free_page(GFP_NOFS);
	if (unlikely(!pathname))
		goto out_h_parent;

	root = sb->s_root;
	path.mnt = h_mnt;
	di_read_lock_parent(root, !AuLock_IR);
	path.dentry = au_h_dptr(root, bindex);
	di_read_unlock(root, !AuLock_IR);
	p = au_build_path(h_parent, &path, pathname, PAGE_SIZE, sb);
	dentry = (void *)p;
	if (IS_ERR(p))
		goto out_pathname;

	si_read_unlock(sb);
	err = vfsub_kern_path(p, LOOKUP_FOLLOW | LOOKUP_DIRECTORY, &path);
	dentry = ERR_PTR(err);
	if (unlikely(err))
		goto out_relock;

	dentry = ERR_PTR(-ENOENT);
	AuDebugOn(au_test_anon(path.dentry));
	if (unlikely(!path.dentry->d_inode))
		goto out_path;

	if (ino != path.dentry->d_inode->i_ino)
		dentry = au_lkup_by_ino(&path, ino, /*nsi_lock*/NULL);
	else
		dentry = dget(path.dentry);

 out_path:
	path_put(&path);
 out_relock:
	if (unlikely(si_nfsd_read_lock(sb, nsi_lock) < 0))
		if (!IS_ERR(dentry)) {
			dput(dentry);
			dentry = ERR_PTR(-ESTALE);
		}
 out_pathname:
	free_page((unsigned long)pathname);
 out_h_parent:
	dput(h_parent);
 out:
	/* au_br_put(br); */
	AuTraceErrPtr(dentry);
	return dentry;
}