vfsops - add two new ops, ncpgen_set, ncpgen_test
authorAlex Hornung <ahornung@gmail.com>
Mon, 5 Mar 2012 21:52:44 +0000 (21:52 +0000)
committerAlex Hornung <ahornung@gmail.com>
Mon, 5 Mar 2012 22:08:05 +0000 (22:08 +0000)
 * ncpgen_set takes care of setting the namecache generation in an ncp,
   while ncpgen_test can force zapping a resolved negative cache hit.

 * Make use of the functions in devfs to keep the functionality we had
   before.

 * Also pass the calls through in nullfs - this should fix a problem
   with posix_openpt when /dev is a nullfs mount of devfs.

Reported-by: Markus Pfeiffer (profmakx)
sys/kern/vfs_cache.c
sys/kern/vfs_default.c
sys/kern/vfs_init.c
sys/sys/mount.h
sys/vfs/devfs/devfs_vfsops.c
sys/vfs/nullfs/null_vfsops.c

index c764e77..ea1dec5 100644 (file)
@@ -920,7 +920,7 @@ _cache_setvp(struct mount *mp, struct namecache *ncp, struct vnode *vp)
                spin_unlock(&ncspin);
                ncp->nc_error = ENOENT;
                if (mp)
-                       ncp->nc_namecache_gen = mp->mnt_namecache_gen;
+                       VFS_NCPGEN_SET(mp, ncp);
        }
        ncp->nc_flag &= ~(NCF_UNRESOLVED | NCF_DEFEREDZAP);
 }
@@ -1032,8 +1032,7 @@ _cache_auto_unresolve(struct mount *mp, struct namecache *ncp)
         * If a resolved negative cache hit is invalid due to
         * the mount's namecache generation being bumped, zap it.
         */
-       if (ncp->nc_vp == NULL &&
-           ncp->nc_namecache_gen != mp->mnt_namecache_gen) {
+       if (ncp->nc_vp == NULL && VFS_NCPGEN_TEST(mp, ncp)) {
                _cache_setunresolved(ncp);
                return;
        }
index f61e4e2..fd91d5c 100644 (file)
@@ -1507,4 +1507,14 @@ vfs_stdac_done(struct mount *mp)
        return (0);
 }
 
+void
+vfs_stdncpgen_set(struct mount *mp, struct namecache *ncp)
+{
+}
+
+int
+vfs_stdncpgen_test(struct mount *mp, struct namecache *ncp)
+{
+       return 0;
+}
 /* end of vfs default ops */
index 11b2560..c8559e0 100644 (file)
@@ -421,6 +421,16 @@ vfs_register(struct vfsconf *vfc)
                vfsops->vfs_extattrctl = vfs_stdextattrctl;
        }
 
