int au_pin(struct au_pin *pin, struct dentry *dentry, aufs_bindex_t bindex, unsigned int udba, unsigned char flags) { au_pin_init(pin, dentry, bindex, AuLsc_DI_PARENT, AuLsc_I_PARENT2, udba, flags); return au_do_pin(pin); }
/* lock them all */ static int au_do_lock(const unsigned char dmsg, struct au_mvd_args *a) { int err; struct dentry *h_trap; a->mvd_h_src_sb = au_sbr_sb(a->sb, a->mvd_bsrc); a->mvd_h_dst_sb = au_sbr_sb(a->sb, a->mvd_bdst); err = au_pin(&a->mvd_pin_dst, a->dentry, a->mvd_bdst, au_opt_udba(a->sb), AuPin_MNT_WRITE | AuPin_DI_LOCKED); AuTraceErr(err); if (unlikely(err)) { AU_MVD_PR(dmsg, "pin_dst failed\n"); goto out; } if (a->mvd_h_src_sb != a->mvd_h_dst_sb) { a->rename_lock = 0; au_pin_init(&a->mvd_pin_src, a->dentry, a->mvd_bsrc, AuLsc_DI_PARENT, AuLsc_I_PARENT3, au_opt_udba(a->sb), AuPin_MNT_WRITE | AuPin_DI_LOCKED); err = au_do_pin(&a->mvd_pin_src); AuTraceErr(err); a->mvd_h_src_dir = d_inode(a->mvd_h_src_parent); if (unlikely(err)) { AU_MVD_PR(dmsg, "pin_src failed\n"); goto out_dst; } goto out; /* success */ } a->rename_lock = 1; au_pin_hdir_unlock(&a->mvd_pin_dst); err = au_pin(&a->mvd_pin_src, a->dentry, a->mvd_bsrc, au_opt_udba(a->sb), AuPin_MNT_WRITE | AuPin_DI_LOCKED); AuTraceErr(err); a->mvd_h_src_dir = d_inode(a->mvd_h_src_parent); if (unlikely(err)) { AU_MVD_PR(dmsg, "pin_src failed\n"); au_pin_hdir_lock(&a->mvd_pin_dst); goto out_dst; } au_pin_hdir_unlock(&a->mvd_pin_src); h_trap = vfsub_lock_rename(a->mvd_h_src_parent, a->mvd_hdir_src, a->mvd_h_dst_parent, a->mvd_hdir_dst); if (h_trap) { err = (h_trap != a->mvd_h_src_parent); if (err) err = (h_trap != a->mvd_h_dst_parent); } BUG_ON(err); /* it should never happen */ if (unlikely(a->mvd_h_src_dir != au_pinned_h_dir(&a->mvd_pin_src))) { err = -EBUSY; AuTraceErr(err); vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src, a->mvd_h_dst_parent, a->mvd_hdir_dst); au_pin_hdir_lock(&a->mvd_pin_src); au_unpin(&a->mvd_pin_src); au_pin_hdir_lock(&a->mvd_pin_dst); goto out_dst; } goto out; /* success */ out_dst: au_unpin(&a->mvd_pin_dst); out: AuTraceErr(err); return err; }