/*
 * free a single branch
 */
static void au_br_do_free(struct au_branch *br)
{
	int i;
	struct au_wbr *wbr;
	struct au_dykey **key;

	au_hnotify_fin_br(br);

	if (br->br_xino.xi_file)
		fput(br->br_xino.xi_file);
	mutex_destroy(&br->br_xino.xi_nondir_mtx);

	AuDebugOn(atomic_read(&br->br_count));

	wbr = br->br_wbr;
	if (wbr) {
		for (i = 0; i < AuBrWh_Last; i++)
			dput(wbr->wbr_wh[i]);
		AuDebugOn(atomic_read(&wbr->wbr_wh_running));
		AuRwDestroy(&wbr->wbr_wh_rwsem);
	}

	key = br->br_dykey;
	for (i = 0; i < AuBrDynOp; i++, key++)
		if (*key)
			au_dy_put(*key);
		else
			break;

	mntput(br->br_mnt);
	kfree(wbr);
	kfree(br);
}
Ejemplo n.º 2
0
/*
 * they are necessary regardless sysfs is disabled.
 */
void au_si_free(struct kobject *kobj)
{
	struct au_sbinfo *sbinfo;
	char *locked __maybe_unused; /* debug only */

	sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
	AuDebugOn(!list_empty(&sbinfo->si_plink.head));
	AuDebugOn(atomic_read(&sbinfo->si_nowait.nw_len));

	au_rw_write_lock(&sbinfo->si_rwsem);
	au_br_free(sbinfo);
	au_rw_write_unlock(&sbinfo->si_rwsem);

	AuDebugOn(radix_tree_gang_lookup
		  (&sbinfo->au_si_pid.tree, (void **)&locked,
		   /*first_index*/PID_MAX_DEFAULT - 1,
		   /*max_items*/sizeof(locked)/sizeof(*locked)));

	kfree(sbinfo->si_branch);
	kfree(sbinfo->au_si_pid.bitmap);
	mutex_destroy(&sbinfo->si_xib_mtx);
	AuRwDestroy(&sbinfo->si_rwsem);

	kfree(sbinfo);
}
Ejemplo n.º 3
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);
}
Ejemplo n.º 4
0
void au_di_fin(struct dentry *dentry)
{
	struct au_dinfo *dinfo;

	dinfo = au_di(dentry);
	AuRwDestroy(&dinfo->di_rwsem);
	au_di_free(dinfo);
}
Ejemplo n.º 5
0
void au_finfo_fin(struct file *file)
{
	struct au_finfo *finfo;

	finfo = au_fi(file);
	AuDebugOn(finfo->fi_hdir);
	AuRwDestroy(&finfo->fi_rwsem);
	au_cache_free_finfo(finfo);
}
Ejemplo n.º 6
0
void au_finfo_fin(struct file *file)
{
	struct au_finfo *finfo;

	au_nfiles_dec(file->f_dentry->d_sb);

	finfo = au_fi(file);
	AuDebugOn(finfo->fi_hdir);
	AuRwDestroy(&finfo->fi_rwsem);
	au_cache_free_finfo(finfo);
}
Ejemplo n.º 7
0
/*
 * they are necessary regardless sysfs is disabled.
 */
void au_si_free(struct kobject *kobj)
{
	struct au_sbinfo *sbinfo;
	struct super_block *sb;

	sbinfo = container_of(kobj, struct au_sbinfo, si_kobj);
	AuDebugOn(!list_empty(&sbinfo->si_plink.head));
	AuDebugOn(sbinfo->si_plink_maint);

	sb = sbinfo->si_sb;
	si_write_lock(sb);
	au_xino_clr(sb);
	au_br_free(sbinfo);
	kfree(sbinfo->si_branch);
	mutex_destroy(&sbinfo->si_xib_mtx);
	si_write_unlock(sb);
	AuRwDestroy(&sbinfo->si_rwsem);

	kfree(sbinfo);
}
Ejemplo n.º 8
0
void au_finfo_fin(struct file *file)
{
	struct au_finfo *finfo;
	aufs_bindex_t bindex, bend;

	fi_write_lock(file);
	bend = au_fbend(file);
	bindex = au_fbstart(file);
	if (bindex >= 0)
		/*
		 * calls fput() instead of filp_close(),
		 * since no dnotify or lock for the lower file.
		 */
		for (; bindex <= bend; bindex++)
			au_set_h_fptr(file, bindex, NULL);

	finfo = au_fi(file);
	au_dbg_verify_hf(finfo);
	kfree(finfo->fi_hfile);
	fi_write_unlock(file);
	AuRwDestroy(&finfo->fi_rwsem);
	au_cache_free_finfo(finfo);
}