Example #1
0
static void aufs_d_release(struct dentry *dentry)
{
	struct au_dinfo *dinfo;
	aufs_bindex_t bend, bindex;

	dinfo = dentry->d_fsdata;
	if (!dinfo)
		return;

	/* dentry may not be revalidated */
	bindex = dinfo->di_bstart;
	if (bindex >= 0) {
		struct au_hdentry *p;

		bend = dinfo->di_bend;
		p = dinfo->di_hdentry + bindex;
		while (bindex++ <= bend) {
			if (p->hd_dentry)
				au_hdput(p);
			p++;
		}
	}
	kfree(dinfo->di_hdentry);
	AuRwDestroy(&dinfo->di_rwsem);
	au_cache_free_dinfo(dinfo);
	au_hin_di_reinit(dentry);
}
Example #2
0
void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
		   struct dentry *h_dentry)
{
	struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex;

	DiMustWriteLock(dentry);

	if (hd->hd_dentry)
		au_hdput(hd);
	hd->hd_dentry = h_dentry;
}
Example #3
0
void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
		   struct dentry *h_dentry)
{
	struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex;
	DiMustWriteLock(dentry);
	AuDebugOn(bindex < au_di(dentry)->di_bstart
		  || bindex > au_di(dentry)->di_bend
		  || (h_dentry && atomic_read(&h_dentry->d_count) <= 0)
		  || (h_dentry && hd->hd_dentry)
		);
	if (hd->hd_dentry)
		au_hdput(hd, /*do_free*/0);
	hd->hd_dentry = h_dentry;
}
Example #4
0
void au_set_h_dptr(struct dentry *dentry, aufs_bindex_t bindex,
		   struct dentry *h_dentry)
{
	struct au_hdentry *hd = au_di(dentry)->di_hdentry + bindex;
	struct au_branch *br;

	DiMustWriteLock(dentry);

	au_hdput(hd);
	hd->hd_dentry = h_dentry;
	if (h_dentry) {
		br = au_sbr(dentry->d_sb, bindex);
		hd->hd_id = br->br_id;
	}
}
Example #5
0
void au_di_free(struct au_dinfo *dinfo)
{
	struct au_hdentry *p;
	aufs_bindex_t bend, bindex;

	/* dentry may not be revalidated */
	bindex = dinfo->di_bstart;
	if (bindex >= 0) {
		bend = dinfo->di_bend;
		p = dinfo->di_hdentry + bindex;
		while (bindex++ <= bend)
			au_hdput(p++);
	}
	kfree(dinfo->di_hdentry);
	au_cache_free_dinfo(dinfo);
}
static int au_do_refresh_hdentry(struct dentry *dentry, struct dentry *parent)
{
	int err;
	aufs_bindex_t new_bindex, bindex, bend, bwh, bdiropq;
	struct au_hdentry tmp, *p, *q;
	struct au_dinfo *dinfo;
	struct super_block *sb;

	DiMustWriteLock(dentry);

	sb = dentry->d_sb;
	dinfo = au_di(dentry);
	bend = dinfo->di_bend;
	bwh = dinfo->di_bwh;
	bdiropq = dinfo->di_bdiropq;
	p = dinfo->di_hdentry + dinfo->di_bstart;
	for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) {
		if (!p->hd_dentry)
			continue;

		new_bindex = au_br_index(sb, p->hd_id);
		if (new_bindex == bindex)
			continue;

		if (dinfo->di_bwh == bindex)
			bwh = new_bindex;
		if (dinfo->di_bdiropq == bindex)
			bdiropq = new_bindex;
		if (new_bindex < 0) {
			au_hdput(p);
			p->hd_dentry = NULL;
			continue;
		}

		/* swap two lower dentries, and loop again */
		q = dinfo->di_hdentry + new_bindex;
		tmp = *q;
		*q = *p;
		*p = tmp;
		if (tmp.hd_dentry) {
			bindex--;
			p--;
		}
	}

	dinfo->di_bwh = -1;
	if (bwh >= 0 && bwh <= au_sbend(sb) && au_sbr_whable(sb, bwh))
		dinfo->di_bwh = bwh;

	dinfo->di_bdiropq = -1;
	if (bdiropq >= 0
	    && bdiropq <= au_sbend(sb)
	    && au_sbr_whable(sb, bdiropq))
		dinfo->di_bdiropq = bdiropq;

	err = -EIO;
	dinfo->di_bstart = -1;
	dinfo->di_bend = -1;
	bend = au_dbend(parent);
	p = dinfo->di_hdentry;
	for (bindex = 0; bindex <= bend; bindex++, p++)
		if (p->hd_dentry) {
			dinfo->di_bstart = bindex;
			break;
		}

	if (dinfo->di_bstart >= 0) {
		p = dinfo->di_hdentry + bend;
		for (bindex = bend; bindex >= 0; bindex--, p--)
			if (p->hd_dentry) {
				dinfo->di_bend = bindex;
				err = 0;
				break;
			}
	}

	return err;
}
Example #7
0
static void au_do_refresh_hdentry(struct au_hdentry *p, struct au_dinfo *dinfo,
				  struct dentry *parent)
{
	struct dentry *h_d, *h_dp;
	struct au_hdentry tmp, *q;
	struct super_block *sb;
	aufs_bindex_t new_bindex, bindex, bend, bwh, bdiropq;

	AuRwMustWriteLock(&dinfo->di_rwsem);

	bend = dinfo->di_bend;
	bwh = dinfo->di_bwh;
	bdiropq = dinfo->di_bdiropq;
	for (bindex = dinfo->di_bstart; bindex <= bend; bindex++, p++) {
		h_d = p->hd_dentry;
		if (!h_d)
			continue;

		h_dp = dget_parent(h_d);
		if (h_dp == au_h_dptr(parent, bindex)) {
			dput(h_dp);
			continue;
		}

		new_bindex = au_find_dbindex(parent, h_dp);
		dput(h_dp);
		if (dinfo->di_bwh == bindex)
			bwh = new_bindex;
		if (dinfo->di_bdiropq == bindex)
			bdiropq = new_bindex;
		if (new_bindex < 0) {
			au_hdput(p);
			p->hd_dentry = NULL;
			continue;
		}

		/* swap two lower dentries, and loop again */
		q = dinfo->di_hdentry + new_bindex;
		tmp = *q;
		*q = *p;
		*p = tmp;
		if (tmp.hd_dentry) {
			bindex--;
			p--;
		}
	}

	sb = parent->d_sb;
	dinfo->di_bwh = -1;
	if (bwh >= 0 && bwh <= au_sbend(sb) && au_sbr_whable(sb, bwh))
		dinfo->di_bwh = bwh;

	dinfo->di_bdiropq = -1;
	if (bdiropq >= 0
	    && bdiropq <= au_sbend(sb)
	    && au_sbr_whable(sb, bdiropq))
		dinfo->di_bdiropq = bdiropq;

	bend = au_dbend(parent);
	p = dinfo->di_hdentry;
	for (bindex = 0; bindex <= bend; bindex++, p++)
		if (p->hd_dentry) {
			dinfo->di_bstart = bindex;
			break;
		}

	p = dinfo->di_hdentry + bend;
	for (bindex = bend; bindex >= 0; bindex--, p--)
		if (p->hd_dentry) {
			dinfo->di_bend = bindex;
			break;
		}
}