diff --git a/debian/changelog b/debian/changelog index f05967a2f..5d4435a1c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -11,6 +11,8 @@ linux-2.6 (2.6.38~rc7-1~experimental.1) UNRELEASED; urgency=low firmware-linux-nonfree 0.29) (Closes: #568454) * perf: Build with libdwarf for improved analysis capabilities * perf: Build with newt for improved user interface (Closes: #615868) + * aufs: Update for 2.6.38 + * aufs: Fix device numbers passed to security_path_mknod() -- maximilian attems Thu, 03 Mar 2011 16:00:38 +0100 diff --git a/debian/config/config b/debian/config/config index 4db4d6276..5a4d3d18b 100644 --- a/debian/config/config +++ b/debian/config/config @@ -2926,21 +2926,21 @@ CONFIG_AFS_FSCACHE=y ## ## file: fs/aufs/Kconfig ## -# CONFIG_AUFS_FS=m -# ## choice: Maximum number of branches -# CONFIG_AUFS_BRANCH_MAX_127=y -# # CONFIG_AUFS_BRANCH_MAX_511 is not set -# # CONFIG_AUFS_BRANCH_MAX_1023 is not set -# # CONFIG_AUFS_BRANCH_MAX_32767 is not set -# ## end choice -# # CONFIG_AUFS_HNOTIFY is not set -# # CONFIG_AUFS_EXPORT is not set -# # CONFIG_AUFS_RDU is not set -# # CONFIG_AUFS_SP_IATTR is not set -# # CONFIG_AUFS_SHWH is not set -# # CONFIG_AUFS_BR_RAMFS is not set -# # CONFIG_AUFS_BR_FUSE is not set -# # CONFIG_AUFS_DEBUG is not set +CONFIG_AUFS_FS=m +## choice: Maximum number of branches +CONFIG_AUFS_BRANCH_MAX_127=y +# CONFIG_AUFS_BRANCH_MAX_511 is not set +# CONFIG_AUFS_BRANCH_MAX_1023 is not set +# CONFIG_AUFS_BRANCH_MAX_32767 is not set +## end choice +# CONFIG_AUFS_HNOTIFY is not set +# CONFIG_AUFS_EXPORT is not set +# CONFIG_AUFS_RDU is not set +# CONFIG_AUFS_SP_IATTR is not set +# CONFIG_AUFS_SHWH is not set +# CONFIG_AUFS_BR_RAMFS is not set +# CONFIG_AUFS_BR_FUSE is not set +# CONFIG_AUFS_DEBUG is not set ## ## file: fs/autofs4/Kconfig diff --git a/debian/patches/features/all/aufs2/Fix-aufs-calling-of-security_path_mknod.patch b/debian/patches/features/all/aufs2/Fix-aufs-calling-of-security_path_mknod.patch new file mode 100644 index 000000000..b62607ab0 --- /dev/null +++ b/debian/patches/features/all/aufs2/Fix-aufs-calling-of-security_path_mknod.patch @@ -0,0 +1,31 @@ +Date: Thu, 24 Feb 2011 09:40:31 -0800 +From: John Johansen +Subject: [natty] Fix aufs calling of security_path_mknod + +Fix aufs calling of security_path_mknod + +BugLink: http://launchpad.net/bugs/724456 + +The security_path_mknod hook requires an encoded 'dev' for its 'dev' paramet +but aufs is calling security_path_mknod with a 'dev' that was already +converted by 'new_decode_dev(dev)'. However security_path_mknod and its +consumer TOMOYO is expecting 'dev' rather than 'new_decode_dev(dev)'. + +This will result in TOMOYO doing new_decode_dev(new_decode_dev(dev)) +(which is wrong) when security_path_mknod() is called from aufs' vfsub_mknod + +Signed-off-by: Tetsuo Handa +Signed-off-by: John Johansen +[bwh: Change source paths for Debian] + +--- a/fs/aufs/vfsub.c ++++ b/fs/aufs/vfsub.c +@@ -276,7 +276,7 @@ int vfsub_mknod(struct inode *dir, struct path *path, int mo + + d = path->dentry; + path->dentry = d->d_parent; +- err = security_path_mknod(path, d, mode, dev); ++ err = security_path_mknod(path, d, mode, new_encode_dev(dev)); + path->dentry = d; + if (unlikely(err)) + goto out; diff --git a/debian/patches/features/all/aufs2/aufs2-add.patch b/debian/patches/features/all/aufs2/aufs2-add.patch index 47361792b..ee82fd264 100644 --- a/debian/patches/features/all/aufs2/aufs2-add.patch +++ b/debian/patches/features/all/aufs2/aufs2-add.patch @@ -1,6 +1,6 @@ diff -urN a/fs/aufs/Kconfig b/fs/aufs/Kconfig --- a/fs/aufs/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/Kconfig 2011-02-12 16:30:08.940114159 +0000 ++++ b/fs/aufs/Kconfig 2011-03-06 23:28:02.616413258 +0000 @@ -0,0 +1,180 @@ +config AUFS_FS + tristate "Aufs (Advanced multi layered unification filesystem) support" @@ -184,7 +184,7 @@ diff -urN a/fs/aufs/Kconfig b/fs/aufs/Kconfig +endif diff -urN a/fs/aufs/Makefile b/fs/aufs/Makefile --- a/fs/aufs/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/Makefile 2011-02-12 16:30:08.940114159 +0000 ++++ b/fs/aufs/Makefile 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,38 @@ + +include ${src}/magic.mk @@ -226,7 +226,7 @@ diff -urN a/fs/aufs/Makefile b/fs/aufs/Makefile +aufs-$(CONFIG_AUFS_MAGIC_SYSRQ) += sysrq.o diff -urN a/fs/aufs/aufs.h b/fs/aufs/aufs.h --- a/fs/aufs/aufs.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/aufs.h 2011-02-12 16:30:08.940114159 +0000 ++++ b/fs/aufs/aufs.h 2011-03-06 23:28:02.616413258 +0000 @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -291,8 +291,8 @@ diff -urN a/fs/aufs/aufs.h b/fs/aufs/aufs.h +#endif /* __AUFS_H__ */ diff -urN a/fs/aufs/branch.c b/fs/aufs/branch.c --- a/fs/aufs/branch.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/branch.c 2011-02-12 16:30:08.940114159 +0000 -@@ -0,0 +1,1072 @@ ++++ b/fs/aufs/branch.c 2011-03-06 23:28:02.616413258 +0000 +@@ -0,0 +1,1160 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima + * @@ -315,6 +315,7 @@ diff -urN a/fs/aufs/branch.c b/fs/aufs/branch.c + * branch management + */ + ++#include +#include +#include +#include "aufs.h" @@ -825,6 +826,18 @@ diff -urN a/fs/aufs/branch.c b/fs/aufs/branch.c + pr_info(fmt, ##__VA_ARGS__); \ +} while (0) + ++static int au_test_ibusy(struct inode *inode, aufs_bindex_t bstart, ++ aufs_bindex_t bend) ++{ ++ return (inode && !S_ISDIR(inode->i_mode)) || bstart == bend; ++} ++ ++static int au_test_dbusy(struct dentry *dentry, aufs_bindex_t bstart, ++ aufs_bindex_t bend) ++{ ++ return au_test_ibusy(dentry->d_inode, bstart, bend); ++} ++ +/* + * test if the branch is deletable or not. + */ @@ -836,7 +849,6 @@ diff -urN a/fs/aufs/branch.c b/fs/aufs/branch.c + struct au_dcsub_pages dpages; + struct au_dpage *dpage; + struct dentry *d; -+ struct inode *inode; + + err = au_dpages_init(&dpages, GFP_NOFS); + if (unlikely(err)) @@ -850,7 +862,7 @@ diff -urN a/fs/aufs/branch.c b/fs/aufs/branch.c + ndentry = dpage->ndentry; + for (j = 0; !err && j < ndentry; j++) { + d = dpage->dentries[j]; -+ AuDebugOn(!atomic_read(&d->d_count)); ++ AuDebugOn(!d->d_count); + if (!au_digen_test(d, sigen)) { + di_read_lock_child(d, AuLock_IR); + if (unlikely(au_dbrange_test(d))) { @@ -873,14 +885,12 @@ diff -urN a/fs/aufs/branch.c b/fs/aufs/branch.c + } + + /* AuDbgDentry(d); */ -+ inode = d->d_inode; + bstart = au_dbstart(d); + bend = au_dbend(d); + if (bstart <= bindex + && bindex <= bend + && au_h_dptr(d, bindex) -+ && ((inode && !S_ISDIR(inode->i_mode)) -+ || bstart == bend)) { ++ && au_test_dbusy(d, bstart, bend)) { + err = -EBUSY; + AuVerbose(verbose, "busy %.*s\n", AuDLNPair(d)); + AuDbgDentry(d); @@ -935,7 +945,7 @@ diff -urN a/fs/aufs/branch.c b/fs/aufs/branch.c + if (bstart <= bindex + && bindex <= bend + && au_h_iptr(i, bindex) -+ && (!S_ISDIR(i->i_mode) || bstart == bend)) { ++ && au_test_ibusy(i, bstart, bend)) { + err = -EBUSY; + AuVerbose(verbose, "busy i%lu\n", i->i_ino); + AuDbgInode(i); @@ -1137,6 +1147,77 @@ diff -urN a/fs/aufs/branch.c b/fs/aufs/branch.c + +/* ---------------------------------------------------------------------- */ + ++static int au_ibusy(struct super_block *sb, struct aufs_ibusy __user *arg) ++{ ++ int err; ++ aufs_bindex_t bstart, bend; ++ struct aufs_ibusy ibusy; ++ struct inode *inode, *h_inode; ++ ++ err = -EPERM; ++ if (unlikely(!capable(CAP_SYS_ADMIN))) ++ goto out; ++ ++ err = copy_from_user(&ibusy, arg, sizeof(ibusy)); ++ if (!err) ++ err = !access_ok(VERIFY_WRITE, &arg->h_ino, sizeof(arg->h_ino)); ++ if (unlikely(err)) { ++ err = -EFAULT; ++ AuTraceErr(err); ++ goto out; ++ } ++ ++ err = -EINVAL; ++ si_read_lock(sb, AuLock_FLUSH); ++ if (unlikely(ibusy.bindex < 0 || ibusy.bindex > au_sbend(sb))) ++ goto out_unlock; ++ ++ err = 0; ++ ibusy.h_ino = 0; /* invalid */ ++ inode = ilookup(sb, ibusy.ino); ++ if (!inode ++ || inode->i_ino == AUFS_ROOT_INO ++ || is_bad_inode(inode)) ++ goto out_unlock; ++ ++ ii_read_lock_child(inode); ++ bstart = au_ibstart(inode); ++ bend = au_ibend(inode); ++ if (bstart <= ibusy.bindex && ibusy.bindex <= bend) { ++ h_inode = au_h_iptr(inode, ibusy.bindex); ++ if (h_inode && au_test_ibusy(inode, bstart, bend)) ++ ibusy.h_ino = h_inode->i_ino; ++ } ++ ii_read_unlock(inode); ++ iput(inode); ++ ++out_unlock: ++ si_read_unlock(sb); ++ if (!err) { ++ err = __put_user(ibusy.h_ino, &arg->h_ino); ++ if (unlikely(err)) { ++ err = -EFAULT; ++ AuTraceErr(err); ++ } ++ } ++out: ++ return err; ++} ++ ++long au_ibusy_ioctl(struct file *file, unsigned long arg) ++{ ++ return au_ibusy(file->f_dentry->d_sb, (void __user *)arg); ++} ++ ++#ifdef CONFIG_COMPAT ++long au_ibusy_compat_ioctl(struct file *file, unsigned long arg) ++{ ++ return au_ibusy(file->f_dentry->d_sb, compat_ptr(arg)); ++} ++#endif ++ ++/* ---------------------------------------------------------------------- */ ++ +/* + * change a branch permission + */ @@ -1206,12 +1287,17 @@ diff -urN a/fs/aufs/branch.c b/fs/aufs/branch.c +static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex) +{ + int err, do_warn; ++ unsigned int mnt_flags; + unsigned long long ull, max; + aufs_bindex_t br_id; ++ unsigned char verbose; + struct file *file, *hf, **array; + struct inode *inode; + struct au_hfile *hfile; + ++ mnt_flags = au_mntflags(sb); ++ verbose = !!au_opt_test(mnt_flags, VERBOSE); ++ + array = au_farray_alloc(sb, &max); + err = PTR_ERR(array); + if (IS_ERR(array)) @@ -1226,6 +1312,8 @@ diff -urN a/fs/aufs/branch.c b/fs/aufs/branch.c + fi_read_lock(file); + if (unlikely(au_test_mmapped(file))) { + err = -EBUSY; ++ AuVerbose(verbose, "mmapped %.*s\n", ++ AuDLNPair(file->f_dentry)); + AuDbgFile(file); + FiMustNoWaiters(file); + fi_read_unlock(file); @@ -1367,8 +1455,8 @@ diff -urN a/fs/aufs/branch.c b/fs/aufs/branch.c +} diff -urN a/fs/aufs/branch.h b/fs/aufs/branch.h --- a/fs/aufs/branch.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/branch.h 2011-02-12 16:30:08.940114159 +0000 -@@ -0,0 +1,229 @@ ++++ b/fs/aufs/branch.h 2011-03-06 23:28:02.616413258 +0000 +@@ -0,0 +1,233 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima + * @@ -1518,6 +1606,10 @@ diff -urN a/fs/aufs/branch.h b/fs/aufs/branch.h +int au_br_add(struct super_block *sb, struct au_opt_add *add, int remount); +struct au_opt_del; +int au_br_del(struct super_block *sb, struct au_opt_del *del, int remount); ++long au_ibusy_ioctl(struct file *file, unsigned long arg); ++#ifdef CONFIG_COMPAT ++long au_ibusy_compat_ioctl(struct file *file, unsigned long arg); ++#endif +struct au_opt_mod; +int au_br_mod(struct super_block *sb, struct au_opt_mod *mod, int remount, + int *do_refresh); @@ -1600,7 +1692,7 @@ diff -urN a/fs/aufs/branch.h b/fs/aufs/branch.h +#endif /* __AUFS_BRANCH_H__ */ diff -urN a/fs/aufs/conf.mk b/fs/aufs/conf.mk --- a/fs/aufs/conf.mk 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/conf.mk 2011-02-12 16:30:08.940114159 +0000 ++++ b/fs/aufs/conf.mk 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,37 @@ + +AuConfStr = CONFIG_AUFS_FS=${CONFIG_AUFS_FS} @@ -1641,7 +1733,7 @@ diff -urN a/fs/aufs/conf.mk b/fs/aufs/conf.mk +-include ${srctree}/${src}/conf_priv.mk diff -urN a/fs/aufs/cpup.c b/fs/aufs/cpup.c --- a/fs/aufs/cpup.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/cpup.c 2011-02-12 16:30:08.940114159 +0000 ++++ b/fs/aufs/cpup.c 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,1063 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -2708,7 +2800,7 @@ diff -urN a/fs/aufs/cpup.c b/fs/aufs/cpup.c +} diff -urN a/fs/aufs/cpup.h b/fs/aufs/cpup.h --- a/fs/aufs/cpup.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/cpup.h 2011-02-12 16:30:08.940114159 +0000 ++++ b/fs/aufs/cpup.h 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -2795,7 +2887,7 @@ diff -urN a/fs/aufs/cpup.h b/fs/aufs/cpup.h +#endif /* __AUFS_CPUP_H__ */ diff -urN a/fs/aufs/dbgaufs.c b/fs/aufs/dbgaufs.c --- a/fs/aufs/dbgaufs.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dbgaufs.c 2011-02-12 16:30:08.940114159 +0000 ++++ b/fs/aufs/dbgaufs.c 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,334 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -3133,7 +3225,7 @@ diff -urN a/fs/aufs/dbgaufs.c b/fs/aufs/dbgaufs.c +} diff -urN a/fs/aufs/dbgaufs.h b/fs/aufs/dbgaufs.h --- a/fs/aufs/dbgaufs.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dbgaufs.h 2011-02-12 16:30:08.940114159 +0000 ++++ b/fs/aufs/dbgaufs.h 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -3189,8 +3281,8 @@ diff -urN a/fs/aufs/dbgaufs.h b/fs/aufs/dbgaufs.h +#endif /* __DBGAUFS_H__ */ diff -urN a/fs/aufs/dcsub.c b/fs/aufs/dcsub.c --- a/fs/aufs/dcsub.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dcsub.c 2011-02-12 16:30:08.940114159 +0000 -@@ -0,0 +1,210 @@ ++++ b/fs/aufs/dcsub.c 2011-03-06 23:28:02.620413138 +0000 +@@ -0,0 +1,243 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima + * @@ -3291,8 +3383,8 @@ diff -urN a/fs/aufs/dcsub.c b/fs/aufs/dcsub.c + dpages->ndpage++; + } + -+ /* d_count can be zero */ -+ dpage->dentries[dpage->ndentry++] = dget_locked(dentry); ++ AuDebugOn(!dentry->d_count); ++ dpage->dentries[dpage->ndentry++] = dget_dlock(dentry); + return 0; /* success */ + +out: @@ -3303,18 +3395,21 @@ diff -urN a/fs/aufs/dcsub.c b/fs/aufs/dcsub.c + au_dpages_test test, void *arg) +{ + int err; -+ struct dentry *this_parent = root; ++ struct dentry *this_parent; + struct list_head *next; + struct super_block *sb = root->d_sb; + + err = 0; -+ spin_lock(&dcache_lock); ++ write_seqlock(&rename_lock); ++ this_parent = root; ++ spin_lock(&this_parent->d_lock); +repeat: + next = this_parent->d_subdirs.next; +resume: + if (this_parent->d_sb == sb + && !IS_ROOT(this_parent) + && au_di(this_parent) ++ && this_parent->d_count + && (!test || test(this_parent, arg))) { + err = au_dpages_append(dpages, this_parent, GFP_ATOMIC); + if (unlikely(err)) @@ -3325,27 +3420,48 @@ diff -urN a/fs/aufs/dcsub.c b/fs/aufs/dcsub.c + struct list_head *tmp = next; + struct dentry *dentry = list_entry(tmp, struct dentry, + d_u.d_child); ++ + next = tmp->next; -+ if (!list_empty(&dentry->d_subdirs)) { -+ this_parent = dentry; -+ goto repeat; -+ } -+ if (dentry->d_sb == sb -+ && au_di(dentry) -+ && (!test || test(dentry, arg))) { -+ err = au_dpages_append(dpages, dentry, GFP_ATOMIC); -+ if (unlikely(err)) -+ goto out; ++ spin_lock_nested(&dentry->d_lock, DENTRY_D_LOCK_NESTED); ++ if (dentry->d_count) { ++ if (!list_empty(&dentry->d_subdirs)) { ++ spin_unlock(&this_parent->d_lock); ++ spin_release(&dentry->d_lock.dep_map, 1, ++ _RET_IP_); ++ this_parent = dentry; ++ spin_acquire(&this_parent->d_lock.dep_map, 0, 1, ++ _RET_IP_); ++ goto repeat; ++ } ++ if (dentry->d_sb == sb ++ && au_di(dentry) ++ && (!test || test(dentry, arg))) ++ err = au_dpages_append(dpages, dentry, ++ GFP_ATOMIC); + } ++ spin_unlock(&dentry->d_lock); ++ if (unlikely(err)) ++ goto out; + } + + if (this_parent != root) { -+ next = this_parent->d_u.d_child.next; -+ this_parent = this_parent->d_parent; /* dcache_lock is locked */ ++ struct dentry *tmp; ++ struct dentry *child; ++ ++ tmp = this_parent->d_parent; ++ rcu_read_lock(); ++ spin_unlock(&this_parent->d_lock); ++ child = this_parent; ++ this_parent = tmp; ++ spin_lock(&this_parent->d_lock); ++ rcu_read_unlock(); ++ next = child->d_u.d_child.next; + goto resume; + } ++ +out: -+ spin_unlock(&dcache_lock); ++ spin_unlock(&this_parent->d_lock); ++ write_sequnlock(&rename_lock); + return err; +} + @@ -3355,24 +3471,33 @@ diff -urN a/fs/aufs/dcsub.c b/fs/aufs/dcsub.c + int err; + + err = 0; -+ spin_lock(&dcache_lock); -+ if (do_include && (!test || test(dentry, arg))) { ++ write_seqlock(&rename_lock); ++ spin_lock(&dentry->d_lock); ++ if (do_include ++ && dentry->d_count ++ && (!test || test(dentry, arg))) + err = au_dpages_append(dpages, dentry, GFP_ATOMIC); -+ if (unlikely(err)) -+ goto out; -+ } ++ spin_unlock(&dentry->d_lock); ++ if (unlikely(err)) ++ goto out; ++ ++ /* ++ * vfsmount_lock is unnecessary since this is a traverse in a single ++ * mount ++ */ + while (!IS_ROOT(dentry)) { -+ dentry = dentry->d_parent; /* dcache_lock is locked */ -+ if (!test || test(dentry, arg)) { ++ dentry = dentry->d_parent; /* rename_lock is locked */ ++ spin_lock(&dentry->d_lock); ++ if (dentry->d_count ++ && (!test || test(dentry, arg))) + err = au_dpages_append(dpages, dentry, GFP_ATOMIC); -+ if (unlikely(err)) -+ break; -+ } ++ spin_unlock(&dentry->d_lock); ++ if (unlikely(err)) ++ break; + } + +out: -+ spin_unlock(&dcache_lock); -+ ++ write_sequnlock(&rename_lock); + return err; +} + @@ -3403,7 +3528,7 @@ diff -urN a/fs/aufs/dcsub.c b/fs/aufs/dcsub.c +} diff -urN a/fs/aufs/dcsub.h b/fs/aufs/dcsub.h --- a/fs/aufs/dcsub.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dcsub.h 2011-02-12 16:30:08.940114159 +0000 ++++ b/fs/aufs/dcsub.h 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -3502,8 +3627,8 @@ diff -urN a/fs/aufs/dcsub.h b/fs/aufs/dcsub.h +#endif /* __AUFS_DCSUB_H__ */ diff -urN a/fs/aufs/debug.c b/fs/aufs/debug.c --- a/fs/aufs/debug.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/debug.c 2011-02-12 16:30:08.940114159 +0000 -@@ -0,0 +1,468 @@ ++++ b/fs/aufs/debug.c 2011-03-06 23:28:02.616413258 +0000 +@@ -0,0 +1,469 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima + * @@ -3648,11 +3773,12 @@ diff -urN a/fs/aufs/debug.c b/fs/aufs/debug.c + return -1; + } + /* do not call dget_parent() here */ ++ /* note: access d_xxx without d_lock */ + dpri("d%d: %.*s?/%.*s, %s, cnt %d, flags 0x%x\n", + bindex, + AuDLNPair(dentry->d_parent), AuDLNPair(dentry), + dentry->d_sb ? au_sbtype(dentry->d_sb) : "??", -+ atomic_read(&dentry->d_count), dentry->d_flags); ++ dentry->d_count, dentry->d_flags); + if (bindex >= 0 && dentry->d_inode && au_test_aufs(dentry->d_sb)) { + struct au_iinfo *iinfo = au_ii(dentry->d_inode); + if (iinfo) @@ -3974,7 +4100,7 @@ diff -urN a/fs/aufs/debug.c b/fs/aufs/debug.c +} diff -urN a/fs/aufs/debug.h b/fs/aufs/debug.h --- a/fs/aufs/debug.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/debug.h 2011-02-12 16:30:08.940114159 +0000 ++++ b/fs/aufs/debug.h 2011-03-06 23:28:02.616413258 +0000 @@ -0,0 +1,245 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -4223,8 +4349,8 @@ diff -urN a/fs/aufs/debug.h b/fs/aufs/debug.h +#endif /* __AUFS_DEBUG_H__ */ diff -urN a/fs/aufs/dentry.c b/fs/aufs/dentry.c --- a/fs/aufs/dentry.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dentry.c 2011-02-12 16:30:08.940114159 +0000 -@@ -0,0 +1,1135 @@ ++++ b/fs/aufs/dentry.c 2011-03-06 23:28:02.620413138 +0000 +@@ -0,0 +1,1140 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima + * @@ -5055,11 +5181,9 @@ diff -urN a/fs/aufs/dentry.c b/fs/aufs/dentry.c + int (*reval)(struct dentry *, struct nameidata *); + + err = 0; -+ reval = NULL; -+ if (h_dentry->d_op) -+ reval = h_dentry->d_op->d_revalidate; -+ if (!reval) ++ if (!(h_dentry->d_flags & DCACHE_OP_REVALIDATE)) + goto out; ++ reval = h_dentry->d_op->d_revalidate; + + AuDbg("b%d\n", bindex); + if (au_test_fs_null_nd(h_dentry->d_sb)) @@ -5142,6 +5266,7 @@ diff -urN a/fs/aufs/dentry.c b/fs/aufs/dentry.c + continue; + + AuDbg("b%d, %.*s\n", bindex, AuDLNPair(h_dentry)); ++ spin_lock(&h_dentry->d_lock); + h_name = &h_dentry->d_name; + if (unlikely(do_udba + && !is_root @@ -5152,8 +5277,10 @@ diff -urN a/fs/aufs/dentry.c b/fs/aufs/dentry.c + AuDbg("unhash 0x%x 0x%x, %.*s %.*s\n", + unhashed, d_unhashed(h_dentry), + AuDLNPair(dentry), AuDLNPair(h_dentry)); ++ spin_unlock(&h_dentry->d_lock); + goto err; + } ++ spin_unlock(&h_dentry->d_lock); + + err = au_do_h_d_reval(h_dentry, nd, dentry, bindex); + if (unlikely(err)) @@ -5272,6 +5399,10 @@ diff -urN a/fs/aufs/dentry.c b/fs/aufs/dentry.c + struct super_block *sb; + struct inode *inode; + ++ /* todo: support rcu-walk? */ ++ if (nd && (nd->flags & LOOKUP_RCU)) ++ return -ECHILD; ++ + valid = 0; + if (unlikely(!au_di(dentry))) + goto out; @@ -5362,7 +5493,7 @@ diff -urN a/fs/aufs/dentry.c b/fs/aufs/dentry.c +}; diff -urN a/fs/aufs/dentry.h b/fs/aufs/dentry.h --- a/fs/aufs/dentry.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dentry.h 2011-02-12 16:30:08.940114159 +0000 ++++ b/fs/aufs/dentry.h 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,237 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -5603,8 +5734,8 @@ diff -urN a/fs/aufs/dentry.h b/fs/aufs/dentry.h +#endif /* __AUFS_DENTRY_H__ */ diff -urN a/fs/aufs/dinfo.c b/fs/aufs/dinfo.c --- a/fs/aufs/dinfo.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dinfo.c 2011-02-12 16:30:08.940114159 +0000 -@@ -0,0 +1,494 @@ ++++ b/fs/aufs/dinfo.c 2011-03-06 23:28:02.620413138 +0000 +@@ -0,0 +1,493 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima + * @@ -5735,7 +5866,6 @@ diff -urN a/fs/aufs/dinfo.c b/fs/aufs/dinfo.c + if (dinfo) { + atomic_set(&dinfo->di_generation, au_sigen(sb)); + /* smp_mb(); */ /* atomic_set */ -+ dentry->d_op = &aufs_dop; + dentry->d_fsdata = dinfo; + } else + err = -ENOMEM; @@ -5926,7 +6056,7 @@ diff -urN a/fs/aufs/dinfo.c b/fs/aufs/dinfo.c + return NULL; + AuDebugOn(bindex < 0); + d = au_di(dentry)->di_hdentry[0 + bindex].hd_dentry; -+ AuDebugOn(d && (atomic_read(&d->d_count) <= 0)); ++ AuDebugOn(d && d->d_count <= 0); + return d; +} + @@ -6101,7 +6231,7 @@ diff -urN a/fs/aufs/dinfo.c b/fs/aufs/dinfo.c +} diff -urN a/fs/aufs/dir.c b/fs/aufs/dir.c --- a/fs/aufs/dir.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dir.c 2011-02-12 16:30:08.944127798 +0000 ++++ b/fs/aufs/dir.c 2011-03-06 23:28:02.616413258 +0000 @@ -0,0 +1,647 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -6752,7 +6882,7 @@ diff -urN a/fs/aufs/dir.c b/fs/aufs/dir.c +}; diff -urN a/fs/aufs/dir.h b/fs/aufs/dir.h --- a/fs/aufs/dir.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dir.h 2011-02-12 16:30:08.944127798 +0000 ++++ b/fs/aufs/dir.h 2011-03-06 23:28:02.616413258 +0000 @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -6894,7 +7024,7 @@ diff -urN a/fs/aufs/dir.h b/fs/aufs/dir.h +#endif /* __AUFS_DIR_H__ */ diff -urN a/fs/aufs/dynop.c b/fs/aufs/dynop.c --- a/fs/aufs/dynop.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dynop.c 2011-02-12 16:30:08.944127798 +0000 ++++ b/fs/aufs/dynop.c 2011-03-06 23:28:02.616413258 +0000 @@ -0,0 +1,426 @@ +/* + * Copyright (C) 2010-2011 Junjiro R. Okajima @@ -7324,7 +7454,7 @@ diff -urN a/fs/aufs/dynop.c b/fs/aufs/dynop.c +} diff -urN a/fs/aufs/dynop.h b/fs/aufs/dynop.h --- a/fs/aufs/dynop.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/dynop.h 2011-02-12 16:30:08.944127798 +0000 ++++ b/fs/aufs/dynop.h 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2010-2011 Junjiro R. Okajima @@ -7417,8 +7547,8 @@ diff -urN a/fs/aufs/dynop.h b/fs/aufs/dynop.h +#endif /* __AUFS_DYNOP_H__ */ diff -urN a/fs/aufs/export.c b/fs/aufs/export.c --- a/fs/aufs/export.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/export.c 2011-02-12 16:30:08.944127798 +0000 -@@ -0,0 +1,798 @@ ++++ b/fs/aufs/export.c 2011-03-06 23:28:02.616413258 +0000 +@@ -0,0 +1,803 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima + * @@ -7506,6 +7636,7 @@ diff -urN a/fs/aufs/export.c b/fs/aufs/export.c + +static int au_test_anon(struct dentry *dentry) +{ ++ /* note: read d_flags without d_lock */ + return !!(dentry->d_flags & DCACHE_DISCONNECTED); +} + @@ -7648,14 +7779,18 @@ diff -urN a/fs/aufs/export.c b/fs/aufs/export.c + if (!dir_ino || S_ISDIR(inode->i_mode)) + dentry = d_find_alias(inode); + else { -+ spin_lock(&dcache_lock); -+ list_for_each_entry(d, &inode->i_dentry, d_alias) ++ spin_lock(&inode->i_lock); ++ list_for_each_entry(d, &inode->i_dentry, d_alias) { ++ spin_lock(&d->d_lock); + if (!au_test_anon(d) + && d->d_parent->d_inode->i_ino == dir_ino) { -+ dentry = dget_locked(d); ++ dentry = dget_dlock(d); ++ spin_unlock(&d->d_lock); + break; + } -+ spin_unlock(&dcache_lock); ++ spin_unlock(&d->d_lock); ++ } ++ spin_unlock(&inode->i_lock); + } + if (unlikely(dentry && au_digen_test(dentry, sigen))) { + dput(dentry); @@ -8219,8 +8354,8 @@ diff -urN a/fs/aufs/export.c b/fs/aufs/export.c +} diff -urN a/fs/aufs/file.c b/fs/aufs/file.c --- a/fs/aufs/file.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/file.c 2011-02-12 16:30:08.944127798 +0000 -@@ -0,0 +1,676 @@ ++++ b/fs/aufs/file.c 2011-03-06 23:28:02.620413138 +0000 +@@ -0,0 +1,679 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima + * @@ -8277,10 +8412,13 @@ diff -urN a/fs/aufs/file.c b/fs/aufs/file.c + h_inode = h_dentry->d_inode; + if (au_test_nfsd() && !h_inode) + goto out; -+ if (unlikely((!d_unhashed(dentry) && d_unlinked(h_dentry)) -+ || !h_inode -+ /* || !dentry->d_inode->i_nlink */ -+ )) ++ spin_lock(&h_dentry->d_lock); ++ err = (!d_unhashed(dentry) && d_unlinked(h_dentry)) ++ || !h_inode ++ /* || !dentry->d_inode->i_nlink */ ++ ; ++ spin_unlock(&h_dentry->d_lock); ++ if (unlikely(err)) + goto out; + + sb = dentry->d_sb; @@ -8899,7 +9037,7 @@ diff -urN a/fs/aufs/file.c b/fs/aufs/file.c +}; diff -urN a/fs/aufs/file.h b/fs/aufs/file.h --- a/fs/aufs/file.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/file.h 2011-02-12 16:30:08.944127798 +0000 ++++ b/fs/aufs/file.h 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,238 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -9141,7 +9279,7 @@ diff -urN a/fs/aufs/file.h b/fs/aufs/file.h +#endif /* __AUFS_FILE_H__ */ diff -urN a/fs/aufs/finfo.c b/fs/aufs/finfo.c --- a/fs/aufs/finfo.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/finfo.c 2011-02-12 16:30:08.944127798 +0000 ++++ b/fs/aufs/finfo.c 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -9319,7 +9457,7 @@ diff -urN a/fs/aufs/finfo.c b/fs/aufs/finfo.c +} diff -urN a/fs/aufs/f_op.c b/fs/aufs/f_op.c --- a/fs/aufs/f_op.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/f_op.c 2011-02-12 16:30:08.944127798 +0000 ++++ b/fs/aufs/f_op.c 2011-03-06 23:28:02.616413258 +0000 @@ -0,0 +1,907 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -10230,7 +10368,7 @@ diff -urN a/fs/aufs/f_op.c b/fs/aufs/f_op.c +}; diff -urN a/fs/aufs/f_op_sp.c b/fs/aufs/f_op_sp.c --- a/fs/aufs/f_op_sp.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/f_op_sp.c 2011-02-12 16:30:08.944127798 +0000 ++++ b/fs/aufs/f_op_sp.c 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,299 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -10533,7 +10671,7 @@ diff -urN a/fs/aufs/f_op_sp.c b/fs/aufs/f_op_sp.c +} diff -urN a/fs/aufs/fstype.h b/fs/aufs/fstype.h --- a/fs/aufs/fstype.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/fstype.h 2011-02-12 16:30:08.944127798 +0000 ++++ b/fs/aufs/fstype.h 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,497 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -11034,7 +11172,7 @@ diff -urN a/fs/aufs/fstype.h b/fs/aufs/fstype.h +#endif /* __AUFS_FSTYPE_H__ */ diff -urN a/fs/aufs/hfsnotify.c b/fs/aufs/hfsnotify.c --- a/fs/aufs/hfsnotify.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/hfsnotify.c 2011-02-12 16:30:08.944127798 +0000 ++++ b/fs/aufs/hfsnotify.c 2011-03-06 23:28:02.616413258 +0000 @@ -0,0 +1,247 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -11285,7 +11423,7 @@ diff -urN a/fs/aufs/hfsnotify.c b/fs/aufs/hfsnotify.c +}; diff -urN a/fs/aufs/hfsplus.c b/fs/aufs/hfsplus.c --- a/fs/aufs/hfsplus.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/hfsplus.c 2011-02-12 16:30:08.944127798 +0000 ++++ b/fs/aufs/hfsplus.c 2011-03-06 23:28:02.616413258 +0000 @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2010-2011 Junjiro R. Okajima @@ -11347,8 +11485,8 @@ diff -urN a/fs/aufs/hfsplus.c b/fs/aufs/hfsplus.c +} diff -urN a/fs/aufs/hnotify.c b/fs/aufs/hnotify.c --- a/fs/aufs/hnotify.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/hnotify.c 2011-02-12 16:30:08.944127798 +0000 -@@ -0,0 +1,696 @@ ++++ b/fs/aufs/hnotify.c 2011-03-06 23:28:02.620413138 +0000 +@@ -0,0 +1,709 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima + * @@ -11562,17 +11700,21 @@ diff -urN a/fs/aufs/hnotify.c b/fs/aufs/hnotify.c + if (!isdir) { + AuDebugOn(!name); + au_iigen_dec(inode); -+ spin_lock(&dcache_lock); ++ spin_lock(&inode->i_lock); + list_for_each_entry(d, &inode->i_dentry, d_alias) { ++ spin_lock(&d->d_lock); + dname = &d->d_name; + if (dname->len != nlen -+ && memcmp(dname->name, name, nlen)) ++ && memcmp(dname->name, name, nlen)) { ++ spin_unlock(&d->d_lock); + continue; ++ } + err = 0; + au_digen_dec(d); ++ spin_unlock(&d->d_lock); + break; + } -+ spin_unlock(&dcache_lock); ++ spin_unlock(&inode->i_lock); + } else { + au_fset_si(au_sbi(inode->i_sb), FAILED_REFRESH_DIR); + d = d_find_alias(inode); @@ -11581,9 +11723,14 @@ diff -urN a/fs/aufs/hnotify.c b/fs/aufs/hnotify.c + goto out; + } + ++ spin_lock(&d->d_lock); + dname = &d->d_name; -+ if (dname->len == nlen && !memcmp(dname->name, name, nlen)) ++ if (dname->len == nlen && !memcmp(dname->name, name, nlen)) { ++ spin_unlock(&d->d_lock); + err = hn_gen_tree(d); ++ spin_lock(&d->d_lock); ++ } ++ spin_unlock(&d->d_lock); + dput(d); + } + @@ -11719,23 +11866,27 @@ diff -urN a/fs/aufs/hnotify.c b/fs/aufs/hnotify.c + return NULL; + + dentry = NULL; -+ spin_lock(&dcache_lock); ++ spin_lock(&parent->d_lock); + list_for_each_entry(d, &parent->d_subdirs, d_u.d_child) { + /* AuDbg("%.*s\n", AuDLNPair(d)); */ ++ spin_lock_nested(&d->d_lock, DENTRY_D_LOCK_NESTED); + dname = &d->d_name; + if (dname->len != nlen || memcmp(dname->name, name, nlen)) -+ continue; ++ goto cont_unlock; + if (au_di(d)) + au_digen_dec(d); + else -+ continue; -+ if (!atomic_read(&d->d_count)) -+ continue; ++ goto cont_unlock; ++ if (d->d_count) { ++ dentry = dget_dlock(d); ++ spin_unlock(&d->d_lock); ++ break; ++ } + -+ dentry = dget(d); -+ break; ++ cont_unlock: ++ spin_unlock(&d->d_lock); + } -+ spin_unlock(&dcache_lock); ++ spin_unlock(&parent->d_lock); + dput(parent); + + if (dentry) @@ -12047,8 +12198,8 @@ diff -urN a/fs/aufs/hnotify.c b/fs/aufs/hnotify.c +} diff -urN a/fs/aufs/iinfo.c b/fs/aufs/iinfo.c --- a/fs/aufs/iinfo.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/iinfo.c 2011-02-12 16:30:08.944127798 +0000 -@@ -0,0 +1,263 @@ ++++ b/fs/aufs/iinfo.c 2011-03-06 23:28:02.616413258 +0000 +@@ -0,0 +1,264 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima + * @@ -12310,11 +12461,12 @@ diff -urN a/fs/aufs/iinfo.c b/fs/aufs/iinfo.c + } + } + kfree(iinfo->ii_hinode); ++ iinfo->ii_hinode = NULL; + AuRwDestroy(&iinfo->ii_rwsem); +} diff -urN a/fs/aufs/inode.c b/fs/aufs/inode.c --- a/fs/aufs/inode.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/inode.c 2011-02-12 16:30:08.944127798 +0000 ++++ b/fs/aufs/inode.c 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,471 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -12789,7 +12941,7 @@ diff -urN a/fs/aufs/inode.c b/fs/aufs/inode.c +} diff -urN a/fs/aufs/inode.h b/fs/aufs/inode.h --- a/fs/aufs/inode.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/inode.h 2011-02-12 16:30:08.944127798 +0000 ++++ b/fs/aufs/inode.h 2011-03-06 23:28:02.616413258 +0000 @@ -0,0 +1,546 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -13339,8 +13491,8 @@ diff -urN a/fs/aufs/inode.h b/fs/aufs/inode.h +#endif /* __AUFS_INODE_H__ */ diff -urN a/fs/aufs/ioctl.c b/fs/aufs/ioctl.c --- a/fs/aufs/ioctl.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/ioctl.c 2011-02-12 16:30:08.948122160 +0000 -@@ -0,0 +1,150 @@ ++++ b/fs/aufs/ioctl.c 2011-03-06 23:28:02.616413258 +0000 +@@ -0,0 +1,158 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima + * @@ -13434,6 +13586,10 @@ diff -urN a/fs/aufs/ioctl.c b/fs/aufs/ioctl.c + err = au_wbr_fd(&file->f_path); + break; + ++ case AUFS_CTL_IBUSY: ++ err = au_ibusy_ioctl(file, arg); ++ break; ++ + default: + /* do not call the lower */ + AuDbg("0x%x\n", cmd); @@ -13475,6 +13631,10 @@ diff -urN a/fs/aufs/ioctl.c b/fs/aufs/ioctl.c + err = au_rdu_compat_ioctl(file, cmd, arg); + break; + ++ case AUFS_CTL_IBUSY: ++ err = au_ibusy_compat_ioctl(file, arg); ++ break; ++ + default: + err = aufs_ioctl_dir(file, cmd, arg); + } @@ -13493,7 +13653,7 @@ diff -urN a/fs/aufs/ioctl.c b/fs/aufs/ioctl.c +#endif diff -urN a/fs/aufs/i_op_add.c b/fs/aufs/i_op_add.c --- a/fs/aufs/i_op_add.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/i_op_add.c 2011-02-12 16:30:08.944127798 +0000 ++++ b/fs/aufs/i_op_add.c 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,702 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -14199,8 +14359,8 @@ diff -urN a/fs/aufs/i_op_add.c b/fs/aufs/i_op_add.c +} diff -urN a/fs/aufs/i_op.c b/fs/aufs/i_op.c --- a/fs/aufs/i_op.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/i_op.c 2011-02-12 16:30:08.944127798 +0000 -@@ -0,0 +1,971 @@ ++++ b/fs/aufs/i_op.c 2011-03-06 23:28:02.616413258 +0000 +@@ -0,0 +1,976 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima + * @@ -14231,7 +14391,7 @@ diff -urN a/fs/aufs/i_op.c b/fs/aufs/i_op.c +#include +#include "aufs.h" + -+static int h_permission(struct inode *h_inode, int mask, ++static int h_permission(struct inode *h_inode, int mask, unsigned int flags, + struct vfsmount *h_mnt, int brperm) +{ + int err; @@ -14255,11 +14415,11 @@ diff -urN a/fs/aufs/i_op.c b/fs/aufs/i_op.c + && write_mask && !(mask & MAY_READ)) + || !h_inode->i_op->permission) { + /* AuLabel(generic_permission); */ -+ err = generic_permission(h_inode, mask, ++ err = generic_permission(h_inode, mask, flags, + h_inode->i_op->check_acl); + } else { + /* AuLabel(h_inode->permission); */ -+ err = h_inode->i_op->permission(h_inode, mask); ++ err = h_inode->i_op->permission(h_inode, mask, flags); + AuTraceErr(err); + } + @@ -14285,7 +14445,7 @@ diff -urN a/fs/aufs/i_op.c b/fs/aufs/i_op.c + return err; +} + -+static int aufs_permission(struct inode *inode, int mask) ++static int aufs_permission(struct inode *inode, int mask, unsigned int flags) +{ + int err; + aufs_bindex_t bindex, bend; @@ -14295,6 +14455,10 @@ diff -urN a/fs/aufs/i_op.c b/fs/aufs/i_op.c + struct super_block *sb; + struct au_branch *br; + ++ /* todo: support rcu-walk? */ ++ if (flags & IPERM_FLAG_RCU) ++ return -ECHILD; ++ + sb = inode->i_sb; + si_read_lock(sb, AuLock_FLUSH); + ii_read_lock_child(inode); @@ -14315,7 +14479,8 @@ diff -urN a/fs/aufs/i_op.c b/fs/aufs/i_op.c + err = 0; + bindex = au_ibstart(inode); + br = au_sbr(sb, bindex); -+ err = h_permission(h_inode, mask, br->br_mnt, br->br_perm); ++ err = h_permission(h_inode, mask, flags, br->br_mnt, ++ br->br_perm); + if (write_mask + && !err + && !special_file(h_inode->i_mode)) { @@ -14341,7 +14506,7 @@ diff -urN a/fs/aufs/i_op.c b/fs/aufs/i_op.c + break; + + br = au_sbr(sb, bindex); -+ err = h_permission(h_inode, mask, br->br_mnt, ++ err = h_permission(h_inode, mask, flags, br->br_mnt, + br->br_perm); + } + } @@ -15174,7 +15339,7 @@ diff -urN a/fs/aufs/i_op.c b/fs/aufs/i_op.c +}; diff -urN a/fs/aufs/i_op_del.c b/fs/aufs/i_op_del.c --- a/fs/aufs/i_op_del.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/i_op_del.c 2011-02-12 16:30:08.944127798 +0000 ++++ b/fs/aufs/i_op_del.c 2011-03-06 23:28:02.616413258 +0000 @@ -0,0 +1,481 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -15659,7 +15824,7 @@ diff -urN a/fs/aufs/i_op_del.c b/fs/aufs/i_op_del.c +} diff -urN a/fs/aufs/i_op_ren.c b/fs/aufs/i_op_ren.c --- a/fs/aufs/i_op_ren.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/i_op_ren.c 2011-02-12 16:30:08.944127798 +0000 ++++ b/fs/aufs/i_op_ren.c 2011-03-06 23:28:02.616413258 +0000 @@ -0,0 +1,1017 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -16680,7 +16845,7 @@ diff -urN a/fs/aufs/i_op_ren.c b/fs/aufs/i_op_ren.c +} diff -urN a/fs/aufs/loop.c b/fs/aufs/loop.c --- a/fs/aufs/loop.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/loop.c 2011-02-12 16:30:08.948122160 +0000 ++++ b/fs/aufs/loop.c 2011-03-06 23:28:02.616413258 +0000 @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -16747,7 +16912,7 @@ diff -urN a/fs/aufs/loop.c b/fs/aufs/loop.c +} diff -urN a/fs/aufs/loop.h b/fs/aufs/loop.h --- a/fs/aufs/loop.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/loop.h 2011-02-12 16:30:08.948122160 +0000 ++++ b/fs/aufs/loop.h 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -16793,7 +16958,7 @@ diff -urN a/fs/aufs/loop.h b/fs/aufs/loop.h +#endif /* __AUFS_LOOP_H__ */ diff -urN a/fs/aufs/magic.mk b/fs/aufs/magic.mk --- a/fs/aufs/magic.mk 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/magic.mk 2011-02-12 16:30:08.948122160 +0000 ++++ b/fs/aufs/magic.mk 2011-03-06 23:28:02.616413258 +0000 @@ -0,0 +1,54 @@ + +# defined in ${srctree}/fs/fuse/inode.c @@ -16851,8 +17016,8 @@ diff -urN a/fs/aufs/magic.mk b/fs/aufs/magic.mk +endif diff -urN a/fs/aufs/module.c b/fs/aufs/module.c --- a/fs/aufs/module.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/module.c 2011-02-12 16:30:08.948122160 +0000 -@@ -0,0 +1,182 @@ ++++ b/fs/aufs/module.c 2011-03-06 23:28:02.616413258 +0000 +@@ -0,0 +1,183 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima + * @@ -16900,6 +17065,7 @@ diff -urN a/fs/aufs/module.c b/fs/aufs/module.c +{ + au_cachep[AuCache_DINFO] = AuCacheCtor(au_dinfo, au_di_init_once); + if (au_cachep[AuCache_DINFO]) ++ /* SLAB_DESTROY_BY_RCU */ + au_cachep[AuCache_ICNTNR] = AuCacheCtor(au_icntnr, + au_icntnr_init_once); + if (au_cachep[AuCache_ICNTNR]) @@ -17037,7 +17203,7 @@ diff -urN a/fs/aufs/module.c b/fs/aufs/module.c +module_exit(aufs_exit); diff -urN a/fs/aufs/module.h b/fs/aufs/module.h --- a/fs/aufs/module.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/module.h 2011-02-12 16:30:08.948122160 +0000 ++++ b/fs/aufs/module.h 2011-03-06 23:28:02.616413258 +0000 @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -17132,7 +17298,7 @@ diff -urN a/fs/aufs/module.h b/fs/aufs/module.h +#endif /* __AUFS_MODULE_H__ */ diff -urN a/fs/aufs/mtx.h b/fs/aufs/mtx.h --- a/fs/aufs/mtx.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/mtx.h 2011-02-12 16:30:08.948122160 +0000 ++++ b/fs/aufs/mtx.h 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2010-2011 Junjiro R. Okajima @@ -17184,7 +17350,7 @@ diff -urN a/fs/aufs/mtx.h b/fs/aufs/mtx.h +#endif /* __AUFS_MTX_H__ */ diff -urN a/fs/aufs/opts.c b/fs/aufs/opts.c --- a/fs/aufs/opts.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/opts.c 2011-02-12 16:30:08.948122160 +0000 ++++ b/fs/aufs/opts.c 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,1595 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -18783,7 +18949,7 @@ diff -urN a/fs/aufs/opts.c b/fs/aufs/opts.c +} diff -urN a/fs/aufs/opts.h b/fs/aufs/opts.h --- a/fs/aufs/opts.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/opts.h 2011-02-12 16:30:08.948122160 +0000 ++++ b/fs/aufs/opts.h 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,210 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -18997,7 +19163,7 @@ diff -urN a/fs/aufs/opts.h b/fs/aufs/opts.h +#endif /* __AUFS_OPTS_H__ */ diff -urN a/fs/aufs/plink.c b/fs/aufs/plink.c --- a/fs/aufs/plink.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/plink.c 2011-02-12 16:30:08.948122160 +0000 ++++ b/fs/aufs/plink.c 2011-03-06 23:28:02.616413258 +0000 @@ -0,0 +1,515 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -19516,7 +19682,7 @@ diff -urN a/fs/aufs/plink.c b/fs/aufs/plink.c +} diff -urN a/fs/aufs/poll.c b/fs/aufs/poll.c --- a/fs/aufs/poll.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/poll.c 2011-02-12 16:30:08.948122160 +0000 ++++ b/fs/aufs/poll.c 2011-03-06 23:28:02.616413258 +0000 @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -19576,7 +19742,7 @@ diff -urN a/fs/aufs/poll.c b/fs/aufs/poll.c +} diff -urN a/fs/aufs/procfs.c b/fs/aufs/procfs.c --- a/fs/aufs/procfs.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/procfs.c 2011-02-12 16:30:08.948122160 +0000 ++++ b/fs/aufs/procfs.c 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,169 @@ +/* + * Copyright (C) 2010-2011 Junjiro R. Okajima @@ -19749,7 +19915,7 @@ diff -urN a/fs/aufs/procfs.c b/fs/aufs/procfs.c +} diff -urN a/fs/aufs/rdu.c b/fs/aufs/rdu.c --- a/fs/aufs/rdu.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/rdu.c 2011-02-12 16:30:08.948122160 +0000 ++++ b/fs/aufs/rdu.c 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,383 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -20136,7 +20302,7 @@ diff -urN a/fs/aufs/rdu.c b/fs/aufs/rdu.c +#endif diff -urN a/fs/aufs/rwsem.h b/fs/aufs/rwsem.h --- a/fs/aufs/rwsem.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/rwsem.h 2011-02-12 16:30:08.948122160 +0000 ++++ b/fs/aufs/rwsem.h 2011-03-06 23:28:02.616413258 +0000 @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -20329,7 +20495,7 @@ diff -urN a/fs/aufs/rwsem.h b/fs/aufs/rwsem.h +#endif /* __AUFS_RWSEM_H__ */ diff -urN a/fs/aufs/sbinfo.c b/fs/aufs/sbinfo.c --- a/fs/aufs/sbinfo.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/sbinfo.c 2011-02-12 16:30:08.948122160 +0000 ++++ b/fs/aufs/sbinfo.c 2011-03-06 23:28:02.616413258 +0000 @@ -0,0 +1,344 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -20677,7 +20843,7 @@ diff -urN a/fs/aufs/sbinfo.c b/fs/aufs/sbinfo.c +} diff -urN a/fs/aufs/spl.h b/fs/aufs/spl.h --- a/fs/aufs/spl.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/spl.h 2011-02-12 16:30:08.948122160 +0000 ++++ b/fs/aufs/spl.h 2011-03-06 23:28:02.616413258 +0000 @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -20747,8 +20913,8 @@ diff -urN a/fs/aufs/spl.h b/fs/aufs/spl.h +#endif /* __AUFS_SPL_H__ */ diff -urN a/fs/aufs/super.c b/fs/aufs/super.c --- a/fs/aufs/super.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/super.c 2011-02-12 16:30:08.948122160 +0000 -@@ -0,0 +1,916 @@ ++++ b/fs/aufs/super.c 2011-03-06 23:28:02.620413138 +0000 +@@ -0,0 +1,925 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima + * @@ -20797,10 +20963,18 @@ diff -urN a/fs/aufs/super.c b/fs/aufs/super.c + return NULL; +} + ++static void aufs_destroy_inode_cb(struct rcu_head *head) ++{ ++ struct inode *inode = container_of(head, struct inode, i_rcu); ++ ++ INIT_LIST_HEAD(&inode->i_dentry); ++ au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode)); ++} ++ +static void aufs_destroy_inode(struct inode *inode) +{ + au_iinfo_fin(inode); -+ au_cache_free_icntnr(container_of(inode, struct au_icntnr, vfs_inode)); ++ call_rcu(&inode->i_rcu, aufs_destroy_inode_cb); +} + +struct inode *au_iget_locked(struct super_block *sb, ino_t ino) @@ -21559,6 +21733,7 @@ diff -urN a/fs/aufs/super.c b/fs/aufs/super.c + /* all timestamps always follow the ones on the branch */ + sb->s_flags |= MS_NOATIME | MS_NODIRATIME; + sb->s_op = &aufs_sop; ++ sb->s_d_op = &aufs_dop; + sb->s_magic = AUFS_SUPER_MAGIC; + sb->s_maxbytes = 0; + au_export_init(sb); @@ -21667,7 +21842,7 @@ diff -urN a/fs/aufs/super.c b/fs/aufs/super.c +}; diff -urN a/fs/aufs/super.h b/fs/aufs/super.h --- a/fs/aufs/super.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/super.h 2011-02-12 16:30:08.948122160 +0000 ++++ b/fs/aufs/super.h 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,527 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -22198,7 +22373,7 @@ diff -urN a/fs/aufs/super.h b/fs/aufs/super.h +#endif /* __AUFS_SUPER_H__ */ diff -urN a/fs/aufs/sysaufs.c b/fs/aufs/sysaufs.c --- a/fs/aufs/sysaufs.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/sysaufs.c 2011-02-12 16:30:08.948122160 +0000 ++++ b/fs/aufs/sysaufs.c 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -22309,7 +22484,7 @@ diff -urN a/fs/aufs/sysaufs.c b/fs/aufs/sysaufs.c +} diff -urN a/fs/aufs/sysaufs.h b/fs/aufs/sysaufs.h --- a/fs/aufs/sysaufs.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/sysaufs.h 2011-02-12 16:30:08.948122160 +0000 ++++ b/fs/aufs/sysaufs.h 2011-03-06 23:28:02.616413258 +0000 @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -22418,7 +22593,7 @@ diff -urN a/fs/aufs/sysaufs.h b/fs/aufs/sysaufs.h +#endif /* __SYSAUFS_H__ */ diff -urN a/fs/aufs/sysfs.c b/fs/aufs/sysfs.c --- a/fs/aufs/sysfs.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/sysfs.c 2011-02-12 16:30:08.948122160 +0000 ++++ b/fs/aufs/sysfs.c 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,250 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -22672,7 +22847,7 @@ diff -urN a/fs/aufs/sysfs.c b/fs/aufs/sysfs.c +} diff -urN a/fs/aufs/sysrq.c b/fs/aufs/sysrq.c --- a/fs/aufs/sysrq.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/sysrq.c 2011-02-12 16:30:08.948122160 +0000 ++++ b/fs/aufs/sysrq.c 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -22824,7 +22999,7 @@ diff -urN a/fs/aufs/sysrq.c b/fs/aufs/sysrq.c +} diff -urN a/fs/aufs/vdir.c b/fs/aufs/vdir.c --- a/fs/aufs/vdir.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/vdir.c 2011-02-12 16:30:08.948122160 +0000 ++++ b/fs/aufs/vdir.c 2011-03-06 23:28:02.616413258 +0000 @@ -0,0 +1,886 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -23714,7 +23889,7 @@ diff -urN a/fs/aufs/vdir.c b/fs/aufs/vdir.c +} diff -urN a/fs/aufs/vfsub.c b/fs/aufs/vfsub.c --- a/fs/aufs/vfsub.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/vfsub.c 2011-02-12 16:30:08.948122160 +0000 ++++ b/fs/aufs/vfsub.c 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,790 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -24448,7 +24623,7 @@ diff -urN a/fs/aufs/vfsub.c b/fs/aufs/vfsub.c + struct dentry *d = a->path->dentry; + struct inode *h_inode; + const int stop_sillyrename = (au_test_nfs(d->d_sb) -+ && atomic_read(&d->d_count) == 1); ++ && d->d_count == 1); + + IMustLock(a->dir); + @@ -24508,7 +24683,7 @@ diff -urN a/fs/aufs/vfsub.c b/fs/aufs/vfsub.c +} diff -urN a/fs/aufs/vfsub.h b/fs/aufs/vfsub.h --- a/fs/aufs/vfsub.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/vfsub.h 2011-02-12 16:30:08.948122160 +0000 ++++ b/fs/aufs/vfsub.h 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,226 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -24738,7 +24913,7 @@ diff -urN a/fs/aufs/vfsub.h b/fs/aufs/vfsub.h +#endif /* __AUFS_VFSUB_H__ */ diff -urN a/fs/aufs/wbr_policy.c b/fs/aufs/wbr_policy.c --- a/fs/aufs/wbr_policy.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/wbr_policy.c 2011-02-12 16:30:08.948122160 +0000 ++++ b/fs/aufs/wbr_policy.c 2011-03-06 23:28:02.616413258 +0000 @@ -0,0 +1,700 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -25442,7 +25617,7 @@ diff -urN a/fs/aufs/wbr_policy.c b/fs/aufs/wbr_policy.c +}; diff -urN a/fs/aufs/whout.c b/fs/aufs/whout.c --- a/fs/aufs/whout.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/whout.c 2011-02-12 16:30:08.948122160 +0000 ++++ b/fs/aufs/whout.c 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,1062 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -25567,7 +25742,7 @@ diff -urN a/fs/aufs/whout.c b/fs/aufs/whout.c +{ + struct dentry *dentry; + int i; -+ char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN_MIN + 1], ++ char defname[NAME_MAX - AUFS_MAX_NAMELEN + DNAME_INLINE_LEN + 1], + *name, *p; + /* strict atomic_t is unnecessary here */ + static unsigned short cnt; @@ -25576,8 +25751,8 @@ diff -urN a/fs/aufs/whout.c b/fs/aufs/whout.c + BUILD_BUG_ON(sizeof(cnt) * 2 > AUFS_WH_TMP_LEN); + + name = defname; -+ qs.len = sizeof(defname) - DNAME_INLINE_LEN_MIN + prefix->len - 1; -+ if (unlikely(prefix->len > DNAME_INLINE_LEN_MIN)) { ++ qs.len = sizeof(defname) - DNAME_INLINE_LEN + prefix->len - 1; ++ if (unlikely(prefix->len > DNAME_INLINE_LEN)) { + dentry = ERR_PTR(-ENAMETOOLONG); + if (unlikely(qs.len > NAME_MAX)) + goto out; @@ -26508,7 +26683,7 @@ diff -urN a/fs/aufs/whout.c b/fs/aufs/whout.c +} diff -urN a/fs/aufs/whout.h b/fs/aufs/whout.h --- a/fs/aufs/whout.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/whout.h 2011-02-12 16:30:08.948122160 +0000 ++++ b/fs/aufs/whout.h 2011-03-06 23:28:02.616413258 +0000 @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -26601,7 +26776,7 @@ diff -urN a/fs/aufs/whout.h b/fs/aufs/whout.h +#endif /* __AUFS_WHOUT_H__ */ diff -urN a/fs/aufs/wkq.c b/fs/aufs/wkq.c --- a/fs/aufs/wkq.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/wkq.c 2011-02-12 16:30:08.952122041 +0000 ++++ b/fs/aufs/wkq.c 2011-03-06 23:28:02.620413138 +0000 @@ -0,0 +1,236 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -26841,7 +27016,7 @@ diff -urN a/fs/aufs/wkq.c b/fs/aufs/wkq.c +} diff -urN a/fs/aufs/wkq.h b/fs/aufs/wkq.h --- a/fs/aufs/wkq.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/wkq.h 2011-02-12 16:30:08.952122041 +0000 ++++ b/fs/aufs/wkq.h 2011-03-06 23:28:02.616413258 +0000 @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -26935,7 +27110,7 @@ diff -urN a/fs/aufs/wkq.h b/fs/aufs/wkq.h +#endif /* __AUFS_WKQ_H__ */ diff -urN a/fs/aufs/xino.c b/fs/aufs/xino.c --- a/fs/aufs/xino.c 1970-01-01 01:00:00.000000000 +0100 -+++ b/fs/aufs/xino.c 2011-02-12 16:30:08.952122041 +0000 ++++ b/fs/aufs/xino.c 2011-03-06 23:28:02.616413258 +0000 @@ -0,0 +1,1265 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima @@ -28204,8 +28379,8 @@ diff -urN a/fs/aufs/xino.c b/fs/aufs/xino.c +} diff -urN a/include/linux/aufs_type.h b/include/linux/aufs_type.h --- a/include/linux/aufs_type.h 1970-01-01 01:00:00.000000000 +0100 -+++ b/include/linux/aufs_type.h 2011-02-12 16:30:08.952122041 +0000 -@@ -0,0 +1,197 @@ ++++ b/include/linux/aufs_type.h 2011-03-06 23:28:02.624413046 +0000 +@@ -0,0 +1,206 @@ +/* + * Copyright (C) 2005-2011 Junjiro R. Okajima + * @@ -28232,7 +28407,7 @@ diff -urN a/include/linux/aufs_type.h b/include/linux/aufs_type.h +#include +#include + -+#define AUFS_VERSION "2.1-standalone.tree-37-20110207" ++#define AUFS_VERSION "2.1-standalone.tree-38-rcN-20110228" + +/* todo? move this to linux-2.6.19/include/magic.h */ +#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's') @@ -28326,7 +28501,10 @@ diff -urN a/include/linux/aufs_type.h b/include/linux/aufs_type.h + AuCtl_RDU_INO, + + /* pathconf wrapper */ -+ AuCtl_WBR_FD ++ AuCtl_WBR_FD, ++ ++ /* busy inode */ ++ AuCtl_IBUSY +}; + +/* borrowed from linux/include/linux/kernel.h */ @@ -28397,9 +28575,15 @@ diff -urN a/include/linux/aufs_type.h b/include/linux/aufs_type.h + struct au_rdu_cookie cookie; +} __aligned(8); + ++struct aufs_ibusy { ++ __u64 ino, h_ino; ++ __s16 bindex; ++} __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 _IO(AuCtlType, AuCtl_WBR_FD) ++#define AUFS_CTL_IBUSY _IOWR(AuCtlType, AuCtl_IBUSY, struct aufs_ibusy) + +#endif /* __AUFS_TYPE_H__ */ diff --git a/debian/patches/features/all/aufs2/aufs2-base.patch b/debian/patches/features/all/aufs2/aufs2-base.patch index 47e2fd5a5..142295cbf 100644 --- a/debian/patches/features/all/aufs2/aufs2-base.patch +++ b/debian/patches/features/all/aufs2/aufs2-base.patch @@ -1,10 +1,10 @@ -aufs2.1 base patch for linux-2.6.37 +aufs2.1 base patch for linux-2.6. diff --git a/fs/namei.c b/fs/namei.c -index 4ff7ca5..a8c583f 100644 +index 0087cf9..cd39cdf 100644 --- a/fs/namei.c +++ b/fs/namei.c -@@ -1161,12 +1161,12 @@ out: +@@ -1841,12 +1841,12 @@ out: * needs parent already locked. Doesn't follow mounts. * SMP-safe. */ @@ -20,10 +20,10 @@ index 4ff7ca5..a8c583f 100644 { unsigned long hash; diff --git a/fs/splice.c b/fs/splice.c -index ce2f025..ff0ae69 100644 +index 50a5d97..886e942 100644 --- a/fs/splice.c +++ b/fs/splice.c -@@ -1092,8 +1092,8 @@ EXPORT_SYMBOL_GPL(generic_splice_sendpage); +@@ -1081,8 +1081,8 @@ EXPORT_SYMBOL_GPL(generic_splice_sendpage); /* * Attempt to initiate a splice from pipe to file. */ @@ -34,7 +34,7 @@ index ce2f025..ff0ae69 100644 { ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); -@@ -1120,9 +1120,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, +@@ -1109,9 +1109,9 @@ static long do_splice_from(struct pipe_inode_info *pipe, struct file *out, /* * Attempt to initiate a splice from a file to a pipe. */ @@ -48,10 +48,10 @@ index ce2f025..ff0ae69 100644 ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); diff --git a/include/linux/namei.h b/include/linux/namei.h -index 05b441d..91bc74e 100644 +index f276d4f..4eb5fcb 100644 --- a/include/linux/namei.h +++ b/include/linux/namei.h -@@ -73,6 +73,9 @@ extern int vfs_path_lookup(struct dentry *, struct vfsmount *, +@@ -79,6 +79,9 @@ extern int vfs_path_lookup(struct dentry *, struct vfsmount *, extern struct file *lookup_instantiate_filp(struct nameidata *nd, struct dentry *dentry, int (*open)(struct inode *, struct file *)); @@ -60,7 +60,7 @@ index 05b441d..91bc74e 100644 + struct dentry *base, int len); extern struct dentry *lookup_one_len(const char *, struct dentry *, int); - extern int follow_down(struct path *); + extern int follow_down_one(struct path *); diff --git a/include/linux/splice.h b/include/linux/splice.h index 997c3b4..be9a153 100644 --- a/include/linux/splice.h diff --git a/debian/patches/features/all/aufs2/aufs2-kbuild.patch b/debian/patches/features/all/aufs2/aufs2-kbuild.patch index 4e58ba197..04f74971b 100644 --- a/debian/patches/features/all/aufs2/aufs2-kbuild.patch +++ b/debian/patches/features/all/aufs2/aufs2-kbuild.patch @@ -1,10 +1,10 @@ -aufs2.1 kbuild patch for linux-2.6.37 +aufs2.1 kbuild patch for linux-2.6. diff --git a/fs/Kconfig b/fs/Kconfig -index 771f457..bb1a52f 100644 +index 3db9caa..c9e1f11 100644 --- a/fs/Kconfig +++ b/fs/Kconfig -@@ -191,6 +191,7 @@ source "fs/romfs/Kconfig" +@@ -190,6 +190,7 @@ source "fs/romfs/Kconfig" source "fs/sysv/Kconfig" source "fs/ufs/Kconfig" source "fs/exofs/Kconfig" @@ -22,10 +22,10 @@ index a7f7cef..95dd4d3 100644 obj-$(CONFIG_CEPH_FS) += ceph/ +obj-$(CONFIG_AUFS_FS) += aufs/ diff --git a/include/linux/Kbuild b/include/linux/Kbuild -index 97319a8..7ebb4b4 100644 +index b0ada6f..5cb5837 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild -@@ -60,6 +60,7 @@ header-y += atmppp.h +@@ -64,6 +64,7 @@ header-y += atmppp.h header-y += atmsap.h header-y += atmsvc.h header-y += audit.h diff --git a/debian/patches/features/all/aufs2/aufs2-standalone.patch b/debian/patches/features/all/aufs2/aufs2-standalone.patch index fb77f7cef..15671dd5c 100644 --- a/debian/patches/features/all/aufs2/aufs2-standalone.patch +++ b/debian/patches/features/all/aufs2/aufs2-standalone.patch @@ -1,7 +1,7 @@ -aufs2.1 standalone patch for linux-2.6.37 +aufs2.1 standalone patch for linux-2.6. diff --git a/fs/file_table.c b/fs/file_table.c -index c3dee38..f529e4d 100644 +index eb36b6b..12f2809 100644 --- a/fs/file_table.c +++ b/fs/file_table.c @@ -393,6 +393,8 @@ void file_sb_list_del(struct file *file) @@ -14,7 +14,7 @@ index c3dee38..f529e4d 100644 /* diff --git a/fs/inode.c b/fs/inode.c -index ae2727a..2c8071a 100644 +index da85e56..b3dc5d8 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -82,6 +82,7 @@ static struct hlist_head *inode_hashtable __read_mostly; @@ -26,10 +26,10 @@ index ae2727a..2c8071a 100644 /* * iprune_sem provides exclusion between the kswapd or try_to_free_pages diff --git a/fs/namei.c b/fs/namei.c -index a8c583f..b020c45 100644 +index cd39cdf..db4290c 100644 --- a/fs/namei.c +++ b/fs/namei.c -@@ -347,6 +347,7 @@ int deny_write_access(struct file * file) +@@ -353,6 +353,7 @@ int deny_write_access(struct file * file) return 0; } @@ -37,7 +37,7 @@ index a8c583f..b020c45 100644 /** * path_get - get a reference to a path -@@ -1165,6 +1166,7 @@ struct dentry *lookup_hash(struct nameidata *nd) +@@ -1845,6 +1846,7 @@ struct dentry *lookup_hash(struct nameidata *nd) { return __lookup_hash(&nd->last, nd->path.dentry, nd); } @@ -45,7 +45,7 @@ index a8c583f..b020c45 100644 int __lookup_one_len(const char *name, struct qstr *this, struct dentry *base, int len) -@@ -1187,6 +1189,7 @@ int __lookup_one_len(const char *name, struct qstr *this, +@@ -1867,6 +1869,7 @@ int __lookup_one_len(const char *name, struct qstr *this, this->hash = end_name_hash(hash); return 0; } @@ -54,10 +54,10 @@ index a8c583f..b020c45 100644 /** * lookup_one_len - filesystem helper to lookup single pathname component diff --git a/fs/namespace.c b/fs/namespace.c -index 3dbfc07..3998762 100644 +index 7b0b953..b304f68 100644 --- a/fs/namespace.c +++ b/fs/namespace.c -@@ -1321,6 +1321,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg, +@@ -1465,6 +1465,7 @@ int iterate_mounts(int (*f)(struct vfsmount *, void *), void *arg, } return 0; } @@ -127,7 +127,7 @@ index 325185e..adede09 100644 static int fsnotify_mark_destroy(void *ignored) { diff --git a/fs/open.c b/fs/open.c -index 4197b9e..912817a 100644 +index 5a2c6eb..f0fa5b2 100644 --- a/fs/open.c +++ b/fs/open.c @@ -60,6 +60,7 @@ int do_truncate(struct dentry *dentry, loff_t length, unsigned int time_attrs, @@ -139,10 +139,10 @@ index 4197b9e..912817a 100644 static long do_sys_truncate(const char __user *pathname, loff_t length) { diff --git a/fs/splice.c b/fs/splice.c -index ff0ae69..1c9e9b0 100644 +index 886e942..9a77a3e 100644 --- a/fs/splice.c +++ b/fs/splice.c -@@ -1116,6 +1116,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out, +@@ -1105,6 +1105,7 @@ long do_splice_from(struct pipe_inode_info *pipe, struct file *out, return splice_write(pipe, out, ppos, len, flags); } @@ -150,7 +150,7 @@ index ff0ae69..1c9e9b0 100644 /* * Attempt to initiate a splice from a file to a pipe. -@@ -1142,6 +1143,7 @@ long do_splice_to(struct file *in, loff_t *ppos, +@@ -1131,6 +1132,7 @@ long do_splice_to(struct file *in, loff_t *ppos, return splice_read(in, ppos, pipe, len, flags); } @@ -180,10 +180,10 @@ index 8d9c48f..29108aa 100644 int devcgroup_inode_mknod(int mode, dev_t dev) { diff --git a/security/security.c b/security/security.c -index 1b798d3..3b7d2ca 100644 +index 7b7308a..140afc7 100644 --- a/security/security.c +++ b/security/security.c -@@ -360,6 +360,7 @@ int security_path_mkdir(struct path *dir, struct dentry *dentry, int mode) +@@ -359,6 +359,7 @@ int security_path_mkdir(struct path *dir, struct dentry *dentry, int mode) return 0; return security_ops->path_mkdir(dir, dentry, mode); } @@ -191,7 +191,7 @@ index 1b798d3..3b7d2ca 100644 int security_path_rmdir(struct path *dir, struct dentry *dentry) { -@@ -367,6 +368,7 @@ int security_path_rmdir(struct path *dir, struct dentry *dentry) +@@ -366,6 +367,7 @@ int security_path_rmdir(struct path *dir, struct dentry *dentry) return 0; return security_ops->path_rmdir(dir, dentry); } @@ -199,7 +199,7 @@ index 1b798d3..3b7d2ca 100644 int security_path_unlink(struct path *dir, struct dentry *dentry) { -@@ -374,6 +376,7 @@ int security_path_unlink(struct path *dir, struct dentry *dentry) +@@ -373,6 +375,7 @@ int security_path_unlink(struct path *dir, struct dentry *dentry) return 0; return security_ops->path_unlink(dir, dentry); } @@ -207,7 +207,7 @@ index 1b798d3..3b7d2ca 100644 int security_path_symlink(struct path *dir, struct dentry *dentry, const char *old_name) -@@ -382,6 +385,7 @@ int security_path_symlink(struct path *dir, struct dentry *dentry, +@@ -381,6 +384,7 @@ int security_path_symlink(struct path *dir, struct dentry *dentry, return 0; return security_ops->path_symlink(dir, dentry, old_name); } @@ -215,7 +215,7 @@ index 1b798d3..3b7d2ca 100644 int security_path_link(struct dentry *old_dentry, struct path *new_dir, struct dentry *new_dentry) -@@ -390,6 +394,7 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir, +@@ -389,6 +393,7 @@ int security_path_link(struct dentry *old_dentry, struct path *new_dir, return 0; return security_ops->path_link(old_dentry, new_dir, new_dentry); } @@ -223,7 +223,7 @@ index 1b798d3..3b7d2ca 100644 int security_path_rename(struct path *old_dir, struct dentry *old_dentry, struct path *new_dir, struct dentry *new_dentry) -@@ -400,6 +405,7 @@ int security_path_rename(struct path *old_dir, struct dentry *old_dentry, +@@ -399,6 +404,7 @@ int security_path_rename(struct path *old_dir, struct dentry *old_dentry, return security_ops->path_rename(old_dir, old_dentry, new_dir, new_dentry); } @@ -231,7 +231,7 @@ index 1b798d3..3b7d2ca 100644 int security_path_truncate(struct path *path) { -@@ -407,6 +413,7 @@ int security_path_truncate(struct path *path) +@@ -406,6 +412,7 @@ int security_path_truncate(struct path *path) return 0; return security_ops->path_truncate(path); } @@ -239,7 +239,7 @@ index 1b798d3..3b7d2ca 100644 int security_path_chmod(struct dentry *dentry, struct vfsmount *mnt, mode_t mode) -@@ -415,6 +422,7 @@ int security_path_chmod(struct dentry *dentry, struct vfsmount *mnt, +@@ -414,6 +421,7 @@ int security_path_chmod(struct dentry *dentry, struct vfsmount *mnt, return 0; return security_ops->path_chmod(dentry, mnt, mode); } @@ -247,7 +247,7 @@ index 1b798d3..3b7d2ca 100644 int security_path_chown(struct path *path, uid_t uid, gid_t gid) { -@@ -422,6 +430,7 @@ int security_path_chown(struct path *path, uid_t uid, gid_t gid) +@@ -421,6 +429,7 @@ int security_path_chown(struct path *path, uid_t uid, gid_t gid) return 0; return security_ops->path_chown(path, uid, gid); } @@ -255,7 +255,7 @@ index 1b798d3..3b7d2ca 100644 int security_path_chroot(struct path *path) { -@@ -498,6 +507,7 @@ int security_inode_readlink(struct dentry *dentry) +@@ -497,6 +506,7 @@ int security_inode_readlink(struct dentry *dentry) return 0; return security_ops->inode_readlink(dentry); } @@ -263,15 +263,15 @@ index 1b798d3..3b7d2ca 100644 int security_inode_follow_link(struct dentry *dentry, struct nameidata *nd) { -@@ -512,6 +522,7 @@ int security_inode_permission(struct inode *inode, int mask) +@@ -511,6 +521,7 @@ int security_inode_permission(struct inode *inode, int mask) return 0; return security_ops->inode_permission(inode, mask); } +EXPORT_SYMBOL_GPL(security_inode_permission); - int security_inode_setattr(struct dentry *dentry, struct iattr *attr) + int security_inode_exec_permission(struct inode *inode, unsigned int flags) { -@@ -611,6 +622,7 @@ int security_file_permission(struct file *file, int mask) +@@ -619,6 +630,7 @@ int security_file_permission(struct file *file, int mask) return fsnotify_perm(file, mask); } @@ -279,7 +279,7 @@ index 1b798d3..3b7d2ca 100644 int security_file_alloc(struct file *file) { -@@ -638,6 +650,7 @@ int security_file_mmap(struct file *file, unsigned long reqprot, +@@ -646,6 +658,7 @@ int security_file_mmap(struct file *file, unsigned long reqprot, return ret; return ima_file_mmap(file, prot); } diff --git a/debian/patches/series/base b/debian/patches/series/base index 02ab8f6f1..639acd18a 100644 --- a/debian/patches/series/base +++ b/debian/patches/series/base @@ -7,13 +7,15 @@ + features/all/sound-pci-cs46xx-request_firmware.patch # patches from aufs2 repository, with s/EXPORT_SYMBOL/&_GPL/ -#+ features/all/aufs2/aufs2-base.patch -#+ features/all/aufs2/aufs2-standalone.patch -#+ features/all/aufs2/aufs2-kbuild.patch -# content of fs/ and include/ from aufs2 repository -#+ features/all/aufs2/aufs2-add.patch ++ features/all/aufs2/aufs2-base.patch ++ features/all/aufs2/aufs2-standalone.patch ++ features/all/aufs2/aufs2-kbuild.patch +# content of fs/ and include/linux/aufs_types.h from aufs2 repository ++ features/all/aufs2/aufs2-add.patch # mark as staging/crap -#+ features/all/aufs2/mark-as-staging.patch ++ features/all/aufs2/mark-as-staging.patch +# fix not upstream yet ++ features/all/aufs2/Fix-aufs-calling-of-security_path_mknod.patch + bugfix/ia64/hardcode-arch-script-output.patch + bugfix/mips/disable-advansys.patch