+       if (vfsops->vfs_ncpgen_set == NULL) {
+               /* namecache generation number */
+               vfsops->vfs_ncpgen_set = vfs_stdncpgen_set;
+       }
+
+       if (vfsops->vfs_ncpgen_test == NULL) {
+               /* check namecache generation */
+               vfsops->vfs_ncpgen_test = vfs_stdncpgen_test;
+       }
+
        /* file system uid and gid accounting */
        if (vfsops->vfs_acinit == NULL) {
                vfsops->vfs_acinit = vfs_stdac_init;
index 5eadb1e..dadd883 100644 (file)
@@ -546,6 +546,8 @@ typedef int vfs_acinit_t(struct mount *mp);
 typedef int vfs_acdone_t(struct mount *mp);
 typedef void vfs_account_t(struct mount *mp,
                        uid_t uid, gid_t gid, int64_t delta);
+typedef void vfs_ncpgen_set_t(struct mount *mp, struct namecache *ncp);
+typedef int vfs_ncpgen_test_t(struct mount *mp, struct namecache *ncp);
 
 int vfs_mount(struct mount *mp, char *path, caddr_t data, struct ucred *cred);
 int vfs_start(struct mount *mp, int flags);
@@ -589,6 +591,8 @@ struct vfsops {
        vfs_acinit_t    *vfs_acinit;
        vfs_acdone_t    *vfs_acdone;
        vfs_account_t   *vfs_account;
+       vfs_ncpgen_set_t        *vfs_ncpgen_set;
+       vfs_ncpgen_test_t       *vfs_ncpgen_test;
 };
 
 #define VFS_MOUNT(MP, PATH, DATA, CRED)                \
@@ -620,6 +624,10 @@ struct vfsops {
 #define VFS_ACCOUNT(MP, U, G, D) \
        if (MP->mnt_op->vfs_account != NULL) \
                MP->mnt_op->vfs_account(MP, U, G, D);
+#define VFS_NCPGEN_SET(MP, NCP) \
+       MP->mnt_op->vfs_ncpgen_set(MP, NCP)
+#define VFS_NCPGEN_TEST(MP, NCP) \
+       MP->mnt_op->vfs_ncpgen_test(MP, NCP)
 
 #endif
 
@@ -728,6 +736,8 @@ vfs_acinit_t        vfs_stdac_init;
 vfs_acdone_t   vfs_stdac_done;
 vfs_account_t  vfs_stdaccount;
 vfs_account_t  vfs_noaccount;
+vfs_ncpgen_set_t       vfs_stdncpgen_set;
+vfs_ncpgen_test_t      vfs_stdncpgen_test;
 
 struct vop_access_args;
 int vop_helper_access(struct vop_access_args *ap, uid_t ino_uid, gid_t ino_gid,
index da82fad..3fdb552 100644 (file)
@@ -37,6 +37,7 @@
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/mount.h>
+#include <sys/namecache.h>
 #include <sys/vnode.h>
 #include <sys/jail.h>
 #include <sys/lock.h>
@@ -252,6 +253,17 @@ devfs_vfs_vget(struct mount *mp, struct vnode *dvp,
        return 0;
 }
 
+static void
+devfs_vfs_ncpgen_set(struct mount *mp, struct namecache *ncp)
+{
+       ncp->nc_namecache_gen = mp->mnt_namecache_gen;
+}
+
+static int
+devfs_vfs_ncpgen_test(struct mount *mp, struct namecache *ncp)
+{
+       return (ncp->nc_namecache_gen != mp->mnt_namecache_gen);
+}
 
 static struct vfsops devfs_vfsops = {
        .vfs_mount      = devfs_vfs_mount,
@@ -261,7 +273,9 @@ static struct vfsops devfs_vfsops = {
        .vfs_sync       = vfs_stdsync,
        .vfs_vget       = devfs_vfs_vget,
        .vfs_vptofh     = devfs_vfs_vptofh,
-       .vfs_fhtovp     = devfs_vfs_fhtovp
+       .vfs_fhtovp     = devfs_vfs_fhtovp,
+       .vfs_ncpgen_set = devfs_vfs_ncpgen_set,
+       .vfs_ncpgen_test        = devfs_vfs_ncpgen_test
 };
 
 VFS_SET(devfs_vfsops, devfs, VFCF_SYNTHETIC);
index ae077f2..fdbe442 100644 (file)
@@ -52,6 +52,7 @@
 #include <sys/malloc.h>
 #include <sys/vnode.h>
 #include <sys/mount.h>
+#include <sys/namecache.h>
 #include <sys/nlookup.h>
 #include <sys/mountctl.h>
 #include "null.h"
@@ -372,6 +373,23 @@ nullfs_extattrctl(struct mount *mp, int cmd, struct vnode *vp,
                              vp, attrnamespace, attrname, cred);
 }
 
+static void
+nullfs_ncpgen_set(struct mount *mp, struct namecache *ncp)
+{
+       struct null_mount *xmp = MOUNTTONULLMOUNT(mp);
+
+       VFS_NCPGEN_SET(xmp->nullm_vfs, ncp);
+}
+
+
+static int
+nullfs_ncpgen_test(struct mount *mp, struct namecache *ncp)
+{
+       struct null_mount *xmp = MOUNTTONULLMOUNT(mp);
+
+       return VFS_NCPGEN_TEST(xmp->nullm_vfs, ncp);
+}
+
 
 static struct vfsops null_vfsops = {
        .vfs_mount =            nullfs_mount,
@@ -383,6 +401,8 @@ static struct vfsops null_vfsops = {
        .vfs_extattrctl =       nullfs_extattrctl,
        .vfs_fhtovp =           nullfs_fhtovp,
        .vfs_vptofh =           nullfs_vptofh,
+       .vfs_ncpgen_set =       nullfs_ncpgen_set,
+       .vfs_ncpgen_test =      nullfs_ncpgen_test,
        .vfs_checkexp =         nullfs_checkexp
 };