static void au_ren_rev_whtmp(int err, struct au_ren_args *a) { int rerr; a->h_path.dentry = au_lkup_one(&a->dst_dentry->d_name, a->dst_h_parent, a->br, /*nd*/NULL); rerr = PTR_ERR(a->h_path.dentry); if (IS_ERR(a->h_path.dentry)) { RevertFailure("lookup %.*s", AuDLNPair(a->dst_dentry)); return; } if (a->h_path.dentry->d_inode) { d_drop(a->h_path.dentry); dput(a->h_path.dentry); return; } rerr = vfsub_rename(a->dst_h_dir, a->h_dst, a->dst_h_dir, &a->h_path); d_drop(a->h_path.dentry); dput(a->h_path.dentry); if (!rerr) au_set_h_dptr(a->dst_dentry, a->btgt, dget(a->h_dst)); else RevertFailure("rename %.*s", AuDLNPair(a->h_dst)); }
/* * rename the @h_dentry on @br to the whiteouted temporary name. */ int au_whtmp_ren(struct dentry *h_dentry, struct au_branch *br) { int err; struct path h_path = { .mnt = au_br_mnt(br) }; struct inode *h_dir; struct dentry *h_parent; h_parent = h_dentry->d_parent; /* dir inode is locked */ h_dir = h_parent->d_inode; IMustLock(h_dir); h_path.dentry = au_whtmp_lkup(h_parent, br, &h_dentry->d_name); err = PTR_ERR(h_path.dentry); if (IS_ERR(h_path.dentry)) goto out; /* under the same dir, no need to lock_rename() */ err = vfsub_rename(h_dir, h_dentry, h_dir, &h_path); AuTraceErr(err); dput(h_path.dentry); out: AuTraceErr(err); return err; }
/* * when we have to copyup the renaming entry, do it with the rename-target name * in order to minimize the cost (the later actual rename is unnecessary). * otherwise rename it on the target branch. */ static int au_ren_or_cpup(struct au_ren_args *a) { int err; struct dentry *d; d = a->src_dentry; if (au_dbstart(d) == a->btgt) { a->h_path.dentry = a->dst_h_dentry; if (au_ftest_ren(a->flags, DIROPQ) && au_dbdiropq(d) == a->btgt) au_fclr_ren(a->flags, DIROPQ); AuDebugOn(au_dbstart(d) != a->btgt); err = vfsub_rename(a->src_h_dir, au_h_dptr(d, a->btgt), a->dst_h_dir, &a->h_path); } else { struct mutex *h_mtx = &a->src_h_dentry->d_inode->i_mutex; struct file *h_file; au_fset_ren(a->flags, CPUP); mutex_lock_nested(h_mtx, AuLsc_I_CHILD); au_set_dbstart(d, a->btgt); au_set_h_dptr(d, a->btgt, dget(a->dst_h_dentry)); h_file = au_h_open_pre(d, a->src_bstart); if (IS_ERR(h_file)) { err = PTR_ERR(h_file); h_file = NULL; } else err = au_sio_cpup_single(d, a->btgt, a->src_bstart, -1, !AuCpup_DTIME, a->dst_parent); mutex_unlock(h_mtx); au_h_open_post(d, a->src_bstart, h_file); if (!err) { d = a->dst_dentry; au_set_h_dptr(d, a->btgt, NULL); au_update_dbstart(d); } else { au_set_h_dptr(d, a->btgt, NULL); au_set_dbstart(d, a->src_bstart); } } if (!err && a->h_dst) /* it will be set to dinfo later */ dget(a->h_dst); return err; }
static void au_ren_rev_rename(int err, struct au_ren_args *a) { int rerr; a->h_path.dentry = au_lkup_one(&a->src_dentry->d_name, a->src_h_parent, a->br, /*nd*/NULL); rerr = PTR_ERR(a->h_path.dentry); if (IS_ERR(a->h_path.dentry)) { RevertFailure("au_lkup_one %.*s", AuDLNPair(a->src_dentry)); return; } rerr = vfsub_rename(a->dst_h_dir, au_h_dptr(a->src_dentry, a->btgt), a->src_h_dir, &a->h_path); d_drop(a->h_path.dentry); dput(a->h_path.dentry); /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */ if (rerr) RevertFailure("rename %.*s", AuDLNPair(a->src_dentry)); }