[kernel] r17013 - in dists/trunk/linux-2.6/debian: . config patches/features/all/aufs2 patches/series

Ben Hutchings benh at alioth.debian.org
Sun Mar 6 23:39:06 UTC 2011


Author: benh
Date: Sun Mar  6 23:39:03 2011
New Revision: 17013

Log:
Update and reenable aufs

Include a fix for a nasty bug in aufs/TOMOYO interaction.
(The fix is not required in squeeze.)

Added:
   dists/trunk/linux-2.6/debian/patches/features/all/aufs2/Fix-aufs-calling-of-security_path_mknod.patch
Modified:
   dists/trunk/linux-2.6/debian/changelog
   dists/trunk/linux-2.6/debian/config/config
   dists/trunk/linux-2.6/debian/patches/features/all/aufs2/aufs2-add.patch
   dists/trunk/linux-2.6/debian/patches/features/all/aufs2/aufs2-base.patch
   dists/trunk/linux-2.6/debian/patches/features/all/aufs2/aufs2-kbuild.patch
   dists/trunk/linux-2.6/debian/patches/features/all/aufs2/aufs2-standalone.patch
   dists/trunk/linux-2.6/debian/patches/series/base

Modified: dists/trunk/linux-2.6/debian/changelog
==============================================================================
--- dists/trunk/linux-2.6/debian/changelog	Sun Mar  6 23:00:01 2011	(r17012)
+++ dists/trunk/linux-2.6/debian/changelog	Sun Mar  6 23:39:03 2011	(r17013)
@@ -11,6 +11,8 @@
     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 <maks at debian.org>  Thu, 03 Mar 2011 16:00:38 +0100
 

Modified: dists/trunk/linux-2.6/debian/config/config
==============================================================================
--- dists/trunk/linux-2.6/debian/config/config	Sun Mar  6 23:00:01 2011	(r17012)
+++ dists/trunk/linux-2.6/debian/config/config	Sun Mar  6 23:39:03 2011	(r17013)
@@ -2926,21 +2926,21 @@
 ##
 ## 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

Added: dists/trunk/linux-2.6/debian/patches/features/all/aufs2/Fix-aufs-calling-of-security_path_mknod.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/trunk/linux-2.6/debian/patches/features/all/aufs2/Fix-aufs-calling-of-security_path_mknod.patch	Sun Mar  6 23:39:03 2011	(r17013)
@@ -0,0 +1,31 @@
+Date: Thu, 24 Feb 2011 09:40:31 -0800
+From: John Johansen <john.johansen at canonical.com>
+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 <penguin-kernel at I-love.SAKURA.ne.jp>
+Signed-off-by: John Johansen <john.johansen at canonical.com>
+[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;

Modified: dists/trunk/linux-2.6/debian/patches/features/all/aufs2/aufs2-add.patch
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/features/all/aufs2/aufs2-add.patch	Sun Mar  6 23:00:01 2011	(r17012)
+++ dists/trunk/linux-2.6/debian/patches/features/all/aufs2/aufs2-add.patch	Sun Mar  6 23:39:03 2011	(r17013)
@@ -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 @@
 +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 @@
 +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 @@
 +#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 @@
 + * branch management
 + */
 +
++#include <linux/compat.h>
 +#include <linux/file.h>
 +#include <linux/statfs.h>
 +#include "aufs.h"
@@ -825,6 +826,18 @@
 +		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 @@
 +	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 @@
 +		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 @@
 +			}
 +
 +			/* 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 @@
 +		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 @@
 +
 +/* ---------------------------------------------------------------------- */
 +
++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 @@
 +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 @@
 +		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.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 @@
 +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 @@
 +#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 @@
 +-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.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 @@
 +#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.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 @@
 +#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 @@
 +		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 @@
 +		   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 @@
 +		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 @@
 +	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.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 @@
 +#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 @@
 +		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.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 @@
 +#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 @@
 +	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 @@
 +			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 @@
 +			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 @@
 +	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.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 @@
 +#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 @@
 +	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 @@
 +		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/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.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 @@
 +#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.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 @@
 +#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 @@
 +
 +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 @@
 +	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/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 @@
 +	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.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 @@
 +#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/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_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/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 @@
 +#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/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/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 @@
 +	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 @@
 +			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 @@
 +		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/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 @@
 +		}
 +	}
 +	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.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 @@
 +#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 @@
 +		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 @@
 +		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 @@
 +#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.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 @@
 +#include <linux/uaccess.h>
 +#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 @@
 +		&& 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 @@
 +	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 @@
 +	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 @@
 +		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 @@
 +				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_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_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/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.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 @@
 +#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 @@
 +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 @@
 +{
 +	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 @@
 +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 @@
 +#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 @@
 +#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.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 @@
 +#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/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/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/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 @@
 +#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 @@
 +#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/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 @@
 +#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 @@
 +	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 @@
 +	/* 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.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 @@
 +#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.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 @@
 +#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/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/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/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 @@
 +	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.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 @@
 +#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/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 @@
 +{
 +	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 @@
 +	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.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 @@
 +#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.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 @@
 +#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/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 @@
 +#include <linux/limits.h>
 +#include <linux/types.h>
 +
-+#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 @@
 +	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 @@
 +	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__ */

Modified: dists/trunk/linux-2.6/debian/patches/features/all/aufs2/aufs2-base.patch
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/features/all/aufs2/aufs2-base.patch	Sun Mar  6 23:00:01 2011	(r17012)
+++ dists/trunk/linux-2.6/debian/patches/features/all/aufs2/aufs2-base.patch	Sun Mar  6 23:39:03 2011	(r17013)
@@ -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 @@
  {
  	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 @@
  {
  	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 @@
  	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 @@
 +			    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

Modified: dists/trunk/linux-2.6/debian/patches/features/all/aufs2/aufs2-kbuild.patch
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/features/all/aufs2/aufs2-kbuild.patch	Sun Mar  6 23:00:01 2011	(r17012)
+++ dists/trunk/linux-2.6/debian/patches/features/all/aufs2/aufs2-kbuild.patch	Sun Mar  6 23:39:03 2011	(r17013)
@@ -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 @@
  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

Modified: dists/trunk/linux-2.6/debian/patches/features/all/aufs2/aufs2-standalone.patch
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/features/all/aufs2/aufs2-standalone.patch	Sun Mar  6 23:00:01 2011	(r17012)
+++ dists/trunk/linux-2.6/debian/patches/features/all/aufs2/aufs2-standalone.patch	Sun Mar  6 23:39:03 2011	(r17013)
@@ -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 @@
  
  /*
 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 @@
  /*
   * 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 @@
  
  /**
   * 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 @@
  
  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 @@
  /**
   * 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 @@
  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 @@
  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 @@
  
  /*
   * 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 @@
  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 @@
  
  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 @@
  
  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 @@
  
  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 @@
  
  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 @@
  
  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 @@
  
  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 @@
  
  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 @@
  
  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 @@
  
  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 @@
  
  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 @@
  
  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);
  }

Modified: dists/trunk/linux-2.6/debian/patches/series/base
==============================================================================
--- dists/trunk/linux-2.6/debian/patches/series/base	Sun Mar  6 23:00:01 2011	(r17012)
+++ dists/trunk/linux-2.6/debian/patches/series/base	Sun Mar  6 23:39:03 2011	(r17013)
@@ -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



More information about the Kernel-svn-changes mailing list