static void do_ii_read_lock(struct inode *inode, unsigned int lsc)
{
	switch (lsc) {
	case AuLsc_DI_CHILD:
		ii_read_lock_child(inode);
		break;
	case AuLsc_DI_CHILD2:
		ii_read_lock_child2(inode);
		break;
	case AuLsc_DI_CHILD3:
		ii_read_lock_child3(inode);
		break;
	case AuLsc_DI_PARENT:
		ii_read_lock_parent(inode);
		break;
	case AuLsc_DI_PARENT2:
		ii_read_lock_parent2(inode);
		break;
	case AuLsc_DI_PARENT3:
		ii_read_lock_parent3(inode);
		break;
	default:
		BUG();
	}
}
Exemple #2
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;
}