The patch titled autofs4 needs to force fail return revalidate (update) has been added to the -mm tree. Its filename is autofs4-needs-to-force-fail-return-revalidate-update.patch See http://www.zip.com.au/~akpm/linux/patches/stuff/added-to-mm.txt to find out what to do about this ------------------------------------------------------ Subject: autofs4 needs to force fail return revalidate (update) From: Ian Kent <raven@xxxxxxxxxx> Signed-off-by: Ian Kent <raven@xxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxx> --- fs/autofs4/root.c | 45 ++++++++++++------ fs/namei.c | 94 ++++++++++++++------------------------- include/linux/dcache.h | 1 3 files changed, 65 insertions(+), 75 deletions(-) diff -puN fs/autofs4/root.c~autofs4-needs-to-force-fail-return-revalidate-update fs/autofs4/root.c --- a/fs/autofs4/root.c~autofs4-needs-to-force-fail-return-revalidate-update +++ a/fs/autofs4/root.c @@ -137,7 +137,9 @@ static int autofs4_dir_open(struct inode nd.flags = LOOKUP_DIRECTORY; ret = (dentry->d_op->d_revalidate)(dentry, &nd); - if (!ret) { + if (ret <= 0) { + if (ret < 0) + status = ret; dcache_dir_close(inode, file); goto out; } @@ -400,13 +402,23 @@ static int autofs4_revalidate(struct den struct autofs_sb_info *sbi = autofs4_sbi(dir->i_sb); int oz_mode = autofs4_oz_mode(sbi); int flags = nd ? nd->flags : 0; - int status = 0; + int status = 1; /* Pending dentry */ if (autofs4_ispending(dentry)) { - if (!oz_mode) - status = try_to_fill_dentry(dentry, flags); - return !status; + /* The daemon never causes a mount to trigger */ + if (oz_mode) + return 1; + + /* + * A zero status is success otherwise we have a + * negative error code. + */ + status = try_to_fill_dentry(dentry, flags); + if (status == 0) + return 1; + + return status; } /* Negative dentry.. invalidate if "old" */ @@ -421,16 +433,19 @@ static int autofs4_revalidate(struct den DPRINTK("dentry=%p %.*s, emptydir", dentry, dentry->d_name.len, dentry->d_name.name); spin_unlock(&dcache_lock); - if (!oz_mode) { - status = try_to_fill_dentry(dentry, flags); - if (status) { - spin_lock(&dentry->d_lock); - dentry->d_flags |= DCACHE_REVAL_FORCE_FAIL; - spin_unlock(&dentry->d_lock); - return 0; - } - } - return !status; + /* The daemon never causes a mount to trigger */ + if (oz_mode) + return 1; + + /* + * A zero status is success otherwise we have a + * negative error code. + */ + status = try_to_fill_dentry(dentry, flags); + if (status == 0) + return 1; + + return status; } spin_unlock(&dcache_lock); diff -puN fs/namei.c~autofs4-needs-to-force-fail-return-revalidate-update fs/namei.c --- a/fs/namei.c~autofs4-needs-to-force-fail-return-revalidate-update +++ a/fs/namei.c @@ -365,6 +365,29 @@ void release_open_intent(struct nameidat fput(nd->intent.open.file); } +static __always_inline struct dentry *do_revalidate(struct dentry *dentry, struct nameidata *nd) +{ + int status = dentry->d_op->d_revalidate(dentry, nd); + if (unlikely(status <= 0)) { + /* + * The dentry failed validation. + * If d_revalidate returned 0 attempt to invalidate + * the dentry otherwise d_revalidate is asking us + * to return a fail status. + */ + if (!status) { + if (!d_invalidate(dentry)) { + dput(dentry); + dentry = NULL; + } + } else { + dput(dentry); + dentry = ERR_PTR(status); + } + } + return dentry; +} + /* * Internal lookup() using the new generic dcache. * SMP-safe @@ -379,27 +402,9 @@ static struct dentry * cached_lookup(str if (!dentry) dentry = d_lookup(parent, name); - if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { - if (!dentry->d_op->d_revalidate(dentry, nd)) { - if (!d_invalidate(dentry)) { - dput(dentry); - return NULL; - } - /* - * As well as the normal validation, check if we need - * to force a fail on a valid dentry (autofs4 browsable - * mounts). - */ - spin_lock(&dentry->d_lock); - if (dentry->d_flags & DCACHE_REVAL_FORCE_FAIL) { - dentry->d_flags &= ~DCACHE_REVAL_FORCE_FAIL; - spin_unlock(&dentry->d_lock); - dput(dentry); - return ERR_PTR(-ENOENT); - } - spin_unlock(&dentry->d_lock); - } - } + if (dentry && dentry->d_op && dentry->d_op->d_revalidate) + dentry = do_revalidate(dentry, nd); + return dentry; } @@ -492,25 +497,9 @@ static struct dentry * real_lookup(struc */ mutex_unlock(&dir->i_mutex); if (result->d_op && result->d_op->d_revalidate) { - if (!result->d_op->d_revalidate(result, nd)) { - if (!d_invalidate(result)) { - dput(result); - return ERR_PTR(-ENOENT); - } - /* - * d_revalidate failed but the dentry is still valid so - * check if we need to force a fail on the dentry (autofs4 - * browsable mounts). - */ - spin_lock(&result->d_lock); - if (result->d_flags & DCACHE_REVAL_FORCE_FAIL) { - result->d_flags &= ~DCACHE_REVAL_FORCE_FAIL; - spin_unlock(&result->d_lock); - dput(result); - return ERR_PTR(-ENOENT); - } - spin_unlock(&result->d_lock); - } + result = do_revalidate(result, nd); + if (!result) + result = ERR_PTR(-ENOENT); } return result; } @@ -790,25 +779,12 @@ need_lookup: goto done; need_revalidate: - if (dentry->d_op->d_revalidate(dentry, nd)) - goto done; - if (d_invalidate(dentry)) { - /* - * d_revalidate failed but the dentry is still valid so check - * if we need to return a fail (autofs4 browsable mounts). - */ - spin_lock(&dentry->d_lock); - if (dentry->d_flags & DCACHE_REVAL_FORCE_FAIL) { - dentry->d_flags &= ~DCACHE_REVAL_FORCE_FAIL; - spin_unlock(&dentry->d_lock); - dput(dentry); - return -ENOENT; - } - spin_unlock(&dentry->d_lock); - goto done; - } - dput(dentry); - goto need_lookup; + dentry = do_revalidate(dentry, nd); + if (!dentry) + goto need_lookup; + if (IS_ERR(dentry)) + goto fail; + goto done; fail: return PTR_ERR(dentry); diff -puN include/linux/dcache.h~autofs4-needs-to-force-fail-return-revalidate-update include/linux/dcache.h --- a/include/linux/dcache.h~autofs4-needs-to-force-fail-return-revalidate-update +++ a/include/linux/dcache.h @@ -163,7 +163,6 @@ d_iput: no no no yes #define DCACHE_UNHASHED 0x0010 #define DCACHE_INOTIFY_PARENT_WATCHED 0x0020 /* Parent inode is watched */ -#define DCACHE_REVAL_FORCE_FAIL 0x0040 /* Force revalidate fail on valid dentry */ extern spinlock_t dcache_lock; _ Patches currently in -mm which might be from raven@xxxxxxxxxx are autofs4-need-to-invalidate-children-on-tree-mount-expire.patch autofs4-needs-to-force-fail-return-revalidate.patch autofs4-needs-to-force-fail-return-revalidate-update.patch fs-use-list_move.patch - To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html