diff --git a/usr.bin/fstat/ext2fs.c b/usr.bin/fstat/ext2fs.c
index 5f32c2b..8930611 100644
--- a/usr.bin/fstat/ext2fs.c
+++ b/usr.bin/fstat/ext2fs.c
@@ -45,46 +45,15 @@ int
 ext2fs_filestat(struct vnode *vp, struct filestat *fsp)
 {
 	struct inode ino;
-	mode_t mode;
 
 	if (!kread(VTOI(vp), &ino, sizeof(ino))) {
 		dprintf(stderr, "can't read inode at %p for pid %d\n",
 		    (void *)VTOI(vp), Pid);
 		return 0;
 	}
-	mode = ino.i_mode;
-	switch (vp->v_type) {
-	case VREG:
-		mode |= S_IFREG;
-		break;
-	case VDIR:
-		mode |= S_IFDIR;
-		break;
-	case VBLK:
-		mode |= S_IFBLK;
-		break;
-	case VCHR:
-		mode |= S_IFCHR;
-		break;
-	case VLNK:
-		mode |= S_IFLNK;
-		break;
-	case VSOCK:
-		mode |= S_IFSOCK;
-		break;
-	case VFIFO:
-		mode |= S_IFIFO;
-		break;
-	case VDATABASE:
-		break;
-	case VINT:
-	case VNON:
-	case VBAD:
-		return 0;
-	}
-
+	fsp->mode = (mode_t)ino.i_mode;
+	fsp->mode |= MTRANS(vp->v_type);
 	fsp->rdev = fsp->fsid = dev2udev(ino.i_dev);
-	fsp->mode = mode;
 	fsp->size = ino.i_din.di_size;
 	fsp->fileid = ino.i_number;
 
diff --git a/usr.bin/fstat/fstat.c b/usr.bin/fstat/fstat.c
index 00efd69..8690e69 100644
--- a/usr.bin/fstat/fstat.c
+++ b/usr.bin/fstat/fstat.c
@@ -113,6 +113,19 @@ int	wflg_cmd = 10;
 int	pid_width = 5;
 int	ino_width = 6;
 
+u_int16_t modelist[11][2] = {
+        { VNON, 0 },
+        { VREG, S_IFREG },
+        { VDIR, S_IFDIR },
+        { VBLK, S_IFBLK },
+        { VCHR, S_IFCHR },
+        { VLNK, S_IFLNK },
+        { VSOCK, S_IFSOCK },
+        { VFIFO, S_IFIFO },
+        { VBAD, 0 },
+        { VDATABASE, S_IFDB },
+        { VINT, 0 }
+};
 
 struct fdnode *ofiles; 	/* buffer of pointers to file structures */
 int maxfiles;
@@ -129,17 +142,17 @@ int maxfiles;
 
 kvm_t *kd;
 
-void dofiles(struct kinfo_proc *kp, struct proc *p);
-void dommap(struct proc *p);
-void vtrans(struct vnode *vp, struct nchandle *ncr, int i, int flag, off_t off);
-int  ufs_filestat(struct vnode *vp, struct filestat *fsp);
-int  nfs_filestat(struct vnode *vp, struct filestat *fsp);
-int  devfs_filestat(struct vnode *vp, struct filestat *fsp);
-char *getmnton(struct mount *m, struct namecache_list *ncplist, struct nchandle *ncr);
-void pipetrans(struct pipe *pi, int i, int flag);
-void socktrans(struct socket *sock, int i);
-void getinetproto(int number);
-int  getfname(const char *filename);
+void dofiles(struct kinfo_proc *, struct proc *);
+void dommap(struct proc *);
+void vtrans(struct vnode *, struct nchandle *, int, int, off_t);
+int  ufs_filestat(struct vnode *, struct filestat *);
+int  nfs_filestat(struct vnode *, struct filestat *);
+int  devfs_filestat(struct vnode *, struct filestat *);
+char *getmnton(struct mount *, struct namecache_list *, struct nchandle *);
+void pipetrans(struct pipe *, int, int);
+void socktrans(struct socket *, int);
+void getinetproto(int);
+int  getfname(const char *);
 void usage(void);
 
 
@@ -604,7 +617,6 @@ int
 nfs_filestat(struct vnode *vp, struct filestat *fsp)
 {
 	struct nfsnode nfsnode;
-	mode_t mode;
 
 	if (!kread(VTONFS(vp), &nfsnode, sizeof (nfsnode))) {
 		dprintf(stderr, "can't read nfsnode at %p for pid %d\n",
@@ -616,37 +628,8 @@ nfs_filestat(struct vnode *vp, struct filestat *fsp)
 	fsp->size = nfsnode.n_size;
 	fsp->rdev = makeudev(nfsnode.n_vattr.va_rmajor,
 			     nfsnode.n_vattr.va_rminor);
-	mode = (mode_t)nfsnode.n_vattr.va_mode;
-	switch (vp->v_type) {
-	case VREG:
-		mode |= S_IFREG;
-		break;
-	case VDIR:
-		mode |= S_IFDIR;
-		break;
-	case VBLK:
-		mode |= S_IFBLK;
-		break;
-	case VCHR:
-		mode |= S_IFCHR;
-		break;
-	case VLNK:
-		mode |= S_IFLNK;
-		break;
-	case VSOCK:
-		mode |= S_IFSOCK;
-		break;
-	case VFIFO:
-		mode |= S_IFIFO;
-		break;
-	case VDATABASE:
-		break;
-	case VINT:
-	case VNON:
-	case VBAD:
-		return 0;
-	}
-	fsp->mode = mode;
+	fsp->mode = (mode_t)nfsnode.n_vattr.va_mode;
+	fsp->mode |= MTRANS(vp->v_type);
 
 	return 1;
 }
diff --git a/usr.bin/fstat/fstat.h b/usr.bin/fstat/fstat.h
index 557c25d..2c465e1 100644
--- a/usr.bin/fstat/fstat.h
+++ b/usr.bin/fstat/fstat.h
@@ -59,16 +59,20 @@ struct  filestat {
 extern kvm_t *kd;
 extern int vflg;
 extern int Pid;
+extern u_int16_t modelist[11][2];
+
+#define MTRANS(n) modelist[n][1]
 
 udev_t dev2udev(void *dev);
 udev_t makeudev(int x, int y);
 
 /* Additional filesystem types */
-int ext2fs_filestat(struct vnode *vp, struct filestat *fsp);
-int hammer_filestat(struct vnode *vp, struct filestat *fsp);
-int isofs_filestat(struct vnode *vp, struct filestat *fsp);
-int msdosfs_filestat(struct vnode *vp, struct filestat *fsp);
-int ntfs_filestat(struct vnode *vp, struct filestat *fsp);
-ssize_t kread(const void *kaddr, void *uaddr, size_t nbytes);
+int ext2fs_filestat(struct vnode *, struct filestat *);
+int hammer_filestat(struct vnode *, struct filestat *);
+int isofs_filestat(struct vnode *, struct filestat *);
+int msdosfs_filestat(struct vnode *, struct filestat *);
+mode_t mtrans(mode_t);
+int ntfs_filestat(struct vnode *, struct filestat *);
+ssize_t kread(const void *, void *, size_t);
 
 #endif /* __FSTAT_H__ */
diff --git a/usr.bin/fstat/hammer.c b/usr.bin/fstat/hammer.c
index 98456ea..e8fefc6 100644
--- a/usr.bin/fstat/hammer.c
+++ b/usr.bin/fstat/hammer.c
@@ -49,7 +49,6 @@ hammer_filestat(struct vnode *vp, struct filestat *fsp)
 {
 	struct hammer_inode ino;
 	struct hammer_pseudofs_inmem pfsm;
-	mode_t mode;
 
 	if (!kread(VTOI(vp), &ino, sizeof(ino))) {
 		dprintf(stderr, "can't read hammer_inode at %p for pid %d\n",
@@ -64,37 +63,8 @@ hammer_filestat(struct vnode *vp, struct filestat *fsp)
 	}
 	fsp->fsid = pfsm.fsid_udev ^ (u_int32_t)ino.obj_asof ^
 	    (u_int32_t)(ino.obj_asof >> 32);
-	mode = (mode_t)ino.ino_data.mode;
-	switch (vp->v_type) {
-	case VREG:
-		mode |= S_IFREG;
-		break;
-	case VDIR:
-		mode |= S_IFDIR;
-		break;
-	case VBLK:
-		mode |= S_IFBLK;
-		break;
-	case VCHR:
-		mode |= S_IFCHR;
-		break;
-	case VLNK:
-		mode |= S_IFLNK;
-		break;
-	case VSOCK:
-		mode |= S_IFSOCK;
-		break;
-	case VFIFO:
-		mode |= S_IFIFO;
-		break;
-	case VDATABASE:
-		break;
-	case VINT:
-	case VNON:
-	case VBAD:
-		return 0;
-	}
-	fsp->mode = mode;
+	fsp->mode = (mode_t)ino.ino_data.mode;
+	fsp->mode |= MTRANS(vp->v_type);
 	fsp->fileid = (long)ino.ino_leaf.base.obj_id;
 	fsp->size = ino.ino_data.size;
 	fsp->rdev = dev2udev(vp->v_rdev);
diff --git a/usr.bin/fstat/ntfs.c b/usr.bin/fstat/ntfs.c
index f11481a..ca760cb 100644
--- a/usr.bin/fstat/ntfs.c
+++ b/usr.bin/fstat/ntfs.c
@@ -48,7 +48,6 @@ ntfs_filestat(struct vnode *vp, struct filestat *fsp)
 	struct fnode fn;
 	struct ntnode ino;
 	struct ntfsmount mp;
-	mode_t mode;
 
 	if (!kread(VTOF(vp), &fn, sizeof(fn))) {
 		dprintf(stderr, "can't read fnode at %p for pid %d\n",
@@ -67,39 +66,9 @@ ntfs_filestat(struct vnode *vp, struct filestat *fsp)
 		    (void *)ino.i_mp, Pid);
 		return 0;
 	}
-	mode = mp.ntm_mode;
-	switch (vp->v_type) {
-	case VREG:
-		mode |= S_IFREG;
-		break;
-	case VDIR:
-		mode |= S_IFDIR;
-		break;
-	case VBLK:
-		mode |= S_IFBLK;
-		break;
-	case VCHR:
-		mode |= S_IFCHR;
-		break;
-	case VLNK:
-		mode |= S_IFLNK;
-		break;
-	case VSOCK:
-		mode |= S_IFSOCK;
-		break;
-	case VFIFO:
-		mode |= S_IFIFO;
-		break;
-	case VDATABASE:
-		break;
-	case VINT:
-	case VNON:
-	case VBAD:
-		return 0;
-	}
-
+	fsp->mode = (mode_t)mp.ntm_mode;
+	fsp->mode |= MTRANS(vp->v_type);
 	fsp->rdev = fsp->fsid = dev2udev(ino.i_dev);
-	fsp->mode = mode;
 	fsp->size = fn.f_size;
 	fsp->fileid = ino.i_number;
 
