This patch doesn't support AppArmor _fully_.
- add struct vfsmount here and there.
- drop struct iattr->ia_file, no file->fsetattr() implemented.
- d_path() is still used, d_namespace_path() is unused.

Signed-off-by: J. R. Okajima <[email protected]>
---
 fs/aufs/cpup.c       |   23 ++++++++++-------
 fs/aufs/debug.c      |    2 +
 fs/aufs/i_op.c       |    7 +++++
 fs/aufs/i_op_add.c   |   31 +++++++++++++++--------
 fs/aufs/i_op_ren.c   |   16 +++++++----
 fs/aufs/misc.c       |    3 ++
 fs/aufs/plink.c      |   11 ++++----
 fs/aufs/vfsub.c      |   63 ++++++++++++++++++++++++++++-------------------
 fs/aufs/vfsub.h      |   66 ++++++++++++++++++++++++++++---------------------
 fs/aufs/wbr_policy.c |    6 +++-
 fs/aufs/whout.c      |   16 ++++++++----
 11 files changed, 153 insertions(+), 91 deletions(-)

diff --git a/fs/aufs/cpup.c b/fs/aufs/cpup.c
index 60e55e0..73d749f 100644
--- a/fs/aufs/cpup.c
+++ b/fs/aufs/cpup.c
@@ -335,9 +335,9 @@ static int au_do_cpup_regular(struct dentry *dentry, 
aufs_bindex_t bdst,
        return err;
 }
 
