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
