+ printf("tag VT_UFS, ino %d, on dev %d, %d%s\n", ip->i_number,
+ major(ip->i_dev), minor(ip->i_dev),
+ (ip->i_flag & ILOCKED) ? " (LOCKED)" : "");
+ if (ip->i_spare0 == 0)
+ return;
+ printf("\towner pid %d", ip->i_spare0);
+ if (ip->i_spare1)
+ printf(" waiting pid %d", ip->i_spare1);
+ printf("\n");
+}
+
+/*
+ * Read wrapper for special devices.
+ */
+ufsspec_read(vp, uio, ioflag, cred)
+ struct vnode *vp;
+ struct uio *uio;
+ int ioflag;
+ struct ucred *cred;
+{
+
+ /*
+ * Set access flag.
+ */
+ VTOI(vp)->i_flag |= IACC;
+ return (spec_read(vp, uio, ioflag, cred));
+}
+
+/*
+ * Write wrapper for special devices.
+ */
+ufsspec_write(vp, uio, ioflag, cred)
+ struct vnode *vp;
+ struct uio *uio;
+ int ioflag;
+ struct ucred *cred;
+{
+
+ /*
+ * Set update and change flags.
+ */
+ VTOI(vp)->i_flag |= IUPD|ICHG;
+ return (spec_write(vp, uio, ioflag, cred));
+}
+
+/*
+ * Close wrapper for special devices.
+ *
+ * Update the times on the inode then do device close.
+ */
+ufsspec_close(vp, fflag, cred)
+ struct vnode *vp;
+ int fflag;
+ struct ucred *cred;
+{
+ register struct inode *ip = VTOI(vp);
+
+ if (vp->v_usecount > 1 && !(ip->i_flag & ILOCKED))
+ ITIMES(ip, &time, &time);
+ return (spec_close(vp, fflag, cred));
+}
+
+/*
+ * Make a new file.
+ */
+maknode(mode, ndp, ipp)
+ int mode;
+ register struct nameidata *ndp;
+ struct inode **ipp;
+{
+ register struct inode *ip;
+ struct inode *tip;
+ register struct inode *pdir = VTOI(ndp->ni_dvp);
+ ino_t ipref;
+ int error;
+
+ *ipp = 0;
+ if ((mode & IFMT) == IFDIR)
+ ipref = dirpref(pdir->i_fs);
+ else
+ ipref = pdir->i_number;
+ error = ialloc(pdir, ipref, mode, &tip);
+ if (error) {
+ iput(pdir);
+ return (error);
+ }
+ ip = tip;
+#ifdef QUOTA
+ if (ip->i_dquot != NODQUOT)
+ panic("maknode: dquot");
+#endif
+ ip->i_flag |= IACC|IUPD|ICHG;
+ if ((mode & IFMT) == 0)
+ mode |= IFREG;
+ ip->i_mode = mode;
+ ITOV(ip)->v_type = IFTOVT(mode); /* Rest init'd in iget() */
+ ip->i_nlink = 1;
+ ip->i_uid = ndp->ni_cred->cr_uid;
+ ip->i_gid = pdir->i_gid;
+ if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, ndp->ni_cred) &&
+ suser(ndp->ni_cred, NULL))
+ ip->i_mode &= ~ISGID;
+#ifdef QUOTA
+ ip->i_dquot = inoquota(ip);
+#endif
+
+ /*
+ * Make sure inode goes to disk before directory entry.
+ */
+ if ((error = iupdat(ip, &time, &time, 1)) ||
+ (error = direnter(ip, ndp))) {
+ /*
+ * Write error occurred trying to update the inode
+ * or the directory so must deallocate the inode.
+ */
+ ip->i_nlink = 0;
+ ip->i_flag |= ICHG;
+ iput(ip);
+ return (error);
+ }
+ *ipp = ip;
+ return (0);