Пример #1
0
int au_opts_remount(struct super_block *sb, struct au_opts *opts)
{
	int err, rerr;
	unsigned char no_dreval;
	struct inode *dir;
	struct au_opt_xino *opt_xino;
	struct au_opt *opt;
	struct au_sbinfo *sbinfo;

	SiMustWriteLock(sb);

	err = 0;
	dir = d_inode(sb->s_root);
	sbinfo = au_sbi(sb);
	opt_xino = NULL;
	opt = opts->opt;
	while (err >= 0 && opt->type != Opt_tail) {
		err = au_opt_simple(sb, opt, opts);
		if (!err)
			err = au_opt_br(sb, opt, opts);
		if (!err)
			err = au_opt_xino(sb, opt, &opt_xino, opts);
		opt++;
	}
	if (err > 0)
		err = 0;
	AuTraceErr(err);
	/* go on even err */

	no_dreval = !!au_ftest_si(sbinfo, NO_DREVAL);
	rerr = au_opts_verify(sb, opts->sb_flags, /*pending*/0);
	if (unlikely(rerr && !err))
		err = rerr;

	if (no_dreval != !!au_ftest_si(sbinfo, NO_DREVAL))
		au_fset_opts(opts->flags, REFRESH_IDOP);

	if (au_ftest_opts(opts->flags, TRUNC_XIB)) {
		rerr = au_xib_trunc(sb);
		if (unlikely(rerr && !err))
			err = rerr;
	}

	/* will be handled by the caller */
	if (!au_ftest_opts(opts->flags, REFRESH)
	    && (opts->given_udba
		|| au_opt_test(sbinfo->si_mntflags, XINO)
		|| au_ftest_opts(opts->flags, REFRESH_IDOP)
		    ))
		au_fset_opts(opts->flags, REFRESH);

	AuDbg("status 0x%x\n", opts->flags);
	return err;
}
Пример #2
0
/*
 * returns tri-state.
 * plus: processed without an error
 * zero: unprocessed
 * minus: error
 */
static int au_opt_br(struct super_block *sb, struct au_opt *opt,
		     struct au_opts *opts)
{
	int err, do_refresh;

	err = 0;
	switch (opt->type) {
	case Opt_append:
		opt->add.bindex = au_sbend(sb) + 1;
		if (opt->add.bindex < 0)
			opt->add.bindex = 0;
		goto add;
	case Opt_prepend:
		opt->add.bindex = 0;
	add:
	case Opt_add:
		err = au_br_add(sb, &opt->add,
				au_ftest_opts(opts->flags, REMOUNT));
		if (!err) {
			err = 1;
			au_fset_opts(opts->flags, REFRESH);
		}
		break;

	case Opt_del:
	case Opt_idel:
		err = au_br_del(sb, &opt->del,
				au_ftest_opts(opts->flags, REMOUNT));
		if (!err) {
			err = 1;
			au_fset_opts(opts->flags, TRUNC_XIB);
			au_fset_opts(opts->flags, REFRESH);
		}
		break;

	case Opt_mod:
	case Opt_imod:
		err = au_br_mod(sb, &opt->mod,
				au_ftest_opts(opts->flags, REMOUNT),
				&do_refresh);
		if (!err) {
			err = 1;
			if (do_refresh)
				au_fset_opts(opts->flags, REFRESH);
		}
		break;
	}

	return err;
}
Пример #3
0
static int au_opt_xino(struct super_block *sb, struct au_opt *opt,
		       struct au_opt_xino **opt_xino,
		       struct au_opts *opts)
{
	int err;
	aufs_bindex_t bend, bindex;
	struct dentry *root, *parent, *h_root;

	err = 0;
	switch (opt->type) {
	case Opt_xino:
		err = au_xino_set(sb, &opt->xino,
				  !!au_ftest_opts(opts->flags, REMOUNT));
		if (unlikely(err))
			break;

		*opt_xino = &opt->xino;
		au_xino_brid_set(sb, -1);

		/* safe d_parent access */
		parent = opt->xino.file->f_dentry->d_parent;
		root = sb->s_root;
		bend = au_sbend(sb);
		for (bindex = 0; bindex <= bend; bindex++) {
			h_root = au_h_dptr(root, bindex);
			if (h_root == parent) {
				au_xino_brid_set(sb, au_sbr_id(sb, bindex));
				break;
			}
		}
		break;

	case Opt_noxino:
		au_xino_clr(sb);
		au_xino_brid_set(sb, -1);
		*opt_xino = (void *)-1;
		break;
	}

	return err;
}