Exemple #1
0
int main(int argc, char** argv)
{
	printf("KEY META     TESTS\n");
	printf("==================\n\n");

	init (argc, argv);
	test_basic();
	test_iterate();
	test_size();
	test_uid();
	test_dup();
	test_comment();
	test_owner();
	test_mode();
	test_type();
	test_examples();
	test_copy();
	test_ro();
	test_new();
	test_copyall();


	printf("\ntest_ks RESULTS: %d test(s) done. %d error(s).\n", nbTest, nbError);

	return nbError;
}
Exemple #2
0
/* common functions to regular file and dir */
struct file *hidden_open(struct dentry *dentry, aufs_bindex_t bindex, int flags)
{
	struct dentry *hidden_dentry;
	struct inode *hidden_inode;
	struct super_block *sb;
	struct vfsmount *hidden_mnt;
	struct file *hidden_file;
	struct aufs_branch *br;
	loff_t old_size;
	int udba;

	LKTRTrace("%.*s, b%d, flags 0%o\n", DLNPair(dentry), bindex, flags);
	DEBUG_ON(!dentry);
	hidden_dentry = au_h_dptr_i(dentry, bindex);
	DEBUG_ON(!hidden_dentry);
	hidden_inode = hidden_dentry->d_inode;
	DEBUG_ON(!hidden_inode);

	sb = dentry->d_sb;
	udba = au_flag_test(sb, AuFlag_UDBA_INOTIFY);
	if (unlikely(udba)) {
		// test here?
	}

	br = stobr(sb, bindex);
	br_get(br);
	/* drop flags for writing */
	if (test_ro(sb, bindex, dentry->d_inode))
		flags = au_file_roflags(flags);
	flags &= ~O_CREAT;
	spin_lock(&hidden_inode->i_lock);
	old_size = i_size_read(hidden_inode);
	spin_unlock(&hidden_inode->i_lock);

	//DbgSleep(3);

	dget(hidden_dentry);
	hidden_mnt = mntget(br->br_mnt);
	hidden_file = dentry_open(hidden_dentry, hidden_mnt, flags);
	//if (LktrCond) {fput(hidden_file); hidden_file = ERR_PTR(-1);}

	if (!IS_ERR(hidden_file)) {
#if 0 // remove this
		if (/* old_size && */ (flags & O_TRUNC)) {
			au_direval_dec(dentry);
			if (!IS_ROOT(dentry))
				au_direval_dec(dentry->d_parent);
		}
#endif
		return hidden_file;
	}

	br_put(br);
	TraceErrPtr(hidden_file);
	return hidden_file;
}
Exemple #3
0
/* returns,
 * 0: wh is unnecessary
 * plus: wh is necessary
 * minus: error
 */
int wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup,
		   struct dentry *locked)
{
	int need_wh, err;
	aufs_bindex_t bstart;
	struct dentry *hidden_dentry;
	struct super_block *sb;

	LKTRTrace("%.*s, isdir %d, *bcpup %d, locked %p\n",
		  DLNPair(dentry), isdir, *bcpup, locked);
	sb = dentry->d_sb;

	bstart = dbstart(dentry);
	LKTRTrace("bcpup %d, bstart %d\n", *bcpup, bstart);
	hidden_dentry = au_h_dptr(dentry);
	if (*bcpup < 0) {
		*bcpup = bstart;
		if (test_ro(sb, bstart, dentry->d_inode)) {
			*bcpup = err = find_rw_parent_br(dentry, bstart);
			//*bcpup = err = find_rw_br(sb, bstart);
			//err = -1;
			if (unlikely(err < 0))
				goto out;
		}
	} else
		DEBUG_ON(bstart < *bcpup
			 || test_ro(sb, *bcpup, dentry->d_inode));
	LKTRTrace("bcpup %d, bstart %d\n", *bcpup, bstart);

	if (*bcpup != bstart) {
		err = cpup_dirs(dentry, *bcpup, locked);
		//err = -1;
		if (unlikely(err))
			goto out;
		need_wh = 1;
	} else {
		//struct nameidata nd;
		aufs_bindex_t old_bend, new_bend, bdiropq = -1;
		old_bend = dbend(dentry);
		if (isdir) {
			bdiropq = dbdiropq(dentry);
			set_dbdiropq(dentry, -1);
		}
		err = need_wh = lkup_dentry(dentry, bstart + 1, /*type*/0);
		//err = -1;
		if (isdir)
			set_dbdiropq(dentry, bdiropq);
		if (unlikely(err < 0))
			goto out;
		new_bend = dbend(dentry);
		if (!need_wh && old_bend != new_bend) {
			set_h_dptr(dentry, new_bend, NULL);
			set_dbend(dentry, old_bend);
#if 0
		} else if (!au_h_dptr_i(dentry, new_bend)->d_inode) {
			LKTRTrace("negative\n");
			set_h_dptr(dentry, new_bend, NULL);
			set_dbend(dentry, old_bend);
			need_wh = 0;
#endif
		}
	}
	LKTRTrace("need_wh %d\n", need_wh);
	err = need_wh;

