Esempio n. 1
0
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);
}
Esempio n. 2
0
/* 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;
}