NULL VFS: store PFS mount points for later use
authorFrancois Tigeot <ftigeot@wolfpond.org>
Wed, 24 Aug 2011 20:00:28 +0000 (22:00 +0200)
committerFran├žois Tigeot <ftigeot@wolfpond.org>
Wed, 14 Dec 2011 13:14:30 +0000 (14:14 +0100)
* This is a hack to obtain the pfs mount point in vop_write()

* PFSes use nullfs mounts. Unfortunately, the nullfs implementation
  does not respect the traditional vfs/vnode layers and its vnodes
  may belong to many mount point at once.

* What's worse, the mount point passed to VFS functions is the one
  of the underlying non-PFS filesystem.

* We use the namecache layer to put the upper mount point of the
  PFS in a new vnode field to work around this limitation.

sys/kern/vfs_cache.c
sys/kern/vfs_vopops.c
sys/sys/vnode.h

index 5b92fe5..c764e77 100644 (file)
@@ -901,6 +901,10 @@ _cache_setvp(struct mount *mp, struct namecache *ncp, struct vnode *vp)
                }
                atomic_add_int(&numcache, 1);
                ncp->nc_error = 0;
+               /* XXX: this is a hack to work-around the lack of a real pfs vfs
+                * implementation*/
+               if (mp != NULL)
+                       vp->v_pfsmp = mp;
        } else {
                /*
                 * When creating a negative cache hit we set the
index 112a967..e016f4b 100644 (file)
@@ -417,7 +417,7 @@ vop_write(struct vop_ops *ops, struct vnode *vp, struct uio *uio, int ioflag,
        int error, do_accounting = 0;
        struct vattr va;
        uint64_t size_before=0, size_after=0;
-       struct mount *mountp = vp->v_mount;
+       struct mount *mp;
 
        ap.a_head.a_desc = &vop_write_desc;
        ap.a_head.a_ops = ops;
@@ -438,7 +438,12 @@ vop_write(struct vop_ops *ops, struct vnode *vp, struct uio *uio, int ioflag,
        DO_OPS(ops, error, &ap, vop_write);
        if ((error == 0) && do_accounting) {
                size_after = vp->v_filesize;
-               VFS_ACCOUNT(mountp, va.va_uid, va.va_gid, size_after - size_before);
+               if (vp->v_pfsmp != NULL) {
+                       mp = vp->v_pfsmp;
+               } else {
+                       mp = vp->v_mount;
+               }
+               VFS_ACCOUNT(mp, va.va_uid, va.va_gid, size_after - size_before);
        }
        VFS_MPUNLOCK(vp->v_mount);
        return(error);
index 24796fc..98a6f79 100644 (file)
@@ -198,6 +198,7 @@ struct vnode {
        } v_pollinfo;
        struct vmresident *v_resident;          /* optional vmresident */
        struct ccms_dataspace v_ccms;           /* cache coherency */
+       struct mount *v_pfsmp;                  /* XXX: hack for PFS accounting */
 #ifdef DEBUG_LOCKS
        const char *filename;                   /* Source file doing locking */
        int line;                               /* Line number doing locking */