 out:
	TraceErr(err);
	return err;
}
Exemple #4
0
/*
 * prepare the @file for writing.
 */
int au_ready_to_write(struct file *file, loff_t len)
{
	int err;
	struct dentry *dentry, *parent, *hidden_dentry, *hidden_parent;
	struct inode *hidden_inode, *hidden_dir, *inode, *dir;
	struct super_block *sb;
	aufs_bindex_t bstart, bcpup;

	dentry = file->f_dentry;
	LKTRTrace("%.*s, len %Ld\n", DLNPair(dentry), len);
	FiMustWriteLock(file);

	sb = dentry->d_sb;
	bstart = fbstart(file);
	DEBUG_ON(ftobr(file, bstart) != stobr(sb, bstart));

	inode = dentry->d_inode;
	ii_read_lock_child(inode);
	LKTRTrace("rdonly %d, bstart %d\n", test_ro(sb, bstart, inode), bstart);
	err = test_ro(sb, bstart, inode);
	ii_read_unlock(inode);
	if (!err && (au_h_fptr(file)->f_mode & FMODE_WRITE))
		return 0;

	/* need to cpup */
	parent = dentry->d_parent; // dget_parent()
	di_write_lock_child(dentry);
	di_write_lock_parent(parent);
	bcpup = err = find_rw_parent_br(dentry, bstart);
	//bcpup = err = find_rw_br(sb, bstart);
	if (unlikely(err < 0))
		goto out_unlock;
	err = 0;

	hidden_parent = au_h_dptr_i(parent, bcpup);
	if (!hidden_parent) {
		err = cpup_dirs(dentry, bcpup, NULL);
		//if (LktrCond) err = -1;
		if (unlikely(err))
			goto out_unlock;
		hidden_parent = au_h_dptr_i(parent, bcpup);
	}

	hidden_dir = hidden_parent->d_inode;
	hidden_dentry = au_h_fptr(file)->f_dentry;
	hidden_inode = hidden_dentry->d_inode;
	dir = parent->d_inode;
	hdir_lock(hidden_dir, dir, bcpup);
	hi_lock_child(hidden_inode);
	if (d_unhashed(dentry) || d_unhashed(hidden_dentry)
	    /* || !hidden_inode->i_nlink */) {
		if (!au_test_perm(hidden_dir, MAY_EXEC | MAY_WRITE,
				  need_dlgt(sb)))
			err = cpup_wh_file(file, bcpup, len);
		else {
			struct cpup_wh_file_args args = {
				.errp	= &err,
				.file	= file,
				.bdst	= bcpup,
				.len	= len
			};
			au_wkq_wait(call_cpup_wh_file, &args, /*dlgt*/0);
		}
		//if (LktrCond) err = -1;
		TraceErr(err);
	} else {
		if (!au_h_dptr_i(dentry, bcpup))
Exemple #5
0
int au_do_open(struct inode *inode, struct file *file,
	       int (*open)(struct file *file, int flags))
{
	int err, coo;
	struct dentry *dentry;
	struct super_block *sb;
	aufs_bindex_t bstart;
	struct inode *h_dir, *dir;

	dentry = file->f_dentry;
	LKTRTrace("i%lu, %.*s\n", inode->i_ino, DLNPair(dentry));

	sb = dentry->d_sb;
	si_read_lock(sb);
	coo = 0;
#if 0
	switch (au_flag_test_coo(sb)) {
	case AuFlag_COO_LEAF:
		coo = !S_ISDIR(inode->i_mode);
		break;
	case AuFlag_COO_ALL:
		coo = 1;
		break;
	}
#endif
	err = au_init_finfo(file);
	//if (LktrCond) {fi_write_unlock(file); fin_finfo(file); err = -1;}
	if (unlikely(err))
		goto out;

	if (!coo) {
		di_read_lock_child(dentry, AUFS_I_RLOCK);
		bstart = dbstart(dentry);
	} else {
		di_write_lock_child(dentry);
		bstart = dbstart(dentry);
		if (test_ro(sb, bstart, dentry->d_inode)) {
			err = do_coo(dentry, bstart);
			if (err) {
				di_write_unlock(dentry);
				goto out_finfo;
			}
			bstart = dbstart(dentry);
		}
		di_downgrade_lock(dentry, AUFS_I_RLOCK);
	}

	// todo: remove this extra locks
	dir = dentry->d_parent->d_inode;
	if (!IS_ROOT(dentry))
		ii_read_lock_parent(dir);
	h_dir = au_h_iptr_i(dir, bstart);
	hdir_lock(h_dir, dir, bstart);
	err = open(file, file->f_flags);
	//if (LktrCond) err = -1;
	hdir_unlock(h_dir, dir, bstart);
	if (!IS_ROOT(dentry))
		ii_read_unlock(dir);
	di_read_unlock(dentry, AUFS_I_RLOCK);

 out_finfo:
	fi_write_unlock(file);
	if (unlikely(err))
		au_fin_finfo(file);
	//DbgFile(file);
 out:
	si_read_unlock(sb);
	TraceErr(err);
	return err;
}