static int test_overlap(struct super_block *sb, struct dentry *h_adding,
			struct dentry *h_root)
{
	if (unlikely(h_adding == h_root
		     || au_test_loopback_overlap(sb, h_adding)))
		return 1;
	if (h_adding->d_sb != h_root->d_sb)
		return 0;
	return au_test_subdir(h_adding, h_root)
		|| au_test_subdir(h_root, h_adding);
}
Example #2
0
/*
 * test if two lower dentries have overlapping branches.
 */
int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding)
{
	struct super_block *h_sb;
	struct file *backing_file;

	if (unlikely(!backing_file_func)) {
		/* don't load "loop" module here */
		backing_file_func = symbol_get(loop_backing_file);
		if (unlikely(!backing_file_func))
			/* "loop" module is not loaded */
			return 0;
	}

	h_sb = h_adding->d_sb;
	backing_file = backing_file_func(h_sb);
	if (!backing_file)
		return 0;

	h_adding = backing_file->f_path.dentry;
	/*
	 * h_adding can be local NFS.
	 * in this case aufs cannot detect the loop.
	 */
	if (unlikely(h_adding->d_sb == sb))
		return 1;
	return !!au_test_subdir(h_adding, sb->s_root);
}
Example #3
0
void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir)
{
	AuDebugOn(d1 == d2
		  || d1->d_inode == d2->d_inode
		  || d1->d_sb != d2->d_sb);

	if (isdir && au_test_subdir(d1, d2)) {
		di_write_lock_parent(d1);
		di_write_lock_parent2(d2);
	} else {
		/* there should be no races */
		di_write_lock_parent(d2);
		di_write_lock_parent2(d1);
	}
}
Example #4
0
/*
 * test if two lower dentries have overlapping branches.
 */
int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_d1,
			     struct dentry *h_d2)
{
	struct inode *h_inode;
	struct loop_device *l;

	h_inode = h_d1->d_inode;
	if (MAJOR(h_inode->i_sb->s_dev) != LOOP_MAJOR)
		return 0;

	l = h_inode->i_sb->s_bdev->bd_disk->private_data;
	h_d1 = l->lo_backing_file->f_dentry;
	/* h_d1 can be local NFS. in this case aufs cannot detect the loop */
	if (unlikely(h_d1->d_sb == sb))
		return 1;
	return au_test_subdir(h_d1, h_d2);
}
Example #5
0
/*
 * test if two lower dentries have overlapping branches.
 */
int au_test_loopback_overlap(struct super_block *sb, struct dentry *h_adding)
{
	struct super_block *h_sb;
	struct loop_device *l;

	h_sb = h_adding->d_sb;
	if (MAJOR(h_sb->s_dev) != LOOP_MAJOR)
		return 0;

	l = h_sb->s_bdev->bd_disk->private_data;
	h_adding = l->lo_backing_file->f_dentry;
	/*
	 * h_adding can be local NFS.
	 * in this case aufs cannot detect the loop.
	 */
	if (unlikely(h_adding->d_sb == sb))
		return 1;
	return !!au_test_subdir(h_adding, sb->s_root);
}