Esempio n. 1
0
static ssize_t au_fhsm_read(struct file *file, char __user *buf, size_t count,
			   loff_t *pos)
{
	ssize_t err;
	int readable;
	aufs_bindex_t nfhsm, bindex, bend;
	struct au_sbinfo *sbinfo;
	struct au_fhsm *fhsm;
	struct au_branch *br;
	struct super_block *sb;

	err = 0;
	sbinfo = file->private_data;
	fhsm = &sbinfo->si_fhsm;
need_data:
	spin_lock_irq(&fhsm->fhsm_wqh.lock);
	if (!atomic_read(&fhsm->fhsm_readable)) {
		if (vfsub_file_flags(file) & O_NONBLOCK)
			err = -EAGAIN;
		else
			err = wait_event_interruptible_locked_irq
				(fhsm->fhsm_wqh,
				 atomic_read(&fhsm->fhsm_readable));
	}
	spin_unlock_irq(&fhsm->fhsm_wqh.lock);
	if (unlikely(err))
		goto out;

	/* sb may already be dead */
	au_rw_read_lock(&sbinfo->si_rwsem);
	readable = atomic_read(&fhsm->fhsm_readable);
	if (readable > 0) {
		sb = sbinfo->si_sb;
		AuDebugOn(!sb);
		/* exclude the bottom branch */
		nfhsm = 0;
		bend = au_fhsm_bottom(sb);
		for (bindex = 0; bindex < bend; bindex++) {
			br = au_sbr(sb, bindex);
			if (au_br_fhsm(br->br_perm))
				nfhsm++;
		}
		err = -EMSGSIZE;
		if (nfhsm * sizeof(struct aufs_stbr) <= count) {
			atomic_set(&fhsm->fhsm_readable, 0);
			err = au_fhsm_do_read(sbinfo->si_sb, (void __user *)buf,
					     count);
		}
	}
	au_rw_read_unlock(&sbinfo->si_rwsem);
	if (!readable)
		goto need_data;

out:
	return err;
}
Esempio n. 2
0
void di_read_unlock(struct dentry *d, int flags)
{
	if (d->d_inode) {
		if (au_ftest_lock(flags, IW))
			ii_write_unlock(d->d_inode);
		else if (au_ftest_lock(flags, IR))
			ii_read_unlock(d->d_inode);
	}
	au_rw_read_unlock(&au_di(d)->di_rwsem);
}
Esempio n. 3
0
void di_read_unlock(struct dentry *d, int flags)
{
	if (d->d_inode) {
		if (au_ftest_lock(flags, IW)) {
			au_dbg_verify_dinode(d);
			ii_write_unlock(d->d_inode);
		} else if (au_ftest_lock(flags, IR)) {
			au_dbg_verify_dinode(d);
			ii_read_unlock(d->d_inode);
		}
	}
	au_rw_read_unlock(&au_di(d)->di_rwsem);
}
Esempio n. 4
0
void di_read_unlock(struct dentry *d, int flags)
{
	LKTRTrace("%.*s\n", AuDLNPair(d));
	SiMustAnyLock(d->d_sb);

	if (d->d_inode) {
		if (au_ftest_lock(flags, IW))
			ii_write_unlock(d->d_inode);
		else if (au_ftest_lock(flags, IR))
			ii_read_unlock(d->d_inode);
	}
	au_rw_read_unlock(&au_di(d)->di_rwsem);
	au_dbg_locked_di_unreg(d, flags);
}