/* * find the index of a branch which is specified by @br_id. */ int au_br_index(struct super_block *sb, aufs_bindex_t br_id) { aufs_bindex_t bindex, bend; bend = au_sbend(sb); for (bindex = 0; bindex <= bend; bindex++) if (au_sbr_id(sb, bindex) == br_id) return bindex; return -1; }
static int au_opt_xino(struct super_block *sb, struct au_opt *opt, struct au_opt_xino **opt_xino, struct au_opts *opts) { int err; aufs_bindex_t bend, bindex; struct dentry *root, *parent, *h_root; err = 0; switch (opt->type) { case Opt_xino: err = au_xino_set(sb, &opt->xino, !!au_ftest_opts(opts->flags, REMOUNT)); if (unlikely(err)) break; *opt_xino = &opt->xino; au_xino_brid_set(sb, -1); /* safe d_parent access */ parent = opt->xino.file->f_dentry->d_parent; root = sb->s_root; bend = au_sbend(sb); for (bindex = 0; bindex <= bend; bindex++) { h_root = au_h_dptr(root, bindex); if (h_root == parent) { au_xino_brid_set(sb, au_sbr_id(sb, bindex)); break; } } break; case Opt_noxino: au_xino_clr(sb); au_xino_brid_set(sb, -1); *opt_xino = (void *)-1; break; } return err; }
void au_dir_ts(struct inode *dir, aufs_bindex_t bindex) { int perm, wkq_err; aufs_bindex_t btop; struct au_dir_ts_arg *arg; struct dentry *dentry; struct super_block *sb; IMustLock(dir); dentry = d_find_any_alias(dir); AuDebugOn(!dentry); sb = dentry->d_sb; btop = au_ibtop(dir); if (btop == bindex) { au_cpup_attr_timesizes(dir); goto out; } perm = au_sbr_perm(sb, btop); if (!au_br_writable(perm)) goto out; arg = kmalloc(sizeof(*arg), GFP_NOFS); if (!arg) goto out; arg->dentry = dget(dentry); /* will be dput-ted by au_do_dir_ts() */ arg->brid = au_sbr_id(sb, bindex); wkq_err = au_wkq_nowait(au_do_dir_ts, arg, sb, /*flags*/0); if (unlikely(wkq_err)) { pr_err("wkq %d\n", wkq_err); dput(dentry); kfree(arg); } out: dput(dentry); }