From 253f2f851644ed9bd6a329cd2a600f3b1abb1375 Mon Sep 17 00:00:00 2001 From: Ben Hutchings Date: Sat, 31 Aug 2013 17:52:31 +0000 Subject: [PATCH] aufs: Update to aufs3.10-20130826 With a minor security fix to it: aufs: mvdown, don't let unprivileged users provoke a WARNING svn path=/dists/sid/linux/; revision=20535 --- debian/changelog | 2 + ...t-let-unprivileged-users-provoke-a-W.patch | 38 + .../features/all/aufs3/aufs3-add.patch | 1639 ++++++++++++----- .../features/all/aufs3/aufs3-base.patch | 2 +- .../features/all/aufs3/aufs3-kbuild.patch | 2 +- .../features/all/aufs3/aufs3-standalone.patch | 2 +- debian/patches/series | 2 + 7 files changed, 1212 insertions(+), 475 deletions(-) create mode 100644 debian/patches/features/all/aufs3/aufs-mvdown-don-t-let-unprivileged-users-provoke-a-W.patch diff --git a/debian/changelog b/debian/changelog index e3b8fc936..1f35c0ace 100644 --- a/debian/changelog +++ b/debian/changelog @@ -53,6 +53,8 @@ linux (3.10.10-1) UNRELEASED; urgency=low - simple-wait: Fix a race condition with swait wakeups vs adding items to the list - rcu: Use swait_wake_all() in rcu_nocb_gp_cleanup() + * aufs: Update to aufs3.10-20130826 + * aufs: mvdown, don't let unprivileged users provoke a WARNING -- Ben Hutchings Fri, 30 Aug 2013 02:31:22 +0100 diff --git a/debian/patches/features/all/aufs3/aufs-mvdown-don-t-let-unprivileged-users-provoke-a-W.patch b/debian/patches/features/all/aufs3/aufs-mvdown-don-t-let-unprivileged-users-provoke-a-W.patch new file mode 100644 index 000000000..fe5732b28 --- /dev/null +++ b/debian/patches/features/all/aufs3/aufs-mvdown-don-t-let-unprivileged-users-provoke-a-W.patch @@ -0,0 +1,38 @@ +From: Ben Hutchings +Date: Sat, 31 Aug 2013 18:34:51 +0100 +Subject: aufs: mvdown, don't let unprivileged users provoke a WARNING +Forwarded: + +Move the WARN_ONCE() about mvdown after the capability check. + +Signed-off-by: Ben Hutchings +--- + fs/aufs/ioctl.c | 1 - + fs/aufs/mvdown.c | 2 ++ + 2 files changed, 2 insertions(+), 1 deletion(-) + +diff --git a/fs/aufs/ioctl.c b/fs/aufs/ioctl.c +index 628d627..1ac7688 100644 +--- a/fs/aufs/ioctl.c ++++ b/fs/aufs/ioctl.c +@@ -152,7 +152,6 @@ long aufs_ioctl_nondir(struct file *file, unsigned int cmd, unsigned long arg) + + switch (cmd) { + case AUFS_CTL_MVDOWN: +- WARN_ONCE(1, "move-down is still testing...\n"); + err = au_mvdown(file->f_dentry, (void __user *)arg); + break; + +diff --git a/fs/aufs/mvdown.c b/fs/aufs/mvdown.c +index e68002e..5f56645 100644 +--- a/fs/aufs/mvdown.c ++++ b/fs/aufs/mvdown.c +@@ -489,6 +489,8 @@ int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *uarg) + if (unlikely(!capable(CAP_SYS_ADMIN))) + goto out; + ++ WARN_ONCE(1, "move-down is still testing...\n"); ++ + err = -ENOMEM; + args = kmalloc(sizeof(*args), GFP_NOFS); + if (unlikely(!args)) diff --git a/debian/patches/features/all/aufs3/aufs3-add.patch b/debian/patches/features/all/aufs3/aufs3-add.patch index 15108a6ac..2a83fb1b6 100644 --- a/debian/patches/features/all/aufs3/aufs3-add.patch +++ b/debian/patches/features/all/aufs3/aufs3-add.patch @@ -1,13 +1,13 @@ From: J. R. Okajima -Date: Fri Aug 2 20:51:57 2013 +0900 -Subject: aufs3.10-20130805 -Origin: http://sourceforge.net/p/aufs/aufs3-standalone/ci/a1069fdacd4c7e2650d1616c172465c74260600f/tree/ +Date: Wed Aug 21 18:26:50 2013 +0900 +Subject: aufs3.10-20130826 +Origin: http://sourceforge.net/p/aufs/aufs3-standalone/ci/20e965e7cd385ace8c9c36e64673479eeefe379e/tree/ Bug-Debian: http://bugs.debian.org/541828 Patch generated by debian/patches/features/all/aufs3/gen-patch --- a/Documentation/ABI/testing/debugfs-aufs 1970-01-01 01:00:00.000000000 +0100 -+++ b/Documentation/ABI/testing/debugfs-aufs 2013-06-02 19:23:34.749538984 +0200 ++++ b/Documentation/ABI/testing/debugfs-aufs 2013-06-02 18:23:34.749538984 +0100 @@ -0,0 +1,50 @@ +What: /debug/aufs/si_/ +Date: March 2009 @@ -60,7 +60,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + When the aufs mount option 'noxino' is specified, it + will be empty. About XINO files, see the aufs manual. --- a/Documentation/ABI/testing/sysfs-aufs 1970-01-01 01:00:00.000000000 +0100 -+++ b/Documentation/ABI/testing/sysfs-aufs 2012-01-10 03:15:56.000000000 +0100 ++++ b/Documentation/ABI/testing/sysfs-aufs 2012-01-10 02:15:56.000000000 +0000 @@ -0,0 +1,24 @@ +What: /sys/fs/aufs/si_/ +Date: March 2009 @@ -87,7 +87,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + When the aufs mount option 'noxino' is specified, it + will be empty. About XINO files, see the aufs manual. --- a/Documentation/filesystems/aufs/README 1970-01-01 01:00:00.000000000 +0100 -+++ b/Documentation/filesystems/aufs/README 2013-08-07 15:04:57.879008639 +0200 ++++ b/Documentation/filesystems/aufs/README 2013-08-07 14:04:57.879008639 +0100 @@ -0,0 +1,346 @@ + +Aufs3 -- advanced multi layered unification filesystem version 3.x @@ -436,7 +436,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +# mode: text; +# End: ; --- a/Documentation/filesystems/aufs/design/01intro.txt 1970-01-01 01:00:00.000000000 +0100 -+++ b/Documentation/filesystems/aufs/design/01intro.txt 2013-03-10 02:48:58.459093058 +0100 ++++ b/Documentation/filesystems/aufs/design/01intro.txt 2013-03-10 01:48:58.459093058 +0000 @@ -0,0 +1,162 @@ + +# Copyright (C) 2005-2013 Junjiro R. Okajima @@ -601,8 +601,8 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +helper, instead of doing in kernel space. Actually I am still thinking +about it. But currently I have implemented it in kernel space. --- a/Documentation/filesystems/aufs/design/02struct.txt 1970-01-01 01:00:00.000000000 +0100 -+++ b/Documentation/filesystems/aufs/design/02struct.txt 2013-03-10 02:48:58.459093058 +0100 -@@ -0,0 +1,226 @@ ++++ b/Documentation/filesystems/aufs/design/02struct.txt 2013-08-31 18:37:45.995378498 +0100 +@@ -0,0 +1,243 @@ + +# Copyright (C) 2005-2013 Junjiro R. Okajima +# @@ -829,8 +829,25 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +internally and makes change to the new file on the upper writable branch. +When the trigger systemcall does not update the timestamps of the parent +dir, aufs reverts it after copy-up. ++ ++ ++Move-down (aufs3.9 and later) ++---------------------------------------------------------------------- ++"Copy-up" is one of the essential feature in aufs. It copies a file from ++the lower readonly branch to the upper writable branch when a user ++changes something about the file. ++"Move-down" is an opposite action of copy-up. Basically this action is ++ran manually instead of automatically and internally. ++ ++Sometimes users want to move-down a file from the upper writable branch ++to the lower readonly or writable branch. For instance, ++- the free space of the upper writable branch is going to run out. ++- create a new intermediate branch between the upper and lower branch. ++- etc. ++ ++For this purpose, use "aumvdown" command in aufs-util.git. --- a/Documentation/filesystems/aufs/design/03lookup.txt 1970-01-01 01:00:00.000000000 +0100 -+++ b/Documentation/filesystems/aufs/design/03lookup.txt 2013-03-10 02:48:58.459093058 +0100 ++++ b/Documentation/filesystems/aufs/design/03lookup.txt 2013-03-10 01:48:58.459093058 +0000 @@ -0,0 +1,106 @@ + +# Copyright (C) 2005-2013 Junjiro R. Okajima @@ -939,7 +956,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + aufs performance when system surely hide the aufs branches from user, + by over-mounting something (or another method). --- a/Documentation/filesystems/aufs/design/04branch.txt 1970-01-01 01:00:00.000000000 +0100 -+++ b/Documentation/filesystems/aufs/design/04branch.txt 2013-03-10 02:48:58.459093058 +0100 ++++ b/Documentation/filesystems/aufs/design/04branch.txt 2013-03-10 01:48:58.459093058 +0000 @@ -0,0 +1,76 @@ + +# Copyright (C) 2005-2013 Junjiro R. Okajima @@ -1018,7 +1035,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + - a regular file on the branch is opened for write and there is no + same named entry on the upper branch. --- a/Documentation/filesystems/aufs/design/05wbr_policy.txt 1970-01-01 01:00:00.000000000 +0100 -+++ b/Documentation/filesystems/aufs/design/05wbr_policy.txt 2013-03-10 02:48:58.459093058 +0100 ++++ b/Documentation/filesystems/aufs/design/05wbr_policy.txt 2013-03-10 01:48:58.459093058 +0000 @@ -0,0 +1,65 @@ + +# Copyright (C) 2005-2013 Junjiro R. Okajima @@ -1086,7 +1103,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + one. If the selected branch is readonly, then aufs follows the + copyup policy. --- a/Documentation/filesystems/aufs/design/06mmap.txt 1970-01-01 01:00:00.000000000 +0100 -+++ b/Documentation/filesystems/aufs/design/06mmap.txt 2013-03-10 02:48:58.459093058 +0100 ++++ b/Documentation/filesystems/aufs/design/06mmap.txt 2013-03-10 01:48:58.459093058 +0000 @@ -0,0 +1,47 @@ + +# Copyright (C) 2005-2013 Junjiro R. Okajima @@ -1136,7 +1153,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +approach, aufs met a hard problem and I could not solve it without +switching the approach. --- a/Documentation/filesystems/aufs/design/07export.txt 1970-01-01 01:00:00.000000000 +0100 -+++ b/Documentation/filesystems/aufs/design/07export.txt 2013-03-10 02:48:58.459093058 +0100 ++++ b/Documentation/filesystems/aufs/design/07export.txt 2013-03-10 01:48:58.459093058 +0000 @@ -0,0 +1,59 @@ + +# Copyright (C) 2005-2013 Junjiro R. Okajima @@ -1198,7 +1215,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +- readdir(): call lockdep_on/off() because filldir in NFSD calls + lookup_one_len(), vfs_getattr(), encode_fh() and others. --- a/Documentation/filesystems/aufs/design/08shwh.txt 1970-01-01 01:00:00.000000000 +0100 -+++ b/Documentation/filesystems/aufs/design/08shwh.txt 2013-03-10 02:48:58.459093058 +0100 ++++ b/Documentation/filesystems/aufs/design/08shwh.txt 2013-03-10 01:48:58.459093058 +0000 @@ -0,0 +1,53 @@ + +# Copyright (C) 2005-2013 Junjiro R. Okajima @@ -1254,7 +1271,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +This new squashfs archive can be stored on the boot device and the +initramfs will use it to replace the old one at the next boot. --- a/Documentation/filesystems/aufs/design/10dynop.txt 1970-01-01 01:00:00.000000000 +0100 -+++ b/Documentation/filesystems/aufs/design/10dynop.txt 2013-03-10 02:48:58.459093058 +0100 ++++ b/Documentation/filesystems/aufs/design/10dynop.txt 2013-03-10 01:48:58.459093058 +0000 @@ -0,0 +1,47 @@ + +# Copyright (C) 2010-2013 Junjiro R. Okajima @@ -1304,7 +1321,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +Currently this approach is applied to file_operations and +vm_operations_struct for regular files only. --- a/Documentation/filesystems/aufs/design/99plan.txt 1970-01-01 01:00:00.000000000 +0100 -+++ b/Documentation/filesystems/aufs/design/99plan.txt 2013-03-10 02:48:58.459093058 +0100 ++++ b/Documentation/filesystems/aufs/design/99plan.txt 2013-03-10 01:48:58.459093058 +0000 @@ -0,0 +1,96 @@ + +# Copyright (C) 2005-2013 Junjiro R. Okajima @@ -1403,7 +1420,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +/new. +Otherwise from /new. --- a/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/Kconfig 2013-08-07 15:04:57.883008639 +0200 ++++ b/fs/aufs/Kconfig 2013-08-31 18:32:36.447371122 +0100 @@ -0,0 +1,202 @@ +config AUFS_FS + tristate "Aufs (Advanced multi layered unification filesystem) support" @@ -1608,7 +1625,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + When aufs supports Magic SysRq, enabled automatically. +endif --- a/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/Makefile 2012-08-01 04:41:52.000000000 +0200 ++++ b/fs/aufs/Makefile 2013-08-31 18:37:45.995378498 +0100 @@ -0,0 +1,42 @@ + +include ${src}/magic.mk @@ -1636,7 +1653,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + finfo.o file.o f_op.o \ + dir.o vdir.o \ + iinfo.o inode.o i_op.o i_op_add.o i_op_del.o i_op_ren.o \ -+ ioctl.o ++ mvdown.o ioctl.o + +# all are boolean +aufs-$(CONFIG_PROC_FS) += procfs.o plink.o @@ -1653,7 +1670,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +aufs-$(CONFIG_AUFS_DEBUG) += debug.o +aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o --- a/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/aufs.h 2013-03-10 02:48:58.459093058 +0100 ++++ b/fs/aufs/aufs.h 2013-03-10 01:48:58.459093058 +0000 @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -1716,7 +1733,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#endif /* __KERNEL__ */ +#endif /* __AUFS_H__ */ --- a/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/branch.c 2013-08-07 15:04:57.883008639 +0200 ++++ b/fs/aufs/branch.c 2013-08-31 18:37:41.071378381 +0100 @@ -0,0 +1,1213 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -2932,7 +2949,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + return err; +} --- a/fs/aufs/branch.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/branch.h 2013-08-07 15:04:57.883008639 +0200 ++++ b/fs/aufs/branch.h 2013-08-07 14:04:57.883008639 +0100 @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -3190,7 +3207,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#endif /* __KERNEL__ */ +#endif /* __AUFS_BRANCH_H__ */ --- a/fs/aufs/conf.mk 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/conf.mk 2012-01-10 03:15:56.000000000 +0100 ++++ b/fs/aufs/conf.mk 2012-01-10 02:15:56.000000000 +0000 @@ -0,0 +1,38 @@ + +AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS} @@ -3231,8 +3248,8 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + +-include ${srctree}/${src}/conf_priv.mk --- a/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/cpup.c 2013-08-07 15:04:57.883008639 +0200 -@@ -0,0 +1,1232 @@ ++++ b/fs/aufs/cpup.c 2013-08-31 18:37:45.995378498 +0100 +@@ -0,0 +1,1266 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima + * @@ -3584,7 +3601,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + * to support a sparse file which is opened with O_APPEND, + * we need to close the file. + */ -+static int au_cp_regular(struct au_cpup_basic *basic) ++static int au_cp_regular(struct au_cp_generic *cpg) +{ + int err, i; + enum { SRC, DST }; @@ -3596,14 +3613,14 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + void *label, *label_file; + } *f, file[] = { + { -+ .bindex = basic->bsrc, ++ .bindex = cpg->bsrc, + .flags = O_RDONLY | O_NOATIME | O_LARGEFILE, + .file = NULL, + .label = &&out, + .label_file = &&out_src + }, + { -+ .bindex = basic->bdst, ++ .bindex = cpg->bdst, + .flags = O_WRONLY | O_NOATIME | O_LARGEFILE, + .file = NULL, + .label = &&out_src, @@ -3613,11 +3630,11 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + struct super_block *sb; + + /* bsrc branch can be ro/rw. */ -+ sb = basic->dentry->d_sb; ++ sb = cpg->dentry->d_sb; + f = file; + for (i = 0; i < 2; i++, f++) { -+ f->dentry = au_h_dptr(basic->dentry, f->bindex); -+ f->file = au_h_open(basic->dentry, f->bindex, f->flags, ++ f->dentry = au_h_dptr(cpg->dentry, f->bindex); ++ f->file = au_h_open(cpg->dentry, f->bindex, f->flags, + /*file*/NULL); + err = PTR_ERR(f->file); + if (IS_ERR(f->file)) @@ -3629,7 +3646,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + + /* try stopping to update while we copyup */ + IMustLock(file[SRC].dentry->d_inode); -+ err = au_copy_file(file[DST].file, file[SRC].file, basic->len); ++ err = au_copy_file(file[DST].file, file[SRC].file, cpg->len); + +out_dst: + fput(file[DST].file); @@ -3641,7 +3658,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + return err; +} + -+static int au_do_cpup_regular(struct au_cpup_basic *basic, struct au_pin *pin, ++static int au_do_cpup_regular(struct au_cp_generic *cpg, + struct au_cpup_reg_attr *h_src_attr) +{ + int err, rerr; @@ -3650,17 +3667,17 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + struct inode *h_src_inode; + + err = 0; -+ h_src_inode = au_h_iptr(basic->dentry->d_inode, basic->bsrc); ++ h_src_inode = au_h_iptr(cpg->dentry->d_inode, cpg->bsrc); + l = i_size_read(h_src_inode); -+ if (basic->len == -1 || l < basic->len) -+ basic->len = l; -+ if (basic->len) { ++ if (cpg->len == -1 || l < cpg->len) ++ cpg->len = l; ++ if (cpg->len) { + /* try stopping to update while we are referencing */ + mutex_lock_nested(&h_src_inode->i_mutex, AuLsc_I_CHILD); -+ au_pin_hdir_unlock(pin); ++ au_pin_hdir_unlock(cpg->pin); + -+ h_path.dentry = au_h_dptr(basic->dentry, basic->bsrc); -+ h_path.mnt = au_sbr_mnt(basic->dentry->d_sb, basic->bsrc); ++ h_path.dentry = au_h_dptr(cpg->dentry, cpg->bsrc); ++ h_path.mnt = au_sbr_mnt(cpg->dentry->d_sb, cpg->bsrc); + h_src_attr->iflags = h_src_inode->i_flags; + err = vfs_getattr(&h_path, &h_src_attr->st); + if (unlikely(err)) { @@ -3668,9 +3685,9 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + goto out; + } + h_src_attr->valid = 1; -+ err = au_cp_regular(basic); ++ err = au_cp_regular(cpg); + mutex_unlock(&h_src_inode->i_mutex); -+ rerr = au_pin_hdir_relock(pin); ++ rerr = au_pin_hdir_relock(cpg->pin); + if (!err && rerr) + err = rerr; + } @@ -3716,15 +3733,14 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +} + +static noinline_for_stack -+int cpup_entry(struct au_cpup_basic *basic, unsigned int flags, -+ struct dentry *dst_parent, struct au_pin *pin, ++int cpup_entry(struct au_cp_generic *cpg, struct dentry *dst_parent, + struct au_cpup_reg_attr *h_src_attr) +{ + int err; + umode_t mode; + unsigned int mnt_flags; + unsigned char isdir; -+ const unsigned char do_dt = !!au_ftest_cpup(flags, DTIME); ++ const unsigned char do_dt = !!au_ftest_cpup(cpg->flags, DTIME); + struct au_dtime dt; + struct path h_path; + struct dentry *h_src, *h_dst, *h_parent; @@ -3732,13 +3748,13 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + struct super_block *sb; + + /* bsrc branch can be ro/rw. */ -+ h_src = au_h_dptr(basic->dentry, basic->bsrc); ++ h_src = au_h_dptr(cpg->dentry, cpg->bsrc); + h_inode = h_src->d_inode; -+ AuDebugOn(h_inode != au_h_iptr(basic->dentry->d_inode, basic->bsrc)); ++ AuDebugOn(h_inode != au_h_iptr(cpg->dentry->d_inode, cpg->bsrc)); + + /* try stopping to be referenced while we are creating */ -+ h_dst = au_h_dptr(basic->dentry, basic->bdst); -+ if (au_ftest_cpup(flags, RENAME)) ++ h_dst = au_h_dptr(cpg->dentry, cpg->bdst); ++ if (au_ftest_cpup(cpg->flags, RENAME)) + AuDebugOn(strncmp(h_dst->d_name.name, AUFS_WH_PFX, + AUFS_WH_PFX_LEN)); + h_parent = h_dst->d_parent; /* dir inode is locked */ @@ -3746,8 +3762,8 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + IMustLock(h_dir); + AuDebugOn(h_parent != h_dst->d_parent); + -+ sb = basic->dentry->d_sb; -+ h_path.mnt = au_sbr_mnt(sb, basic->bdst); ++ sb = cpg->dentry->d_sb; ++ h_path.mnt = au_sbr_mnt(sb, cpg->bdst); + if (do_dt) { + h_path.dentry = h_parent; + au_dtime_store(&dt, dst_parent, &h_path); @@ -3761,7 +3777,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + err = vfsub_create(h_dir, &h_path, mode | S_IWUSR, + /*want_excl*/true); + if (!err) -+ err = au_do_cpup_regular(basic, pin, h_src_attr); ++ err = au_do_cpup_regular(cpg, h_src_attr); + break; + case S_IFDIR: + isdir = 1; @@ -3771,10 +3787,10 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + * strange behaviour from the users view, + * particularry setattr case + */ -+ if (au_ibstart(dst_parent->d_inode) == basic->bdst) ++ if (au_ibstart(dst_parent->d_inode) == cpg->bdst) + au_cpup_attr_nlink(dst_parent->d_inode, + /*force*/1); -+ au_cpup_attr_nlink(basic->dentry->d_inode, /*force*/1); ++ au_cpup_attr_nlink(cpg->dentry->d_inode, /*force*/1); + } + break; + case S_IFLNK: @@ -3799,10 +3815,10 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + && au_opt_test(mnt_flags, XINO) + && h_inode->i_nlink == 1 + /* todo: unnecessary? */ -+ /* && basic->dentry->d_inode->i_nlink == 1 */ -+ && basic->bdst < basic->bsrc -+ && !au_ftest_cpup(flags, KEEPLINO)) -+ au_xino_write(sb, basic->bsrc, h_inode->i_ino, /*ino*/0); ++ /* && cpg->dentry->d_inode->i_nlink == 1 */ ++ && cpg->bdst < cpg->bsrc ++ && !au_ftest_cpup(cpg->flags, KEEPLINO)) ++ au_xino_write(sb, cpg->bsrc, h_inode->i_ino, /*ino*/0); + /* ignore this error */ + + if (do_dt) @@ -3810,23 +3826,35 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + return err; +} + -+static int au_do_ren_after_cpup(struct dentry *dentry, aufs_bindex_t bdst, -+ struct path *h_path) ++static int au_do_ren_after_cpup(struct au_cp_generic *cpg, struct path *h_path) +{ + int err; -+ struct dentry *h_dentry, *h_parent; ++ struct dentry *dentry, *h_dentry, *h_parent, *parent; + struct inode *h_dir; ++ aufs_bindex_t bdst; + -+ h_dentry = dget(au_h_dptr(dentry, bdst)); -+ au_set_h_dptr(dentry, bdst, NULL); -+ err = au_lkup_neg(dentry, bdst, /*wh*/0); -+ if (unlikely(err)) { ++ dentry = cpg->dentry; ++ bdst = cpg->bdst; ++ h_dentry = au_h_dptr(dentry, bdst); ++ if (!au_ftest_cpup(cpg->flags, OVERWRITE)) { ++ dget(h_dentry); ++ au_set_h_dptr(dentry, bdst, NULL); ++ err = au_lkup_neg(dentry, bdst, /*wh*/0); ++ if (!err) ++ h_path->dentry = dget(au_h_dptr(dentry, bdst)); + au_set_h_dptr(dentry, bdst, h_dentry); -+ goto out; ++ } else { ++ err = 0; ++ parent = dget_parent(dentry); ++ h_parent = au_h_dptr(parent, bdst); ++ dput(parent); ++ h_path->dentry = vfsub_lkup_one(&dentry->d_name, h_parent); ++ if (IS_ERR(h_path->dentry)) ++ err = PTR_ERR(h_path->dentry); + } ++ if (unlikely(err)) ++ goto out; + -+ h_path->dentry = dget(au_h_dptr(dentry, bdst)); -+ au_set_h_dptr(dentry, bdst, h_dentry); + h_parent = h_dentry->d_parent; /* dir inode is locked */ + h_dir = h_parent->d_inode; + IMustLock(h_dir); @@ -3843,82 +3871,86 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + * the caller must set the both of lower dentries. + * @len is for truncating when it is -1 copyup the entire file. + * in link/rename cases, @dst_parent may be different from the real one. ++ * basic->bsrc can be larger than basic->bdst. + */ -+static int au_cpup_single(struct au_cpup_basic *basic, unsigned int flags, -+ struct dentry *dst_parent, struct au_pin *pin) ++static int au_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent) +{ + int err, rerr; + aufs_bindex_t old_ibstart; + unsigned char isdir, plink; -+ struct au_dtime dt; -+ struct path h_path; + struct dentry *h_src, *h_dst, *h_parent; + struct inode *dst_inode, *h_dir, *inode; + struct super_block *sb; + struct au_branch *br; -+ struct au_cpup_reg_attr h_src_attr = { -+ .valid = 0 -+ }; ++ /* to reuduce stack size */ ++ struct { ++ struct au_dtime dt; ++ struct path h_path; ++ struct au_cpup_reg_attr h_src_attr; ++ } *a; + -+ AuDebugOn(basic->bsrc <= basic->bdst); ++ err = -ENOMEM; ++ a = kmalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ a->h_src_attr.valid = 0; + -+ sb = basic->dentry->d_sb; -+ br = au_sbr(sb, basic->bdst); -+ h_path.mnt = au_br_mnt(br); -+ h_dst = au_h_dptr(basic->dentry, basic->bdst); ++ sb = cpg->dentry->d_sb; ++ br = au_sbr(sb, cpg->bdst); ++ a->h_path.mnt = au_br_mnt(br); ++ h_dst = au_h_dptr(cpg->dentry, cpg->bdst); + h_parent = h_dst->d_parent; /* dir inode is locked */ + h_dir = h_parent->d_inode; + IMustLock(h_dir); + -+ h_src = au_h_dptr(basic->dentry, basic->bsrc); -+ inode = basic->dentry->d_inode; ++ h_src = au_h_dptr(cpg->dentry, cpg->bsrc); ++ inode = cpg->dentry->d_inode; + + if (!dst_parent) -+ dst_parent = dget_parent(basic->dentry); ++ dst_parent = dget_parent(cpg->dentry); + else + dget(dst_parent); + + plink = !!au_opt_test(au_mntflags(sb), PLINK); -+ dst_inode = au_h_iptr(inode, basic->bdst); ++ dst_inode = au_h_iptr(inode, cpg->bdst); + if (dst_inode) { + if (unlikely(!plink)) { + err = -EIO; + AuIOErr("hi%lu(i%lu) exists on b%d " + "but plink is disabled\n", -+ dst_inode->i_ino, inode->i_ino, basic->bdst); -+ goto out; ++ dst_inode->i_ino, inode->i_ino, cpg->bdst); ++ goto out_parent; + } + + if (dst_inode->i_nlink) { -+ const int do_dt = au_ftest_cpup(flags, DTIME); ++ const int do_dt = au_ftest_cpup(cpg->flags, DTIME); + -+ h_src = au_plink_lkup(inode, basic->bdst); ++ h_src = au_plink_lkup(inode, cpg->bdst); + err = PTR_ERR(h_src); + if (IS_ERR(h_src)) -+ goto out; ++ goto out_parent; + if (unlikely(!h_src->d_inode)) { + err = -EIO; + AuIOErr("i%lu exists on a upper branch " + "but not pseudo-linked\n", + inode->i_ino); + dput(h_src); -+ goto out; ++ goto out_parent; + } + + if (do_dt) { -+ h_path.dentry = h_parent; -+ au_dtime_store(&dt, dst_parent, &h_path); ++ a->h_path.dentry = h_parent; ++ au_dtime_store(&a->dt, dst_parent, &a->h_path); + } + -+ h_path.dentry = h_dst; -+ err = vfsub_link(h_src, h_dir, &h_path); -+ if (!err && au_ftest_cpup(flags, RENAME)) -+ err = au_do_ren_after_cpup -+ (basic->dentry, basic->bdst, &h_path); ++ a->h_path.dentry = h_dst; ++ err = vfsub_link(h_src, h_dir, &a->h_path); ++ if (!err && au_ftest_cpup(cpg->flags, RENAME)) ++ err = au_do_ren_after_cpup(cpg, &a->h_path); + if (do_dt) -+ au_dtime_revert(&dt); ++ au_dtime_revert(&a->dt); + dput(h_src); -+ goto out; ++ goto out_parent; + } else + /* todo: cpup_wh_file? */ + /* udba work */ @@ -3927,38 +3959,40 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + + isdir = S_ISDIR(inode->i_mode); + old_ibstart = au_ibstart(inode); -+ err = cpup_entry(basic, flags, dst_parent, pin, &h_src_attr); ++ err = cpup_entry(cpg, dst_parent, &a->h_src_attr); + if (unlikely(err)) + goto out_rev; + dst_inode = h_dst->d_inode; + mutex_lock_nested(&dst_inode->i_mutex, AuLsc_I_CHILD2); + /* todo: necessary? */ -+ /* au_pin_hdir_unlock(pin); */ ++ /* au_pin_hdir_unlock(cpg->pin); */ + -+ err = cpup_iattr(basic->dentry, basic->bdst, h_src, &h_src_attr); ++ err = cpup_iattr(cpg->dentry, cpg->bdst, h_src, &a->h_src_attr); + if (unlikely(err)) { + /* todo: necessary? */ -+ /* au_pin_hdir_relock(pin); */ /* ignore an error */ ++ /* au_pin_hdir_relock(cpg->pin); */ /* ignore an error */ + mutex_unlock(&dst_inode->i_mutex); + goto out_rev; + } + -+ if (basic->bdst < old_ibstart) { ++ if (cpg->bdst < old_ibstart) { + if (S_ISREG(inode->i_mode)) { -+ err = au_dy_iaop(inode, basic->bdst, dst_inode); ++ err = au_dy_iaop(inode, cpg->bdst, dst_inode); + if (unlikely(err)) { -+ /* au_pin_hdir_relock(pin); ignore an error */ ++ /* ignore an error */ ++ /* au_pin_hdir_relock(cpg->pin); */ + mutex_unlock(&dst_inode->i_mutex); + goto out_rev; + } + } -+ au_set_ibstart(inode, basic->bdst); -+ } -+ au_set_h_iptr(inode, basic->bdst, au_igrab(dst_inode), ++ au_set_ibstart(inode, cpg->bdst); ++ } else ++ au_set_ibend(inode, cpg->bdst); ++ au_set_h_iptr(inode, cpg->bdst, au_igrab(dst_inode), + au_hi_flags(inode, isdir)); + + /* todo: necessary? */ -+ /* err = au_pin_hdir_relock(pin); */ ++ /* err = au_pin_hdir_relock(cpg->pin); */ + mutex_unlock(&dst_inode->i_mutex); + if (unlikely(err)) + goto out_rev; @@ -3966,53 +4000,53 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + if (!isdir + && h_src->d_inode->i_nlink > 1 + && plink) -+ au_plink_append(inode, basic->bdst, h_dst); ++ au_plink_append(inode, cpg->bdst, h_dst); + -+ if (au_ftest_cpup(flags, RENAME)) { -+ h_path.dentry = h_dst; -+ err = au_do_ren_after_cpup(basic->dentry, basic->bdst, &h_path); ++ if (au_ftest_cpup(cpg->flags, RENAME)) { ++ a->h_path.dentry = h_dst; ++ err = au_do_ren_after_cpup(cpg, &a->h_path); + } + if (!err) -+ goto out; /* success */ ++ goto out_parent; /* success */ + + /* revert */ +out_rev: -+ h_path.dentry = h_parent; -+ au_dtime_store(&dt, dst_parent, &h_path); -+ h_path.dentry = h_dst; ++ a->h_path.dentry = h_parent; ++ au_dtime_store(&a->dt, dst_parent, &a->h_path); ++ a->h_path.dentry = h_dst; + rerr = 0; + if (h_dst->d_inode) { + if (!isdir) -+ rerr = vfsub_unlink(h_dir, &h_path, /*force*/0); ++ rerr = vfsub_unlink(h_dir, &a->h_path, /*force*/0); + else -+ rerr = vfsub_rmdir(h_dir, &h_path); ++ rerr = vfsub_rmdir(h_dir, &a->h_path); + } -+ au_dtime_revert(&dt); ++ au_dtime_revert(&a->dt); + if (rerr) { + AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr); + err = -EIO; + } -+out: ++out_parent: + dput(dst_parent); ++ kfree(a); ++out: + return err; +} + +#if 0 /* unused */ +struct au_cpup_single_args { + int *errp; -+ struct au_cpup_basic *basic; -+ unsigned int flags; ++ struct au_cp_generic *cpg; + struct dentry *dst_parent; -+ struct au_pin *pin; +}; + +static void au_call_cpup_single(void *args) +{ + struct au_cpup_single_args *a = args; + -+ au_pin_hdir_acquire_nest(a->pin); -+ *a->errp = au_cpup_single(a->basic, a->flags, a->dst_parent, a->pin); -+ au_pin_hdir_release(a->pin); ++ au_pin_hdir_acquire_nest(a->cpg->pin); ++ *a->errp = au_cpup_single(a->cpg, a->dst_parent); ++ au_pin_hdir_release(a->cpg->pin); +} +#endif + @@ -4056,22 +4090,19 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +} + +#if 0 /* unused */ -+int au_sio_cpup_single(struct au_cpup_basic *basic, unsigned int flags, -+ struct dentry *dst_parent, struct au_pin *pin) ++int au_sio_cpup_single(struct au_cp_generic *cpg, struct dentry *dst_parent) +{ + int err, wkq_err; + struct dentry *h_dentry; + -+ h_dentry = au_h_dptr(basic->dentry, basic->bsrc); ++ h_dentry = au_h_dptr(cpg->dentry, cpg->bsrc); + if (!au_cpup_sio_test(pin, h_dentry->d_inode->i_mode)) -+ err = au_cpup_single(basic, flags, dst_parent, pin); ++ err = au_cpup_single(cpg, dst_parent); + else { + struct au_cpup_single_args args = { + .errp = &err, -+ .basic = basic, -+ .flags = flags, -+ .dst_parent = dst_parent, -+ .pin = pin ++ .cpg = cpg, ++ .dst_parent = dst_parent + }; + wkq_err = au_wkq_wait(au_call_cpup_single, &args); + if (unlikely(wkq_err)) @@ -4086,38 +4117,29 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + * copyup the @dentry from the first active lower branch to @bdst, + * using au_cpup_single(). + */ -+static int au_cpup_simple(struct au_cpup_basic *basic, unsigned int flags, -+ struct au_pin *pin) ++static int au_cpup_simple(struct au_cp_generic *cpg) +{ + int err; -+ aufs_bindex_t bsrc, bend; -+ struct dentry *dentry, *h_dentry; ++ unsigned int flags_orig; ++ struct dentry *dentry; + -+ dentry = basic->dentry; ++ AuDebugOn(cpg->bsrc < 0); ++ ++ dentry = cpg->dentry; + DiMustWriteLock(dentry); + -+ bend = au_dbend(dentry); -+ if (basic->bsrc < 0) { -+ for (bsrc = basic->bdst + 1; bsrc <= bend; bsrc++) { -+ h_dentry = au_h_dptr(dentry, bsrc); -+ if (h_dentry) { -+ AuDebugOn(!h_dentry->d_inode); -+ break; -+ } -+ } -+ AuDebugOn(bsrc > bend); -+ basic->bsrc = bsrc; -+ } -+ -+ err = au_lkup_neg(dentry, basic->bdst, /*wh*/1); ++ err = au_lkup_neg(dentry, cpg->bdst, /*wh*/1); + if (!err) { -+ err = au_cpup_single(basic, flags | AuCpup_RENAME, NULL, pin); ++ flags_orig = cpg->flags; ++ au_fset_cpup(cpg->flags, RENAME); ++ err = au_cpup_single(cpg, NULL); ++ cpg->flags = flags_orig; + if (!err) + return 0; /* success */ + + /* revert */ -+ au_set_h_dptr(dentry, basic->bdst, NULL); -+ au_set_dbstart(dentry, basic->bsrc); ++ au_set_h_dptr(dentry, cpg->bdst, NULL); ++ au_set_dbstart(dentry, cpg->bsrc); + } + + return err; @@ -4125,49 +4147,44 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + +struct au_cpup_simple_args { + int *errp; -+ struct au_cpup_basic *basic; -+ unsigned int flags; -+ struct au_pin *pin; ++ struct au_cp_generic *cpg; +}; + +static void au_call_cpup_simple(void *args) +{ + struct au_cpup_simple_args *a = args; + -+ au_pin_hdir_acquire_nest(a->pin); -+ *a->errp = au_cpup_simple(a->basic, a->flags, a->pin); -+ au_pin_hdir_release(a->pin); ++ au_pin_hdir_acquire_nest(a->cpg->pin); ++ *a->errp = au_cpup_simple(a->cpg); ++ au_pin_hdir_release(a->cpg->pin); +} + -+int au_sio_cpup_simple(struct au_cpup_basic *basic, unsigned int flags, -+ struct au_pin *pin) ++static int au_do_sio_cpup_simple(struct au_cp_generic *cpg) +{ + int err, wkq_err; + struct dentry *dentry, *parent; + struct file *h_file; + struct inode *h_dir; + -+ dentry = basic->dentry; ++ dentry = cpg->dentry; + h_file = NULL; -+ if (au_ftest_cpup(flags, HOPEN)) { -+ AuDebugOn(basic->bsrc < 0); -+ h_file = au_h_open_pre(dentry, basic->bsrc); ++ if (au_ftest_cpup(cpg->flags, HOPEN)) { ++ AuDebugOn(cpg->bsrc < 0); ++ h_file = au_h_open_pre(dentry, cpg->bsrc); + err = PTR_ERR(h_file); + if (IS_ERR(h_file)) + goto out; + } + + parent = dget_parent(dentry); -+ h_dir = au_h_iptr(parent->d_inode, basic->bdst); ++ h_dir = au_h_iptr(parent->d_inode, cpg->bdst); + if (!au_test_h_perm_sio(h_dir, MAY_EXEC | MAY_WRITE) -+ && !au_cpup_sio_test(pin, dentry->d_inode->i_mode)) -+ err = au_cpup_simple(basic, flags, pin); ++ && !au_cpup_sio_test(cpg->pin, dentry->d_inode->i_mode)) ++ err = au_cpup_simple(cpg); + else { + struct au_cpup_simple_args args = { + .errp = &err, -+ .basic = basic, -+ .flags = flags, -+ .pin = pin ++ .cpg = cpg + }; + wkq_err = au_wkq_wait(au_call_cpup_simple, &args); + if (unlikely(wkq_err)) @@ -4176,55 +4193,86 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + + dput(parent); + if (h_file) -+ au_h_open_post(dentry, basic->bsrc, h_file); ++ au_h_open_post(dentry, cpg->bsrc, h_file); + +out: + return err; +} + ++int au_sio_cpup_simple(struct au_cp_generic *cpg) ++{ ++ aufs_bindex_t bsrc, bend; ++ struct dentry *dentry, *h_dentry; ++ ++ if (cpg->bsrc < 0) { ++ dentry = cpg->dentry; ++ bend = au_dbend(dentry); ++ for (bsrc = cpg->bdst + 1; bsrc <= bend; bsrc++) { ++ h_dentry = au_h_dptr(dentry, bsrc); ++ if (h_dentry) { ++ AuDebugOn(!h_dentry->d_inode); ++ break; ++ } ++ } ++ AuDebugOn(bsrc > bend); ++ cpg->bsrc = bsrc; ++ } ++ AuDebugOn(cpg->bsrc <= cpg->bdst); ++ return au_do_sio_cpup_simple(cpg); ++} ++ ++int au_sio_cpdown_simple(struct au_cp_generic *cpg) ++{ ++ AuDebugOn(cpg->bdst <= cpg->bsrc); ++ return au_do_sio_cpup_simple(cpg); ++} ++ +/* ---------------------------------------------------------------------- */ + +/* + * copyup the deleted file for writing. + */ -+static int au_do_cpup_wh(struct au_cpup_basic *basic, struct dentry *wh_dentry, -+ struct file *file, struct au_pin *pin) ++static int au_do_cpup_wh(struct au_cp_generic *cpg, struct dentry *wh_dentry, ++ struct file *file) +{ + int err; ++ unsigned int flags_orig; + aufs_bindex_t bsrc_orig; + struct dentry *h_d_dst, *h_d_start; + struct au_dinfo *dinfo; + struct au_hdentry *hdp; + -+ dinfo = au_di(basic->dentry); ++ dinfo = au_di(cpg->dentry); + AuRwMustWriteLock(&dinfo->di_rwsem); + -+ bsrc_orig = basic->bsrc; -+ basic->bsrc = dinfo->di_bstart; ++ bsrc_orig = cpg->bsrc; ++ cpg->bsrc = dinfo->di_bstart; + hdp = dinfo->di_hdentry; -+ h_d_dst = hdp[0 + basic->bdst].hd_dentry; -+ dinfo->di_bstart = basic->bdst; -+ hdp[0 + basic->bdst].hd_dentry = wh_dentry; ++ h_d_dst = hdp[0 + cpg->bdst].hd_dentry; ++ dinfo->di_bstart = cpg->bdst; ++ hdp[0 + cpg->bdst].hd_dentry = wh_dentry; + h_d_start = NULL; + if (file) { -+ h_d_start = hdp[0 + basic->bsrc].hd_dentry; -+ hdp[0 + basic->bsrc].hd_dentry = au_hf_top(file)->f_dentry; ++ h_d_start = hdp[0 + cpg->bsrc].hd_dentry; ++ hdp[0 + cpg->bsrc].hd_dentry = au_hf_top(file)->f_dentry; + } -+ err = au_cpup_single(basic, !AuCpup_DTIME, /*h_parent*/NULL, pin); ++ flags_orig = cpg->flags; ++ cpg->flags = !AuCpup_DTIME; ++ err = au_cpup_single(cpg, /*h_parent*/NULL); ++ cpg->flags = flags_orig; + if (file) { + if (!err) + err = au_reopen_nondir(file); -+ hdp[0 + basic->bsrc].hd_dentry = h_d_start; ++ hdp[0 + cpg->bsrc].hd_dentry = h_d_start; + } -+ hdp[0 + basic->bdst].hd_dentry = h_d_dst; -+ dinfo->di_bstart = basic->bsrc; -+ basic->bsrc = bsrc_orig; ++ hdp[0 + cpg->bdst].hd_dentry = h_d_dst; ++ dinfo->di_bstart = cpg->bsrc; ++ cpg->bsrc = bsrc_orig; + + return err; +} + -+static int au_cpup_wh(struct au_cpup_basic *basic, struct file *file, -+ struct au_pin *pin) ++static int au_cpup_wh(struct au_cp_generic *cpg, struct file *file) +{ + int err; + aufs_bindex_t bdst; @@ -4233,8 +4281,8 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + struct au_branch *br; + struct path h_path; + -+ dentry = basic->dentry; -+ bdst = basic->bdst; ++ dentry = cpg->dentry; ++ bdst = cpg->bdst; + br = au_sbr(dentry->d_sb, bdst); + parent = dget_parent(dentry); + h_parent = au_h_dptr(parent, bdst); @@ -4246,7 +4294,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + h_path.dentry = h_parent; + h_path.mnt = au_br_mnt(br); + au_dtime_store(&dt, parent, &h_path); -+ err = au_do_cpup_wh(basic, wh_dentry, file, pin); ++ err = au_do_cpup_wh(cpg, wh_dentry, file); + if (unlikely(err)) + goto out_wh; + @@ -4273,38 +4321,37 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + +struct au_cpup_wh_args { + int *errp; -+ struct au_cpup_basic *basic; ++ struct au_cp_generic *cpg; + struct file *file; -+ struct au_pin *pin; +}; + +static void au_call_cpup_wh(void *args) +{ + struct au_cpup_wh_args *a = args; + -+ au_pin_hdir_acquire_nest(a->pin); -+ *a->errp = au_cpup_wh(a->basic, a->file, a->pin); -+ au_pin_hdir_release(a->pin); ++ au_pin_hdir_acquire_nest(a->cpg->pin); ++ *a->errp = au_cpup_wh(a->cpg, a->file); ++ au_pin_hdir_release(a->cpg->pin); +} + -+int au_sio_cpup_wh(struct au_cpup_basic *basic, struct file *file, -+ struct au_pin *pin) ++int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file) +{ + int err, wkq_err; + aufs_bindex_t bdst; + struct dentry *dentry, *parent, *h_orph, *h_parent, *h_dentry; + struct inode *dir, *h_dir, *h_tmpdir; + struct au_wbr *wbr; -+ struct au_pin wh_pin; ++ struct au_pin wh_pin, *pin_orig; + -+ dentry = basic->dentry; -+ bdst = basic->bdst; ++ dentry = cpg->dentry; ++ bdst = cpg->bdst; + parent = dget_parent(dentry); + dir = parent->d_inode; + h_orph = NULL; + h_parent = NULL; + h_dir = au_igrab(au_h_iptr(dir, bdst)); + h_tmpdir = h_dir; ++ pin_orig = NULL; + if (!h_dir->i_nlink) { + wbr = au_sbr(dentry->d_sb, bdst)->br_wbr; + h_orph = wbr->wbr_orph; @@ -4321,20 +4368,20 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + mutex_lock_nested(&h_tmpdir->i_mutex, AuLsc_I_PARENT3); + /* todo: au_h_open_pre()? */ + ++ pin_orig = cpg->pin; + au_pin_init(&wh_pin, dentry, bdst, AuLsc_DI_PARENT, -+ AuLsc_I_PARENT3, pin->udba, AuPin_DI_LOCKED); -+ pin = &wh_pin; ++ AuLsc_I_PARENT3, cpg->pin->udba, AuPin_DI_LOCKED); ++ cpg->pin = &wh_pin; + } + + if (!au_test_h_perm_sio(h_tmpdir, MAY_EXEC | MAY_WRITE) -+ && !au_cpup_sio_test(pin, dentry->d_inode->i_mode)) -+ err = au_cpup_wh(basic, file, pin); ++ && !au_cpup_sio_test(cpg->pin, dentry->d_inode->i_mode)) ++ err = au_cpup_wh(cpg, file); + else { + struct au_cpup_wh_args args = { + .errp = &err, -+ .basic = basic, -+ .file = file, -+ .pin = pin ++ .cpg = cpg, ++ .file = file + }; + wkq_err = au_wkq_wait(au_call_cpup_wh, &args); + if (unlikely(wkq_err)) @@ -4346,6 +4393,8 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + /* todo: au_h_open_post()? */ + au_set_h_iptr(dir, bdst, au_igrab(h_dir), /*flags*/0); + au_set_h_dptr(parent, bdst, h_parent); ++ AuDebugOn(!pin_orig); ++ cpg->pin = pin_orig; + } + iput(h_dir); + dput(parent); @@ -4428,13 +4477,15 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + struct dentry *h_parent __maybe_unused , + void *arg __maybe_unused) +{ -+ struct au_cpup_basic basic = { ++ struct au_cp_generic cpg = { + .dentry = dentry, + .bdst = bdst, + .bsrc = -1, -+ .len = 0 ++ .len = 0, ++ .pin = pin, ++ .flags = AuCpup_DTIME + }; -+ return au_sio_cpup_simple(&basic, AuCpup_DTIME, pin); ++ return au_sio_cpup_simple(&cpg); +} + +int au_cpup_dirs(struct dentry *dentry, aufs_bindex_t bdst) @@ -4466,8 +4517,8 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + return err; +} --- a/fs/aufs/cpup.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/cpup.h 2013-08-07 15:04:57.883008639 +0200 -@@ -0,0 +1,89 @@ ++++ b/fs/aufs/cpup.h 2013-08-31 18:37:45.995378498 +0100 +@@ -0,0 +1,93 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima + * @@ -4510,18 +4561,23 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + +/* ---------------------------------------------------------------------- */ + -+struct au_cpup_basic { ++struct au_cp_generic { + struct dentry *dentry; + aufs_bindex_t bdst, bsrc; + loff_t len; ++ struct au_pin *pin; ++ unsigned int flags; +}; + +/* cpup flags */ -+#define AuCpup_DTIME 1 /* do dtime_store/revert */ -+#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino, -+ for link(2) */ -+#define AuCpup_RENAME (1 << 2) /* rename after cpup */ -+#define AuCpup_HOPEN (1 << 3) /* call h_open_pre/post() in cpup */ ++#define AuCpup_DTIME 1 /* do dtime_store/revert */ ++#define AuCpup_KEEPLINO (1 << 1) /* do not clear the lower xino, ++ for link(2) */ ++#define AuCpup_RENAME (1 << 2) /* rename after cpup */ ++#define AuCpup_HOPEN (1 << 3) /* call h_open_pre/post() in ++ cpup */ ++#define AuCpup_OVERWRITE (1 << 4) /* allow overwriting the ++ existing entry */ + +#define au_ftest_cpup(flags, name) ((flags) & AuCpup_##name) +#define au_fset_cpup(flags, name) \ @@ -4530,10 +4586,9 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + do { (flags) &= ~AuCpup_##name; } while (0) + +int au_copy_file(struct file *dst, struct file *src, loff_t len); -+int au_sio_cpup_simple(struct au_cpup_basic *basic, unsigned int flags, -+ struct au_pin *pin); -+int au_sio_cpup_wh(struct au_cpup_basic *basic, struct file *file, -+ struct au_pin *pin); ++int au_sio_cpup_simple(struct au_cp_generic *cpg); ++int au_sio_cpdown_simple(struct au_cp_generic *cpg); ++int au_sio_cpup_wh(struct au_cp_generic *cpg, struct file *file); + +int au_cp_dirs(struct dentry *dentry, aufs_bindex_t bdst, + int (*cp)(struct dentry *dentry, aufs_bindex_t bdst, @@ -4558,7 +4613,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#endif /* __KERNEL__ */ +#endif /* __AUFS_CPUP_H__ */ --- a/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dbgaufs.c 2013-08-07 15:04:57.883008639 +0200 ++++ b/fs/aufs/dbgaufs.c 2013-08-07 14:04:57.883008639 +0100 @@ -0,0 +1,433 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -4994,7 +5049,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + return err; +} --- a/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dbgaufs.h 2013-03-10 02:48:58.459093058 +0100 ++++ b/fs/aufs/dbgaufs.h 2013-03-10 01:48:58.459093058 +0000 @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -5046,7 +5101,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#endif /* __KERNEL__ */ +#endif /* __DBGAUFS_H__ */ --- a/fs/aufs/dcsub.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dcsub.c 2013-08-04 01:24:24.666688807 +0200 ++++ b/fs/aufs/dcsub.c 2013-08-31 18:37:41.071378381 +0100 @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -5292,7 +5347,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + return path_is_under(path + 0, path + 1); +} --- a/fs/aufs/dcsub.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dcsub.h 2013-03-10 02:48:58.459093058 +0100 ++++ b/fs/aufs/dcsub.h 2013-03-10 01:48:58.459093058 +0000 @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -5389,7 +5444,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#endif /* __KERNEL__ */ +#endif /* __AUFS_DCSUB_H__ */ --- a/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/debug.c 2013-08-07 15:04:57.883008639 +0200 ++++ b/fs/aufs/debug.c 2013-08-31 18:37:45.995378498 +0100 @@ -0,0 +1,491 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -5480,7 +5535,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + return -1; + } + -+ /* the type of i_blocks depends upon CONFIG_LSF */ ++ /* the type of i_blocks depends upon CONFIG_LBDAF */ + BUILD_BUG_ON(sizeof(inode->i_blocks) != sizeof(unsigned long) + && sizeof(inode->i_blocks) != sizeof(u64)); + if (wh) { @@ -5883,7 +5938,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + return 0; +} --- a/fs/aufs/debug.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/debug.h 2013-08-07 15:04:57.883008639 +0200 ++++ b/fs/aufs/debug.h 2013-08-07 14:04:57.883008639 +0100 @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -6128,7 +6183,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#endif /* __KERNEL__ */ +#endif /* __AUFS_DEBUG_H__ */ --- a/fs/aufs/dentry.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dentry.c 2013-08-07 15:04:57.883008639 +0200 ++++ b/fs/aufs/dentry.c 2013-08-07 14:04:57.883008639 +0100 @@ -0,0 +1,1065 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -7196,7 +7251,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + .d_release = aufs_d_release +}; --- a/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dentry.h 2013-08-07 15:04:57.883008639 +0200 ++++ b/fs/aufs/dentry.h 2013-08-07 14:04:57.883008639 +0100 @@ -0,0 +1,234 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -7433,7 +7488,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#endif /* __KERNEL__ */ +#endif /* __AUFS_DENTRY_H__ */ --- a/fs/aufs/dinfo.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dinfo.c 2013-08-04 01:24:24.666688807 +0200 ++++ b/fs/aufs/dinfo.c 2013-08-31 18:37:41.071378381 +0100 @@ -0,0 +1,543 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -7979,7 +8034,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + return -1; +} --- a/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dir.c 2013-08-07 15:04:57.883008639 +0200 ++++ b/fs/aufs/dir.c 2013-08-31 18:37:41.071378381 +0100 @@ -0,0 +1,632 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -8614,7 +8669,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + .fsync = aufs_fsync_dir +}; --- a/fs/aufs/dir.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dir.h 2013-08-04 01:24:24.666688807 +0200 ++++ b/fs/aufs/dir.h 2013-08-31 18:37:41.071378381 +0100 @@ -0,0 +1,137 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -8754,7 +8809,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#endif /* __KERNEL__ */ +#endif /* __AUFS_DIR_H__ */ --- a/fs/aufs/dynop.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dynop.c 2013-08-07 15:04:57.883008639 +0200 ++++ b/fs/aufs/dynop.c 2013-08-31 18:37:41.071378381 +0100 @@ -0,0 +1,379 @@ +/* + * Copyright (C) 2010-2013 Junjiro R. Okajima @@ -9136,7 +9191,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + WARN_ON(!list_empty(&dynop[i].head)); +} --- a/fs/aufs/dynop.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dynop.h 2013-03-10 02:48:58.459093058 +0100 ++++ b/fs/aufs/dynop.h 2013-03-10 01:48:58.459093058 +0000 @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2010-2013 Junjiro R. Okajima @@ -9215,7 +9270,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#endif /* __KERNEL__ */ +#endif /* __AUFS_DYNOP_H__ */ --- a/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/export.c 2013-08-07 15:04:57.883008639 +0200 ++++ b/fs/aufs/export.c 2013-08-31 18:37:41.071378381 +0100 @@ -0,0 +1,826 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -10044,7 +10099,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + atomic_set(&sbinfo->si_xigen_next, u); +} --- a/fs/aufs/f_op.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/f_op.c 2013-08-07 15:04:57.887008639 +0200 ++++ b/fs/aufs/f_op.c 2013-08-31 18:37:45.995378498 +0100 @@ -0,0 +1,721 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -10750,7 +10805,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#endif + .unlocked_ioctl = aufs_ioctl_nondir, +#ifdef CONFIG_COMPAT -+ .compat_ioctl = aufs_ioctl_nondir, /* same */ ++ .compat_ioctl = aufs_compat_ioctl_nondir, +#endif + .mmap = aufs_mmap, + .open = aufs_open_nondir, @@ -10768,8 +10823,8 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#endif +}; --- a/fs/aufs/f_op_sp.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/f_op_sp.c 2013-08-07 15:04:57.887008639 +0200 -@@ -0,0 +1,381 @@ ++++ b/fs/aufs/f_op_sp.c 2013-08-31 18:37:45.995378498 +0100 +@@ -0,0 +1,383 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima + * @@ -10809,7 +10864,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + +struct au_finfo_sp { + struct hlist_node hlist; -+ struct file *file; ++ struct file *file; + struct au_finfo *finfo; +}; + @@ -11024,11 +11079,13 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + .force_btgt = -1, + .flags = 0 + }; -+ struct au_cpup_basic basic = { ++ struct au_cp_generic cpg = { + .dentry = dentry, + .bdst = -1, + .bsrc = -1, -+ .len = -1 ++ .len = -1, ++ .pin = &pin, ++ .flags = AuCpup_DTIME + }; + + AuDbg("%.*s\n", AuDLNPair(dentry)); @@ -11038,15 +11095,15 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + err = au_wr_dir(dentry, /*src_dentry*/NULL, &wr_dir_args); + if (unlikely(err < 0)) + goto out; -+ basic.bdst = err; ++ cpg.bdst = err; + err = 0; -+ if (basic.bdst == au_dbstart(dentry)) ++ if (cpg.bdst == au_dbstart(dentry)) + goto out; /* success */ + -+ err = au_pin(&pin, dentry, basic.bdst, au_opt_udba(dentry->d_sb), ++ err = au_pin(&pin, dentry, cpg.bdst, au_opt_udba(dentry->d_sb), + AuPin_MNT_WRITE); + if (!err) { -+ err = au_sio_cpup_simple(&basic, AuCpup_DTIME, &pin); ++ err = au_sio_cpup_simple(&cpg); + au_unpin(&pin); + } + @@ -11152,8 +11209,8 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + return ret; +} --- a/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/file.c 2013-08-07 15:04:57.887008639 +0200 -@@ -0,0 +1,704 @@ ++++ b/fs/aufs/file.c 2013-08-31 18:37:45.995378498 +0100 +@@ -0,0 +1,708 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima + * @@ -11379,33 +11436,34 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + int err; + struct inode *inode, *h_inode; + struct dentry *h_dentry, *hi_wh; -+ struct au_cpup_basic basic = { ++ struct au_cp_generic cpg = { + .dentry = file->f_dentry, + .bdst = bcpup, + .bsrc = -1, -+ .len = len ++ .len = len, ++ .pin = pin + }; + -+ au_update_dbstart(basic.dentry); -+ inode = basic.dentry->d_inode; ++ au_update_dbstart(cpg.dentry); ++ inode = cpg.dentry->d_inode; + h_inode = NULL; -+ if (au_dbstart(basic.dentry) <= bcpup -+ && au_dbend(basic.dentry) >= bcpup) { -+ h_dentry = au_h_dptr(basic.dentry, bcpup); ++ if (au_dbstart(cpg.dentry) <= bcpup ++ && au_dbend(cpg.dentry) >= bcpup) { ++ h_dentry = au_h_dptr(cpg.dentry, bcpup); + if (h_dentry) + h_inode = h_dentry->d_inode; + } + hi_wh = au_hi_wh(inode, bcpup); + if (!hi_wh && !h_inode) -+ err = au_sio_cpup_wh(&basic, file, pin); ++ err = au_sio_cpup_wh(&cpg, file); + else + /* already copied-up after unlink */ + err = au_reopen_wh(file, bcpup, hi_wh); + + if (!err + && inode->i_nlink > 1 -+ && au_opt_test(au_mntflags(basic.dentry->d_sb), PLINK)) -+ au_plink_append(inode, bcpup, au_h_dptr(basic.dentry, bcpup)); ++ && au_opt_test(au_mntflags(cpg.dentry->d_sb), PLINK)) ++ au_plink_append(inode, bcpup, au_h_dptr(cpg.dentry, bcpup)); + + return err; +} @@ -11421,73 +11479,74 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + struct inode *inode; + struct super_block *sb; + struct file *h_file; -+ struct au_cpup_basic basic = { ++ struct au_cp_generic cpg = { + .dentry = file->f_dentry, + .bdst = -1, + .bsrc = -1, -+ .len = len ++ .len = len, ++ .pin = pin, ++ .flags = AuCpup_DTIME + }; + -+ sb = basic.dentry->d_sb; -+ inode = basic.dentry->d_inode; ++ sb = cpg.dentry->d_sb; ++ inode = cpg.dentry->d_inode; + AuDebugOn(au_special_file(inode->i_mode)); -+ basic.bsrc = au_fbstart(file); -+ err = au_test_ro(sb, basic.bsrc, inode); ++ cpg.bsrc = au_fbstart(file); ++ err = au_test_ro(sb, cpg.bsrc, inode); + if (!err && (au_hf_top(file)->f_mode & FMODE_WRITE)) { -+ err = au_pin(pin, basic.dentry, basic.bsrc, AuOpt_UDBA_NONE, ++ err = au_pin(pin, cpg.dentry, cpg.bsrc, AuOpt_UDBA_NONE, + /*flags*/0); + goto out; + } + + /* need to cpup or reopen */ -+ parent = dget_parent(basic.dentry); ++ parent = dget_parent(cpg.dentry); + di_write_lock_parent(parent); -+ err = AuWbrCopyup(au_sbi(sb), basic.dentry); -+ basic.bdst = err; ++ err = AuWbrCopyup(au_sbi(sb), cpg.dentry); ++ cpg.bdst = err; + if (unlikely(err < 0)) + goto out_dgrade; + err = 0; + -+ if (!d_unhashed(basic.dentry) && !au_h_dptr(parent, basic.bdst)) { -+ err = au_cpup_dirs(basic.dentry, basic.bdst); ++ if (!d_unhashed(cpg.dentry) && !au_h_dptr(parent, cpg.bdst)) { ++ err = au_cpup_dirs(cpg.dentry, cpg.bdst); + if (unlikely(err)) + goto out_dgrade; + } + -+ err = au_pin(pin, basic.dentry, basic.bdst, AuOpt_UDBA_NONE, ++ err = au_pin(pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE, + AuPin_DI_LOCKED | AuPin_MNT_WRITE); + if (unlikely(err)) + goto out_dgrade; + + h_dentry = au_hf_top(file)->f_dentry; -+ dbstart = au_dbstart(basic.dentry); -+ if (dbstart <= basic.bdst) { -+ h_dentry = au_h_dptr(basic.dentry, basic.bdst); ++ dbstart = au_dbstart(cpg.dentry); ++ if (dbstart <= cpg.bdst) { ++ h_dentry = au_h_dptr(cpg.dentry, cpg.bdst); + AuDebugOn(!h_dentry); -+ basic.bsrc = basic.bdst; ++ cpg.bsrc = cpg.bdst; + } + -+ if (dbstart <= basic.bdst /* just reopen */ -+ || !d_unhashed(basic.dentry) /* copyup and reopen */ ++ if (dbstart <= cpg.bdst /* just reopen */ ++ || !d_unhashed(cpg.dentry) /* copyup and reopen */ + ) { -+ h_file = au_h_open_pre(basic.dentry, basic.bsrc); ++ h_file = au_h_open_pre(cpg.dentry, cpg.bsrc); + if (IS_ERR(h_file)) + err = PTR_ERR(h_file); + else { + di_downgrade_lock(parent, AuLock_IR); -+ if (dbstart > basic.bdst) -+ err = au_sio_cpup_simple(&basic, AuCpup_DTIME, -+ pin); ++ if (dbstart > cpg.bdst) ++ err = au_sio_cpup_simple(&cpg); + if (!err) + err = au_reopen_nondir(file); -+ au_h_open_post(basic.dentry, basic.bsrc, h_file); ++ au_h_open_post(cpg.dentry, cpg.bsrc, h_file); + } + } else { /* copyup as wh and reopen */ + /* + * since writable hfsplus branch is not supported, + * h_open_pre/post() are unnecessary. + */ -+ err = au_ready_to_write_wh(file, len, basic.bdst, pin); ++ err = au_ready_to_write_wh(file, len, cpg.bdst, pin); + di_downgrade_lock(parent, AuLock_IR); + } + @@ -11542,28 +11601,30 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + struct dentry *parent, *hi_wh; + struct inode *inode; + struct super_block *sb; -+ struct au_cpup_basic basic = { ++ struct au_cp_generic cpg = { + .dentry = file->f_dentry, + .bdst = -1, + .bsrc = -1, -+ .len = -1 ++ .len = -1, ++ .pin = &pin, ++ .flags = AuCpup_DTIME + }; + + FiMustWriteLock(file); + + err = 0; + finfo = au_fi(file); -+ sb = basic.dentry->d_sb; -+ inode = basic.dentry->d_inode; -+ basic.bdst = au_ibstart(inode); -+ if (basic.bdst == finfo->fi_btop || IS_ROOT(basic.dentry)) ++ sb = cpg.dentry->d_sb; ++ inode = cpg.dentry->d_inode; ++ cpg.bdst = au_ibstart(inode); ++ if (cpg.bdst == finfo->fi_btop || IS_ROOT(cpg.dentry)) + goto out; + -+ parent = dget_parent(basic.dentry); -+ if (au_test_ro(sb, basic.bdst, inode)) { ++ parent = dget_parent(cpg.dentry); ++ if (au_test_ro(sb, cpg.bdst, inode)) { + di_read_lock_parent(parent, !AuLock_IR); -+ err = AuWbrCopyup(au_sbi(sb), basic.dentry); -+ basic.bdst = err; ++ err = AuWbrCopyup(au_sbi(sb), cpg.dentry); ++ cpg.bdst = err; + di_read_unlock(parent, !AuLock_IR); + if (unlikely(err < 0)) + goto out_parent; @@ -11571,26 +11632,26 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + } + + di_read_lock_parent(parent, AuLock_IR); -+ hi_wh = au_hi_wh(inode, basic.bdst); ++ hi_wh = au_hi_wh(inode, cpg.bdst); + if (!S_ISDIR(inode->i_mode) + && au_opt_test(au_mntflags(sb), PLINK) + && au_plink_test(inode) -+ && !d_unhashed(basic.dentry) -+ && basic.bdst < au_dbstart(basic.dentry)) { -+ err = au_test_and_cpup_dirs(basic.dentry, basic.bdst); ++ && !d_unhashed(cpg.dentry) ++ && cpg.bdst < au_dbstart(cpg.dentry)) { ++ err = au_test_and_cpup_dirs(cpg.dentry, cpg.bdst); + if (unlikely(err)) + goto out_unlock; + + /* always superio. */ -+ err = au_pin(&pin, basic.dentry, basic.bdst, AuOpt_UDBA_NONE, ++ err = au_pin(&pin, cpg.dentry, cpg.bdst, AuOpt_UDBA_NONE, + AuPin_DI_LOCKED | AuPin_MNT_WRITE); + if (!err) { -+ err = au_sio_cpup_simple(&basic, AuCpup_DTIME, &pin); ++ err = au_sio_cpup_simple(&cpg); + au_unpin(&pin); + } + } else if (hi_wh) { + /* already copied-up after unlink */ -+ err = au_reopen_wh(file, basic.bdst, hi_wh); ++ err = au_reopen_wh(file, cpg.bdst, hi_wh); + *need_reopen = 0; + } + @@ -11859,8 +11920,8 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#endif /* CONFIG_AUFS_DEBUG */ +}; --- a/fs/aufs/file.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/file.h 2013-08-07 15:04:57.887008639 +0200 -@@ -0,0 +1,308 @@ ++++ b/fs/aufs/file.h 2013-08-31 18:37:45.995378498 +0100 +@@ -0,0 +1,310 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima + * @@ -12006,6 +12067,8 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#ifdef CONFIG_COMPAT +long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd, + unsigned long arg); ++long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd, ++ unsigned long arg); +#endif + +/* ---------------------------------------------------------------------- */ @@ -12170,7 +12233,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#endif /* __KERNEL__ */ +#endif /* __AUFS_FILE_H__ */ --- a/fs/aufs/finfo.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/finfo.c 2013-03-10 02:48:58.459093058 +0100 ++++ b/fs/aufs/finfo.c 2013-03-10 01:48:58.459093058 +0000 @@ -0,0 +1,157 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -12330,8 +12393,8 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + return err; +} --- a/fs/aufs/fstype.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/fstype.h 2013-08-07 15:04:57.887008639 +0200 -@@ -0,0 +1,480 @@ ++++ b/fs/aufs/fstype.h 2013-08-31 18:37:45.995378498 +0100 +@@ -0,0 +1,470 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima + * @@ -12444,15 +12507,6 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#endif +} + -+static inline int au_test_smbfs(struct super_block *sb __maybe_unused) -+{ -+#if defined(CONFIG_SMB_FS) || defined(CONFIG_SMB_FS_MODULE) -+ return sb->s_magic == SMB_SUPER_MAGIC; -+#else -+ return 0; -+#endif -+} -+ +static inline int au_test_ocfs2(struct super_block *sb __maybe_unused) +{ +#if defined(CONFIG_OCFS2_FS) || defined(CONFIG_OCFS2_FS_MODULE) @@ -12491,7 +12545,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + +static inline int au_test_ext4(struct super_block *sb __maybe_unused) +{ -+#if defined(CONFIG_EXT4DEV_FS) || defined(CONFIG_EXT4DEV_FS_MODULE) ++#if defined(CONFIG_EXT4_FS) || defined(CONFIG_EXT4_FS_MODULE) + return sb->s_magic == EXT4_SUPER_MAGIC; +#else + return 0; @@ -12699,7 +12753,6 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +{ + return au_test_nfs(sb) + || au_test_fuse(sb) -+ /* || au_test_smbfs(sb) */ /* untested */ + /* || au_test_ocfs2(sb) */ /* untested */ + /* || au_test_btrfs(sb) */ /* untested */ + /* || au_test_coda(sb) */ /* untested */ @@ -12813,7 +12866,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#endif /* __KERNEL__ */ +#endif /* __AUFS_FSTYPE_H__ */ --- a/fs/aufs/hfsnotify.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/hfsnotify.c 2013-08-07 15:04:57.887008639 +0200 ++++ b/fs/aufs/hfsnotify.c 2013-08-07 14:04:57.887008639 +0100 @@ -0,0 +1,296 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -13112,7 +13165,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + .init_br = au_hfsn_init_br +}; --- a/fs/aufs/hfsplus.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/hfsplus.c 2013-06-02 19:23:34.753538984 +0200 ++++ b/fs/aufs/hfsplus.c 2013-06-02 18:23:34.753538984 +0100 @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2010-2013 Junjiro R. Okajima @@ -13171,7 +13224,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + } +} --- a/fs/aufs/hnotify.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/hnotify.c 2013-08-07 15:04:57.887008639 +0200 ++++ b/fs/aufs/hnotify.c 2013-08-31 18:37:41.075378381 +0100 @@ -0,0 +1,712 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -13886,8 +13939,8 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + au_hn_destroy_cache(); +} --- a/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/i_op.c 2013-08-07 15:04:57.887008639 +0200 -@@ -0,0 +1,1111 @@ ++++ b/fs/aufs/i_op.c 2013-08-31 18:37:45.995378498 +0100 +@@ -0,0 +1,1115 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima + * @@ -14150,10 +14203,12 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + + err = 0; + if (!au_h_dptr(parent, bcpup)) { -+ if (bstart < bcpup) ++ if (bstart > bcpup) ++ err = au_cpup_dirs(dentry, bcpup); ++ else if (bstart < bcpup) + err = au_cpdown_dirs(dentry, bcpup); + else -+ err = au_cpup_dirs(dentry, bcpup); ++ BUG(); + } + if (!err && add_entry) { + h_parent = au_h_dptr(parent, bcpup); @@ -14565,13 +14620,14 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + if (au_ftest_icpup(a->flags, DID_CPUP) && d_unlinked(dentry)) { + hi_wh = au_hi_wh(inode, a->btgt); + if (!hi_wh) { -+ struct au_cpup_basic basic = { ++ struct au_cp_generic cpg = { + .dentry = dentry, + .bdst = a->btgt, + .bsrc = -1, -+ .len = sz ++ .len = sz, ++ .pin = &a->pin + }; -+ err = au_sio_cpup_wh(&basic, /*file*/NULL, &a->pin); ++ err = au_sio_cpup_wh(&cpg, /*file*/NULL); + if (unlikely(err)) + goto out_unlock; + hi_wh = au_hi_wh(inode, a->btgt); @@ -14589,14 +14645,15 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + goto out; /* success */ + + if (!d_unhashed(dentry)) { -+ struct au_cpup_basic basic = { ++ struct au_cp_generic cpg = { + .dentry = dentry, + .bdst = a->btgt, + .bsrc = bstart, -+ .len = sz ++ .len = sz, ++ .pin = &a->pin, ++ .flags = AuCpup_DTIME | AuCpup_HOPEN + }; -+ err = au_sio_cpup_simple(&basic, AuCpup_DTIME | AuCpup_HOPEN, -+ &a->pin); ++ err = au_sio_cpup_simple(&cpg); + if (!err) + a->h_path.dentry = au_h_dptr(dentry, a->btgt); + } else if (!hi_wh) @@ -15000,8 +15057,8 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + .update_time = aufs_update_time +}; --- a/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/i_op_add.c 2013-08-07 15:04:57.887008639 +0200 -@@ -0,0 +1,728 @@ ++++ b/fs/aufs/i_op_add.c 2013-08-31 18:37:45.995378498 +0100 +@@ -0,0 +1,739 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima + * @@ -15238,47 +15295,55 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + int err; + aufs_bindex_t bstart; + unsigned char created; -+ struct au_dtime dt; -+ struct au_pin pin; -+ struct path h_path; + struct dentry *wh_dentry, *parent; + struct inode *h_dir; -+ struct au_wr_dir_args wr_dir_args = { -+ .force_btgt = -1, -+ .flags = AuWrDir_ADD_ENTRY -+ }; ++ /* to reuduce stack size */ ++ struct { ++ struct au_dtime dt; ++ struct au_pin pin; ++ struct path h_path; ++ struct au_wr_dir_args wr_dir_args; ++ } *a; + + AuDbg("%.*s\n", AuDLNPair(dentry)); + IMustLock(dir); + ++ err = -ENOMEM; ++ a = kmalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ a->wr_dir_args.force_btgt = -1; ++ a->wr_dir_args.flags = AuWrDir_ADD_ENTRY; ++ + parent = dentry->d_parent; /* dir inode is locked */ + err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN); + if (unlikely(err)) -+ goto out; ++ goto out_free; + err = au_d_may_add(dentry); + if (unlikely(err)) + goto out_unlock; + di_write_lock_parent(parent); -+ wh_dentry = lock_hdir_lkup_wh(dentry, &dt, /*src_dentry*/NULL, &pin, -+ &wr_dir_args); ++ wh_dentry = lock_hdir_lkup_wh(dentry, &a->dt, /*src_dentry*/NULL, ++ &a->pin, &a->wr_dir_args); + err = PTR_ERR(wh_dentry); + if (IS_ERR(wh_dentry)) + goto out_parent; + + bstart = au_dbstart(dentry); -+ h_path.dentry = au_h_dptr(dentry, bstart); -+ h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart); -+ h_dir = au_pinned_h_dir(&pin); ++ a->h_path.dentry = au_h_dptr(dentry, bstart); ++ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart); ++ h_dir = au_pinned_h_dir(&a->pin); + switch (arg->type) { + case Creat: -+ err = vfsub_create(h_dir, &h_path, arg->u.c.mode, ++ err = vfsub_create(h_dir, &a->h_path, arg->u.c.mode, + arg->u.c.want_excl); + break; + case Symlink: -+ err = vfsub_symlink(h_dir, &h_path, arg->u.s.symname); ++ err = vfsub_symlink(h_dir, &a->h_path, arg->u.s.symname); + break; + case Mknod: -+ err = vfsub_mknod(h_dir, &h_path, arg->u.m.mode, arg->u.m.dev); ++ err = vfsub_mknod(h_dir, &a->h_path, arg->u.m.mode, ++ arg->u.m.dev); + break; + default: + BUG(); @@ -15288,18 +15353,18 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + err = epilog(dir, bstart, wh_dentry, dentry); + + /* revert */ -+ if (unlikely(created && err && h_path.dentry->d_inode)) { ++ if (unlikely(created && err && a->h_path.dentry->d_inode)) { + int rerr; -+ rerr = vfsub_unlink(h_dir, &h_path, /*force*/0); ++ rerr = vfsub_unlink(h_dir, &a->h_path, /*force*/0); + if (rerr) { + AuIOErr("%.*s revert failure(%d, %d)\n", + AuDLNPair(dentry), err, rerr); + err = -EIO; + } -+ au_dtime_revert(&dt); ++ au_dtime_revert(&a->dt); + } + -+ au_unpin(&pin); ++ au_unpin(&a->pin); + dput(wh_dentry); + +out_parent: @@ -15310,6 +15375,8 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + d_drop(dentry); + } + aufs_read_unlock(dentry, AuLock_DW); ++out_free: ++ kfree(a); +out: + return err; +} @@ -15363,11 +15430,13 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +{ + int err; + struct dentry *h_src_dentry; -+ struct au_cpup_basic basic = { ++ struct au_cp_generic cpg = { + .dentry = src_dentry, + .bdst = a->bdst, + .bsrc = a->bsrc, -+ .len = -1 ++ .len = -1, ++ .pin = &a->pin, ++ .flags = AuCpup_DTIME | AuCpup_HOPEN /* | AuCpup_KEEPLINO */ + }; + + di_read_lock_parent(a->src_parent, AuLock_IR); @@ -15382,9 +15451,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + if (unlikely(err)) + goto out; + -+ err = au_sio_cpup_simple(&basic, AuCpup_DTIME | AuCpup_HOPEN, -+ /* AuCpup_KEEPLINO */ -+ &a->pin); ++ err = au_sio_cpup_simple(&cpg); + au_unpin(&a->pin); + +out: @@ -15423,14 +15490,15 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + if (IS_ERR(h_file)) + err = PTR_ERR(h_file); + else { -+ struct au_cpup_basic basic = { ++ struct au_cp_generic cpg = { + .dentry = dentry, + .bdst = a->bdst, + .bsrc = -1, -+ .len = -1 ++ .len = -1, ++ .pin = &a->pin, ++ .flags = AuCpup_KEEPLINO + }; -+ err = au_sio_cpup_simple(&basic, AuCpup_KEEPLINO, -+ &a->pin); ++ err = au_sio_cpup_simple(&cpg); + au_h_open_post(dentry, a->bsrc, h_file); + if (!err) { + dput(a->h_path.dentry); @@ -15731,8 +15799,8 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + return err; +} --- a/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/i_op_del.c 2013-08-07 15:04:57.887008639 +0200 -@@ -0,0 +1,477 @@ ++++ b/fs/aufs/i_op_del.c 2013-08-31 18:37:45.995378498 +0100 +@@ -0,0 +1,502 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima + * @@ -16034,17 +16102,25 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +{ + int err; + aufs_bindex_t bwh, bindex, bstart; -+ struct au_dtime dt; -+ struct au_pin pin; -+ struct path h_path; + struct inode *inode, *h_dir; + struct dentry *parent, *wh_dentry; ++ /* to reuduce stack size */ ++ struct { ++ struct au_dtime dt; ++ struct au_pin pin; ++ struct path h_path; ++ } *a; + + IMustLock(dir); + ++ err = -ENOMEM; ++ a = kmalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ + err = aufs_read_lock(dentry, AuLock_DW | AuLock_GEN); + if (unlikely(err)) -+ goto out; ++ goto out_free; + err = au_d_hashed_positive(dentry); + if (unlikely(err)) + goto out_unlock; @@ -16059,17 +16135,18 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + bindex = -1; + parent = dentry->d_parent; /* dir inode is locked */ + di_write_lock_parent(parent); -+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &dt, &pin); ++ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/0, &bindex, &a->dt, ++ &a->pin); + err = PTR_ERR(wh_dentry); + if (IS_ERR(wh_dentry)) + goto out_parent; + -+ h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart); -+ h_path.dentry = au_h_dptr(dentry, bstart); -+ dget(h_path.dentry); ++ a->h_path.mnt = au_sbr_mnt(dentry->d_sb, bstart); ++ a->h_path.dentry = au_h_dptr(dentry, bstart); ++ dget(a->h_path.dentry); + if (bindex == bstart) { -+ h_dir = au_pinned_h_dir(&pin); -+ err = vfsub_unlink(h_dir, &h_path, /*force*/0); ++ h_dir = au_pinned_h_dir(&a->pin); ++ err = vfsub_unlink(h_dir, &a->h_path, /*force*/0); + } else { + /* dir inode is locked */ + h_dir = wh_dentry->d_parent->d_inode; @@ -16083,8 +16160,9 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + + /* update target timestamps */ + if (bindex == bstart) { -+ vfsub_update_h_iattr(&h_path, /*did*/NULL); /*ignore*/ -+ inode->i_ctime = h_path.dentry->d_inode->i_ctime; ++ vfsub_update_h_iattr(&a->h_path, /*did*/NULL); ++ /*ignore*/ ++ inode->i_ctime = a->h_path.dentry->d_inode->i_ctime; + } else + /* todo: this timestamp may be reverted later */ + inode->i_ctime = h_dir->i_ctime; @@ -16095,19 +16173,22 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + if (wh_dentry) { + int rerr; + -+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry, &dt); ++ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry, ++ &a->dt); + if (rerr) + err = rerr; + } + +out_unpin: -+ au_unpin(&pin); ++ au_unpin(&a->pin); + dput(wh_dentry); -+ dput(h_path.dentry); ++ dput(a->h_path.dentry); +out_parent: + di_write_unlock(parent); +out_unlock: + aufs_read_unlock(dentry, AuLock_DW); ++out_free: ++ kfree(a); +out: + return err; +} @@ -16116,17 +16197,25 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +{ + int err, rmdir_later; + aufs_bindex_t bwh, bindex, bstart; -+ struct au_dtime dt; -+ struct au_pin pin; + struct inode *inode; + struct dentry *parent, *wh_dentry, *h_dentry; + struct au_whtmp_rmdir *args; ++ /* to reuduce stack size */ ++ struct { ++ struct au_dtime dt; ++ struct au_pin pin; ++ } *a; + + IMustLock(dir); + ++ err = -ENOMEM; ++ a = kmalloc(sizeof(*a), GFP_NOFS); ++ if (unlikely(!a)) ++ goto out; ++ + err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH | AuLock_GEN); + if (unlikely(err)) -+ goto out; ++ goto out_free; + err = au_alive_dir(dentry); + if (unlikely(err)) + goto out_unlock; @@ -16150,7 +16239,8 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + bstart = au_dbstart(dentry); + bwh = au_dbwh(dentry); + bindex = -1; -+ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &dt, &pin); ++ wh_dentry = lock_hdir_create_wh(dentry, /*isdir*/1, &bindex, &a->dt, ++ &a->pin); + err = PTR_ERR(wh_dentry); + if (IS_ERR(wh_dentry)) + goto out_parent; @@ -16191,13 +16281,14 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + if (wh_dentry) { + int rerr; + -+ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry, &dt); ++ rerr = do_revert(err, dir, bindex, bwh, wh_dentry, dentry, ++ &a->dt); + if (rerr) + err = rerr; + } + +out_unpin: -+ au_unpin(&pin); ++ au_unpin(&a->pin); + dput(wh_dentry); + dput(h_dentry); +out_parent: @@ -16206,12 +16297,14 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + au_whtmp_rmdir_free(args); +out_unlock: + aufs_read_unlock(dentry, AuLock_DW); ++out_free: ++ kfree(a); +out: + AuTraceErr(err); + return err; +} --- a/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/i_op_ren.c 2013-08-07 15:04:57.887008639 +0200 ++++ b/fs/aufs/i_op_ren.c 2013-08-31 18:37:45.995378498 +0100 @@ -0,0 +1,1009 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -17140,16 +17233,16 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + au_opt_udba(a->src_dentry->d_sb), + AuPin_DI_LOCKED | AuPin_MNT_WRITE); + if (!err) { -+ struct au_cpup_basic basic = { ++ struct au_cp_generic cpg = { + .dentry = a->src_dentry, + .bdst = a->btgt, + .bsrc = a->src_bstart, -+ .len = -1 ++ .len = -1, ++ .pin = &pin, ++ .flags = AuCpup_DTIME | AuCpup_HOPEN + }; + AuDebugOn(au_dbstart(a->src_dentry) != a->src_bstart); -+ err = au_sio_cpup_simple(&basic, -+ AuCpup_DTIME | AuCpup_HOPEN, -+ &pin); ++ err = au_sio_cpup_simple(&cpg); + au_unpin(&pin); + } + if (unlikely(err)) @@ -17223,7 +17316,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + return err; +} --- a/fs/aufs/iinfo.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/iinfo.c 2013-03-10 02:48:58.463093058 +0100 ++++ b/fs/aufs/iinfo.c 2013-03-10 01:48:58.463093058 +0000 @@ -0,0 +1,276 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -17502,7 +17595,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + AuRwDestroy(&iinfo->ii_rwsem); +} --- a/fs/aufs/inode.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/inode.c 2013-08-07 15:04:57.887008639 +0200 ++++ b/fs/aufs/inode.c 2013-08-07 14:04:57.887008639 +0100 @@ -0,0 +1,492 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -17997,7 +18090,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + return au_test_h_perm(h_inode, mask); +} --- a/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/inode.h 2013-08-07 15:04:57.887008639 +0200 ++++ b/fs/aufs/inode.h 2013-08-07 14:04:57.887008639 +0100 @@ -0,0 +1,600 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -18600,8 +18693,8 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#endif /* __KERNEL__ */ +#endif /* __AUFS_INODE_H__ */ --- a/fs/aufs/ioctl.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/ioctl.c 2013-03-10 02:48:58.463093058 +0100 -@@ -0,0 +1,196 @@ ++++ b/fs/aufs/ioctl.c 2013-08-31 18:37:45.995378498 +0100 +@@ -0,0 +1,202 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima + * @@ -18624,8 +18717,11 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + * ioctl + * plink-management and readdir in userspace. + * assist the pathconf(3) wrapper library. ++ * move-down + */ + ++#include ++#include +#include "aufs.h" + +static int au_wbr_fd(struct path *path, struct aufs_wbr_fd __user *arg) @@ -18752,6 +18848,11 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + long err; + + switch (cmd) { ++ case AUFS_CTL_MVDOWN: ++ WARN_ONCE(1, "move-down is still testing...\n"); ++ err = au_mvdown(file->f_dentry, (void __user *)arg); ++ break; ++ + case AUFS_CTL_WBR_FD: + err = au_wbr_fd(&file->f_path, (void __user *)arg); + break; @@ -18790,16 +18891,14 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + return err; +} + -+#if 0 /* unused yet */ +long aufs_compat_ioctl_nondir(struct file *file, unsigned int cmd, + unsigned long arg) +{ + return aufs_ioctl_nondir(file, cmd, (unsigned long)compat_ptr(arg)); +} +#endif -+#endif --- a/fs/aufs/loop.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/loop.c 2013-08-04 01:24:24.670688807 +0200 ++++ b/fs/aufs/loop.c 2013-08-31 18:37:41.079378381 +0100 @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -18937,7 +19036,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + kfree(au_warn_loopback_array); +} --- a/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/loop.h 2013-08-04 01:24:24.670688807 +0200 ++++ b/fs/aufs/loop.h 2013-08-31 18:37:41.079378381 +0100 @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -18990,7 +19089,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#endif /* __KERNEL__ */ +#endif /* __AUFS_LOOP_H__ */ --- a/fs/aufs/magic.mk 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/magic.mk 2012-01-10 03:15:56.000000000 +0100 ++++ b/fs/aufs/magic.mk 2012-01-10 02:15:56.000000000 +0000 @@ -0,0 +1,54 @@ + +# defined in ${srctree}/fs/fuse/inode.c @@ -19047,7 +19146,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +ccflags-y += -DHFSPLUS_SUPER_MAGIC=0x482b +endif --- a/fs/aufs/module.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/module.c 2013-08-07 15:04:57.887008639 +0200 ++++ b/fs/aufs/module.c 2013-08-07 14:04:57.887008639 +0100 @@ -0,0 +1,203 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -19253,7 +19352,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +module_init(aufs_init); +module_exit(aufs_exit); --- a/fs/aufs/module.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/module.h 2013-03-10 02:48:58.463093058 +0100 ++++ b/fs/aufs/module.h 2013-03-10 01:48:58.463093058 +0000 @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -19360,8 +19459,573 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + +#endif /* __KERNEL__ */ +#endif /* __AUFS_MODULE_H__ */ +--- a/fs/aufs/mvdown.c 1970-01-01 01:00:00.000000000 +0100 ++++ b/fs/aufs/mvdown.c 2013-08-31 18:37:45.995378498 +0100 +@@ -0,0 +1,562 @@ ++/* ++ * Copyright (C) 2011-2013 Junjiro R. Okajima ++ * ++ * This program, aufs is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ++ */ ++ ++#include "aufs.h" ++ ++enum { ++ AUFS_MVDOWN_SRC, ++ AUFS_MVDOWN_DST, ++ AUFS_MVDOWN_NARRAY ++}; ++ ++struct au_mvd_args { ++ struct { ++ struct super_block *h_sb; ++ struct dentry *h_parent; ++ struct au_hinode *hdir; ++ struct inode *h_dir; ++ } info[AUFS_MVDOWN_NARRAY]; ++ ++ struct aufs_mvdown mvdown; ++ struct dentry *dentry, *parent; ++ struct inode *inode, *dir; ++ struct super_block *sb; ++ aufs_bindex_t bopq, bwh, bfound; ++ unsigned char rename_lock; ++ struct au_pin pin; ++}; ++ ++#define mvd_errno mvdown.output.au_errno ++#define mvd_bsrc mvdown.output.bsrc ++#define mvd_bdst mvdown.output.bdst ++ ++#define mvd_h_src_sb info[AUFS_MVDOWN_SRC].h_sb ++#define mvd_h_src_parent info[AUFS_MVDOWN_SRC].h_parent ++#define mvd_hdir_src info[AUFS_MVDOWN_SRC].hdir ++#define mvd_h_src_dir info[AUFS_MVDOWN_SRC].h_dir ++ ++#define mvd_h_dst_sb info[AUFS_MVDOWN_DST].h_sb ++#define mvd_h_dst_parent info[AUFS_MVDOWN_DST].h_parent ++#define mvd_hdir_dst info[AUFS_MVDOWN_DST].hdir ++#define mvd_h_dst_dir info[AUFS_MVDOWN_DST].h_dir ++ ++#define AU_MVD_PR(flag, ...) do { \ ++ if (flag) \ ++ pr_err(__VA_ARGS__); \ ++ } while (0) ++ ++/* make the parent dir on bdst */ ++static int au_do_mkdir(const unsigned char dmsg, struct au_mvd_args *a) ++{ ++ int err; ++ ++ err = 0; ++ a->mvd_hdir_src = au_hi(a->dir, a->mvd_bsrc); ++ a->mvd_hdir_dst = au_hi(a->dir, a->mvd_bdst); ++ a->mvd_h_src_parent = au_h_dptr(a->parent, a->mvd_bsrc); ++ a->mvd_h_dst_parent = NULL; ++ if (au_dbend(a->parent) >= a->mvd_bdst) ++ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst); ++ if (!a->mvd_h_dst_parent) { ++ err = au_cpdown_dirs(a->dentry, a->mvd_bdst); ++ if (unlikely(err)) { ++ AU_MVD_PR(dmsg, "cpdown_dirs failed\n"); ++ goto out; ++ } ++ a->mvd_h_dst_parent = au_h_dptr(a->parent, a->mvd_bdst); ++ } ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++/* 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); ++ if (a->mvd_h_src_sb != a->mvd_h_dst_sb) { ++ a->rename_lock = 0; ++ err = au_pin(&a->pin, a->dentry, a->mvd_bdst, ++ au_opt_udba(a->sb), ++ AuPin_MNT_WRITE | AuPin_DI_LOCKED); ++ if (!err) { ++ a->mvd_h_src_dir = a->mvd_h_src_parent->d_inode; ++ mutex_lock_nested(&a->mvd_h_src_dir->i_mutex, ++ AuLsc_I_PARENT3); ++ } else ++ AU_MVD_PR(dmsg, "pin failed\n"); ++ goto out; ++ } ++ ++ err = 0; ++ a->rename_lock = 1; ++ 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 */ ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++static void au_do_unlock(const unsigned char dmsg, struct au_mvd_args *a) ++{ ++ if (!a->rename_lock) { ++ mutex_unlock(&a->mvd_h_src_dir->i_mutex); ++ au_unpin(&a->pin); ++ } else ++ vfsub_unlock_rename(a->mvd_h_src_parent, a->mvd_hdir_src, ++ a->mvd_h_dst_parent, a->mvd_hdir_dst); ++} ++ ++/* copy-down the file */ ++static int au_do_cpdown(const unsigned char dmsg, struct au_mvd_args *a) ++{ ++ int err; ++ struct au_cp_generic cpg = { ++ .dentry = a->dentry, ++ .bdst = a->mvd_bdst, ++ .bsrc = a->mvd_bsrc, ++ .len = -1, ++ .pin = &a->pin, ++ .flags = AuCpup_DTIME | AuCpup_HOPEN ++ }; ++ ++ AuDbg("b%d, b%d\n", cpg.bsrc, cpg.bdst); ++ if (a->mvdown.flags & AUFS_MVDOWN_OWLOWER) ++ au_fset_cpup(cpg.flags, OVERWRITE); ++ err = au_sio_cpdown_simple(&cpg); ++ if (unlikely(err)) ++ AU_MVD_PR(dmsg, "cpdown failed\n"); ++ ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ++ * unlink the whiteout on bdst if exist which may be created by UDBA while we ++ * were sleeping ++ */ ++static int au_do_unlink_wh(const unsigned char dmsg, struct au_mvd_args *a) ++{ ++ int err; ++ struct path h_path; ++ struct au_branch *br; ++ ++ br = au_sbr(a->sb, a->mvd_bdst); ++ h_path.dentry = au_wh_lkup(a->mvd_h_dst_parent, &a->dentry->d_name, br); ++ err = PTR_ERR(h_path.dentry); ++ if (IS_ERR(h_path.dentry)) { ++ AU_MVD_PR(dmsg, "wh_lkup failed\n"); ++ goto out; ++ } ++ ++ err = 0; ++ if (h_path.dentry->d_inode) { ++ h_path.mnt = au_br_mnt(br); ++ err = vfsub_unlink(a->mvd_h_dst_parent->d_inode, &h_path, ++ /*force*/0); ++ if (unlikely(err)) ++ AU_MVD_PR(dmsg, "wh_unlink failed\n"); ++ } ++ dput(h_path.dentry); ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ++ * unlink the topmost h_dentry ++ * Note: the target file MAY be modified by UDBA between this mutex_unlock() and ++ * mutex_lock() in vfs_unlink(). in this case, such changes may be lost. ++ */ ++static int au_do_unlink(const unsigned char dmsg, struct au_mvd_args *a) ++{ ++ int err; ++ struct path h_path; ++ ++ h_path.mnt = au_sbr_mnt(a->sb, a->mvd_bsrc); ++ h_path.dentry = au_h_dptr(a->dentry, a->mvd_bsrc); ++ err = vfsub_unlink(a->mvd_h_src_dir, &h_path, /*force*/0); ++ if (unlikely(err)) ++ AU_MVD_PR(dmsg, "unlink failed\n"); ++ ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ++ * copy-down the file and unlink the bsrc file. ++ * - unlink the bdst whout if exist ++ * - copy-down the file (with whtmp name and rename) ++ * - unlink the bsrc file ++ */ ++static int au_do_mvdown(const unsigned char dmsg, struct au_mvd_args *a) ++{ ++ int err; ++ ++ err = au_do_mkdir(dmsg, a); ++ if (!err) ++ err = au_do_lock(dmsg, a); ++ if (unlikely(err)) ++ goto out; ++ ++ /* ++ * do not revert the activities we made on bdst since they should be ++ * harmless in aufs. ++ */ ++ ++ err = au_do_cpdown(dmsg, a); ++ if (!err) ++ err = au_do_unlink_wh(dmsg, a); ++ if (!err && !(a->mvdown.flags & AUFS_MVDOWN_KUPPER)) ++ err = au_do_unlink(dmsg, a); ++ if (unlikely(err)) ++ goto out_unlock; ++ ++ /* maintain internal array */ ++ if (!(a->mvdown.flags & AUFS_MVDOWN_KUPPER)) { ++ au_set_h_dptr(a->dentry, a->mvd_bsrc, NULL); ++ 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); ++ } ++ if (au_dbend(a->dentry) < a->mvd_bdst) ++ au_set_dbend(a->dentry, a->mvd_bdst); ++ if (au_ibend(a->inode) < a->mvd_bdst) ++ au_set_ibend(a->inode, a->mvd_bdst); ++ ++out_unlock: ++ au_do_unlock(dmsg, a); ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++/* ---------------------------------------------------------------------- */ ++ ++static int find_lower_writable(struct super_block *sb, aufs_bindex_t bindex) ++{ ++ aufs_bindex_t bend; ++ struct au_branch *br; ++ ++ bend = au_sbend(sb); ++ for (bindex++; bindex <= bend; bindex++) { ++ br = au_sbr(sb, bindex); ++ if (!au_br_rdonly(br)) ++ return bindex; ++ } ++ ++ return -1; ++} ++ ++/* make sure the file is idle */ ++static int au_mvd_args_busy(const unsigned char dmsg, struct au_mvd_args *a) ++{ ++ int err, plinked; ++ struct inode *h_src_inode; ++ ++ err = 0; ++ h_src_inode = au_h_iptr(a->inode, a->mvd_bsrc); ++ plinked = !!au_opt_test(au_mntflags(a->sb), PLINK); ++ if (au_dbstart(a->dentry) == a->mvd_bsrc ++ && a->dentry->d_count == 1 ++ && atomic_read(&a->inode->i_count) == 1 ++ /* && h_src_inode->i_nlink == 1 */ ++ && (!plinked || !au_plink_test(a->inode)) ++ && a->inode->i_nlink == 1) ++ goto out; ++ ++ err = -EBUSY; ++ AU_MVD_PR(dmsg, ++ "b%d, d{b%d, c%u?}, i{c%d?, l%u}, hi{l%u}, p{%d, %d}\n", ++ a->mvd_bsrc, au_dbstart(a->dentry), a->dentry->d_count, ++ atomic_read(&a->inode->i_count), a->inode->i_nlink, ++ h_src_inode->i_nlink, ++ plinked, plinked ? au_plink_test(a->inode) : 0); ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++/* make sure the parent dir is fine */ ++static int au_mvd_args_parent(const unsigned char dmsg, ++ struct au_mvd_args *a) ++{ ++ int err; ++ aufs_bindex_t bindex; ++ ++ err = 0; ++ if (unlikely(au_alive_dir(a->parent))) { ++ err = -ENOENT; ++ AU_MVD_PR(dmsg, "parent dir is dead\n"); ++ goto out; ++ } ++ ++ a->bopq = au_dbdiropq(a->parent); ++ bindex = au_wbr_nonopq(a->dentry, a->mvd_bdst); ++ AuDbg("b%d\n", bindex); ++ if (unlikely((bindex >= 0 && bindex < a->mvd_bdst) ++ || (a->bopq != -1 && a->bopq < a->mvd_bdst))) { ++ err = -EINVAL; ++ a->mvd_errno = EAU_MVDOWN_OPAQUE; ++ AU_MVD_PR(dmsg, "ancestor is opaque b%d, b%d\n", ++ a->bopq, a->mvd_bdst); ++ } ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++static int au_mvd_args_intermediate(const unsigned char dmsg, ++ struct au_mvd_args *a) ++{ ++ int err; ++ struct au_dinfo *dinfo, *tmp; ++ ++ /* lookup the next lower positive entry */ ++ err = -ENOMEM; ++ tmp = au_di_alloc(a->sb, AuLsc_DI_TMP); ++ if (unlikely(!tmp)) ++ goto out; ++ ++ a->bfound = -1; ++ a->bwh = -1; ++ dinfo = au_di(a->dentry); ++ au_di_cp(tmp, dinfo); ++ au_di_swap(tmp, dinfo); ++ ++ /* returns the number of positive dentries */ ++ err = au_lkup_dentry(a->dentry, a->mvd_bsrc + 1, /*type*/0); ++ if (!err) ++ a->bwh = au_dbwh(a->dentry); ++ else if (err > 0) ++ a->bfound = au_dbstart(a->dentry); ++ ++ au_di_swap(tmp, dinfo); ++ au_rw_write_unlock(&tmp->di_rwsem); ++ au_di_free(tmp); ++ if (unlikely(err < 0)) ++ AU_MVD_PR(dmsg, "failed look-up lower\n"); ++ ++ /* ++ * here, we have these cases. ++ * bfound == -1 ++ * no positive dentry under bsrc. there are more sub-cases. ++ * bwh < 0 ++ * there no whiteout, we can safely move-down. ++ * bwh <= bsrc ++ * impossible ++ * bsrc < bwh && bwh < bdst ++ * there is a whiteout on RO branch. cannot proceed. ++ * bwh == bdst ++ * there is a whiteout on the RW target branch. it should ++ * be removed. ++ * bdst < bwh ++ * there is a whiteout somewhere unrelated branch. ++ * -1 < bfound && bfound <= bsrc ++ * impossible. ++ * bfound < bdst ++ * found, but it is on RO branch between bsrc and bdst. cannot ++ * proceed. ++ * bfound == bdst ++ * found, replace it if AUFS_MVDOWN_FORCE is set. otherwise return ++ * error. ++ * bdst < bfound ++ * found, after we create the file on bdst, it will be hidden. ++ */ ++ ++ AuDebugOn(a->bfound == -1 ++ && a->bwh != -1 ++ && a->bwh <= a->mvd_bsrc); ++ AuDebugOn(-1 < a->bfound ++ && a->bfound <= a->mvd_bsrc); ++ ++ err = -EINVAL; ++ if (a->bfound == -1 ++ && a->mvd_bsrc < a->bwh ++ && a->bwh != -1 ++ && a->bwh < a->mvd_bdst) { ++ a->mvd_errno = EAU_MVDOWN_WHITEOUT; ++ AU_MVD_PR(dmsg, "bsrc %d, bdst %d, bfound %d, bwh %d\n", ++ a->mvd_bsrc, a->mvd_bdst, a->bfound, a->bwh); ++ goto out; ++ } else if (a->bfound != -1 && a->bfound < a->mvd_bdst) { ++ a->mvd_errno = EAU_MVDOWN_UPPER; ++ AU_MVD_PR(dmsg, "bdst %d, bfound %d\n", ++ a->mvd_bdst, a->bfound); ++ goto out; ++ } ++ ++ err = 0; /* success */ ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++static int au_mvd_args_exist(const unsigned char dmsg, struct au_mvd_args *a) ++{ ++ int err; ++ ++ err = 0; ++ if (!(a->mvdown.flags & AUFS_MVDOWN_OWLOWER) ++ && a->bfound == a->mvd_bdst) ++ err = -EEXIST; ++ AuTraceErr(err); ++ return err; ++} ++ ++static int au_mvd_args(const unsigned char dmsg, struct au_mvd_args *a) ++{ ++ int err; ++ struct au_branch *br; ++ ++ err = -EISDIR; ++ if (unlikely(S_ISDIR(a->inode->i_mode))) ++ goto out; ++ ++ err = -EINVAL; ++ a->mvd_bsrc = au_ibstart(a->inode); ++ if (unlikely(a->mvd_bsrc == au_sbend(a->sb))) { ++ a->mvd_errno = EAU_MVDOWN_BOTTOM; ++ AU_MVD_PR(dmsg, "on the bottom\n"); ++ goto out; ++ } ++ br = au_sbr(a->sb, a->mvd_bsrc); ++ err = au_br_rdonly(br); ++ if (unlikely(err)) ++ goto out; ++ ++ err = -EINVAL; ++ a->mvd_bdst = find_lower_writable(a->sb, a->mvd_bsrc); ++ if (unlikely(a->mvd_bdst < 0)) { ++ a->mvd_errno = EAU_MVDOWN_BOTTOM; ++ AU_MVD_PR(dmsg, "no writable lower branch\n"); ++ goto out; ++ } ++ ++ err = au_mvd_args_busy(dmsg, a); ++ if (!err) ++ err = au_mvd_args_parent(dmsg, a); ++ if (!err) ++ err = au_mvd_args_intermediate(dmsg, a); ++ if (!err) ++ err = au_mvd_args_exist(dmsg, a); ++ if (!err) ++ AuDbg("b%d, b%d\n", a->mvd_bsrc, a->mvd_bdst); ++ ++out: ++ AuTraceErr(err); ++ return err; ++} ++ ++int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *uarg) ++{ ++ int err, e; ++ unsigned char dmsg; ++ struct au_mvd_args *args; ++ ++ err = -EPERM; ++ if (unlikely(!capable(CAP_SYS_ADMIN))) ++ goto out; ++ ++ err = -ENOMEM; ++ args = kmalloc(sizeof(*args), GFP_NOFS); ++ if (unlikely(!args)) ++ goto out; ++ ++ err = copy_from_user(&args->mvdown, uarg, sizeof(args->mvdown)); ++ if (!err) ++ err = !access_ok(VERIFY_WRITE, &uarg->output, ++ sizeof(uarg->output)); ++ if (unlikely(err)) { ++ err = -EFAULT; ++ AuTraceErr(err); ++ goto out_free; ++ } ++ AuDbg("flags 0x%x\n", args->mvdown.flags); ++ args->mvdown.output.au_errno = 0; ++ args->dentry = dentry; ++ args->inode = dentry->d_inode; ++ args->sb = dentry->d_sb; ++ ++ err = -ENOENT; ++ dmsg = !!(args->mvdown.flags & AUFS_MVDOWN_DMSG); ++ args->parent = dget_parent(dentry); ++ args->dir = args->parent->d_inode; ++ mutex_lock_nested(&args->dir->i_mutex, I_MUTEX_PARENT); ++ dput(args->parent); ++ if (unlikely(args->parent != dentry->d_parent)) { ++ AU_MVD_PR(dmsg, "parent dir is moved\n"); ++ goto out_dir; ++ } ++ ++ mutex_lock_nested(&args->inode->i_mutex, I_MUTEX_CHILD); ++ err = aufs_read_lock(dentry, AuLock_DW | AuLock_FLUSH); ++ if (unlikely(err)) ++ goto out_inode; ++ ++ di_write_lock_parent(args->parent); ++ err = au_mvd_args(dmsg, args); ++ if (unlikely(err)) ++ goto out_parent; ++ ++ AuDbgDentry(dentry); ++ AuDbgInode(args->inode); ++ err = au_do_mvdown(dmsg, args); ++ if (unlikely(err)) ++ goto out_parent; ++ AuDbgDentry(dentry); ++ AuDbgInode(args->inode); ++ ++ 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_digen_dec(dentry); */ ++ ++out_parent: ++ di_write_unlock(args->parent); ++ aufs_read_unlock(dentry, AuLock_DW); ++out_inode: ++ mutex_unlock(&args->inode->i_mutex); ++out_dir: ++ mutex_unlock(&args->dir->i_mutex); ++out_free: ++ e = copy_to_user(&uarg->output, &args->mvdown.output, ++ sizeof(args->mvdown.output)); ++ if (unlikely(e)) ++ err = -EFAULT; ++ kfree(args); ++out: ++ AuTraceErr(err); ++ return err; ++} --- a/fs/aufs/opts.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/opts.c 2013-06-02 19:23:34.753538984 +0200 ++++ b/fs/aufs/opts.c 2013-06-02 18:23:34.753538984 +0100 @@ -0,0 +1,1697 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -21061,7 +21725,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + return au_mntflags(sb) & AuOptMask_UDBA; +} --- a/fs/aufs/opts.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/opts.h 2013-03-10 02:48:58.463093058 +0100 ++++ b/fs/aufs/opts.h 2013-03-10 01:48:58.463093058 +0000 @@ -0,0 +1,209 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -21273,7 +21937,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#endif /* __KERNEL__ */ +#endif /* __AUFS_OPTS_H__ */ --- a/fs/aufs/plink.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/plink.c 2013-08-07 15:04:57.887008639 +0200 ++++ b/fs/aufs/plink.c 2013-08-07 14:04:57.887008639 +0100 @@ -0,0 +1,520 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -21796,7 +22460,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + } +} --- a/fs/aufs/poll.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/poll.c 2013-03-10 02:48:58.463093058 +0100 ++++ b/fs/aufs/poll.c 2013-03-10 01:48:58.463093058 +0000 @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -21855,7 +22519,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + return mask; +} --- a/fs/aufs/procfs.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/procfs.c 2013-03-10 02:48:58.463093058 +0100 ++++ b/fs/aufs/procfs.c 2013-03-10 01:48:58.463093058 +0000 @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2010-2013 Junjiro R. Okajima @@ -22028,7 +22692,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + return err; +} --- a/fs/aufs/rdu.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/rdu.c 2013-08-07 15:04:57.887008639 +0200 ++++ b/fs/aufs/rdu.c 2013-08-31 18:37:41.079378381 +0100 @@ -0,0 +1,384 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -22415,7 +23079,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +} +#endif --- a/fs/aufs/rwsem.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/rwsem.h 2013-03-10 02:48:58.463093058 +0100 ++++ b/fs/aufs/rwsem.h 2013-03-10 01:48:58.463093058 +0000 @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -22606,7 +23270,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#endif /* __KERNEL__ */ +#endif /* __AUFS_RWSEM_H__ */ --- a/fs/aufs/sbinfo.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/sbinfo.c 2013-06-02 19:23:34.753538984 +0200 ++++ b/fs/aufs/sbinfo.c 2013-06-02 18:23:34.753538984 +0100 @@ -0,0 +1,346 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -22955,7 +23619,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + spin_unlock(&sbinfo->au_si_pid.tree_lock); +} --- a/fs/aufs/spl.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/spl.h 2013-06-02 19:23:34.753538984 +0200 ++++ b/fs/aufs/spl.h 2013-06-02 18:23:34.753538984 +0100 @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -23070,7 +23734,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#endif /* __KERNEL__ */ +#endif /* __AUFS_SPL_H__ */ --- a/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/super.c 2013-08-07 15:04:57.887008639 +0200 ++++ b/fs/aufs/super.c 2013-08-31 18:37:45.995378498 +0100 @@ -0,0 +1,992 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -23205,14 +23869,14 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + + AuRwMustAnyLock(&sbinfo->si_rwsem); + -+ seq_printf(m, ",create="); ++ seq_puts(m, ",create="); + pat = au_optstr_wbr_create(v); + switch (v) { + case AuWbrCreate_TDP: + case AuWbrCreate_RR: + case AuWbrCreate_MFS: + case AuWbrCreate_PMFS: -+ seq_printf(m, pat); ++ seq_puts(m, pat); + break; + case AuWbrCreate_MFSV: + seq_printf(m, /*pat*/"mfs:%lu", @@ -24065,8 +24729,8 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + .owner = THIS_MODULE, +}; --- a/fs/aufs/super.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/super.h 2013-06-02 19:23:34.753538984 +0200 -@@ -0,0 +1,555 @@ ++++ b/fs/aufs/super.h 2013-08-31 18:37:45.995378498 +0100 +@@ -0,0 +1,559 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima + * @@ -24340,6 +25004,10 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +extern struct au_wbr_copyup_operations au_wbr_copyup_ops[]; +extern struct au_wbr_create_operations au_wbr_create_ops[]; +int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst); ++int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex); ++ ++/* mvdown.c */ ++int au_mvdown(struct dentry *dentry, struct aufs_mvdown __user *arg); + +/* ---------------------------------------------------------------------- */ + @@ -24623,7 +25291,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#endif /* __KERNEL__ */ +#endif /* __AUFS_SUPER_H__ */ --- a/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/sysaufs.c 2013-03-10 02:48:58.463093058 +0100 ++++ b/fs/aufs/sysaufs.c 2013-03-10 01:48:58.463093058 +0000 @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -24731,7 +25399,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + return err; +} --- a/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/sysaufs.h 2013-03-10 02:48:58.463093058 +0100 ++++ b/fs/aufs/sysaufs.h 2013-03-10 01:48:58.463093058 +0000 @@ -0,0 +1,104 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -24838,7 +25506,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#endif /* __KERNEL__ */ +#endif /* __SYSAUFS_H__ */ --- a/fs/aufs/sysfs.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/sysfs.c 2013-06-02 19:23:34.753538984 +0200 ++++ b/fs/aufs/sysfs.c 2013-06-02 18:23:34.753538984 +0100 @@ -0,0 +1,257 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -25098,7 +25766,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + } +} --- a/fs/aufs/sysrq.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/sysrq.c 2013-08-07 15:04:57.887008639 +0200 ++++ b/fs/aufs/sysrq.c 2013-08-07 14:04:57.887008639 +0100 @@ -0,0 +1,151 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -25252,7 +25920,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + pr_err("err %d (ignored)\n", err); +} --- a/fs/aufs/vdir.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/vdir.c 2013-08-07 15:04:57.887008639 +0200 ++++ b/fs/aufs/vdir.c 2013-08-31 18:37:41.079378381 +0100 @@ -0,0 +1,878 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -26133,7 +26801,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + return 0; +} --- a/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/vfsub.c 2013-08-07 15:04:57.891008639 +0200 ++++ b/fs/aufs/vfsub.c 2013-08-31 18:37:41.079378381 +0100 @@ -0,0 +1,769 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -26905,7 +27573,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + return err; +} --- a/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/vfsub.h 2013-08-07 15:04:57.891008639 +0200 ++++ b/fs/aufs/vfsub.h 2013-08-31 18:37:41.083378381 +0100 @@ -0,0 +1,294 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -27202,8 +27870,8 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#endif /* __KERNEL__ */ +#endif /* __AUFS_VFSUB_H__ */ --- a/fs/aufs/wbr_policy.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/wbr_policy.c 2013-06-02 19:23:34.753538984 +0200 -@@ -0,0 +1,701 @@ ++++ b/fs/aufs/wbr_policy.c 2013-08-31 18:37:45.995378498 +0100 +@@ -0,0 +1,693 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima + * @@ -27266,13 +27934,8 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#define au_fclr_cpdown(flags, name) \ + do { (flags) &= ~AuCpdown_##name; } while (0) + -+struct au_cpdown_dir_args { -+ struct dentry *parent; -+ unsigned int flags; -+}; -+ +static int au_cpdown_dir_opq(struct dentry *dentry, aufs_bindex_t bdst, -+ struct au_cpdown_dir_args *a) ++ unsigned int *flags) +{ + int err; + struct dentry *opq_dentry; @@ -27282,7 +27945,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + if (IS_ERR(opq_dentry)) + goto out; + dput(opq_dentry); -+ au_fset_cpdown(a->flags, DIROPQ); ++ au_fset_cpdown(*flags, DIROPQ); + +out: + return err; @@ -27322,7 +27985,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + struct path h_path; + struct dentry *parent; + struct inode *h_dir, *h_inode, *inode, *dir; -+ struct au_cpdown_dir_args *args = arg; ++ unsigned int *flags = arg; + + bstart = au_dbstart(dentry); + /* dentry is di-locked */ @@ -27341,19 +28004,19 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + S_IRWXU | S_IRUGO | S_IXUGO); + if (unlikely(err)) + goto out_put; -+ au_fset_cpdown(args->flags, MADE_DIR); ++ au_fset_cpdown(*flags, MADE_DIR); + + bopq = au_dbdiropq(dentry); -+ au_fclr_cpdown(args->flags, WHED); -+ au_fclr_cpdown(args->flags, DIROPQ); ++ au_fclr_cpdown(*flags, WHED); ++ au_fclr_cpdown(*flags, DIROPQ); + if (au_dbwh(dentry) == bdst) -+ au_fset_cpdown(args->flags, WHED); -+ if (!au_ftest_cpdown(args->flags, PARENT_OPQ) && bopq <= bdst) -+ au_fset_cpdown(args->flags, PARENT_OPQ); ++ au_fset_cpdown(*flags, WHED); ++ if (!au_ftest_cpdown(*flags, PARENT_OPQ) && bopq <= bdst) ++ au_fset_cpdown(*flags, PARENT_OPQ); + h_inode = h_path.dentry->d_inode; + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); -+ if (au_ftest_cpdown(args->flags, WHED)) { -+ err = au_cpdown_dir_opq(dentry, bdst, args); ++ if (au_ftest_cpdown(*flags, WHED)) { ++ err = au_cpdown_dir_opq(dentry, bdst, flags); + if (unlikely(err)) { + mutex_unlock(&h_inode->i_mutex); + goto out_dir; @@ -27365,7 +28028,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + if (unlikely(err)) + goto out_opq; + -+ if (au_ftest_cpdown(args->flags, WHED)) { ++ if (au_ftest_cpdown(*flags, WHED)) { + err = au_cpdown_dir_wh(dentry, h_parent, dir, bdst); + if (unlikely(err)) + goto out_opq; @@ -27380,7 +28043,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + + /* revert */ +out_opq: -+ if (au_ftest_cpdown(args->flags, DIROPQ)) { ++ if (au_ftest_cpdown(*flags, DIROPQ)) { + mutex_lock_nested(&h_inode->i_mutex, AuLsc_I_CHILD); + rerr = au_diropq_remove(dentry, bdst); + mutex_unlock(&h_inode->i_mutex); @@ -27392,7 +28055,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + } + } +out_dir: -+ if (au_ftest_cpdown(args->flags, MADE_DIR)) { ++ if (au_ftest_cpdown(*flags, MADE_DIR)) { + rerr = vfsub_sio_rmdir(au_h_iptr(dir, bdst), &h_path); + if (unlikely(rerr)) { + AuIOErr("failed removing %.*s b%d (%d)\n", @@ -27412,13 +28075,10 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +int au_cpdown_dirs(struct dentry *dentry, aufs_bindex_t bdst) +{ + int err; -+ struct au_cpdown_dir_args args = { -+ .parent = dget_parent(dentry), -+ .flags = 0 -+ }; ++ unsigned int flags; + -+ err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &args); -+ dput(args.parent); ++ flags = 0; ++ err = au_cp_dirs(dentry, bdst, au_cpdown_dir, &flags); + + return err; +} @@ -27427,7 +28087,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + +/* policies for create */ + -+static int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex) ++int au_wbr_nonopq(struct dentry *dentry, aufs_bindex_t bindex) +{ + int err, i, j, ndentry; + aufs_bindex_t bopq; @@ -27906,7 +28566,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + } +}; --- a/fs/aufs/whout.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/whout.c 2013-08-07 15:04:57.891008639 +0200 ++++ b/fs/aufs/whout.c 2013-08-07 14:04:57.891008639 +0100 @@ -0,0 +1,1022 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -28931,7 +29591,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + } +} --- a/fs/aufs/whout.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/whout.h 2013-06-02 19:23:34.753538984 +0200 ++++ b/fs/aufs/whout.h 2013-06-02 18:23:34.753538984 +0100 @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -29021,7 +29681,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#endif /* __KERNEL__ */ +#endif /* __AUFS_WHOUT_H__ */ --- a/fs/aufs/wkq.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/wkq.c 2013-08-07 15:04:57.891008639 +0200 ++++ b/fs/aufs/wkq.c 2013-08-31 18:37:45.995378498 +0100 @@ -0,0 +1,213 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -29087,7 +29747,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +/* + * Since struct completion is large, try allocating it dynamically. + */ -+#if defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS) ++#if 1 /* defined(CONFIG_4KSTACKS) || defined(AuTest4KSTACKS) */ +#define AuWkqCompDeclare(name) struct completion *comp = NULL + +static int au_wkq_comp_alloc(struct au_wkinfo *wkinfo, struct completion **comp) @@ -29237,7 +29897,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + return err; +} --- a/fs/aufs/wkq.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/wkq.h 2013-03-10 02:48:58.463093058 +0100 ++++ b/fs/aufs/wkq.h 2013-03-10 01:48:58.463093058 +0000 @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -29332,7 +29992,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch +#endif /* __KERNEL__ */ +#endif /* __AUFS_WKQ_H__ */ --- a/fs/aufs/xino.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/xino.c 2013-08-07 15:04:57.891008639 +0200 ++++ b/fs/aufs/xino.c 2013-08-07 14:04:57.891008639 +0100 @@ -0,0 +1,1264 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima @@ -30599,7 +31259,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + return err; +} --- a/include/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/include/linux/aufs_type.h 2013-08-07 15:04:57.891008639 +0200 ++++ b/include/linux/aufs_type.h 2013-08-07 14:04:57.891008639 +0100 @@ -0,0 +1,19 @@ +/* + * Copyright (C) 2012-2013 Junjiro R. Okajima @@ -30621,8 +31281,8 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + +#include --- a/include/uapi/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/include/uapi/linux/aufs_type.h 2013-08-07 15:04:57.891008639 +0200 -@@ -0,0 +1,235 @@ ++++ b/include/uapi/linux/aufs_type.h 2013-08-31 18:37:45.995378498 +0100 +@@ -0,0 +1,270 @@ +/* + * Copyright (C) 2005-2013 Junjiro R. Okajima + * @@ -30665,7 +31325,7 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + +#include + -+#define AUFS_VERSION "3.10-20130805" ++#define AUFS_VERSION "3.10-20130826" + +/* todo? move this to linux-2.6.19/include/magic.h */ +#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') @@ -30758,7 +31418,10 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + AuCtl_WBR_FD, + + /* busy inode */ -+ AuCtl_IBUSY ++ AuCtl_IBUSY, ++ ++ /* move-down */ ++ AuCtl_MVDOWN +}; + +/* borrowed from linux/include/linux/kernel.h */ @@ -30850,11 +31513,43 @@ Patch generated by debian/patches/features/all/aufs3/gen-patch + +/* ---------------------------------------------------------------------- */ + ++/* error code for move-down */ ++/* the actual message strings are implemented in aufs-util.git */ ++enum { ++ EAU_MVDOWN_OPAQUE = 1, ++ EAU_MVDOWN_WHITEOUT, ++ EAU_MVDOWN_UPPER, ++ EAU_MVDOWN_BOTTOM, ++ EAU_Last ++}; ++ ++/* flags for move-down */ ++#define AUFS_MVDOWN_DMSG 1 ++#define AUFS_MVDOWN_OWLOWER (1 << 1) /* overwrite lower */ ++#define AUFS_MVDOWN_KUPPER (1 << 2) /* keep upper */ ++/* will be added more */ ++ ++struct aufs_mvdown { ++ /* input */ ++ uint8_t flags; ++ /* will be added more */ ++ ++ /* output */ ++ struct { ++ int16_t bsrc, bdst; ++ int8_t au_errno; ++ } output; ++} __aligned(8); ++ ++/* ---------------------------------------------------------------------- */ ++ +#define AuCtlType 'A' +#define AUFS_CTL_RDU _IOWR(AuCtlType, AuCtl_RDU, struct aufs_rdu) +#define AUFS_CTL_RDU_INO _IOWR(AuCtlType, AuCtl_RDU_INO, struct aufs_rdu) +#define AUFS_CTL_WBR_FD _IOW(AuCtlType, AuCtl_WBR_FD, \ + struct aufs_wbr_fd) +#define AUFS_CTL_IBUSY _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy) ++#define AUFS_CTL_MVDOWN _IOWR(AuCtlType, AuCtl_MVDOWN, \ ++ struct aufs_mvdown) + +#endif /* __AUFS_TYPE_H__ */ diff --git a/debian/patches/features/all/aufs3/aufs3-base.patch b/debian/patches/features/all/aufs3/aufs3-base.patch index e40fbb4cb..dc708f1f3 100644 --- a/debian/patches/features/all/aufs3/aufs3-base.patch +++ b/debian/patches/features/all/aufs3/aufs3-base.patch @@ -1,7 +1,7 @@ From: J. R. Okajima Date: Wed Jul 3 13:35:19 2013 +0900 Subject: aufs3.10 base patch -Origin: http://sourceforge.net/p/aufs/aufs3-standalone/ci/a1069fdacd4c7e2650d1616c172465c74260600f/tree/ +Origin: http://sourceforge.net/p/aufs/aufs3-standalone/ci/20e965e7cd385ace8c9c36e64673479eeefe379e/tree/ Bug-Debian: http://bugs.debian.org/541828 Patch headers added by debian/patches/features/all/aufs3/gen-patch diff --git a/debian/patches/features/all/aufs3/aufs3-kbuild.patch b/debian/patches/features/all/aufs3/aufs3-kbuild.patch index cf617e1e1..61ab974cf 100644 --- a/debian/patches/features/all/aufs3/aufs3-kbuild.patch +++ b/debian/patches/features/all/aufs3/aufs3-kbuild.patch @@ -1,7 +1,7 @@ From: J. R. Okajima Date: Wed Jul 3 13:35:19 2013 +0900 Subject: aufs3.10 kbuild patch -Origin: http://sourceforge.net/p/aufs/aufs3-standalone/ci/a1069fdacd4c7e2650d1616c172465c74260600f/tree/ +Origin: http://sourceforge.net/p/aufs/aufs3-standalone/ci/20e965e7cd385ace8c9c36e64673479eeefe379e/tree/ Bug-Debian: http://bugs.debian.org/541828 Patch headers added by debian/patches/features/all/aufs3/gen-patch diff --git a/debian/patches/features/all/aufs3/aufs3-standalone.patch b/debian/patches/features/all/aufs3/aufs3-standalone.patch index 2225217ea..863d9a4f1 100644 --- a/debian/patches/features/all/aufs3/aufs3-standalone.patch +++ b/debian/patches/features/all/aufs3/aufs3-standalone.patch @@ -1,7 +1,7 @@ From: J. R. Okajima Date: Wed Jul 3 13:35:19 2013 +0900 Subject: aufs3.10 standalone patch -Origin: http://sourceforge.net/p/aufs/aufs3-standalone/ci/a1069fdacd4c7e2650d1616c172465c74260600f/tree/ +Origin: http://sourceforge.net/p/aufs/aufs3-standalone/ci/20e965e7cd385ace8c9c36e64673479eeefe379e/tree/ Bug-Debian: http://bugs.debian.org/541828 Patch headers added by debian/patches/features/all/aufs3/gen-patch diff --git a/debian/patches/series b/debian/patches/series index 1fa1b9dbc..619f63667 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -28,6 +28,8 @@ features/all/aufs3/aufs3-add.patch debian/aufs3-mark-as-staging.patch # hide broken config option debian/AUFS_PROC_MAP-is-BROKEN.patch +# security fix +features/all/aufs3/aufs-mvdown-don-t-let-unprivileged-users-provoke-a-W.patch # Change some defaults for security reasons features/all/sysrq-mask.patch