- * Convert a pointer to an inode into a reference to an inode.
- *
- * This is basically the internal piece of iget (after the
- * inode pointer is located) but without the test for mounted
- * filesystems. It is caller's responsibility to check that
- * the inode pointer is valid.
- */
-igrab(ip)
- register struct inode *ip;
-{
- register struct vnode *vp = ITOV(ip);
-
- while ((ip->i_flag&ILOCKED) != 0) {
- ip->i_flag |= IWANT;
- sleep((caddr_t)ip, PINOD);
- }
- if (vp->v_count == 0) { /* ino on free list */
- register struct inode *iq;
-
- if (iq = ip->i_freef)
- iq->i_freeb = ip->i_freeb;
- else
- ifreet = ip->i_freeb;
- *ip->i_freeb = iq;
- ip->i_freef = NULL;
- ip->i_freeb = NULL;
- }
- vp->v_count++;
- ip->i_flag |= ILOCKED;
-}
-
-/*
- * Create a vnode for a block device.
- * Used for root filesystem, argdev, and swap areas.
- */
-bdevvp(dev, vpp)
- dev_t dev;
- struct vnode **vpp;
-{
- register struct inode *ip;
- register struct vnode *vp;
- struct inode *nip;
- int error;
-
- /*
- * Check for the existence of an existing vnode.
- */
-again:
- for (ip = bdevlisth; ip; ip = ip->i_devlst) {
- vp = ITOV(ip);
- if (dev != vp->v_rdev)
- continue;
- igrab(ip);
- if (dev != vp->v_rdev) {
- iput(ip);
- goto again;
- }
- IUNLOCK(ip);
- *vpp = vp;
- return (0);
- }
- if (error = getnewino(NODEV, (ino_t)0, &nip)) {
- *vpp = 0;
- return (error);
- }
- ip = nip;
- ip->i_fs = 0;
- ip->i_devlst = bdevlisth;
- bdevlisth = ip;
- vp = ITOV(ip);
- vinit(vp, 0, VBLK, &blk_vnodeops);
- vp->v_rdev = dev;
- IUNLOCK(ip);
- *vpp = vp;
- return (0);
-}
-
-/*
- * Decrement reference count of
- * an inode structure.
- * On the last reference,
- * write the inode out and if necessary,
- * truncate and deallocate the file.