aboutsummaryrefslogtreecommitdiff
path: root/ubuntu
diff options
context:
space:
mode:
authorAndy Whitcroft <apw@canonical.com>2011-05-16 11:04:39 +0100
committerJohn Rigby <john.rigby@linaro.org>2011-11-16 14:24:18 -0700
commitd09bba867f764b36afdd6203eb2984e7b6292e48 (patch)
tree9c64f0844f8700f411988651a1627a7acfadcce7 /ubuntu
parenta1e5843c0d882b7bca9cebc86d065e89cb24a9fd (diff)
UBUNTU: ubuntu: AUFS -- update to c6b76974311efc5bf3eddf921cd015b6aae46935
Remaining Ubuntu Changes: UBUNTU: ubuntu: AUFS -- suppress benign plink warning messages Upstream Changelog: commit c6b76974311efc5bf3eddf921cd015b6aae46935 Author: J. R. Okajima <hooanon05@yahoo.co.jp> Date: Fri Apr 15 18:14:01 2011 +0900 aufs: for .38, replace dcache_lock by i_lock Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> commit 02687391b4084d24af377a774ae25911df49b9e3 Author: J. R. Okajima <hooanon05@yahoo.co.jp> Date: Thu Apr 14 10:47:58 2011 +0900 aufs: possible bugfix, aufs_link supports for a flushed plink In aufs_link(), the given dentry may be a psuedo-link. In this case, aufs should detect it and call vfs_link() for the real inode on the highest branch. A new function au_h_d_alias() is introduced. Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> commit a74d7008d25093b5d1fecb7f33df98570fddbf7e Author: J. R. Okajima <hooanon05@yahoo.co.jp> Date: Wed Apr 13 23:10:40 2011 +0900 aufs: debug, new debug print au_dpri_dalias Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> commit ad8f42b1ece790644d3a050907009a48153de71c Author: J. R. Okajima <hooanon05@yahoo.co.jp> Date: Tue Apr 12 23:38:58 2011 +0900 aufs: possible bugfix, decode_by_ino support for obsolete dentry In decoding the NFS file handle, the cached dentry may be obsoleted by aufs branch mgmt. To support this case, decode_by_ino() returns NULL to force falling to the next level of decoding, eg decode_by_dir_ino. In decode_by_dir_ino(), a new lookup is issued and the dentry will be refreshed. Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> commit 1f2bca01f562d4247494bbf20bcd8860b341d30c Author: J. R. Okajima <hooanon05@yahoo.co.jp> Date: Thu Apr 7 22:07:34 2011 +0900 aufs: tiny, note about ./include/linux/Kbuild Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> commit 2bc4f0f5c84d7f06f24afc30a3d527b6c5762bdf Author: J. R. Okajima <hooanon05@yahoo.co.jp> Date: Thu Apr 7 00:25:09 2011 +0900 aufs: for 2.6.39, more lockdep mgmt a missing lockdep_off/on(). Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> commit 27e557259bad6ebc48d4a811d5ef9db94070aa8b Author: J. R. Okajima <hooanon05@yahoo.co.jp> Date: Mon Apr 4 02:35:07 2011 +0900 aufs: tiny, delete an unnecessary space Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> commit cfab7ccc2ecc838898a3f1a6bb6203ac433791a9 Author: J. R. Okajima <hooanon05@yahoo.co.jp> Date: Fri Apr 1 14:25:49 2011 +0900 aufs: for 2.6.39, lockdep upgrades Simply insert lockdef_off/on() calls in "sub-VFS" character of aufs. Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> commit 17eac367b03334e57a93e8051eb712add24d2534 Author: J. R. Okajima <hooanon05@yahoo.co.jp> Date: Fri Apr 1 16:31:22 2011 +0900 aufs: for 2.6.39, limit the support for IMA Since it acquires i_mutex and causes a deadlock, replace a ima_file_check() call by i_readcount_inc(). Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> commit 4b09fd3cf305c00199059dddb977eea15b43bd47 Author: J. R. Okajima <hooanon05@yahoo.co.jp> Date: Fri Apr 1 14:18:28 2011 +0900 aufs: for 2.6.39, a_op->sync_page is removed Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> commit 8c6f250f54267fd05c2213d5e4a424ea5927dc3b Author: J. R. Okajima <hooanon05@yahoo.co.jp> Date: Fri Apr 1 14:17:44 2011 +0900 aufs stdalone: for 2.6.39, CONFIG_EXPORTFS becomes boolean Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> commit 0932903afb6ceda5523240a9187b7896c446432d Author: J. R. Okajima <hooanon05@yahoo.co.jp> Date: Fri Apr 1 14:17:03 2011 +0900 aufs stdalone: for 2.6.39, export inode_sb_list_lock The role of inode_lock is split into several locks. Simply aufs follows it. Export inode_sb_list_lock for modules. Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> commit 102c58ce81b28613a53b65657bc45e6c52d56534 Author: J. R. Okajima <hooanon05@yahoo.co.jp> Date: Fri Apr 1 14:16:22 2011 +0900 aufs: for 2.6.39, split inode_lock into several locks The role of inode_lock was split into several locks. Simply aufs follows it. Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> commit a2235254f63941d7bcd4099bfbabd134465c3600 Author: J. R. Okajima <hooanon05@yahoo.co.jp> Date: Fri Apr 1 14:11:11 2011 +0900 aufs: for 2.6.39, replace __lookup_one_len by vfsub_name_hash By the commit, 6a96ba5 2011-03-14 kill __lookup_one_len() the function was removed and merged into lookup_one_len(). Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> commit 5ec0835848ad10501993a1ef21ab69c9a6a6b01c Author: J. R. Okajima <hooanon05@yahoo.co.jp> Date: Tue Mar 29 16:26:35 2011 +0900 aufs: tiny, support for new fmode macros Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> commit 26a0f8af5829c88d42db3446ae3778127c7a3f0c Author: J. R. Okajima <hooanon05@yahoo.co.jp> Date: Wed Mar 23 02:27:17 2011 +0900 aufs: version string for aufs2.1-39 Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> commit eef0b4de3c91b95cb48d33286500a486ea3f4424 Author: J. R. Okajima <hooanon05@yahoo.co.jp> Date: Wed Mar 23 02:13:27 2011 +0900 aufs: version string for aufs2.1-38 Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> commit b7f6b930cc0671ccbd7ba4cc0f3aff35ee995834 Author: J. R. Okajima <hooanon05@yahoo.co.jp> Date: Tue Mar 22 23:43:56 2011 +0900 aufs: update donators Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> commit 1c0c29f20a09d1767bfb97348f28b23a056ca5c7 Author: J. R. Okajima <hooanon05@yahoo.co.jp> Date: Wed Mar 2 13:36:35 2011 +0900 aufs: refine a mutex for mmap 3/3, add a condition Acquire fi_mmap mutex lock only when necessary, ie. the file is not mmapped yet. Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> commit 6c4dbe7a9a28134e0246bafbcbdfac1614539fbd Author: J. R. Okajima <hooanon05@yahoo.co.jp> Date: Wed Mar 2 13:34:55 2011 +0900 aufs: refine a mutex for mmap 2/3, replace lockdep_off by dep_map Since it can hide an important debug message, calling lockdep_off/on is a bad approach. But aufs_mmap() does it in switching the owner of fi_mmap mutex lock. Delegating a top-half of aufs_mmap() and switching the owner of fi_mmap is still an ugly approach, but I don't find another way. Without lockdep_off, the kernel debugging feature produces a false message. Stop calling lockdep_off/on, use lockdep_acquire/release instead thus we can get benefit from the debugging feature. This is slightly tricky and a feature for debugging only. Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> commit dcdfe3b9d0e67b2a9636813d452159495d205e92 Author: J. R. Okajima <hooanon05@yahoo.co.jp> Date: Wed Mar 2 13:26:14 2011 +0900 aufs: refine a mutex for mmap 1/3, move functions and make them static Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> commit dcb6ad5eba7d9ef18909068285eefbb1cfe5e589 Author: John Johansen <john.johansen@canonical.com> Date: Mon Feb 28 22:19:38 2011 -0800 Fix aufs call of security_path_mknod 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@I-love.SAKURA.ne.jp> Signed-off-by: John Johansen <john.johansen@canonical.com> Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> commit 36d328cd7d0a68b79b4cbc9dad0af7653b403d36 Author: J. R. Okajima <hooanon05@yahoo.co.jp> Date: Wed Feb 23 01:25:05 2011 +0900 aufs: update the donators list Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> commit f4f4f752d0e83a59b8b36cc6870ca8635ff6f8af Author: J. R. Okajima <hooanon05@yahoo.co.jp> Date: Mon Feb 14 20:57:35 2011 +0900 aufs: tiny, support verbose by au_br_mod() Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> commit 6c2bad0b72d2299476a6fa8f6a6da0b4a2e115eb Author: J. R. Okajima <hooanon05@yahoo.co.jp> Date: Mon Feb 14 15:32:24 2011 +0900 aufs: new ioctl AUFS_CTL_IBUSY This new ioctl interface receives an inode number and a branch index. When the actual (hidden) ino on that branch is in use and makes the branch busy (un-removable), returns the h_ino. Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> commit 5c0aa28ddfc1510834a5eac418e71f242d6061c9 Author: J. R. Okajima <hooanon05@yahoo.co.jp> Date: Mon Feb 14 14:22:18 2011 +0900 aufs: new functions to test EBUSY Extract parts from test_dentry_busy() and test_inode_busy() and create new helper functions au_test_dbusy() and au_test_ibusy(). These functions will be used by a new ioctl to test EBUSY in the future. Signed-off-by: J. R. Okajima <hooanon05@yahoo.co.jp> Signed-off-by: Andy Whitcroft <apw@canonical.com>
Diffstat (limited to 'ubuntu')
-rw-r--r--ubuntu/aufs/BOM2
-rw-r--r--ubuntu/aufs/Kconfig2
-rw-r--r--ubuntu/aufs/branch.c98
-rw-r--r--ubuntu/aufs/branch.h4
-rw-r--r--ubuntu/aufs/debug.c10
-rw-r--r--ubuntu/aufs/debug.h7
-rw-r--r--ubuntu/aufs/dentry.c2
-rw-r--r--ubuntu/aufs/dentry.h1
-rw-r--r--ubuntu/aufs/dinfo.c50
-rw-r--r--ubuntu/aufs/dynop.c1
-rw-r--r--ubuntu/aufs/export.c4
-rw-r--r--ubuntu/aufs/f_op.c42
-rw-r--r--ubuntu/aufs/file.c5
-rw-r--r--ubuntu/aufs/file.h2
-rw-r--r--ubuntu/aufs/finfo.c19
-rw-r--r--ubuntu/aufs/i_op_add.c19
-rw-r--r--ubuntu/aufs/ioctl.c8
-rw-r--r--ubuntu/aufs/super.c16
-rw-r--r--ubuntu/aufs/sysrq.c9
-rw-r--r--ubuntu/aufs/vfsub.c108
-rw-r--r--ubuntu/aufs/vfsub.h5
-rw-r--r--ubuntu/aufs/xino.c4
-rw-r--r--ubuntu/include/linux/aufs_type.h13
23 files changed, 334 insertions, 97 deletions
diff --git a/ubuntu/aufs/BOM b/ubuntu/aufs/BOM
index 1d4f1617bb0..069c9f19c99 100644
--- a/ubuntu/aufs/BOM
+++ b/ubuntu/aufs/BOM
@@ -1,2 +1,2 @@
URL: http://git.c3sl.ufpr.br/pub/scm/aufs/aufs2-standalone.git
-COMMIT: 65835da20b77c98fb538c9114fc31f5de1328230
+COMMIT: c6b76974311efc5bf3eddf921cd015b6aae46935
diff --git a/ubuntu/aufs/Kconfig b/ubuntu/aufs/Kconfig
index 17f8f75a5a6..8ff2bf78a86 100644
--- a/ubuntu/aufs/Kconfig
+++ b/ubuntu/aufs/Kconfig
@@ -72,7 +72,7 @@ endchoice
config AUFS_EXPORT
bool "NFS-exportable aufs"
- depends on (AUFS_FS = y && EXPORTFS = y) || (AUFS_FS = m && EXPORTFS)
+ depends on EXPORTFS
help
If you want to export your mounted aufs via NFS, then enable this
option. There are several requirements for this configuration.
diff --git a/ubuntu/aufs/branch.c b/ubuntu/aufs/branch.c
index 3690dcba970..0c6aabc34dd 100644
--- a/ubuntu/aufs/branch.c
+++ b/ubuntu/aufs/branch.c
@@ -20,6 +20,7 @@
* branch management
*/
+#include <linux/compat.h>
#include <linux/file.h>
#include <linux/statfs.h>
#include "aufs.h"
@@ -530,6 +531,18 @@ out:
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.
*/
@@ -541,7 +554,6 @@ static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
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))
@@ -578,14 +590,12 @@ static int test_dentry_busy(struct dentry *root, aufs_bindex_t bindex,
}
/* 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);
@@ -640,7 +650,7 @@ static int test_inode_busy(struct super_block *sb, aufs_bindex_t bindex,
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);
@@ -842,6 +852,77 @@ out:
/* ---------------------------------------------------------------------- */
+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
*/
@@ -911,12 +992,17 @@ static void au_farray_free(struct file **a, unsigned long long max)
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))
@@ -931,6 +1017,8 @@ static int au_br_mod_files_ro(struct super_block *sb, aufs_bindex_t bindex)
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);
diff --git a/ubuntu/aufs/branch.h b/ubuntu/aufs/branch.h
index fdcaca2cd9f..4fa2b29c636 100644
--- a/ubuntu/aufs/branch.h
+++ b/ubuntu/aufs/branch.h
@@ -147,6 +147,10 @@ struct au_opt_add;
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);
diff --git a/ubuntu/aufs/debug.c b/ubuntu/aufs/debug.c
index 7fea72ae7f6..0b51ff521b0 100644
--- a/ubuntu/aufs/debug.c
+++ b/ubuntu/aufs/debug.c
@@ -133,6 +133,16 @@ void au_dpri_inode(struct inode *inode)
iinfo->ii_hinode[0 + bindex].hi_whdentry);
}
+void au_dpri_dalias(struct inode *inode)
+{
+ struct dentry *d;
+
+ spin_lock(&inode->i_lock);
+ list_for_each_entry(d, &inode->i_dentry, d_alias)
+ au_dpri_dentry(d);
+ spin_unlock(&inode->i_lock);
+}
+
static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry)
{
struct dentry *wh = NULL;
diff --git a/ubuntu/aufs/debug.h b/ubuntu/aufs/debug.h
index 1881844ec59..453459e664d 100644
--- a/ubuntu/aufs/debug.h
+++ b/ubuntu/aufs/debug.h
@@ -122,6 +122,7 @@ struct au_vdir;
void au_dpri_vdir(struct au_vdir *vdir);
struct inode;
void au_dpri_inode(struct inode *inode);
+void au_dpri_dalias(struct inode *inode);
void au_dpri_dentry(struct dentry *dentry);
struct file;
void au_dpri_file(struct file *filp);
@@ -156,6 +157,11 @@ void au_debug_sbinfo_init(struct au_sbinfo *sbinfo);
au_dpri_inode(i); \
} while (0)
+#define AuDbgDAlias(i) do { \
+ AuDbg(#i "\n"); \
+ au_dpri_dalias(i); \
+} while (0)
+
#define AuDbgDentry(d) do { \
AuDbg(#d "\n"); \
au_dpri_dentry(d); \
@@ -210,6 +216,7 @@ AuStubVoid(au_debug_sbinfo_init, struct au_sbinfo *sbinfo)
#define AuDbgWhlist(w) do {} while (0)
#define AuDbgVdir(v) do {} while (0)
#define AuDbgInode(i) do {} while (0)
+#define AuDbgDAlias(i) do {} while (0)
#define AuDbgDentry(d) do {} while (0)
#define AuDbgFile(f) do {} while (0)
#define AuDbgSb(sb) do {} while (0)
diff --git a/ubuntu/aufs/dentry.c b/ubuntu/aufs/dentry.c
index 3c0d0ff0481..176fbdcd6ec 100644
--- a/ubuntu/aufs/dentry.c
+++ b/ubuntu/aufs/dentry.c
@@ -62,7 +62,7 @@ struct dentry *au_lkup_one(struct qstr *name, struct dentry *h_parent,
h_nd.path.dentry = h_parent;
h_nd.path.mnt = br->br_mnt;
- err = __lookup_one_len(name->name, &h_nd.last, NULL, name->len);
+ err = vfsub_name_hash(name->name, &h_nd.last, name->len);
h_dentry = ERR_PTR(err);
if (!err) {
path_get(&h_nd.path);
diff --git a/ubuntu/aufs/dentry.h b/ubuntu/aufs/dentry.h
index 8fd0eba055f..4f0827583c4 100644
--- a/ubuntu/aufs/dentry.h
+++ b/ubuntu/aufs/dentry.h
@@ -80,6 +80,7 @@ void di_write_lock2_parent(struct dentry *d1, struct dentry *d2, int isdir);
void di_write_unlock2(struct dentry *d1, struct dentry *d2);
struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex);
+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex);
aufs_bindex_t au_dbtail(struct dentry *dentry);
aufs_bindex_t au_dbtaildir(struct dentry *dentry);
diff --git a/ubuntu/aufs/dinfo.c b/ubuntu/aufs/dinfo.c
index 17864425311..a2a6809ca7c 100644
--- a/ubuntu/aufs/dinfo.c
+++ b/ubuntu/aufs/dinfo.c
@@ -322,6 +322,56 @@ struct dentry *au_h_dptr(struct dentry *dentry, aufs_bindex_t bindex)
return d;
}
+/*
+ * extended version of au_h_dptr().
+ * returns a hashed and positive h_dentry in bindex, NULL, or error.
+ */
+struct dentry *au_h_d_alias(struct dentry *dentry, aufs_bindex_t bindex)
+{
+ struct dentry *h_dentry;
+ struct inode *inode, *h_inode;
+
+ inode = dentry->d_inode;
+ AuDebugOn(!inode);
+
+ h_dentry = NULL;
+ if (au_dbstart(dentry) <= bindex
+ && bindex <= au_dbend(dentry))
+ h_dentry = au_h_dptr(dentry, bindex);
+ if (h_dentry && !au_d_hashed_positive(h_dentry)) {
+ dget(h_dentry);
+ goto out; /* success */
+ }
+
+ AuDebugOn(bindex < au_ibstart(inode));
+ AuDebugOn(au_ibend(inode) < bindex);
+ h_inode = au_h_iptr(inode, bindex);
+ h_dentry = d_find_alias(h_inode);
+ if (h_dentry) {
+ if (!IS_ERR(h_dentry)) {
+ if (!au_d_hashed_positive(h_dentry))
+ goto out; /* success */
+ dput(h_dentry);
+ } else
+ goto out;
+ }
+
+ if (au_opt_test(au_mntflags(dentry->d_sb), PLINK)) {
+ h_dentry = au_plink_lkup(inode, bindex);
+ AuDebugOn(!h_dentry);
+ if (!IS_ERR(h_dentry)) {
+ if (!au_d_hashed_positive(h_dentry))
+ goto out; /* success */
+ dput(h_dentry);
+ h_dentry = NULL;
+ }
+ }
+
+out:
+ AuDbgDentry(h_dentry);
+ return h_dentry;
+}
+
aufs_bindex_t au_dbtail(struct dentry *dentry)
{
aufs_bindex_t bend, bwh;
diff --git a/ubuntu/aufs/dynop.c b/ubuntu/aufs/dynop.c
index 23b2691af7a..9241616332d 100644
--- a/ubuntu/aufs/dynop.c
+++ b/ubuntu/aufs/dynop.c
@@ -178,7 +178,6 @@ static void dy_aop(struct au_dykey *key, const void *h_op,
DySetAop(writepage);
DySetAopForce(readpage); /* force */
- DySetAop(sync_page);
DySetAop(writepages);
DySetAop(set_page_dirty);
DySetAop(readpages);
diff --git a/ubuntu/aufs/export.c b/ubuntu/aufs/export.c
index 3a6ba18583e..05656fd1cf3 100644
--- a/ubuntu/aufs/export.c
+++ b/ubuntu/aufs/export.c
@@ -242,13 +242,15 @@ static struct dentry *decode_by_ino(struct super_block *sb, ino_t ino,
spin_unlock(&inode->i_lock);
}
if (unlikely(dentry && au_digen_test(dentry, sigen))) {
+ /* need to refresh */
dput(dentry);
- dentry = ERR_PTR(-ESTALE);
+ dentry = NULL;
}
out_iput:
iput(inode);
out:
+ AuTraceErrPtr(dentry);
return dentry;
}
diff --git a/ubuntu/aufs/f_op.c b/ubuntu/aufs/f_op.c
index aa8e3a88eb7..2a875768019 100644
--- a/ubuntu/aufs/f_op.c
+++ b/ubuntu/aufs/f_op.c
@@ -67,7 +67,7 @@ static int aufs_open_nondir(struct inode *inode __maybe_unused,
int err;
struct super_block *sb;
- AuDbg("%.*s, f_ flags 0x%x, f_mode 0x%x\n",
+ AuDbg("%.*s, f_flags 0x%x, f_mode 0x%x\n",
AuDLNPair(file->f_dentry), vfsub_file_flags(file),
file->f_mode);
@@ -225,7 +225,9 @@ static ssize_t au_do_aio(struct file *h_file, int rw, struct kiocb *kio,
if (func) {
file = kio->ki_filp;
kio->ki_filp = h_file;
+ lockdep_off();
err = func(kio, iov, nv, pos);
+ lockdep_on();
kio->ki_filp = file;
} else
/* currently there is no such fs */
@@ -568,6 +570,33 @@ out:
/* very ugly approach */
#include "mtx.h"
+static void au_fi_mmap_lock_and_sell(struct file *file)
+{
+ struct mutex *mtx;
+
+ FiMustWriteLock(file);
+
+ mtx = &au_fi(file)->fi_mmap;
+ mutex_lock(mtx);
+ mutex_release(&mtx->dep_map, /*nested*/0, _RET_IP_);
+}
+
+static void au_fi_mmap_buy(struct file *file)
+{
+ struct mutex *mtx;
+
+ mtx = &au_fi(file)->fi_mmap;
+ MtxMustLock(mtx);
+
+ mutex_set_owner(mtx);
+ mutex_acquire(&mtx->dep_map, /*subclass*/0, /*trylock*/0, _RET_IP_);
+}
+
+static void au_fi_mmap_unlock(struct file *file)
+{
+ mutex_unlock(&au_fi(file)->fi_mmap);
+}
+
struct au_mmap_pre_args {
/* input */
struct file *file;
@@ -613,7 +642,8 @@ static int au_mmap_pre(struct file *file, struct vm_area_struct *vma,
*br = au_sbr(sb, bstart);
*h_file = au_hf_top(file);
get_file(*h_file);
- au_fi_mmap_lock(file);
+ if (!*mmapped)
+ au_fi_mmap_lock_and_sell(file);
out_unlock:
fi_write_unlock(file);
@@ -647,8 +677,8 @@ static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
err = wkq_err;
if (unlikely(err))
goto out;
- finfo = au_fi(file);
- mutex_set_owner(&finfo->fi_mmap);
+ if (!args.mmapped)
+ au_fi_mmap_buy(file);
h_dentry = args.h_file->f_dentry;
if (!args.mmapped && au_test_fs_bad_mapping(h_dentry->d_sb)) {
@@ -667,6 +697,7 @@ static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
err = PTR_ERR(h_vmop);
if (IS_ERR(h_vmop))
goto out_unlock;
+ finfo = au_fi(file);
AuDebugOn(args.mmapped && h_vmop != finfo->fi_hvmop);
vmop = (void *)au_dy_vmop(file, args.br, h_vmop);
@@ -695,7 +726,8 @@ static int aufs_mmap(struct file *file, struct vm_area_struct *vma)
fsstack_copy_attr_atime(file->f_dentry->d_inode, h_dentry->d_inode);
out_unlock:
- au_fi_mmap_unlock(file);
+ if (!args.mmapped)
+ au_fi_mmap_unlock(file);
fput(args.h_file);
out:
return err;
diff --git a/ubuntu/aufs/file.c b/ubuntu/aufs/file.c
index 27785ddc168..b798891953f 100644
--- a/ubuntu/aufs/file.c
+++ b/ubuntu/aufs/file.c
@@ -66,7 +66,7 @@ struct file *au_h_open(struct dentry *dentry, aufs_bindex_t bindex, int flags,
sb = dentry->d_sb;
br = au_sbr(sb, bindex);
h_file = ERR_PTR(-EACCES);
- exec_flag = flags & vfsub_fmode_to_uint(FMODE_EXEC);
+ exec_flag = flags & __FMODE_EXEC;
if (exec_flag && (br->br_mnt->mnt_flags & MNT_NOEXEC))
goto out;
@@ -633,8 +633,6 @@ static int aufs_write_end(struct file *file, struct address_space *mapping,
{ AuUnsupport(); return 0; }
static int aufs_writepage(struct page *page, struct writeback_control *wbc)
{ AuUnsupport(); return 0; }
-static void aufs_sync_page(struct page *page)
-{ AuUnsupport(); }
static int aufs_set_page_dirty(struct page *page)
{ AuUnsupport(); return 0; }
@@ -662,7 +660,6 @@ const struct address_space_operations aufs_aop = {
.get_xip_mem = aufs_get_xip_mem,
#ifdef CONFIG_AUFS_DEBUG
.writepage = aufs_writepage,
- .sync_page = aufs_sync_page,
/* no writepages, because of writepage */
.set_page_dirty = aufs_set_page_dirty,
/* no readpages, because of readpage */
diff --git a/ubuntu/aufs/file.h b/ubuntu/aufs/file.h
index 5ee45a10abd..7454a0e5e2b 100644
--- a/ubuntu/aufs/file.h
+++ b/ubuntu/aufs/file.h
@@ -129,8 +129,6 @@ void au_set_h_fptr(struct file *file, aufs_bindex_t bindex,
struct file *h_file);
void au_update_figen(struct file *file);
-void au_fi_mmap_lock(struct file *file);
-void au_fi_mmap_unlock(struct file *file);
struct au_fidir *au_fidir_alloc(struct super_block *sb);
int au_fidir_realloc(struct au_finfo *finfo, int nbr);
diff --git a/ubuntu/aufs/finfo.c b/ubuntu/aufs/finfo.c
index b8fa4d853a4..b3882063f34 100644
--- a/ubuntu/aufs/finfo.c
+++ b/ubuntu/aufs/finfo.c
@@ -26,7 +26,7 @@
void au_hfput(struct au_hfile *hf, struct file *file)
{
/* todo: direct access f_flags */
- if (vfsub_file_flags(file) & vfsub_fmode_to_uint(FMODE_EXEC))
+ if (vfsub_file_flags(file) & __FMODE_EXEC)
allow_write_access(hf->hf_file);
fput(hf->hf_file);
hf->hf_file = NULL;
@@ -64,23 +64,6 @@ void au_update_figen(struct file *file)
/* ---------------------------------------------------------------------- */
-void au_fi_mmap_lock(struct file *file)
-{
- FiMustWriteLock(file);
- lockdep_off();
- mutex_lock(&au_fi(file)->fi_mmap);
- lockdep_on();
-}
-
-void au_fi_mmap_unlock(struct file *file)
-{
- lockdep_off();
- mutex_unlock(&au_fi(file)->fi_mmap);
- lockdep_on();
-}
-
-/* ---------------------------------------------------------------------- */
-
struct au_fidir *au_fidir_alloc(struct super_block *sb)
{
struct au_fidir *fidir;
diff --git a/ubuntu/aufs/i_op_add.c b/ubuntu/aufs/i_op_add.c
index 070f6314ece..8bf18f496e2 100644
--- a/ubuntu/aufs/i_op_add.c
+++ b/ubuntu/aufs/i_op_add.c
@@ -453,6 +453,7 @@ static int au_cpup_or_link(struct dentry *src_dentry, struct au_link_args *a)
au_plink_append(inode, a->bdst, a->h_path.dentry);
out:
+ AuTraceErr(err);
return err;
}
@@ -492,7 +493,7 @@ int aufs_link(struct dentry *src_dentry, struct inode *dir,
goto out_unlock;
a->src_parent = dget_parent(src_dentry);
- wr_dir_args.force_btgt = au_dbstart(src_dentry);
+ wr_dir_args.force_btgt = au_ibstart(inode);
di_write_lock_parent(a->parent);
wr_dir_args.force_btgt = au_wbr(dentry, wr_dir_args.force_btgt);
@@ -507,21 +508,29 @@ int aufs_link(struct dentry *src_dentry, struct inode *dir,
a->bdst = au_dbstart(dentry);
a->h_path.dentry = au_h_dptr(dentry, a->bdst);
a->h_path.mnt = au_sbr_mnt(sb, a->bdst);
- a->bsrc = au_dbstart(src_dentry);
+ a->bsrc = au_ibstart(inode);
+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
+ if (!h_src_dentry) {
+ a->bsrc = au_dbstart(src_dentry);
+ h_src_dentry = au_h_d_alias(src_dentry, a->bsrc);
+ AuDebugOn(!h_src_dentry);
+ } else if (IS_ERR(h_src_dentry))
+ goto out_parent;
+
if (au_opt_test(au_mntflags(sb), PLINK)) {
if (a->bdst < a->bsrc
/* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */)
err = au_cpup_or_link(src_dentry, a);
- else {
- h_src_dentry = au_h_dptr(src_dentry, a->bdst);
+ else
err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
&a->h_path);
- }
+ dput(h_src_dentry);
} else {
/*
* copyup src_dentry to the branch we process,
* and then link(2) to it.
*/
+ dput(h_src_dentry);
if (a->bdst < a->bsrc
/* && h_src_dentry->d_sb != a->h_path.dentry->d_sb */) {
au_unpin(&a->pin);
diff --git a/ubuntu/aufs/ioctl.c b/ubuntu/aufs/ioctl.c
index bb87a2229a8..e6695086dc5 100644
--- a/ubuntu/aufs/ioctl.c
+++ b/ubuntu/aufs/ioctl.c
@@ -91,6 +91,10 @@ long aufs_ioctl_dir(struct file *file, unsigned int cmd, unsigned long arg)
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);
@@ -132,6 +136,10 @@ long aufs_compat_ioctl_dir(struct file *file, unsigned int cmd,
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);
}
diff --git a/ubuntu/aufs/super.c b/ubuntu/aufs/super.c
index d5e0cd58087..bb5b1829d0e 100644
--- a/ubuntu/aufs/super.c
+++ b/ubuntu/aufs/super.c
@@ -450,17 +450,21 @@ static unsigned long long au_iarray_cb(void *a,
n = 0;
p = a;
head = arg;
- spin_lock(&inode_lock);
+ spin_lock(&inode_sb_list_lock);
list_for_each_entry(inode, head, i_sb_list) {
if (!is_bad_inode(inode)
&& au_ii(inode)->ii_bstart >= 0) {
- au_igrab(inode);
- *p++ = inode;
- n++;
- AuDebugOn(n > max);
+ spin_lock(&inode->i_lock);
+ if (atomic_read(&inode->i_count)) {
+ au_igrab(inode);
+ *p++ = inode;
+ n++;
+ AuDebugOn(n > max);
+ }
+ spin_unlock(&inode->i_lock);
}
}
- spin_unlock(&inode_lock);
+ spin_unlock(&inode_sb_list_lock);
return n;
}
diff --git a/ubuntu/aufs/sysrq.c b/ubuntu/aufs/sysrq.c
index 99589d3048a..b427e477c02 100644
--- a/ubuntu/aufs/sysrq.c
+++ b/ubuntu/aufs/sysrq.c
@@ -76,11 +76,14 @@ static void sysrq_sb(struct super_block *sb)
{
struct inode *i;
printk(KERN_WARNING AUFS_NAME ": isolated inode\n");
- spin_lock(&inode_lock);
- list_for_each_entry(i, &sb->s_inodes, i_sb_list)
+ spin_lock(&inode_sb_list_lock);
+ list_for_each_entry(i, &sb->s_inodes, i_sb_list) {
+ spin_lock(&i->i_lock);
if (1 || list_empty(&i->i_dentry))
au_dpri_inode(i);
- spin_unlock(&inode_lock);
+ spin_unlock(&i->i_lock);
+ }
+ spin_unlock(&inode_sb_list_lock);
}
#endif
printk(KERN_WARNING AUFS_NAME ": files\n");
diff --git a/ubuntu/aufs/vfsub.c b/ubuntu/aufs/vfsub.c
index 40f6aefefa8..7b3cf55f342 100644
--- a/ubuntu/aufs/vfsub.c
+++ b/ubuntu/aufs/vfsub.c
@@ -50,51 +50,18 @@ int vfsub_update_h_iattr(struct path *h_path, int *did)
/* ---------------------------------------------------------------------- */
-static int au_conv_oflags(int flags)
-{
- int mask = 0;
-
-#ifdef CONFIG_IMA
- fmode_t fmode;
-
- /* mask = MAY_OPEN; */
- fmode = OPEN_FMODE(flags);
- if (fmode & FMODE_READ)
- mask |= MAY_READ;
- if ((fmode & FMODE_WRITE)
- || (flags & O_TRUNC))
- mask |= MAY_WRITE;
- /*
- * if (flags & O_APPEND)
- * mask |= MAY_APPEND;
- */
- if (flags & vfsub_fmode_to_uint(FMODE_EXEC))
- mask |= MAY_EXEC;
-
- AuDbg("flags 0x%x, mask 0x%x\n", flags, mask);
-#endif
-
- return mask;
-}
-
struct file *vfsub_dentry_open(struct path *path, int flags)
{
struct file *file;
- int err;
path_get(path);
file = dentry_open(path->dentry, path->mnt,
- flags /* | vfsub_fmode_to_uint(FMODE_NONOTIFY) */,
+ flags /* | __FMODE_NONOTIFY */,
current_cred());
- if (IS_ERR(file))
- goto out;
+ if (!IS_ERR_OR_NULL(file)
+ && (file->f_mode & (FMODE_READ | FMODE_WRITE)) == FMODE_READ)
+ i_readcount_inc(path->dentry->d_inode);
- err = ima_file_check(file, au_conv_oflags(flags));
- if (unlikely(err)) {
- fput(file);
- file = ERR_PTR(err);
- }
-out:
return file;
}
@@ -102,9 +69,11 @@ struct file *vfsub_filp_open(const char *path, int oflags, int mode)
{
struct file *file;
+ lockdep_off();
file = filp_open(path,
- oflags /* | vfsub_fmode_to_uint(FMODE_NONOTIFY) */,
+ oflags /* | __FMODE_NONOTIFY */,
mode);
+ lockdep_on();
if (IS_ERR(file))
goto out;
vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
@@ -163,6 +132,34 @@ out:
return path.dentry;
}
+/*
+ * this is "VFS:__lookup_one_len()" which was removed and merged into
+ * VFS:lookup_one_len() by the commit.
+ * 6a96ba5 2011-03-14 kill __lookup_one_len()
+ * this function should always be equivalent to the corresponding part in
+ * VFS:lookup_one_len().
+ */
+int vfsub_name_hash(const char *name, struct qstr *this, int len)
+{
+ unsigned long hash;
+ unsigned int c;
+
+ this->name = name;
+ this->len = len;
+ if (!len)
+ return -EACCES;
+
+ hash = init_name_hash();
+ while (len--) {
+ c = *(const unsigned char *)name++;
+ if (c == '/' || c == '\0')
+ return -EACCES;
+ hash = partial_name_hash(c, hash);
+ }
+ this->hash = end_name_hash(hash);
+ return 0;
+}
+
/* ---------------------------------------------------------------------- */
struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
@@ -170,7 +167,9 @@ struct dentry *vfsub_lock_rename(struct dentry *d1, struct au_hinode *hdir1,
{
struct dentry *d;
+ lockdep_off();
d = lock_rename(d1, d2);
+ lockdep_on();
au_hn_suspend(hdir1);
if (hdir1 != hdir2)
au_hn_suspend(hdir2);
@@ -184,7 +183,9 @@ void vfsub_unlock_rename(struct dentry *d1, struct au_hinode *hdir1,
au_hn_resume(hdir1);
if (hdir1 != hdir2)
au_hn_resume(hdir2);
+ lockdep_off();
unlock_rename(d1, d2);
+ lockdep_on();
}
/* ---------------------------------------------------------------------- */
@@ -326,7 +327,9 @@ int vfsub_link(struct dentry *src_dentry, struct inode *dir, struct path *path)
if (unlikely(err))
goto out;
+ lockdep_off();
err = vfs_link(src_dentry, dir, path->dentry);
+ lockdep_on();
if (!err) {
struct path tmp = *path;
int did;
@@ -366,7 +369,9 @@ int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
if (unlikely(err))
goto out;
+ lockdep_off();
err = vfs_rename(src_dir, src_dentry, dir, path->dentry);
+ lockdep_on();
if (!err) {
int did;
@@ -430,7 +435,9 @@ int vfsub_rmdir(struct inode *dir, struct path *path)
if (unlikely(err))
goto out;
+ lockdep_off();
err = vfs_rmdir(dir, path->dentry);
+ lockdep_on();
if (!err) {
struct path tmp = {
.dentry = path->dentry->d_parent,
@@ -451,7 +458,9 @@ ssize_t vfsub_read_u(struct file *file, char __user *ubuf, size_t count,
{
ssize_t err;
+ lockdep_off();
err = vfs_read(file, ubuf, count, ppos);
+ lockdep_on();
if (err >= 0)
vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
return err;
@@ -481,7 +490,9 @@ ssize_t vfsub_write_u(struct file *file, const char __user *ubuf, size_t count,
{
ssize_t err;
+ lockdep_off();
err = vfs_write(file, ubuf, count, ppos);
+ lockdep_on();
if (err >= 0)
vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
return err;
@@ -510,7 +521,13 @@ int vfsub_flush(struct file *file, fl_owner_t id)
err = 0;
if (file->f_op && file->f_op->flush) {
- err = file->f_op->flush(file, id);
+ if (!au_test_nfs(file->f_dentry->d_sb))
+ err = file->f_op->flush(file, id);
+ else {
+ lockdep_off();
+ err = file->f_op->flush(file, id);
+ lockdep_on();
+ }
if (!err)
vfsub_update_h_iattr(&file->f_path, /*did*/NULL);
/*ignore*/
@@ -522,7 +539,9 @@ int vfsub_readdir(struct file *file, filldir_t filldir, void *arg)
{
int err;
+ lockdep_off();
err = vfs_readdir(file, filldir, arg);
+ lockdep_on();
if (err >= 0)
vfsub_update_h_iattr(&file->f_path, /*did*/NULL); /*ignore*/
return err;
@@ -534,7 +553,9 @@ long vfsub_splice_to(struct file *in, loff_t *ppos,
{
long err;
+ lockdep_off();
err = do_splice_to(in, ppos, pipe, len, flags);
+ lockdep_on();
file_accessed(in);
if (err >= 0)
vfsub_update_h_iattr(&in->f_path, /*did*/NULL); /*ignore*/
@@ -546,7 +567,9 @@ long vfsub_splice_from(struct pipe_inode_info *pipe, struct file *out,
{
long err;
+ lockdep_off();
err = do_splice_from(pipe, out, ppos, len, flags);
+ lockdep_on();
if (err >= 0)
vfsub_update_h_iattr(&out->f_path, /*did*/NULL); /*ignore*/
return err;
@@ -578,8 +601,11 @@ int vfsub_trunc(struct path *h_path, loff_t length, unsigned int attr,
err = locks_verify_truncate(h_inode, h_file, length);
if (!err)
err = security_path_truncate(h_path);
- if (!err)
+ if (!err) {
+ lockdep_off();
err = do_truncate(h_path->dentry, length, attr, h_file);
+ lockdep_on();
+ }
out_inode:
if (!h_file)
@@ -746,7 +772,9 @@ static void call_unlink(void *args)
if (h_inode)
ihold(h_inode);
+ lockdep_off();
*a->errp = vfs_unlink(a->dir, d);
+ lockdep_on();
if (!*a->errp) {
struct path tmp = {
.dentry = d->d_parent,
diff --git a/ubuntu/aufs/vfsub.h b/ubuntu/aufs/vfsub.h
index 7615bf02546..486ef20448f 100644
--- a/ubuntu/aufs/vfsub.h
+++ b/ubuntu/aufs/vfsub.h
@@ -30,8 +30,10 @@
#include "debug.h"
/* copied from linux/fs/internal.h */
+/* todo: BAD approach!! */
DECLARE_BRLOCK(vfsmount_lock);
extern void file_sb_list_del(struct file *f);
+extern spinlock_t inode_sb_list_lock;
/* copied from linux/fs/file_table.c */
DECLARE_LGLOCK(files_lglock);
@@ -107,6 +109,7 @@ int vfsub_kern_path(const char *name, unsigned int flags, struct path *path);
struct dentry *vfsub_lookup_one_len(const char *name, struct dentry *parent,
int len);
struct dentry *vfsub_lookup_hash(struct nameidata *nd);
+int vfsub_name_hash(const char *name, struct qstr *this, int len);
/* ---------------------------------------------------------------------- */
@@ -182,7 +185,9 @@ static inline loff_t vfsub_llseek(struct file *file, loff_t offset, int origin)
{
loff_t err;
+ lockdep_off();
err = vfs_llseek(file, offset, origin);
+ lockdep_on();
return err;
}
diff --git a/ubuntu/aufs/xino.c b/ubuntu/aufs/xino.c
index 7c8bb43631a..7c9f521d054 100644
--- a/ubuntu/aufs/xino.c
+++ b/ubuntu/aufs/xino.c
@@ -169,7 +169,7 @@ struct file *au_xino_create2(struct file *base_file, struct file *copy_src)
path.mnt = base_file->f_vfsmnt;
file = vfsub_dentry_open(&path,
O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
- /* | FMODE_NONOTIFY */);
+ /* | __FMODE_NONOTIFY */);
if (IS_ERR(file)) {
pr_err("%.*s open err %ld\n", AuLNPair(name), PTR_ERR(file));
goto out_dput;
@@ -686,7 +686,7 @@ struct file *au_xino_create(struct super_block *sb, char *fname, int silent)
* when a user specified the xino, we cannot get au_hdir to be ignored.
*/
file = vfsub_filp_open(fname, O_RDWR | O_CREAT | O_EXCL | O_LARGEFILE
- /* | FMODE_NONOTIFY */,
+ /* | __FMODE_NONOTIFY */,
S_IRUGO | S_IWUGO);
if (IS_ERR(file)) {
if (!silent)
diff --git a/ubuntu/include/linux/aufs_type.h b/ubuntu/include/linux/aufs_type.h
index 640673bbf00..487a693a213 100644
--- a/ubuntu/include/linux/aufs_type.h
+++ b/ubuntu/include/linux/aufs_type.h
@@ -24,7 +24,7 @@
#include <linux/limits.h>
#include <linux/types.h>
-#define AUFS_VERSION "2.1-standalone.tree-38-rcN-20110207"
+#define AUFS_VERSION "2.1-standalone.tree-39-rcN-20110418"
/* todo? move this to linux-2.6.19/include/magic.h */
#define AUFS_SUPER_MAGIC ('a' << 24 | 'u' << 16 | 'f' << 8 | 's')
@@ -118,7 +118,10 @@ enum {
AuCtl_RDU_INO,
/* pathconf wrapper */
- AuCtl_WBR_FD
+ AuCtl_WBR_FD,
+
+ /* busy inode */
+ AuCtl_IBUSY
};
/* borrowed from linux/include/linux/kernel.h */
@@ -189,9 +192,15 @@ struct aufs_rdu {
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__ */