static void au_br_do_del(struct super_block *sb, aufs_bindex_t bindex, struct au_branch *br) { aufs_bindex_t bend; struct au_sbinfo *sbinfo; struct dentry *root, *h_root; struct inode *inode, *h_inode; struct au_hinode *hinode; SiMustWriteLock(sb); root = sb->s_root; inode = root->d_inode; sbinfo = au_sbi(sb); bend = sbinfo->si_bend; h_root = au_h_dptr(root, bindex); hinode = au_hi(inode, bindex); h_inode = au_igrab(hinode->hi_inode); au_hiput(hinode); au_sbilist_lock(); au_br_do_del_brp(sbinfo, bindex, bend); au_br_do_del_hdp(au_di(root), bindex, bend); au_br_do_del_hip(au_ii(inode), bindex, bend); au_sbilist_unlock(); dput(h_root); iput(h_inode); au_br_do_free(br); }
int au_refresh_hinode_self(struct inode *inode, int do_attr) { int err, e; aufs_bindex_t bindex, new_bindex; unsigned char update; struct au_hinode *p, *q, tmp; struct super_block *sb; struct au_iinfo *iinfo; IiMustWriteLock(inode); update = 0; sb = inode->i_sb; iinfo = au_ii(inode); err = au_ii_realloc(iinfo, au_sbend(sb) + 1); if (unlikely(err)) goto out; p = iinfo->ii_hinode + iinfo->ii_bstart; err = 0; for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; bindex++, p++) { if (!p->hi_inode) continue; new_bindex = au_br_index(sb, p->hi_id); if (new_bindex == bindex) continue; if (new_bindex < 0) { update = 1; au_hiput(p); p->hi_inode = NULL; continue; } if (new_bindex < iinfo->ii_bstart) iinfo->ii_bstart = new_bindex; if (iinfo->ii_bend < new_bindex) iinfo->ii_bend = new_bindex; /* swap two lower inode, and loop again */ q = iinfo->ii_hinode + new_bindex; tmp = *q; *q = *p; *p = tmp; if (tmp.hi_inode) { bindex--; p--; } } au_update_ibrange(inode, /*do_put_zero*/0); e = au_dy_irefresh(inode); if (unlikely(e && !err)) err = e; if (do_attr) au_refresh_hinode_attr(inode, update && S_ISDIR(inode->i_mode)); out: return err; }
static int au_ii_refresh(struct inode *inode, int *update) { int err, e; umode_t type; aufs_bindex_t bindex, new_bindex; struct super_block *sb; struct au_iinfo *iinfo; struct au_hinode *p, *q, tmp; IiMustWriteLock(inode); *update = 0; sb = inode->i_sb; type = inode->i_mode & S_IFMT; iinfo = au_ii(inode); err = au_ii_realloc(iinfo, au_sbend(sb) + 1); if (unlikely(err)) goto out; AuDebugOn(iinfo->ii_bstart < 0); p = iinfo->ii_hinode + iinfo->ii_bstart; for (bindex = iinfo->ii_bstart; bindex <= iinfo->ii_bend; bindex++, p++) { if (!p->hi_inode) continue; AuDebugOn(type != (p->hi_inode->i_mode & S_IFMT)); new_bindex = au_br_index(sb, p->hi_id); if (new_bindex == bindex) continue; if (new_bindex < 0) { *update = 1; au_hiput(p); p->hi_inode = NULL; continue; } if (new_bindex < iinfo->ii_bstart) iinfo->ii_bstart = new_bindex; if (iinfo->ii_bend < new_bindex) iinfo->ii_bend = new_bindex; /* swap two lower inode, and loop again */ q = iinfo->ii_hinode + new_bindex; tmp = *q; *q = *p; *p = tmp; if (tmp.hi_inode) { bindex--; p--; } } au_update_ibrange(inode, /*do_put_zero*/0); e = au_dy_irefresh(inode); if (unlikely(e && !err)) err = e; out: AuTraceErr(err); return err; }