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_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; }
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; }
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; } }
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; }
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; } }