-static int au_do_cpup_symlink(struct dentry *h_dst, struct dentry *h_src,
-                             struct inode *h_dir, umode_t mode,
-                             struct vfsub_args *vargs)
+static int au_do_cpup_symlink(struct dentry *h_dst, struct vfsmount *h_mnt,
+                             struct dentry *h_src, struct inode *h_dir,
+                             umode_t mode, struct vfsub_args *vargs)
 {
        int err, symlen;
        char *sym;
@@ -359,7 +359,7 @@ static int au_do_cpup_symlink(struct dentry *h_dst, struct 
dentry *h_src,
 
        if (symlen > 0) {
                sym[symlen] = 0;
-               err = vfsub_symlink(h_dir, h_dst, sym, mode, vargs);
+               err = vfsub_symlink(h_dir, h_dst, h_mnt, sym, mode, vargs);
        }
        __putname(sym);
 
@@ -377,6 +377,7 @@ int cpup_entry(struct dentry *dentry, aufs_bindex_t bdst, 
aufs_bindex_t bsrc,
        int err;
        unsigned char isdir, hinotify;
        struct dentry *h_src, *h_dst, *h_parent, *gparent;
+       struct vfsmount *h_mnt;
        struct inode *h_inode, *h_dir;
        struct au_dtime dt;
        umode_t mode;
@@ -391,6 +392,7 @@ int cpup_entry(struct dentry *dentry, aufs_bindex_t bdst, 
aufs_bindex_t bsrc,
        sb = dentry->d_sb;
        AuDebugOn(bdst >= bsrc || au_test_ro(sb, bdst, NULL));
        /* bsrc branch can be ro/rw. */
+       h_mnt = au_sbr_mnt(sb, bdst);
 
        h_src = au_h_dptr(dentry, bsrc);
        AuDebugOn(!h_src);
@@ -441,7 +443,7 @@ int cpup_entry(struct dentry *dentry, aufs_bindex_t bdst, 
aufs_bindex_t bsrc,
                break;
        case S_IFDIR:
                isdir = 1;
-               err = vfsub_mkdir(h_dir, h_dst, mode, vargs);
+               err = vfsub_mkdir(h_dir, h_dst, h_mnt, mode, vargs);
                if (!err) {
                        /* setattr case: dir is not locked */
                        if (0 && au_ibstart(dst_parent->d_inode) == bdst)
@@ -451,7 +453,7 @@ int cpup_entry(struct dentry *dentry, aufs_bindex_t bdst, 
aufs_bindex_t bsrc,
                }
                break;
        case S_IFLNK:
-               err = au_do_cpup_symlink(h_dst, h_src, h_dir, mode, vargs);
+               err = au_do_cpup_symlink(h_dst, h_mnt, h_src, h_dir, mode, 
vargs);
                break;
        case S_IFCHR:
        case S_IFBLK:
@@ -459,7 +461,7 @@ int cpup_entry(struct dentry *dentry, aufs_bindex_t bdst, 
aufs_bindex_t bsrc,
                /*FALLTHROUGH*/
        case S_IFIFO:
        case S_IFSOCK:
-               err = vfsub_mknod(h_dir, h_dst, mode,
+               err = vfsub_mknod(h_dir, h_dst, h_mnt, mode,
                                  au_h_rdev(h_inode, /*h_mnt*/NULL, h_src),
                                  vargs);
                break;
@@ -503,11 +505,13 @@ static int au_cpup_single(struct dentry *dentry, 
aufs_bindex_t bdst,
        struct inode *dst_inode, *h_dir, *inode;
        struct super_block *sb;
        struct au_hinode *hgdir, *hdir;
+       struct vfsmount *h_mnt;
 
        LKTRTrace("%.*s, i%lu, bdst %d, bsrc %d, len %lld, flags 0x%x\n",
                  AuDLNPair(dentry), dentry->d_inode->i_ino, bdst, bsrc, len,
                  flags);
        sb = dentry->d_sb;
+       h_mnt = au_sbr_mnt(sb, bdst);
        AuDebugOn(bsrc <= bdst);
        h_dst = au_h_dptr(dentry, bdst);
        AuDebugOn(!h_dst || h_dst->d_inode);
@@ -566,7 +570,8 @@ static int au_cpup_single(struct dentry *dentry, 
aufs_bindex_t bdst,
                        }
                        vfsub_args_reinit(vargs);
                        vfsub_ign_hinode(vargs, IN_CREATE, hdir);
-                       err = vfsub_link(h_src, h_dir, h_dst, vargs);
+                       err = vfsub_link(h_src, h_mnt, h_dir, h_dst, h_mnt,
+                                        vargs);
                        if (do_dt)
                                au_dtime_revert(&dt);
                        dput(h_src);
@@ -618,7 +623,7 @@ static int au_cpup_single(struct dentry *dentry, 
aufs_bindex_t bdst,
        if (!isdir)
                rerr = vfsub_unlink(h_dir, h_dst, vargs);
        else
-               rerr = vfsub_rmdir(h_dir, h_dst, vargs);
+               rerr = vfsub_rmdir(h_dir, h_dst, h_mnt, vargs);
        au_dtime_revert(&dt);
        if (rerr) {
                AuIOErr("failed removing broken entry(%d, %d)\n", err, rerr);
diff --git a/fs/aufs/debug.c b/fs/aufs/debug.c
index 2591694..2feba39 100644
--- a/fs/aufs/debug.c
+++ b/fs/aufs/debug.c
@@ -344,7 +344,9 @@ void au_dbg_iattr(struct iattr *ia)
        AuBit(KILL_PRIV);
        AuBit(OPEN);
 #undef AuBit
+#if 0
        dpri("ia_file %p\n", ia->ia_file);
+#endif
 }
 
 /* ---------------------------------------------------------------------- */
diff --git a/fs/aufs/i_op.c b/fs/aufs/i_op.c
index 3153263..450b154 100644
--- a/fs/aufs/i_op.c
+++ b/fs/aufs/i_op.c
@@ -725,12 +725,15 @@ static int aufs_setattr(struct dentry *dentry, struct 
iattr *ia)
        si_read_lock(sb, AuLock_FLUSH);
        vfsub_args_init(&a->vargs, a->ign, au_test_dlgt(au_mntflags(sb)), 0);
 
+#warning struct iattr.ia_file is removed by AppArmor
+#if 0
        if (ia->ia_valid & ATTR_FILE) {
                /* currently ftruncate(2) only */
                file = ia->ia_file;
                fi_write_lock(file);
                ia->ia_file = au_h_fptr(file, au_fbstart(file));
        }
+#endif
 
        sz = -1;
        if ((ia->ia_valid & ATTR_SIZE)
@@ -739,10 +742,12 @@ static int aufs_setattr(struct dentry *dentry, struct 
iattr *ia)
        err = au_lock_and_icpup(dentry, sz, a);
        if (unlikely(err < 0))
                goto out_si;
+#if 0
        if (a->did_cpup) {
                ia->ia_file = NULL;
                ia->ia_valid &= ~ATTR_FILE;
        }
+#endif
 
        if ((ia->ia_valid & ATTR_SIZE)
            && ia->ia_size < i_size_read(inode)) {
@@ -776,11 +781,13 @@ static int aufs_setattr(struct dentry *dentry, struct 
iattr *ia)
        au_unpin(&a->pin);
        di_write_unlock(dentry);
  out_si:
+#if 0
        if (file) {
                fi_write_unlock(file);
                ia->ia_file = file;
                ia->ia_valid |= ATTR_FILE;
        }
+#endif
        si_read_unlock(sb);
        kfree(a);
  out:
diff --git a/fs/aufs/i_op_add.c b/fs/aufs/i_op_add.c
index cebc07f..5a82383 100644
--- a/fs/aufs/i_op_add.c
+++ b/fs/aufs/i_op_add.c
@@ -279,6 +279,7 @@ static int add_simple(struct inode *dir, struct dentry 
*dentry,
        struct au_dtime dt;
        struct vfsub_args vargs;
        struct super_block *sb;
+       struct vfsmount *h_mnt;
        aufs_bindex_t bstart;
        unsigned char created;
        struct au_hin_ignore ign;
@@ -294,6 +295,7 @@ static int add_simple(struct inode *dir, struct dentry 
*dentry,
        sb = dir->i_sb;
        parent = dentry->d_parent; /* dir inode is locked */
        aufs_read_lock(dentry, AuLock_DW);
+       h_mnt = au_sbr_mnt(sb, au_dbstart(dentry));
        vfsub_args_init(&vargs, &ign, !!au_test_dlgt(au_mntflags(sb)), 0);
        di_write_lock_parent(parent);
        wh_dentry = lock_hdir_lkup_wh(dentry, &dt, /*src_dentry*/NULL, &pin,
@@ -314,12 +316,12 @@ static int add_simple(struct inode *dir, struct dentry 
*dentry,
                                  arg->u.c.nd, au_nfsmnt(sb, bstart));
                break;
        case Symlink:
-               err = vfsub_symlink(h_dir, h_dentry, arg->u.s.symname,
+               err = vfsub_symlink(h_dir, h_dentry, h_mnt, arg->u.s.symname,
                                    S_IALLUGO, &vargs);
                break;
        case Mknod:
-               err = vfsub_mknod(h_dir, h_dentry, arg->u.m.mode, arg->u.m.dev,
-                                 &vargs);
+               err = vfsub_mknod(h_dir, h_dentry, h_mnt, arg->u.m.mode,
+                                 arg->u.m.dev, &vargs);
                break;
        default:
                BUG();
@@ -405,6 +407,7 @@ struct au_link_args {
        struct au_hin_ignore ign;
        struct dentry *h_dentry;
        struct dentry *src_parent, *parent;
+       struct vfsmount *h_mnt;
 };
 
 static int au_cpup_before_link(struct dentry *src_dentry, struct inode *dir,
@@ -475,8 +478,9 @@ static int au_cpup_or_link(struct dentry *src_dentry, 
struct au_link_args *a)
                        /* vfsub_args_reinit(&a->vargs); */
                        vfsub_ign_hinode(&a->vargs, IN_CREATE,
                                         au_pinned_hdir(&a->pin));
-                       err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
-                                        a->h_dentry, &a->vargs);
+                       err = vfsub_link(h_src_dentry, a->h_mnt,
+                                        au_pinned_h_dir(&a->pin), a->h_dentry,
+                                        a->h_mnt, &a->vargs);
                        dput(h_src_dentry);
                } else {
                        AuIOErr("no dentry found for i%lu on b%d\n",
@@ -538,6 +542,7 @@ int aufs_link(struct dentry *src_dentry, struct inode *dir,
 
        a->bdst = au_dbstart(dentry);
        a->h_dentry = au_h_dptr(dentry, a->bdst);
+       a->h_mnt = au_sbr_mnt(sb, a->bdst);
 
        /* todo: minor optimize,
           their sb may be same while their bindex differs? */
@@ -552,8 +557,9 @@ int aufs_link(struct dentry *src_dentry, struct inode *dir,
                        AuDebugOn(!h_src_dentry->d_inode);
                        vfsub_ign_hinode(&a->vargs, IN_CREATE,
                                         au_pinned_hdir(&a->pin));
-                       err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
-                                        a->h_dentry, &a->vargs);
+                       err = vfsub_link(h_src_dentry, a->h_mnt,
+                                        au_pinned_h_dir(&a->pin), a->h_dentry,
+                                        a->h_mnt, &a->vargs);
                }
        } else {
                /*
@@ -582,8 +588,9 @@ int aufs_link(struct dentry *src_dentry, struct inode *dir,
                        vfsub_ign_hinode(&a->vargs, IN_CREATE,
                                         au_pinned_hdir(&a->pin));
                        h_src_dentry = au_h_dptr(src_dentry, a->bdst);
-                       err = vfsub_link(h_src_dentry, au_pinned_h_dir(&a->pin),
-                                        a->h_dentry, &a->vargs);
+                       err = vfsub_link(h_src_dentry, a->h_mnt,
+                                        au_pinned_h_dir(&a->pin), a->h_dentry,
+                                        a->h_mnt, &a->vargs);
                }
        }
        if (unlikely(err))
@@ -659,6 +666,7 @@ int aufs_mkdir(struct inode *dir, struct dentry *dentry, 
int mode)
        int err, rerr;
        struct dentry *h_dentry, *wh_dentry, *parent, *opq_dentry;
        struct inode *h_inode;
+       struct vfsmount *h_mnt;
        struct au_dtime dt;
        aufs_bindex_t bindex;
        unsigned char diropq, dlgt;
@@ -690,8 +698,9 @@ int aufs_mkdir(struct inode *dir, struct dentry *dentry, 
int mode)
 
        bindex = au_dbstart(dentry);
        h_dentry = au_h_dptr(dentry, bindex);
+       h_mnt = au_sbr_mnt(dentry->d_sb, bindex);
        vfsub_ign_hinode(&vargs, IN_CREATE, au_pinned_hdir(&pin));
-       err = vfsub_mkdir(au_pinned_h_dir(&pin), h_dentry, mode, &vargs);
+       err = vfsub_mkdir(au_pinned_h_dir(&pin), h_dentry, h_mnt, mode, &vargs);
        if (unlikely(err))
                goto out_unlock;
 
@@ -732,7 +741,7 @@ int aufs_mkdir(struct inode *dir, struct dentry *dentry, 
int mode)
        LKTRLabel(revert dir);
        vfsub_args_reinit(&vargs);
        vfsub_ign_hinode(&vargs, IN_DELETE, au_pinned_hdir(&pin));
-       rerr = vfsub_rmdir(au_pinned_h_dir(&pin), h_dentry, &vargs);
+       rerr = vfsub_rmdir(au_pinned_h_dir(&pin), h_dentry, h_mnt, &vargs);
        if (rerr) {
                AuIOErr("%.*s reverting dir failed(%d, %d)\n",
                        AuDLNPair(dentry), err, rerr);
diff --git a/fs/aufs/i_op_ren.c b/fs/aufs/i_op_ren.c
index 89706ca..903da95 100644
--- a/fs/aufs/i_op_ren.c
+++ b/fs/aufs/i_op_ren.c
@@ -57,6 +57,7 @@ struct au_ren_args {
        /* do_rename() only */
        unsigned char need_diropq, bycpup;
        struct super_block *sb;
+       struct vfsmount *h_mnt;
        unsigned int flags;
        unsigned int mnt_flags;
        struct au_ndx ndx;
@@ -116,8 +117,9 @@ void au_ren_rev_rename(int err, struct au_ren_args *a)
                         au_pinned_hdir(a->pin + DST));
        vfsub_ign_hinode(&a->vargs, IN_MOVED_TO, au_pinned_hdir(a->pin + SRC));
        rerr = vfsub_rename(au_pinned_h_dir(a->pin + DST),
-                           au_h_dptr(a->src_dentry, a->btgt),
-                           au_pinned_h_dir(a->pin + SRC), h_d, &a->vargs);
+                           au_h_dptr(a->src_dentry, a->btgt), a->h_mnt,
+                           au_pinned_h_dir(a->pin + SRC), h_d, a->h_mnt,
+                           &a->vargs);
        d_drop(h_d);
        dput(h_d);
        /* au_set_h_dptr(a->src_dentry, a->btgt, NULL); */
@@ -167,8 +169,9 @@ void au_ren_rev_whtmp(int err, struct au_ren_args *a)
        vfsub_args_reinit(&a->vargs);
        vfsub_ign_hinode(&a->vargs, IN_MOVED_TO | IN_MOVED_FROM,
                         au_pinned_hdir(a->pin + DST));
-       rerr = vfsub_rename(au_pinned_h_dir(a->pin + DST), a->h_dst,
-                           au_pinned_h_dir(a->pin + DST), h_d, &a->vargs);
+       rerr = vfsub_rename(au_pinned_h_dir(a->pin + DST), a->h_dst, a->h_mnt,
+                           au_pinned_h_dir(a->pin + DST), h_d, a->h_mnt,
+                           &a->vargs);
        d_drop(h_d);
        dput(h_d);
        if (!rerr) {
@@ -215,9 +218,9 @@ int au_ren_or_cpup(struct au_ren_args *a)
                                         au_pinned_hdir(a->pin + DST));
                AuDebugOn(au_dbstart(a->src_dentry) != a->btgt);
                err = vfsub_rename(au_pinned_h_dir(a->pin + SRC),
-                                  au_h_dptr(a->src_dentry, a->btgt),
+                                  au_h_dptr(a->src_dentry, a->btgt), a->h_mnt,
                                   au_pinned_h_dir(a->pin + DST),
-                                  a->h_dentry[DST], &a->vargs);
+                                  a->h_dentry[DST], a->h_mnt, &a->vargs);
        } else {
                struct inode *h_inode = a->h_dentry[SRC]->d_inode;
 
@@ -1110,6 +1113,7 @@ int aufs_rename(struct inode *src_dir, struct dentry 
*src_dentry,
                au_fset_ren(p->a.flags, WHSRC);
 
        hinotify = au_opt_test(p->a.mnt_flags, UDBA_INOTIFY);
+       p->a.h_mnt = au_sbr_mnt(p->a.sb, p->a.btgt);
        p->a.h_parent[SRC] = au_h_dptr(p->a.parent[SRC], p->a.btgt);
        p->a.h_parent[DST] = au_h_dptr(p->a.parent[DST], p->a.btgt);
        err = au_ren_lock(&p->a);
diff --git a/fs/aufs/misc.c b/fs/aufs/misc.c
index 7caf178..ccb7981 100644
--- a/fs/aufs/misc.c
+++ b/fs/aufs/misc.c
@@ -304,7 +304,10 @@ int au_copy_file(struct file *dst, struct file *src, 
loff_t len,
                        ia = (void *)buf;
                        ia->ia_size = dst->f_pos;
                        ia->ia_valid = ATTR_SIZE | ATTR_FILE;
+#warning struct iattr.ia_file is removed by AppArmor
+#if 0
                        ia->ia_file = dst;
+#endif
                        vfsub_args_reinit(vargs);
                        vfsub_ign_hinode(vargs, vfsub_events_notify_change(ia),
                                         hdir);
diff --git a/fs/aufs/plink.c b/fs/aufs/plink.c
index ef19ad0..b3dbc26 100644
--- a/fs/aufs/plink.c
+++ b/fs/aufs/plink.c
@@ -126,8 +126,8 @@ struct dentry *au_plink_lkup(struct super_block *sb, 
aufs_bindex_t bindex,
 }
 
 static int do_whplink(char *tgt, int len, struct dentry *h_parent,
-                     struct dentry *h_dentry, struct vfsmount *nfsmnt,
-                     struct super_block *sb)
+                     struct dentry *h_dentry, struct vfsmount *h_mnt,
+                     struct vfsmount *nfsmnt, struct super_block *sb)
 {
        int err, dlgt;
        struct dentry *h_tgt;
@@ -157,7 +157,7 @@ static int do_whplink(char *tgt, int len, struct dentry 
*h_parent,
        if (h_tgt->d_inode && h_tgt->d_inode != h_dentry->d_inode)
                err = vfsub_unlink(h_dir, h_tgt, &vargs);
        if (!err && !h_tgt->d_inode) {
-               err = vfsub_link(h_dentry, h_dir, h_tgt, &vargs);
+               err = vfsub_link(h_dentry, h_mnt, h_dir, h_tgt, h_mnt, &vargs);
                /* todo: unnecessary? */
                /* inc_nlink(inode); */
        }
@@ -174,6 +174,7 @@ struct do_whplink_args {
        int len;
        struct dentry *h_parent;
        struct dentry *h_dentry;
+       struct vfsmount *h_mnt;
        struct vfsmount *nfsmnt;
        struct super_block *sb;
 };
@@ -182,7 +183,7 @@ static void call_do_whplink(void *args)
 {
        struct do_whplink_args *a = args;
        *a->errp = do_whplink(a->tgt, a->len, a->h_parent, a->h_dentry,
-                             a->nfsmnt, a->sb);
+                             a->h_mnt, a->nfsmnt, a->sb);
 }
 
 static int whplink(struct dentry *h_dentry, struct inode *inode,
@@ -223,7 +224,7 @@ static int whplink(struct dentry *h_dentry, struct inode 
*inode,
                        err = wkq_err;
        } else
                err = do_whplink(tgtname, len, h_parent, h_dentry,
-                                au_do_nfsmnt(br->br_mnt), sb);
+                                br->br_mnt, au_do_nfsmnt(br->br_mnt), sb);
        vfsub_i_unlock(h_dir);
 
        AuTraceErr(err);
diff --git a/fs/aufs/vfsub.c b/fs/aufs/vfsub.c
index 3744387..d346ec1 100644
--- a/fs/aufs/vfsub.c
+++ b/fs/aufs/vfsub.c
@@ -126,7 +126,7 @@ int do_vfsub_create(struct inode *dir, struct dentry 
*dentry, int mode,
 }
 
 int do_vfsub_symlink(struct inode *dir, struct dentry *dentry,
-                    const char *symname, int mode)
+                    struct vfsmount *mnt, const char *symname, int mode)
 {
        int err;
 
@@ -134,7 +134,7 @@ int do_vfsub_symlink(struct inode *dir, struct dentry 
*dentry,
                  dir->i_ino, AuDLNPair(dentry), symname, mode);
        IMustLock(dir);
 
-       err = vfs_symlink(dir, dentry, symname, mode);
+       err = vfs_symlink(dir, dentry, mnt, symname, mode);
        if (!err) {
                /* dir inode is locked */
                au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/
@@ -143,15 +143,15 @@ int do_vfsub_symlink(struct inode *dir, struct dentry 
*dentry,
        return err;
 }
 
-int do_vfsub_mknod(struct inode *dir, struct dentry *dentry, int mode,
-                  dev_t dev)
+int do_vfsub_mknod(struct inode *dir, struct dentry *dentry,
+                  struct vfsmount *mnt, int mode, dev_t dev)
 {
        int err;
 
        LKTRTrace("i%lu, %.*s, 0x%x\n", dir->i_ino, AuDLNPair(dentry), mode);
        IMustLock(dir);
 
-       err = vfs_mknod(dir, dentry, mode, dev);
+       err = vfs_mknod(dir, dentry, mnt, mode, dev);
        if (!err) {
                /* dir inode is locked */
                au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/
@@ -160,8 +160,9 @@ int do_vfsub_mknod(struct inode *dir, struct dentry 
*dentry, int mode,
        return err;
 }
 
-int do_vfsub_link(struct dentry *src_dentry, struct inode *dir,
-                 struct dentry *dentry)
+int do_vfsub_link(struct dentry *src_dentry, struct vfsmount *src_mnt,
+                 struct inode *dir,
+                 struct dentry *dentry, struct vfsmount *mnt)
 {
        int err;
 
@@ -170,7 +171,7 @@ int do_vfsub_link(struct dentry *src_dentry, struct inode 
*dir,
        IMustLock(dir);
 
        lockdep_off();
-       err = vfs_link(src_dentry, dir, dentry);
+       err = vfs_link(src_dentry, src_mnt, dir, dentry, mnt);
        lockdep_on();
        if (!err) {
                LKTRTrace("src_i %p, dst_i %p\n",
@@ -185,7 +186,9 @@ int do_vfsub_link(struct dentry *src_dentry, struct inode 
*dir,
 }
 
 int do_vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
-                   struct inode *dir, struct dentry *dentry)
+                   struct vfsmount *src_mnt,
+                   struct inode *dir, struct dentry *dentry,
+                   struct vfsmount *mnt)
 {
        int err;
 
@@ -197,7 +200,7 @@ int do_vfsub_rename(struct inode *src_dir, struct dentry 
*src_dentry,
        AuDebugOn(src_dir != dir && !vfsub_is_rename_mutex_locked(dir->i_sb));
 
        lockdep_off();
-       err = vfs_rename(src_dir, src_dentry, dir, dentry);
+       err = vfs_rename(src_dir, src_dentry, src_mnt, dir, dentry, mnt);
        lockdep_on();
        if (!err) {
                /* dir inode is locked */
@@ -208,14 +211,15 @@ int do_vfsub_rename(struct inode *src_dir, struct dentry 
*src_dentry,
        return err;
 }
 
-int do_vfsub_mkdir(struct inode *dir, struct dentry *dentry, int mode)
+int do_vfsub_mkdir(struct inode *dir, struct dentry *dentry,
+                  struct vfsmount *mnt, int mode)
 {
        int err;
 
        LKTRTrace("i%lu, %.*s, 0x%x\n", dir->i_ino, AuDLNPair(dentry), mode);
        IMustLock(dir);
 
-       err = vfs_mkdir(dir, dentry, mode);
+       err = vfs_mkdir(dir, dentry, mnt, mode);
        if (!err) {
                /* dir inode is locked */
                au_update_fuse_h_inode(NULL, dentry->d_parent); /*ignore*/
@@ -224,7 +228,8 @@ int do_vfsub_mkdir(struct inode *dir, struct dentry 
*dentry, int mode)
        return err;
 }
 
-int do_vfsub_rmdir(struct inode *dir, struct dentry *dentry)
+int do_vfsub_rmdir(struct inode *dir, struct dentry *dentry,
+                  struct vfsmount *mnt)
 {
        int err;
 
@@ -232,7 +237,7 @@ int do_vfsub_rmdir(struct inode *dir, struct dentry *dentry)
        IMustLock(dir);
 
        lockdep_off();
-       err = vfs_rmdir(dir, dentry);
+       err = vfs_rmdir(dir, dentry, mnt);
        lockdep_on();
        /* dir inode is locked */
        if (!err)
@@ -240,7 +245,8 @@ int do_vfsub_rmdir(struct inode *dir, struct dentry *dentry)
        return err;
 }
 
-int do_vfsub_unlink(struct inode *dir, struct dentry *dentry)
+int do_vfsub_unlink(struct inode *dir, struct dentry *dentry,
+                   struct vfsmount *mnt)
 {
        int err;
 
@@ -249,7 +255,7 @@ int do_vfsub_unlink(struct inode *dir, struct dentry 
*dentry)
 
        /* vfs_unlink() locks inode */
        lockdep_off();
-       err = vfs_unlink(dir, dentry);
+       err = vfs_unlink(dir, dentry, mnt);
        lockdep_on();
        /* dir inode is locked */
        if (!err)
@@ -380,6 +386,7 @@ struct au_vfsub_mkdir_args {
        int *errp;
        struct inode *dir;
        struct dentry *dentry;
+       struct vfsmount *mnt;
        int mode;
        struct vfsub_args *vargs;
 };
@@ -387,11 +394,11 @@ struct au_vfsub_mkdir_args {
 static void au_call_vfsub_mkdir(void *args)
 {
        struct au_vfsub_mkdir_args *a = args;
-       *a->errp = vfsub_mkdir(a->dir, a->dentry, a->mode, a->vargs);
+       *a->errp = vfsub_mkdir(a->dir, a->dentry, a->mnt, a->mode, a->vargs);
 }
 
-int vfsub_sio_mkdir(struct au_hinode *hdir, struct dentry *dentry, int mode,
-                   int dlgt)
+int vfsub_sio_mkdir(struct au_hinode *hdir, struct dentry *dentry,
+                   struct vfsmount *mnt, int mode, int dlgt)
 {
        int err, do_sio, wkq_err;
        struct inode *dir = hdir->hi_inode;
@@ -404,12 +411,13 @@ int vfsub_sio_mkdir(struct au_hinode *hdir, struct dentry 
*dentry, int mode,
        vfsub_ign_hinode(&vargs, IN_CREATE, hdir);
        do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE, dlgt);
        if (!do_sio)
-               err = vfsub_mkdir(dir, dentry, mode, &vargs);
+               err = vfsub_mkdir(dir, dentry, mnt, mode, &vargs);
        else {
                struct au_vfsub_mkdir_args args = {
                        .errp   = &err,
                        .dir    = dir,
                        .dentry = dentry,
+                       .mnt    = mnt,
                        .mode   = mode,
                        .vargs  = &vargs
                };
@@ -427,16 +435,18 @@ struct au_vfsub_rmdir_args {
        int *errp;
        struct inode *dir;
        struct dentry *dentry;
+       struct vfsmount *mnt;
        struct vfsub_args *vargs;
 };
 
 static void au_call_vfsub_rmdir(void *args)
 {
        struct au_vfsub_rmdir_args *a = args;
-       *a->errp = vfsub_rmdir(a->dir, a->dentry, a->vargs);
+       *a->errp = vfsub_rmdir(a->dir, a->dentry, a->mnt, a->vargs);
 }
 
-int vfsub_sio_rmdir(struct au_hinode *hdir, struct dentry *dentry, int dlgt)
+int vfsub_sio_rmdir(struct au_hinode *hdir, struct dentry *dentry,
+                   struct vfsmount *mnt, int dlgt)
 {
        int err, do_sio, wkq_err;
        struct inode *dir = hdir->hi_inode;
@@ -449,12 +459,13 @@ int vfsub_sio_rmdir(struct au_hinode *hdir, struct dentry 
*dentry, int dlgt)
        vfsub_ign_hinode(&vargs, IN_DELETE, hdir);
        do_sio = au_test_h_perm_sio(dir, MAY_EXEC | MAY_WRITE, dlgt);
        if (!do_sio)
-               err = vfsub_rmdir(dir, dentry, &vargs);
+               err = vfsub_rmdir(dir, dentry, mnt, &vargs);
        else {
                struct au_vfsub_rmdir_args args = {
                        .errp           = &err,
                        .dir            = dir,
                        .dentry         = dentry,
+                       .mnt            = mnt,
                        .vargs          = &vargs
                };
                vfsub_fclr(vargs.flags, DLGT);
@@ -472,6 +483,7 @@ int vfsub_sio_rmdir(struct au_hinode *hdir, struct dentry 
*dentry, int dlgt)
 struct notify_change_args {
        int *errp;
        struct dentry *h_dentry;
+       struct vfsmount *h_mnt;
        struct iattr *ia;
        struct vfsub_args *vargs;
 };
@@ -490,7 +502,7 @@ static void call_notify_change(void *args)
        if (!IS_IMMUTABLE(h_inode) && !IS_APPEND(h_inode)) {
                vfsub_ignore(a->vargs);
                lockdep_off();
-               *a->errp = notify_change(a->h_dentry, a->ia);
+               *a->errp = notify_change(a->h_dentry, a->h_mnt, a->ia);
                lockdep_on();
                if (!*a->errp)
                        au_update_fuse_h_inode(NULL, a->h_dentry); /*ignore*/
@@ -573,6 +585,7 @@ struct unlink_args {
        int *errp;
        struct inode *dir;
        struct dentry *dentry;
+       struct vfsmount *mnt;
        struct vfsub_args *vargs;
 };
 
@@ -593,7 +606,7 @@ static void call_unlink(void *args)
        if (h_inode)
                atomic_inc_return(&h_inode->i_count);
        vfsub_ignore(a->vargs);
-       *a->errp = do_vfsub_unlink(a->dir, a->dentry);
+       *a->errp = do_vfsub_unlink(a->dir, a->dentry, a->mnt);
        if (unlikely(*a->errp || (a->dentry->d_flags & DCACHE_NFSFS_RENAMED)))
                vfsub_unignore(a->vargs);
        au_dbg_hin_list(a->vargs);
diff --git a/fs/aufs/vfsub.h b/fs/aufs/vfsub.h
index 0bd9719..4851742 100644
--- a/fs/aufs/vfsub.h
+++ b/fs/aufs/vfsub.h
@@ -324,16 +324,22 @@ struct dentry *vfsub__lookup_hash(struct qstr *name, 
struct dentry *parent,
 int do_vfsub_create(struct inode *dir, struct dentry *dentry, int mode,
                    struct nameidata *nd);
 int do_vfsub_symlink(struct inode *dir, struct dentry *dentry,
-                    const char *symname, int mode);
-int do_vfsub_mknod(struct inode *dir, struct dentry *dentry, int mode,
-                  dev_t dev);
-int do_vfsub_link(struct dentry *src_dentry, struct inode *dir,
-                 struct dentry *dentry);
+                    struct vfsmount *mnt, const char *symname, int mode);
+int do_vfsub_mknod(struct inode *dir, struct dentry *dentry,
+                  struct vfsmount *mnt, int mode, dev_t dev);
+int do_vfsub_link(struct dentry *src_dentry, struct vfsmount *src_mnt,
+                 struct inode *dir, struct dentry *dentry,
+                 struct vfsmount *mnt);
 int do_vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
-                   struct inode *dir, struct dentry *dentry);
-int do_vfsub_mkdir(struct inode *dir, struct dentry *dentry, int mode);
-int do_vfsub_rmdir(struct inode *dir, struct dentry *dentry);
-int do_vfsub_unlink(struct inode *dir, struct dentry *dentry);
+                   struct vfsmount *src_mnt,
+                   struct inode *dir, struct dentry *dentry,
+                   struct vfsmount *mnt);
+int do_vfsub_mkdir(struct inode *dir, struct dentry *dentry,
+                  struct vfsmount *mnt, int mode);
+int do_vfsub_rmdir(struct inode *dir, struct dentry *dentry,
+                  struct vfsmount *mnt);
+int do_vfsub_unlink(struct inode *dir, struct dentry *dentry,
+                   struct vfsmount *mnt);
 
 /* ---------------------------------------------------------------------- */
 
@@ -457,46 +463,49 @@ int vfsub_create(struct inode *dir, struct dentry 
*dentry, int mode,
 }
 
 static inline
-int vfsub_symlink(struct inode *dir, struct dentry *dentry, const char 
*symname,
-                 int mode, struct vfsub_args *vargs)
+int vfsub_symlink(struct inode *dir, struct dentry *dentry,
+                 struct vfsmount *mnt, const char *symname, int mode,
+                 struct vfsub_args *vargs)
 {
-       return do_vfsub_symlink(dir, dentry, symname, mode);
+       return do_vfsub_symlink(dir, dentry, mnt, symname, mode);
 }
 
 static inline
-int vfsub_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev,
-               struct vfsub_args *vargs)
+int vfsub_mknod(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt,
+               int mode, dev_t dev, struct vfsub_args *vargs)
 {
-       return do_vfsub_mknod(dir, dentry, mode, dev);
+       return do_vfsub_mknod(dir, dentry, mnt, mode, dev);
 }
 
 static inline
-int vfsub_link(struct dentry *src_dentry, struct inode *dir,
-              struct dentry *dentry, struct vfsub_args *vargs)
+int vfsub_link(struct dentry *src_dentry, struct vfsmount *src_mnt,
+              struct inode *dir, struct dentry *dentry, struct vfsmount *mnt,
+              struct vfsub_args *vargs)
 {
-       return do_vfsub_link(src_dentry, dir, dentry);
+       return do_vfsub_link(src_dentry, src_mnt, dir, dentry, mnt);
 }
 
 static inline
 int vfsub_rename(struct inode *src_dir, struct dentry *src_dentry,
-                struct inode *dir, struct dentry *dentry,
+                struct vfsmount *src_mnt, struct inode *dir,
+                struct dentry *dentry, struct vfsmount *mnt,
                 struct vfsub_args *vargs)
 {
-       return do_vfsub_rename(src_dir, src_dentry, dir, dentry);
+       return do_vfsub_rename(src_dir, src_dentry, src_mnt, dir, dentry, mnt);
 }
 
 static inline
-int vfsub_mkdir(struct inode *dir, struct dentry *dentry, int mode,
-               struct vfsub_args *vargs)
+int vfsub_mkdir(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt,
+               int mode, struct vfsub_args *vargs)
 {
-       return do_vfsub_mkdir(dir, dentry, mode);
+       return do_vfsub_mkdir(dir, dentry, mnt, mode);
 }
 
 static inline
-int vfsub_rmdir(struct inode *dir, struct dentry *dentry,
+int vfsub_rmdir(struct inode *dir, struct dentry *dentry, struct vfsmount *mnt,
                struct vfsub_args *vargs)
 {
-       return do_vfsub_rmdir(dir, dentry);
+       return do_vfsub_rmdir(dir, dentry, mnt);
 }
 
 static inline
@@ -559,9 +568,10 @@ int vfsub_getattr(struct vfsmount *mnt, struct dentry 
*dentry, struct kstat *st,
 
 /* ---------------------------------------------------------------------- */
 
-int vfsub_sio_mkdir(struct au_hinode *hdir, struct dentry *dentry, int mode,
-                   int dlgt);
-int vfsub_sio_rmdir(struct au_hinode *hdir, struct dentry *dentry, int dlgt);
+int vfsub_sio_mkdir(struct au_hinode *hdir, struct dentry *dentry,
+                   struct vfsmount *mnt, int mode, int dlgt);
+int vfsub_sio_rmdir(struct au_hinode *hdir, struct dentry *dentry,
+                   struct vfsmount *mnt, int dlgt);
 int vfsub_sio_notify_change(struct au_hinode *hdir, struct dentry *dentry,
                            struct iattr *ia);
 
diff --git a/fs/aufs/wbr_policy.c b/fs/aufs/wbr_policy.c
index 701b4a1..5919cb5 100644
--- a/fs/aufs/wbr_policy.c
+++ b/fs/aufs/wbr_policy.c
@@ -73,6 +73,7 @@ static int au_cpdown_dir(struct dentry *dentry, aufs_bindex_t 
bdst,
        unsigned char parent_opq, whed, dlgt, do_opq, made_dir, diropq;
        struct dentry *h_dentry, *opq_dentry, *wh_dentry, *parent;
        struct inode *h_dir, *h_inode, *inode, *dir;
+       struct vfsmount *h_mnt;
 
        LKTRTrace("%.*s, b%d\n", AuDLNPair(dentry), bdst);
        bstart = au_dbstart(dentry);
@@ -92,9 +93,10 @@ static int au_cpdown_dir(struct dentry *dentry, 
aufs_bindex_t bdst,
        err = au_lkup_neg(dentry, bdst);
        if (unlikely(err < 0))
                goto out;
+       h_mnt = au_sbr_mnt(dentry->d_sb, bdst);
        h_dentry = au_h_dptr(dentry, bdst);
        dlgt = !!au_test_dlgt(au_mntflags(dentry->d_sb));
-       err = vfsub_sio_mkdir(au_hi(dir, bdst), h_dentry,
+       err = vfsub_sio_mkdir(au_hi(dir, bdst), h_dentry, h_mnt,
                              S_IRWXU | S_IRUGO | S_IXUGO, dlgt);
        if (unlikely(err))
                goto out_put;
@@ -163,7 +165,7 @@ static int au_cpdown_dir(struct dentry *dentry, 
aufs_bindex_t bdst,
        }
  out_dir:
        if (made_dir) {
-               rerr = vfsub_sio_rmdir(au_hi(dir, bdst), h_dentry, dlgt);
+               rerr = vfsub_sio_rmdir(au_hi(dir, bdst), h_dentry, h_mnt, dlgt);
                if (unlikely(rerr)) {
                        AuIOErr("failed removing %.*s b%d (%d)\n",
                                AuDLNPair(dentry), bdst, rerr);
diff --git a/fs/aufs/whout.c b/fs/aufs/whout.c
index 79f44dd..8521cc2 100644
--- a/fs/aufs/whout.c
+++ b/fs/aufs/whout.c
@@ -216,6 +216,7 @@ int au_whtmp_ren(struct inode *dir, aufs_bindex_t bindex,
        struct inode *h_dir;
        struct dentry *h_parent, *tmp_dentry;
        struct super_block *sb;
+       struct vfsmount *h_mnt;
        unsigned int mnt_flags;
        struct au_hin_ignore ign;
        struct vfsub_args vargs;
@@ -243,11 +244,13 @@ int au_whtmp_ren(struct inode *dir, aufs_bindex_t bindex,
                goto out;
 
        /* under the same dir, no need to lock_rename() */
+       h_mnt = au_sbr_mnt(sb, bindex);
        vfsub_args_init(&vargs, &ign, dlgt, 0);
        AuDebugOn(!S_ISDIR(h_dentry->d_inode->i_mode));
        vfsub_ign_hinode(&vargs, IN_MOVED_FROM | IN_MOVED_TO,
                         au_hi(dir, bindex));
-       err = vfsub_rename(h_dir, h_dentry, h_dir, tmp_dentry, &vargs);
+       err = vfsub_rename(h_dir, h_dentry, h_mnt, h_dir, tmp_dentry, h_mnt,
+                          &vargs);
        AuTraceErr(err);
        dput(tmp_dentry);
 
@@ -367,7 +370,7 @@ static void au_whdir_clean(struct inode *h_dir, struct path 
*whpath,
        if (!err) {
                vfsub_args_reinit(vargs);
                vfsub_ign_hinode(vargs, IN_DELETE, hdir);
-               err = vfsub_rmdir(h_dir, whpath->dentry, vargs);
+               err = vfsub_rmdir(h_dir, whpath->dentry, whpath->mnt, vargs);
                au_mnt_drop_write(whpath->mnt);
        }
        if (unlikely(err))
@@ -397,7 +400,8 @@ static int au_whdir(struct inode *h_dir, struct path *path,
                if (!err) {
                        vfsub_args_reinit(vargs);
                        vfsub_ign_hinode(vargs, IN_CREATE, hdir);
-                       err = vfsub_mkdir(h_dir, path->dentry, mode, vargs);
+                       err = vfsub_mkdir(h_dir, path->dentry, path->mnt, mode,
+                                         vargs);
                        au_mnt_drop_write(path->mnt);
                }
        } else if (S_ISDIR(path->dentry->d_inode->i_mode))
@@ -745,7 +749,8 @@ static int link_or_create_wh(struct super_block *sb, 
aufs_bindex_t bindex,
                vfsub_args_init(&vargs, &ign, dlgt, 0);
                if (dir)
                        vfsub_ign_hinode(&vargs, IN_CREATE, au_hi(dir, bindex));
-               err = vfsub_link(wbr->wbr_whbase, h_dir, wh, &vargs);
+               err = vfsub_link(wbr->wbr_whbase, br->br_mnt, h_dir, wh,
+                                br->br_mnt, &vargs);
                if (!err || err != -EMLINK)
                        goto out;
 
@@ -1067,7 +1072,8 @@ int au_whtmp_rmdir(struct inode *dir, aufs_bindex_t 
bindex,
        if (!err) {
                vfsub_args_init(&vargs, &ign, dlgt, 0);
                vfsub_ign_hinode(&vargs, IN_DELETE, au_hi(dir, bindex));
-               err = vfsub_rmdir(h_dir, wh_dentry, &vargs);
+               err = vfsub_rmdir(h_dir, wh_dentry, au_sbr_mnt(sb, bindex),
+                                 &vargs);
                /* d_drop(h_dentry); */
        }
 
-- 
1.6.1.284.g5dc13


------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july

Reply via email to