diff options
Diffstat (limited to 'fs/aufs/mvdown.c')
-rw-r--r-- | fs/aufs/mvdown.c | 21 |
1 files changed, 15 insertions, 6 deletions
diff --git a/fs/aufs/mvdown.c b/fs/aufs/mvdown.c index bec20d360..53e0f6af9 100644 --- a/fs/aufs/mvdown.c +++ b/fs/aufs/mvdown.c @@ -353,6 +353,12 @@ static int au_do_mvdown(const unsigned char dmsg, struct au_mvd_args *a) au_set_dbstart(a->dentry, a->mvd_bdst); au_set_h_iptr(a->inode, a->mvd_bsrc, NULL, /*flags*/0); au_set_ibstart(a->inode, a->mvd_bdst); + } else { + /* hide the lower */ + au_set_h_dptr(a->dentry, a->mvd_bdst, NULL); + au_set_dbend(a->dentry, a->mvd_bsrc); + au_set_h_iptr(a->inode, a->mvd_bdst, NULL, /*flags*/0); + au_set_ibend(a->inode, a->mvd_bsrc); } if (au_dbend(a->dentry) < a->mvd_bdst) au_set_dbend(a->dentry, a->mvd_bdst); @@ -608,7 +614,9 @@ int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *uarg) int err, e; unsigned char dmsg; struct au_mvd_args *args; + struct inode *inode; + inode = d_inode(dentry); err = -EPERM; if (unlikely(!capable(CAP_SYS_ADMIN))) goto out; @@ -630,7 +638,7 @@ int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *uarg) args->mvdown.flags &= ~(AUFS_MVDOWN_ROLOWER_R | AUFS_MVDOWN_ROUPPER_R); args->mvdown.au_errno = 0; args->dentry = dentry; - args->inode = d_inode(dentry); + args->inode = inode; args->sb = dentry->d_sb; err = -ENOENT; @@ -644,8 +652,8 @@ int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *uarg) goto out_dir; } - mutex_lock_nested(&args->inode->i_mutex, I_MUTEX_CHILD); - err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH); + mutex_lock_nested(&inode->i_mutex, I_MUTEX_CHILD); + err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_NOPLMW); if (unlikely(err)) goto out_inode; @@ -659,15 +667,16 @@ int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *uarg) goto out_parent; au_cpup_attr_timesizes(args->dir); - au_cpup_attr_timesizes(args->inode); - au_cpup_igen(args->inode, au_h_iptr(args->inode, args->mvd_bdst)); + au_cpup_attr_timesizes(inode); + if (!(args->mvdown.flags & AUFS_MVDOWN_KUPPER)) + au_cpup_igen(inode, au_h_iptr(inode, args->mvd_bdst)); /* au_digen_dec(dentry); */ out_parent: di_write_unlock(args->parent); aufs_read_unlock(dentry, AuLock_DW); out_inode: - mutex_unlock(&args->inode->i_mutex); + mutex_unlock(&inode->i_mutex); out_dir: mutex_unlock(&args->dir->i_mutex); out_free: |