/* * 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); }
/* * 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); }
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); }
void au_di_fin(struct dentry *dentry) { struct au_dinfo *dinfo; dinfo = au_di(dentry); AuRwDestroy(&dinfo->di_rwsem); au_di_free(dinfo); }
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); }
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); }
/* * 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); }
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); }