diff options
Diffstat (limited to 'fs/aufs')
-rw-r--r-- | fs/aufs/debug.c | 11 | ||||
-rw-r--r-- | fs/aufs/dentry.c | 22 | ||||
-rw-r--r-- | fs/aufs/dentry.h | 14 | ||||
-rw-r--r-- | fs/aufs/i_op.c | 14 | ||||
-rw-r--r-- | fs/aufs/i_op_del.c | 3 | ||||
-rw-r--r-- | fs/aufs/mvdown.c | 3 | ||||
-rw-r--r-- | fs/aufs/vfsub.h | 2 |
7 files changed, 39 insertions, 30 deletions
diff --git a/fs/aufs/debug.c b/fs/aufs/debug.c index 4fdc9d422..44bdb5ff8 100644 --- a/fs/aufs/debug.c +++ b/fs/aufs/debug.c @@ -163,9 +163,9 @@ static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry) { struct dentry *wh = NULL; int hn; + struct inode *inode; struct au_iinfo *iinfo; struct au_hinode *hi; - struct inode *inode; if (!dentry || IS_ERR(dentry)) { dpri("d%d: err %ld\n", bindex, PTR_ERR(dentry)); @@ -180,11 +180,12 @@ static int do_pri_dentry(aufs_bindex_t bindex, struct dentry *dentry) d_unhashed(dentry) ? "un" : ""); hn = -1; inode = NULL; - if (bindex >= 0 - && d_is_positive(dentry) - && au_test_aufs(dentry->d_sb)) + if (d_is_positive(dentry)) inode = d_inode(dentry); - if (inode && !au_is_bad_inode(inode)) { + if (inode + && au_test_aufs(dentry->d_sb) + && bindex >= 0 + && !au_is_bad_inode(inode)) { iinfo = au_ii(inode); hi = au_hinode(iinfo, bindex); hn = !!au_hn(hi); diff --git a/fs/aufs/dentry.c b/fs/aufs/dentry.c index 080fac9c8..4bb153086 100644 --- a/fs/aufs/dentry.c +++ b/fs/aufs/dentry.c @@ -9,14 +9,6 @@ #include <linux/namei.h> #include "aufs.h" -#define AuLkup_ALLOW_NEG 1 -#define AuLkup_IGNORE_PERM (1 << 1) -#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name) -#define au_fset_lkup(flags, name) \ - do { (flags) |= AuLkup_##name; } while (0) -#define au_fclr_lkup(flags, name) \ - do { (flags) &= ~AuLkup_##name; } while (0) - struct au_do_lookup_args { unsigned int flags; mode_t type; @@ -119,15 +111,15 @@ static int au_test_shwh(struct super_block *sb, const struct qstr *name) * otherwise an error. * can be called at unlinking with @type is zero. */ -int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t btop, mode_t type) +int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t btop, + unsigned int flags) { int npositive, err; aufs_bindex_t bindex, btail, bdiropq; unsigned char isdir, dirperm1; struct qstr whname; struct au_do_lookup_args args = { - .flags = 0, - .type = type + .flags = flags }; const struct qstr *name = &dentry->d_name; struct dentry *parent; @@ -143,8 +135,6 @@ int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t btop, mode_t type) goto out; isdir = !!d_is_dir(dentry); - if (!type) - au_fset_lkup(args.flags, ALLOW_NEG); dirperm1 = !!au_opt_test(au_mntflags(sb), DIRPERM1); npositive = 0; @@ -158,9 +148,7 @@ int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t btop, mode_t type) if (h_dentry) { if (d_is_positive(h_dentry)) npositive++; - if (type != S_IFDIR) - break; - continue; + break; } h_parent = au_h_dptr(parent, bindex); if (!h_parent || !d_is_dir(h_parent)) @@ -761,7 +749,7 @@ int au_refresh_dentry(struct dentry *dentry, struct dentry *parent) * if current working dir is removed, it returns an error. * but the dentry is legal. */ - err = au_lkup_dentry(dentry, /*btop*/0, /*type*/0); + err = au_lkup_dentry(dentry, /*btop*/0, AuLkup_ALLOW_NEG); AuDbgDentry(dentry); au_di_swap(tmp, dinfo); if (err == -ENOENT) diff --git a/fs/aufs/dentry.h b/fs/aufs/dentry.h index c52fe583f..bdc1af622 100644 --- a/fs/aufs/dentry.h +++ b/fs/aufs/dentry.h @@ -30,6 +30,17 @@ struct au_dinfo { /* ---------------------------------------------------------------------- */ +/* flags for au_lkup_dentry() */ +#define AuLkup_ALLOW_NEG 1 +#define AuLkup_IGNORE_PERM (1 << 1) +#define au_ftest_lkup(flags, name) ((flags) & AuLkup_##name) +#define au_fset_lkup(flags, name) \ + do { (flags) |= AuLkup_##name; } while (0) +#define au_fclr_lkup(flags, name) \ + do { (flags) &= ~AuLkup_##name; } while (0) + +/* ---------------------------------------------------------------------- */ + /* dentry.c */ extern const struct dentry_operations aufs_dop, aufs_dop_noreval; struct au_branch; @@ -37,7 +48,8 @@ struct dentry *au_sio_lkup_one(struct qstr *name, struct dentry *parent); int au_h_verify(struct dentry *h_dentry, unsigned int udba, struct inode *h_dir, struct dentry *h_parent, struct au_branch *br); -int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t btop, mode_t type); +int au_lkup_dentry(struct dentry *dentry, aufs_bindex_t btop, + unsigned int flags); int au_lkup_neg(struct dentry *dentry, aufs_bindex_t bindex, int wh); int au_refresh_dentry(struct dentry *dentry, struct dentry *parent); int au_reval_dpath(struct dentry *dentry, unsigned int sigen); diff --git a/fs/aufs/i_op.c b/fs/aufs/i_op.c index ac3bf9437..c274958dd 100644 --- a/fs/aufs/i_op.c +++ b/fs/aufs/i_op.c @@ -184,8 +184,9 @@ static struct dentry *aufs_lookup(struct inode *dir, struct dentry *dentry, if (!err) err = au_digen_test(parent, au_sigen(sb)); if (!err) { + /* regardless LOOKUP_CREATE, always ALLOW_NEG */ npositive = au_lkup_dentry(dentry, au_dbtop(parent), - /*type*/0); + AuLkup_ALLOW_NEG); err = npositive; } di_read_unlock(parent, AuLock_IR); @@ -266,6 +267,7 @@ static int aufs_atomic_open(struct inode *dir, struct dentry *dentry, umode_t create_mode, int *opened) { int err, h_opened = *opened; + unsigned int lkup_flags; struct dentry *parent; struct dentry *d; struct au_sphlhead *aopen; @@ -279,14 +281,18 @@ static int aufs_atomic_open(struct inode *dir, struct dentry *dentry, }; IMustLock(dir); - AuDbg("open_flag 0x%x\n", open_flag); + AuDbg("open_flag 0%o\n", open_flag); AuDbgDentry(dentry); err = 0; if (!au_di(dentry)) { - d = aufs_lookup(dir, dentry, /*flags*/0); + lkup_flags = LOOKUP_OPEN; + if (open_flag & O_CREAT) + lkup_flags |= LOOKUP_CREATE; + d = aufs_lookup(dir, dentry, lkup_flags); if (IS_ERR(d)) { err = PTR_ERR(d); + AuTraceErr(err); goto out; } else if (d) { /* @@ -312,7 +318,7 @@ static int aufs_atomic_open(struct inode *dir, struct dentry *dentry, parent = dentry->d_parent; /* dir is locked */ di_write_lock_parent(parent); - err = au_lkup_dentry(dentry, /*btop*/0, /*type*/0); + err = au_lkup_dentry(dentry, /*btop*/0, AuLkup_ALLOW_NEG); if (unlikely(err)) goto out_unlock; diff --git a/fs/aufs/i_op_del.c b/fs/aufs/i_op_del.c index bda70b008..35b923ccc 100644 --- a/fs/aufs/i_op_del.c +++ b/fs/aufs/i_op_del.c @@ -54,7 +54,8 @@ int au_wr_dir_need_wh(struct dentry *dentry, int isdir, aufs_bindex_t *bcpup) au_di_cp(tmp, dinfo); au_di_swap(tmp, dinfo); /* returns the number of positive dentries */ - need_wh = au_lkup_dentry(dentry, btop + 1, /*type*/0); + need_wh = au_lkup_dentry(dentry, btop + 1, + /* AuLkup_IGNORE_PERM */ 0); au_di_swap(tmp, dinfo); au_rw_write_unlock(&tmp->di_rwsem); au_di_free(tmp); diff --git a/fs/aufs/mvdown.c b/fs/aufs/mvdown.c index 334f25c13..a48aa1c50 100644 --- a/fs/aufs/mvdown.c +++ b/fs/aufs/mvdown.c @@ -451,7 +451,8 @@ static int au_mvd_args_intermediate(const unsigned char dmsg, au_di_swap(tmp, dinfo); /* returns the number of positive dentries */ - err = au_lkup_dentry(a->dentry, a->mvd_bsrc + 1, /*type*/0); + err = au_lkup_dentry(a->dentry, a->mvd_bsrc + 1, + /* AuLkup_IGNORE_PERM */ 0); if (!err) a->bwh = au_dbwh(a->dentry); else if (err > 0) diff --git a/fs/aufs/vfsub.h b/fs/aufs/vfsub.h index 4e08d33c2..291bfae7a 100644 --- a/fs/aufs/vfsub.h +++ b/fs/aufs/vfsub.h @@ -207,7 +207,7 @@ static inline void vfsub_touch_atime(struct vfsmount *h_mnt, static inline int vfsub_update_time(struct inode *h_inode, struct timespec *ts, int flags) { - return generic_update_time(h_inode, ts, flags); + return update_time(h_inode, ts, flags); /* no vfsub_update_h_iattr() since we don't have struct path */ } |