home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / ufs / ufs_vnops.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-20  |  41.4 KB  |  1,864 lines

  1. /*
  2.  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  *
  33.  *    @(#)ufs_vnops.c    7.64 (Berkeley) 5/16/91
  34.  */
  35.  
  36. #include "param.h"
  37. #include "systm.h"
  38. #include "namei.h"
  39. #include "resourcevar.h"
  40. #include "kernel.h"
  41. #include "file.h"
  42. #include "stat.h"
  43. #include "buf.h"
  44. #include "proc.h"
  45. #include "conf.h"
  46. #include "mount.h"
  47. #include "vnode.h"
  48. #include "specdev.h"
  49. #include "fifo.h"
  50. #include "malloc.h"
  51.  
  52. #include "lockf.h"
  53. #include "quota.h"
  54. #include "inode.h"
  55. #include "dir.h"
  56. #include "fs.h"
  57.  
  58. /*
  59.  * Create a regular file
  60.  */
  61. ufs_create(ndp, vap, p)
  62.     struct nameidata *ndp;
  63.     struct vattr *vap;
  64.     struct proc *p;
  65. {
  66.     struct inode *ip;
  67.     int error;
  68.  
  69.     if (error = maknode(MAKEIMODE(vap->va_type, vap->va_mode), ndp, &ip))
  70.         return (error);
  71.     ndp->ni_vp = ITOV(ip);
  72.     return (0);
  73. }
  74.  
  75. /*
  76.  * Mknod vnode call
  77.  */
  78. /* ARGSUSED */
  79. ufs_mknod(ndp, vap, cred, p)
  80.     struct nameidata *ndp;
  81.     struct ucred *cred;
  82.     struct vattr *vap;
  83.     struct proc *p;
  84. {
  85.     register struct vnode *vp;
  86.     struct inode *ip;
  87.     int error;
  88.  
  89.     if (error = maknode(MAKEIMODE(vap->va_type, vap->va_mode), ndp, &ip))
  90.         return (error);
  91.     ip->i_flag |= IACC|IUPD|ICHG;
  92.     if (vap->va_rdev != VNOVAL) {
  93.         /*
  94.          * Want to be able to use this to make badblock
  95.          * inodes, so don't truncate the dev number.
  96.          */
  97.         ip->i_rdev = vap->va_rdev;
  98.     }
  99.     /*
  100.      * Remove inode so that it will be reloaded by iget and
  101.      * checked to see if it is an alias of an existing entry
  102.      * in the inode cache.
  103.      */
  104.     vp = ITOV(ip);
  105.     vput(vp);
  106.     vp->v_type = VNON;
  107.     vgone(vp);
  108.     return (0);
  109. }
  110.  
  111. /*
  112.  * Open called.
  113.  *
  114.  * Nothing to do.
  115.  */
  116. /* ARGSUSED */
  117. ufs_open(vp, mode, cred, p)
  118.     struct vnode *vp;
  119.     int mode;
  120.     struct ucred *cred;
  121.     struct proc *p;
  122. {
  123.  
  124.     return (0);
  125. }
  126.  
  127. /*
  128.  * Close called
  129.  *
  130.  * Update the times on the inode.
  131.  */
  132. /* ARGSUSED */
  133. ufs_close(vp, fflag, cred, p)
  134.     struct vnode *vp;
  135.     int fflag;
  136.     struct ucred *cred;
  137.     struct proc *p;
  138. {
  139.     register struct inode *ip = VTOI(vp);
  140.  
  141.     if (vp->v_usecount > 1 && !(ip->i_flag & ILOCKED))
  142.         ITIMES(ip, &time, &time);
  143.     return (0);
  144. }
  145.  
  146. /*
  147.  * Check mode permission on inode pointer. Mode is READ, WRITE or EXEC.
  148.  * The mode is shifted to select the owner/group/other fields. The
  149.  * super user is granted all permissions.
  150.  */
  151. ufs_access(vp, mode, cred, p)
  152.     struct vnode *vp;
  153.     register int mode;
  154.     struct ucred *cred;
  155.     struct proc *p;
  156. {
  157.     register struct inode *ip = VTOI(vp);
  158.     register gid_t *gp;
  159.     int i, error;
  160.  
  161. #ifdef DIAGNOSTIC
  162.     if (!VOP_ISLOCKED(vp)) {
  163.         vprint("ufs_access: not locked", vp);
  164.         panic("ufs_access: not locked");
  165.     }
  166. #endif
  167. #ifdef QUOTA
  168.     if (mode & VWRITE) {
  169.         switch (vp->v_type) {
  170.         case VREG: case VDIR: case VLNK:
  171.             if (error = getinoquota(ip))
  172.                 return (error);
  173.         }
  174.     }
  175. #endif /* QUOTA */
  176.     /*
  177.      * If you're the super-user, you always get access.
  178.      */
  179.     if (cred->cr_uid == 0)
  180.         return (0);
  181.     /*
  182.      * Access check is based on only one of owner, group, public.
  183.      * If not owner, then check group. If not a member of the
  184.      * group, then check public access.
  185.      */
  186.     if (cred->cr_uid != ip->i_uid) {
  187.         mode >>= 3;
  188.         gp = cred->cr_groups;
  189.         for (i = 0; i < cred->cr_ngroups; i++, gp++)
  190.             if (ip->i_gid == *gp)
  191.                 goto found;
  192.         mode >>= 3;
  193. found:
  194.         ;
  195.     }
  196.     if ((ip->i_mode & mode) != 0)
  197.         return (0);
  198.     return (EACCES);
  199. }
  200.  
  201. /* ARGSUSED */
  202. ufs_getattr(vp, vap, cred, p)
  203.     struct vnode *vp;
  204.     register struct vattr *vap;
  205.     struct ucred *cred;
  206.     struct proc *p;
  207. {
  208.     register struct inode *ip = VTOI(vp);
  209.  
  210.     ITIMES(ip, &time, &time);
  211.     /*
  212.      * Copy from inode table
  213.      */
  214.     vap->va_fsid = ip->i_dev;
  215.     vap->va_fileid = ip->i_number;
  216.     vap->va_mode = ip->i_mode & ~IFMT;
  217.     vap->va_nlink = ip->i_nlink;
  218.     vap->va_uid = ip->i_uid;
  219.     vap->va_gid = ip->i_gid;
  220.     vap->va_rdev = (dev_t)ip->i_rdev;
  221. #ifdef tahoe
  222.     vap->va_size = ip->i_size;
  223.     vap->va_size_rsv = 0;
  224. #else
  225.     vap->va_qsize = ip->i_din.di_qsize;
  226. #endif
  227.     vap->va_atime.tv_sec = ip->i_atime;
  228.     vap->va_atime.tv_usec = 0;
  229.     vap->va_mtime.tv_sec = ip->i_mtime;
  230.     vap->va_mtime.tv_usec = 0;
  231.     vap->va_ctime.tv_sec = ip->i_ctime;
  232.     vap->va_ctime.tv_usec = 0;
  233.     vap->va_flags = ip->i_flags;
  234.     vap->va_gen = ip->i_gen;
  235.     /* this doesn't belong here */
  236.     if (vp->v_type == VBLK)
  237.         vap->va_blocksize = BLKDEV_IOSIZE;
  238.     else if (vp->v_type == VCHR)
  239.         vap->va_blocksize = MAXBSIZE;
  240.     else
  241.         vap->va_blocksize = ip->i_fs->fs_bsize;
  242.     vap->va_bytes = dbtob(ip->i_blocks);
  243.     vap->va_bytes_rsv = 0;
  244.     vap->va_type = vp->v_type;
  245.     return (0);
  246. }
  247.  
  248. /*
  249.  * Set attribute vnode op. called from several syscalls
  250.  */
  251. ufs_setattr(vp, vap, cred, p)
  252.     register struct vnode *vp;
  253.     register struct vattr *vap;
  254.     register struct ucred *cred;
  255.     struct proc *p;
  256. {
  257.     register struct inode *ip = VTOI(vp);
  258.     int error = 0;
  259.  
  260.     /*
  261.      * Check for unsetable attributes.
  262.      */
  263.     if ((vap->va_type != VNON) || (vap->va_nlink != VNOVAL) ||
  264.         (vap->va_fsid != VNOVAL) || (vap->va_fileid != VNOVAL) ||
  265.         (vap->va_blocksize != VNOVAL) || (vap->va_rdev != VNOVAL) ||
  266.         ((int)vap->va_bytes != VNOVAL) || (vap->va_gen != VNOVAL)) {
  267.         return (EINVAL);
  268.     }
  269.     /*
  270.      * Go through the fields and update iff not VNOVAL.
  271.      */
  272.     if (vap->va_uid != (u_short)VNOVAL || vap->va_gid != (u_short)VNOVAL)
  273.         if (error = chown1(vp, vap->va_uid, vap->va_gid, p))
  274.             return (error);
  275.     if (vap->va_size != VNOVAL) {
  276.         if (vp->v_type == VDIR)
  277.             return (EISDIR);
  278.         if (error = itrunc(ip, vap->va_size, 0)) /* XXX IO_SYNC? */
  279.             return (error);
  280.     }
  281.     if (vap->va_atime.tv_sec != VNOVAL || vap->va_mtime.tv_sec != VNOVAL) {
  282.         if (cred->cr_uid != ip->i_uid &&
  283.             (error = suser(cred, &p->p_acflag)))
  284.             return (error);
  285.         if (vap->va_atime.tv_sec != VNOVAL)
  286.             ip->i_flag |= IACC;
  287.         if (vap->va_mtime.tv_sec != VNOVAL)
  288.             ip->i_flag |= IUPD;
  289.         ip->i_flag |= ICHG;
  290.         if (error = iupdat(ip, &vap->va_atime, &vap->va_mtime, 1))
  291.             return (error);
  292.     }
  293.     if (vap->va_mode != (u_short)VNOVAL)
  294.         error = chmod1(vp, (int)vap->va_mode, p);
  295.     if (vap->va_flags != VNOVAL) {
  296.         if (cred->cr_uid != ip->i_uid &&
  297.             (error = suser(cred, &p->p_acflag)))
  298.             return (error);
  299.         if (cred->cr_uid == 0) {
  300.             ip->i_flags = vap->va_flags;
  301.         } else {
  302.             ip->i_flags &= 0xffff0000;
  303.             ip->i_flags |= (vap->va_flags & 0xffff);
  304.         }
  305.         ip->i_flag |= ICHG;
  306.     }
  307.     return (error);
  308. }
  309.  
  310. /*
  311.  * Change the mode on a file.
  312.  * Inode must be locked before calling.
  313.  */
  314. chmod1(vp, mode, p)
  315.     register struct vnode *vp;
  316.     register int mode;
  317.     struct proc *p;
  318. {
  319.     register struct ucred *cred = p->p_ucred;
  320.     register struct inode *ip = VTOI(vp);
  321.     int error;
  322.  
  323.     if (cred->cr_uid != ip->i_uid &&
  324.         (error = suser(cred, &p->p_acflag)))
  325.         return (error);
  326.     if (cred->cr_uid) {
  327.         if (vp->v_type != VDIR && (mode & ISVTX))
  328.             return (EFTYPE);
  329.         if (!groupmember(ip->i_gid, cred) && (mode & ISGID))
  330.             return (EPERM);
  331.     }
  332.     ip->i_mode &= ~07777;
  333.     ip->i_mode |= mode & 07777;
  334.     ip->i_flag |= ICHG;
  335.     if ((vp->v_flag & VTEXT) && (ip->i_mode & ISVTX) == 0)
  336.         (void) vnode_pager_uncache(vp);
  337.     return (0);
  338. }
  339.  
  340. /*
  341.  * Perform chown operation on inode ip;
  342.  * inode must be locked prior to call.
  343.  */
  344. chown1(vp, uid, gid, p)
  345.     register struct vnode *vp;
  346.     uid_t uid;
  347.     gid_t gid;
  348.     struct proc *p;
  349. {
  350.     register struct inode *ip = VTOI(vp);
  351.     register struct ucred *cred = p->p_ucred;
  352.     uid_t ouid;
  353.     gid_t ogid;
  354.     int error = 0;
  355. #ifdef QUOTA
  356.     register int i;
  357.     long change;
  358. #endif
  359.  
  360.     if (uid == (u_short)VNOVAL)
  361.         uid = ip->i_uid;
  362.     if (gid == (u_short)VNOVAL)
  363.         gid = ip->i_gid;
  364.     /*
  365.      * If we don't own the file, are trying to change the owner
  366.      * of the file, or are not a member of the target group,
  367.      * the caller must be superuser or the call fails.
  368.      */
  369.     if ((cred->cr_uid != ip->i_uid || uid != ip->i_uid ||
  370.         !groupmember((gid_t)gid, cred)) &&
  371.         (error = suser(cred, &p->p_acflag)))
  372.         return (error);
  373.     ouid = ip->i_uid;
  374.     ogid = ip->i_gid;
  375. #ifdef QUOTA
  376.     if (error = getinoquota(ip))
  377.         return (error);
  378.     if (ouid == uid) {
  379.         dqrele(vp, ip->i_dquot[USRQUOTA]);
  380.         ip->i_dquot[USRQUOTA] = NODQUOT;
  381.     }
  382.     if (ogid == gid) {
  383.         dqrele(vp, ip->i_dquot[GRPQUOTA]);
  384.         ip->i_dquot[GRPQUOTA] = NODQUOT;
  385.     }
  386.     change = ip->i_blocks;
  387.     (void) chkdq(ip, -change, cred, CHOWN);
  388.     (void) chkiq(ip, -1, cred, CHOWN);
  389.     for (i = 0; i < MAXQUOTAS; i++) {
  390.         dqrele(vp, ip->i_dquot[i]);
  391.         ip->i_dquot[i] = NODQUOT;
  392.     }
  393. #endif
  394.     ip->i_uid = uid;
  395.     ip->i_gid = gid;
  396. #ifdef QUOTA
  397.     if ((error = getinoquota(ip)) == 0) {
  398.         if (ouid == uid) {
  399.             dqrele(vp, ip->i_dquot[USRQUOTA]);
  400.             ip->i_dquot[USRQUOTA] = NODQUOT;
  401.         }
  402.         if (ogid == gid) {
  403.             dqrele(vp, ip->i_dquot[GRPQUOTA]);
  404.             ip->i_dquot[GRPQUOTA] = NODQUOT;
  405.         }
  406.         if ((error = chkdq(ip, change, cred, CHOWN)) == 0) {
  407.             if ((error = chkiq(ip, 1, cred, CHOWN)) == 0)
  408.                 goto good;
  409.             else
  410.                 (void) chkdq(ip, -change, cred, CHOWN|FORCE);
  411.         }
  412.         for (i = 0; i < MAXQUOTAS; i++) {
  413.             dqrele(vp, ip->i_dquot[i]);
  414.             ip->i_dquot[i] = NODQUOT;
  415.         }
  416.     }
  417.     ip->i_uid = ouid;
  418.     ip->i_gid = ogid;
  419.     if (getinoquota(ip) == 0) {
  420.         if (ouid == uid) {
  421.             dqrele(vp, ip->i_dquot[USRQUOTA]);
  422.             ip->i_dquot[USRQUOTA] = NODQUOT;
  423.         }
  424.         if (ogid == gid) {
  425.             dqrele(vp, ip->i_dquot[GRPQUOTA]);
  426.             ip->i_dquot[GRPQUOTA] = NODQUOT;
  427.         }
  428.         (void) chkdq(ip, change, cred, FORCE|CHOWN);
  429.         (void) chkiq(ip, 1, cred, FORCE|CHOWN);
  430.         (void) getinoquota(ip);
  431.     }
  432.     return (error);
  433. good:
  434.     if (getinoquota(ip))
  435.         panic("chown: lost quota");
  436. #endif /* QUOTA */
  437.     if (ouid != uid || ogid != gid)
  438.         ip->i_flag |= ICHG;
  439.     if (ouid != uid && cred->cr_uid != 0)
  440.         ip->i_mode &= ~ISUID;
  441.     if (ogid != gid && cred->cr_uid != 0)
  442.         ip->i_mode &= ~ISGID;
  443.     return (0);
  444. }
  445.  
  446. /*
  447.  * Vnode op for reading.
  448.  */
  449. /* ARGSUSED */
  450. ufs_read(vp, uio, ioflag, cred)
  451.     struct vnode *vp;
  452.     register struct uio *uio;
  453.     int ioflag;
  454.     struct ucred *cred;
  455. {
  456.     register struct inode *ip = VTOI(vp);
  457.     register struct fs *fs;
  458.     struct buf *bp;
  459.     daddr_t lbn, bn, rablock;
  460.     int size, diff, error = 0;
  461.     long n, on, type;
  462.  
  463. #ifdef DIAGNOSTIC
  464.     if (uio->uio_rw != UIO_READ)
  465.         panic("ufs_read mode");
  466.     type = ip->i_mode & IFMT;
  467.     if (type != IFDIR && type != IFREG && type != IFLNK)
  468.         panic("ufs_read type");
  469. #endif
  470.     if (uio->uio_resid == 0)
  471.         return (0);
  472.     if (uio->uio_offset < 0)
  473.         return (EINVAL);
  474.     ip->i_flag |= IACC;
  475.     fs = ip->i_fs;
  476.     do {
  477.         lbn = lblkno(fs, uio->uio_offset);
  478.         on = blkoff(fs, uio->uio_offset);
  479.         n = MIN((unsigned)(fs->fs_bsize - on), uio->uio_resid);
  480.         diff = ip->i_size - uio->uio_offset;
  481.         if (diff <= 0)
  482.             return (0);
  483.         if (diff < n)
  484.             n = diff;
  485.         size = blksize(fs, ip, lbn);
  486.         rablock = lbn + 1;
  487.         if (vp->v_lastr + 1 == lbn &&
  488.             lblktosize(fs, rablock) < ip->i_size)
  489.             error = breada(ITOV(ip), lbn, size, rablock,
  490.                 blksize(fs, ip, rablock), NOCRED, &bp);
  491.         else
  492.             error = bread(ITOV(ip), lbn, size, NOCRED, &bp);
  493.         vp->v_lastr = lbn;
  494.         n = MIN(n, size - bp->b_resid);
  495.         if (error) {
  496.             brelse(bp);
  497.             return (error);
  498.         }
  499.         error = uiomove(bp->b_un.b_addr + on, (int)n, uio);
  500.         if (n + on == fs->fs_bsize || uio->uio_offset == ip->i_size)
  501.             bp->b_flags |= B_AGE;
  502.         brelse(bp);
  503.     } while (error == 0 && uio->uio_resid > 0 && n != 0);
  504.     return (error);
  505. }
  506.  
  507. /*
  508.  * Vnode op for writing.
  509.  */
  510. ufs_write(vp, uio, ioflag, cred)
  511.     register struct vnode *vp;
  512.     struct uio *uio;
  513.     int ioflag;
  514.     struct ucred *cred;
  515. {
  516.     struct proc *p = uio->uio_procp;
  517.     register struct inode *ip = VTOI(vp);
  518.     register struct fs *fs;
  519.     struct buf *bp;
  520.     daddr_t lbn, bn;
  521.     u_long osize;
  522.     int n, on, flags;
  523.     int size, resid, error = 0;
  524.  
  525. #ifdef DIAGNOSTIC
  526.     if (uio->uio_rw != UIO_WRITE)
  527.         panic("ufs_write mode");
  528. #endif
  529.     switch (vp->v_type) {
  530.     case VREG:
  531.         if (ioflag & IO_APPEND)
  532.             uio->uio_offset = ip->i_size;
  533.         /* fall through */
  534.     case VLNK:
  535.         break;
  536.  
  537.     case VDIR:
  538.         if ((ioflag & IO_SYNC) == 0)
  539.             panic("ufs_write nonsync dir write");
  540.         break;
  541.  
  542.     default:
  543.         panic("ufs_write type");
  544.     }
  545.     if (uio->uio_offset < 0)
  546.         return (EINVAL);
  547.     if (uio->uio_resid == 0)
  548.         return (0);
  549.     /*
  550.      * Maybe this should be above the vnode op call, but so long as
  551.      * file servers have no limits, i don't think it matters
  552.      */
  553.     if (vp->v_type == VREG && p &&
  554.         uio->uio_offset + uio->uio_resid >
  555.           p->p_rlimit[RLIMIT_FSIZE].rlim_cur) {
  556.         psignal(p, SIGXFSZ);
  557.         return (EFBIG);
  558.     }
  559.     resid = uio->uio_resid;
  560.     osize = ip->i_size;
  561.     fs = ip->i_fs;
  562.     flags = 0;
  563.     if (ioflag & IO_SYNC)
  564.         flags = B_SYNC;
  565.     do {
  566.         lbn = lblkno(fs, uio->uio_offset);
  567.         on = blkoff(fs, uio->uio_offset);
  568.         n = MIN((unsigned)(fs->fs_bsize - on), uio->uio_resid);
  569.         if (n < fs->fs_bsize)
  570.             flags |= B_CLRBUF;
  571.         else
  572.             flags &= ~B_CLRBUF;
  573.         if (error = balloc(ip, lbn, (int)(on + n), &bp, flags))
  574.             break;
  575.         bn = bp->b_blkno;
  576.         if (uio->uio_offset + n > ip->i_size) {
  577.             ip->i_size = uio->uio_offset + n;
  578.             vnode_pager_setsize(vp, ip->i_size);
  579.         }
  580.         size = blksize(fs, ip, lbn);
  581.         (void) vnode_pager_uncache(vp);
  582.         n = MIN(n, size - bp->b_resid);
  583.         error = uiomove(bp->b_un.b_addr + on, n, uio);
  584.         if (ioflag & IO_SYNC)
  585.             (void) bwrite(bp);
  586.         else if (n + on == fs->fs_bsize) {
  587.             bp->b_flags |= B_AGE;
  588.             bawrite(bp);
  589.         } else
  590.             bdwrite(bp);
  591.         ip->i_flag |= IUPD|ICHG;
  592.         if (cred->cr_uid != 0)
  593.             ip->i_mode &= ~(ISUID|ISGID);
  594.     } while (error == 0 && uio->uio_resid > 0 && n != 0);
  595.     if (error && (ioflag & IO_UNIT)) {
  596.         (void) itrunc(ip, osize, ioflag & IO_SYNC);
  597.         uio->uio_offset -= resid - uio->uio_resid;
  598.         uio->uio_resid = resid;
  599.     }
  600.     if (!error && (ioflag & IO_SYNC))
  601.         error = iupdat(ip, &time, &time, 1);
  602.     return (error);
  603. }
  604.  
  605. /* ARGSUSED */
  606. ufs_ioctl(vp, com, data, fflag, cred, p)
  607.     struct vnode *vp;
  608.     int com;
  609.     caddr_t data;
  610.     int fflag;
  611.     struct ucred *cred;
  612.     struct proc *p;
  613. {
  614.  
  615.     return (ENOTTY);
  616. }
  617.  
  618. /* ARGSUSED */
  619. ufs_select(vp, which, fflags, cred, p)
  620.     struct vnode *vp;
  621.     int which, fflags;
  622.     struct ucred *cred;
  623.     struct proc *p;
  624. {
  625.  
  626.     /*
  627.      * We should really check to see if I/O is possible.
  628.      */
  629.     return (1);
  630. }
  631.  
  632. /*
  633.  * Mmap a file
  634.  *
  635.  * NB Currently unsupported.
  636.  */
  637. /* ARGSUSED */
  638. ufs_mmap(vp, fflags, cred, p)
  639.     struct vnode *vp;
  640.     int fflags;
  641.     struct ucred *cred;
  642.     struct proc *p;
  643. {
  644.  
  645.     return (EINVAL);
  646. }
  647.  
  648. /*
  649.  * Synch an open file.
  650.  */
  651. /* ARGSUSED */
  652. ufs_fsync(vp, fflags, cred, waitfor, p)
  653.     struct vnode *vp;
  654.     int fflags;
  655.     struct ucred *cred;
  656.     int waitfor;
  657.     struct proc *p;
  658. {
  659.     struct inode *ip = VTOI(vp);
  660.  
  661.     if (fflags & FWRITE)
  662.         ip->i_flag |= ICHG;
  663.     vflushbuf(vp, waitfor == MNT_WAIT ? B_SYNC : 0);
  664.     return (iupdat(ip, &time, &time, waitfor == MNT_WAIT));
  665. }
  666.  
  667. /*
  668.  * Seek on a file
  669.  *
  670.  * Nothing to do, so just return.
  671.  */
  672. /* ARGSUSED */
  673. ufs_seek(vp, oldoff, newoff, cred)
  674.     struct vnode *vp;
  675.     off_t oldoff, newoff;
  676.     struct ucred *cred;
  677. {
  678.  
  679.     return (0);
  680. }
  681.  
  682. /*
  683.  * ufs remove
  684.  * Hard to avoid races here, especially
  685.  * in unlinking directories.
  686.  */
  687. ufs_remove(ndp, p)
  688.     struct nameidata *ndp;
  689.     struct proc *p;
  690. {
  691.     register struct inode *ip, *dp;
  692.     int error;
  693.  
  694.     ip = VTOI(ndp->ni_vp);
  695.     dp = VTOI(ndp->ni_dvp);
  696.     error = dirremove(ndp);
  697.     if (!error) {
  698.         ip->i_nlink--;
  699.         ip->i_flag |= ICHG;
  700.     }
  701.     if (dp == ip)
  702.         vrele(ITOV(ip));
  703.     else
  704.         iput(ip);
  705.     iput(dp);
  706.     return (error);
  707. }
  708.  
  709. /*
  710.  * link vnode call
  711.  */
  712. ufs_link(vp, ndp, p)
  713.     register struct vnode *vp;
  714.     register struct nameidata *ndp;
  715.     struct proc *p;
  716. {
  717.     register struct inode *ip = VTOI(vp);
  718.     int error;
  719.  
  720. #ifdef DIANOSTIC
  721.     if ((ndp->ni_nameiop & HASBUF) == 0)
  722.         panic("ufs_link: no name");
  723. #endif
  724.     if ((unsigned short)ip->i_nlink >= LINK_MAX) {
  725.         free(ndp->ni_pnbuf, M_NAMEI);
  726.         return (EMLINK);
  727.     }
  728.     if (ndp->ni_dvp != vp)
  729.         ILOCK(ip);
  730.     ip->i_nlink++;
  731.     ip->i_flag |= ICHG;
  732.     error = iupdat(ip, &time, &time, 1);
  733.     if (!error)
  734.         error = direnter(ip, ndp);
  735.     if (ndp->ni_dvp != vp)
  736.         IUNLOCK(ip);
  737.     FREE(ndp->ni_pnbuf, M_NAMEI);
  738.     vput(ndp->ni_dvp);
  739.     if (error) {
  740.         ip->i_nlink--;
  741.         ip->i_flag |= ICHG;
  742.     }
  743.     return (error);
  744. }
  745.  
  746. /*
  747.  * Rename system call.
  748.  *     rename("foo", "bar");
  749.  * is essentially
  750.  *    unlink("bar");
  751.  *    link("foo", "bar");
  752.  *    unlink("foo");
  753.  * but ``atomically''.  Can't do full commit without saving state in the
  754.  * inode on disk which isn't feasible at this time.  Best we can do is
  755.  * always guarantee the target exists.
  756.  *
  757.  * Basic algorithm is:
  758.  *
  759.  * 1) Bump link count on source while we're linking it to the
  760.  *    target.  This also ensure the inode won't be deleted out
  761.  *    from underneath us while we work (it may be truncated by
  762.  *    a concurrent `trunc' or `open' for creation).
  763.  * 2) Link source to destination.  If destination already exists,
  764.  *    delete it first.
  765.  * 3) Unlink source reference to inode if still around. If a
  766.  *    directory was moved and the parent of the destination
  767.  *    is different from the source, patch the ".." entry in the
  768.  *    directory.
  769.  */
  770. ufs_rename(fndp, tndp, p)
  771.     register struct nameidata *fndp, *tndp;
  772.     struct proc *p;
  773. {
  774.     register struct inode *ip, *xp, *dp;
  775.     struct dirtemplate dirbuf;
  776.     int doingdirectory = 0, oldparent = 0, newparent = 0;
  777.     int error = 0;
  778.  
  779. #ifdef DIANOSTIC
  780.     if ((tndp->ni_nameiop & HASBUF) == 0 ||
  781.         (fndp->ni_nameiop & HASBUF) == 0)
  782.         panic("ufs_rename: no name");
  783. #endif
  784.     dp = VTOI(fndp->ni_dvp);
  785.     ip = VTOI(fndp->ni_vp);
  786.     /*
  787.      * Check if just deleting a link name.
  788.      */
  789.     if (fndp->ni_vp == tndp->ni_vp) {
  790.         VOP_ABORTOP(tndp);
  791.         vput(tndp->ni_dvp);
  792.         vput(tndp->ni_vp);
  793.         vrele(fndp->ni_dvp);
  794.         if ((ip->i_mode&IFMT) == IFDIR) {
  795.             VOP_ABORTOP(fndp);
  796.             vrele(fndp->ni_vp);
  797.             return (EINVAL);
  798.         }
  799.         doingdirectory = 0;
  800.         goto unlinkit;
  801.     }
  802.     ILOCK(ip);
  803.     if ((ip->i_mode&IFMT) == IFDIR) {
  804.         /*
  805.          * Avoid ".", "..", and aliases of "." for obvious reasons.
  806.          */
  807.         if ((fndp->ni_namelen == 1 && fndp->ni_ptr[0] == '.') ||
  808.             dp == ip || fndp->ni_isdotdot || (ip->i_flag & IRENAME)) {
  809.             VOP_ABORTOP(tndp);
  810.             vput(tndp->ni_dvp);
  811.             if (tndp->ni_vp)
  812.                 vput(tndp->ni_vp);
  813.             VOP_ABORTOP(fndp);
  814.             vrele(fndp->ni_dvp);
  815.             vput(fndp->ni_vp);
  816.             return (EINVAL);
  817.         }
  818.         ip->i_flag |= IRENAME;
  819.         oldparent = dp->i_number;
  820.         doingdirectory++;
  821.     }
  822.     vrele(fndp->ni_dvp);
  823.  
  824.     /*
  825.      * 1) Bump link count while we're moving stuff
  826.      *    around.  If we crash somewhere before
  827.      *    completing our work, the link count
  828.      *    may be wrong, but correctable.
  829.      */
  830.     ip->i_nlink++;
  831.     ip->i_flag |= ICHG;
  832.     error = iupdat(ip, &time, &time, 1);
  833.     IUNLOCK(ip);
  834.  
  835.     /*
  836.      * When the target exists, both the directory
  837.      * and target vnodes are returned locked.
  838.      */
  839.     dp = VTOI(tndp->ni_dvp);
  840.     xp = NULL;
  841.     if (tndp->ni_vp)
  842.         xp = VTOI(tndp->ni_vp);
  843.     /*
  844.      * If ".." must be changed (ie the directory gets a new
  845.      * parent) then the source directory must not be in the
  846.      * directory heirarchy above the target, as this would
  847.      * orphan everything below the source directory. Also
  848.      * the user must have write permission in the source so
  849.      * as to be able to change "..". We must repeat the call 
  850.      * to namei, as the parent directory is unlocked by the
  851.      * call to checkpath().
  852.      */
  853.     if (oldparent != dp->i_number)
  854.         newparent = dp->i_number;
  855.     if (doingdirectory && newparent) {
  856.         VOP_LOCK(fndp->ni_vp);
  857.         error = ufs_access(fndp->ni_vp, VWRITE, tndp->ni_cred, p);
  858.         VOP_UNLOCK(fndp->ni_vp);
  859.         if (error)
  860.             goto bad;
  861.         if (xp != NULL)
  862.             iput(xp);
  863.         if (error = checkpath(ip, dp, tndp->ni_cred))
  864.             goto out;
  865.         if ((tndp->ni_nameiop & SAVESTART) == 0)
  866.             panic("ufs_rename: lost to startdir");
  867.         if (error = lookup(tndp, p))
  868.             goto out;
  869.         dp = VTOI(tndp->ni_dvp);
  870.         xp = NULL;
  871.         if (tndp->ni_vp)
  872.             xp = VTOI(tndp->ni_vp);
  873.     }
  874.     /*
  875.      * 2) If target doesn't exist, link the target
  876.      *    to the source and unlink the source. 
  877.      *    Otherwise, rewrite the target directory
  878.      *    entry to reference the source inode and
  879.      *    expunge the original entry's existence.
  880.      */
  881.     if (xp == NULL) {
  882.         if (dp->i_dev != ip->i_dev)
  883.             panic("rename: EXDEV");
  884.         /*
  885.          * Account for ".." in new directory.
  886.          * When source and destination have the same
  887.          * parent we don't fool with the link count.
  888.          */
  889.         if (doingdirectory && newparent) {
  890.             if ((unsigned short)dp->i_nlink >= LINK_MAX) {
  891.                 error = EMLINK;
  892.                 goto bad;
  893.             }
  894.             dp->i_nlink++;
  895.             dp->i_flag |= ICHG;
  896.             if (error = iupdat(dp, &time, &time, 1))
  897.                 goto bad;
  898.         }
  899.         if (error = direnter(ip, tndp)) {
  900.             if (doingdirectory && newparent) {
  901.                 dp->i_nlink--;
  902.                 dp->i_flag |= ICHG;
  903.                 (void) iupdat(dp, &time, &time, 1);
  904.             }
  905.             goto bad;
  906.         }
  907.         iput(dp);
  908.     } else {
  909.         if (xp->i_dev != dp->i_dev || xp->i_dev != ip->i_dev)
  910.             panic("rename: EXDEV");
  911.         /*
  912.          * Short circuit rename(foo, foo).
  913.          */
  914.         if (xp->i_number == ip->i_number)
  915.             panic("rename: same file");
  916.         /*
  917.          * If the parent directory is "sticky", then the user must
  918.          * own the parent directory, or the destination of the rename,
  919.          * otherwise the destination may not be changed (except by
  920.          * root). This implements append-only directories.
  921.          */
  922.         if ((dp->i_mode & ISVTX) && tndp->ni_cred->cr_uid != 0 &&
  923.             tndp->ni_cred->cr_uid != dp->i_uid &&
  924.             xp->i_uid != tndp->ni_cred->cr_uid) {
  925.             error = EPERM;
  926.             goto bad;
  927.         }
  928.         /*
  929.          * Target must be empty if a directory and have no links
  930.          * to it. Also, ensure source and target are compatible
  931.          * (both directories, or both not directories).
  932.          */
  933.         if ((xp->i_mode&IFMT) == IFDIR) {
  934.             if (!dirempty(xp, dp->i_number, tndp->ni_cred) || 
  935.                 xp->i_nlink > 2) {
  936.                 error = ENOTEMPTY;
  937.                 goto bad;
  938.             }
  939.             if (!doingdirectory) {
  940.                 error = ENOTDIR;
  941.                 goto bad;
  942.             }
  943.             cache_purge(ITOV(dp));
  944.         } else if (doingdirectory) {
  945.             error = EISDIR;
  946.             goto bad;
  947.         }
  948.         if (error = dirrewrite(dp, ip, tndp))
  949.             goto bad;
  950.         /*
  951.          * If the target directory is in the same
  952.          * directory as the source directory,
  953.          * decrement the link count on the parent
  954.          * of the target directory.
  955.          */
  956.          if (doingdirectory && !newparent) {
  957.             dp->i_nlink--;
  958.             dp->i_flag |= ICHG;
  959.         }
  960.         vput(ITOV(dp));
  961.         /*
  962.          * Adjust the link count of the target to
  963.          * reflect the dirrewrite above.  If this is
  964.          * a directory it is empty and there are
  965.          * no links to it, so we can squash the inode and
  966.          * any space associated with it.  We disallowed
  967.          * renaming over top of a directory with links to
  968.          * it above, as the remaining link would point to
  969.          * a directory without "." or ".." entries.
  970.          */
  971.         xp->i_nlink--;
  972.         if (doingdirectory) {
  973.             if (--xp->i_nlink != 0)
  974.                 panic("rename: linked directory");
  975.             error = itrunc(xp, (u_long)0, IO_SYNC);
  976.         }
  977.         xp->i_flag |= ICHG;
  978.         iput(xp);
  979.         xp = NULL;
  980.     }
  981.  
  982.     /*
  983.      * 3) Unlink the source.
  984.      */
  985. unlinkit:
  986.     fndp->ni_nameiop &= ~MODMASK;
  987.     fndp->ni_nameiop |= LOCKPARENT | LOCKLEAF;
  988.     if ((fndp->ni_nameiop & SAVESTART) == 0)
  989.         panic("ufs_rename: lost from startdir");
  990.     (void) lookup(fndp, p);
  991.     if (fndp->ni_vp != NULL) {
  992.         xp = VTOI(fndp->ni_vp);
  993.         dp = VTOI(fndp->ni_dvp);
  994.     } else {
  995.         /*
  996.          * From name has disappeared.
  997.          */
  998.         if (doingdirectory)
  999.             panic("rename: lost dir entry");
  1000.         vrele(ITOV(ip));
  1001.         return (0);
  1002.     }
  1003.     /*
  1004.      * Ensure that the directory entry still exists and has not
  1005.      * changed while the new name has been entered. If the source is
  1006.      * a file then the entry may have been unlinked or renamed. In
  1007.      * either case there is no further work to be done. If the source
  1008.      * is a directory then it cannot have been rmdir'ed; its link
  1009.      * count of three would cause a rmdir to fail with ENOTEMPTY.
  1010.      * The IRENAME flag ensures that it cannot be moved by another
  1011.      * rename.
  1012.      */
  1013.     if (xp != ip) {
  1014.         if (doingdirectory)
  1015.             panic("rename: lost dir entry");
  1016.     } else {
  1017.         /*
  1018.          * If the source is a directory with a
  1019.          * new parent, the link count of the old
  1020.          * parent directory must be decremented
  1021.          * and ".." set to point to the new parent.
  1022.          */
  1023.         if (doingdirectory && newparent) {
  1024.             dp->i_nlink--;
  1025.             dp->i_flag |= ICHG;
  1026.             error = vn_rdwr(UIO_READ, ITOV(xp), (caddr_t)&dirbuf,
  1027.                 sizeof (struct dirtemplate), (off_t)0,
  1028.                 UIO_SYSSPACE, IO_NODELOCKED, 
  1029.                 tndp->ni_cred, (int *)0, (struct proc *)0);
  1030.             if (error == 0) {
  1031.                 if (dirbuf.dotdot_namlen != 2 ||
  1032.                     dirbuf.dotdot_name[0] != '.' ||
  1033.                     dirbuf.dotdot_name[1] != '.') {
  1034.                     dirbad(xp, 12, "rename: mangled dir");
  1035.                 } else {
  1036.                     dirbuf.dotdot_ino = newparent;
  1037.                     (void) vn_rdwr(UIO_WRITE, ITOV(xp),
  1038.                         (caddr_t)&dirbuf,
  1039.                         sizeof (struct dirtemplate),
  1040.                         (off_t)0, UIO_SYSSPACE,
  1041.                         IO_NODELOCKED|IO_SYNC,
  1042.                         tndp->ni_cred, (int *)0,
  1043.                         (struct proc *)0);
  1044.                     cache_purge(ITOV(dp));
  1045.                 }
  1046.             }
  1047.         }
  1048.         error = dirremove(fndp);
  1049.         if (!error) {
  1050.             xp->i_nlink--;
  1051.             xp->i_flag |= ICHG;
  1052.         }
  1053.         xp->i_flag &= ~IRENAME;
  1054.     }
  1055.     if (dp)
  1056.         vput(ITOV(dp));
  1057.     if (xp)
  1058.         vput(ITOV(xp));
  1059.     vrele(ITOV(ip));
  1060.     return (error);
  1061.  
  1062. bad:
  1063.     if (xp)
  1064.         vput(ITOV(xp));
  1065.     vput(ITOV(dp));
  1066. out:
  1067.     ip->i_nlink--;
  1068.     ip->i_flag |= ICHG;
  1069.     vrele(ITOV(ip));
  1070.     return (error);
  1071. }
  1072.  
  1073. /*
  1074.  * A virgin directory (no blushing please).
  1075.  */
  1076. struct dirtemplate mastertemplate = {
  1077.     0, 12, 1, ".",
  1078.     0, DIRBLKSIZ - 12, 2, ".."
  1079. };
  1080.  
  1081. /*
  1082.  * Mkdir system call
  1083.  */
  1084. ufs_mkdir(ndp, vap, p)
  1085.     struct nameidata *ndp;
  1086.     struct vattr *vap;
  1087.     struct proc *p;
  1088. {
  1089.     register struct inode *ip, *dp;
  1090.     struct inode *tip;
  1091.     struct vnode *dvp;
  1092.     struct dirtemplate dirtemplate;
  1093.     int error;
  1094.     int dmode;
  1095.  
  1096. #ifdef DIANOSTIC
  1097.     if ((ndp->ni_nameiop & HASBUF) == 0)
  1098.         panic("ufs_mkdir: no name");
  1099. #endif
  1100.     dvp = ndp->ni_dvp;
  1101.     dp = VTOI(dvp);
  1102.     if ((unsigned short)dp->i_nlink >= LINK_MAX) {
  1103.         free(ndp->ni_pnbuf, M_NAMEI);
  1104.         iput(dp);
  1105.         return (EMLINK);
  1106.     }
  1107.     dmode = vap->va_mode&0777;
  1108.     dmode |= IFDIR;
  1109.     /*
  1110.      * Must simulate part of maknode here to acquire the inode, but
  1111.      * not have it entered in the parent directory. The entry is made
  1112.      * later after writing "." and ".." entries.
  1113.      */
  1114.     if (error = ialloc(dp, dirpref(dp->i_fs), dmode, ndp->ni_cred, &tip)) {
  1115.         free(ndp->ni_pnbuf, M_NAMEI);
  1116.         iput(dp);
  1117.         return (error);
  1118.     }
  1119.     ip = tip;
  1120.     ip->i_uid = ndp->ni_cred->cr_uid;
  1121.     ip->i_gid = dp->i_gid;
  1122. #ifdef QUOTA
  1123.     if ((error = getinoquota(ip)) ||
  1124.         (error = chkiq(ip, 1, ndp->ni_cred, 0))) {
  1125.         free(ndp->ni_pnbuf, M_NAMEI);
  1126.         ifree(ip, ip->i_number, dmode);
  1127.         iput(ip);
  1128.         iput(dp);
  1129.         return (error);
  1130.     }
  1131. #endif
  1132.     ip->i_flag |= IACC|IUPD|ICHG;
  1133.     ip->i_mode = dmode;
  1134.     ITOV(ip)->v_type = VDIR;    /* Rest init'd in iget() */
  1135.     ip->i_nlink = 2;
  1136.     error = iupdat(ip, &time, &time, 1);
  1137.  
  1138.     /*
  1139.      * Bump link count in parent directory
  1140.      * to reflect work done below.  Should
  1141.      * be done before reference is created
  1142.      * so reparation is possible if we crash.
  1143.      */
  1144.     dp->i_nlink++;
  1145.     dp->i_flag |= ICHG;
  1146.     if (error = iupdat(dp, &time, &time, 1))
  1147.         goto bad;
  1148.  
  1149.     /*
  1150.      * Initialize directory with "."
  1151.      * and ".." from static template.
  1152.      */
  1153.     dirtemplate = mastertemplate;
  1154.     dirtemplate.dot_ino = ip->i_number;
  1155.     dirtemplate.dotdot_ino = dp->i_number;
  1156.     error = vn_rdwr(UIO_WRITE, ITOV(ip), (caddr_t)&dirtemplate,
  1157.         sizeof (dirtemplate), (off_t)0, UIO_SYSSPACE,
  1158.         IO_NODELOCKED|IO_SYNC, ndp->ni_cred, (int *)0, (struct proc *)0);
  1159.     if (error) {
  1160.         dp->i_nlink--;
  1161.         dp->i_flag |= ICHG;
  1162.         goto bad;
  1163.     }
  1164.     if (DIRBLKSIZ > dp->i_fs->fs_fsize) {
  1165.         panic("mkdir: blksize");     /* XXX - should grow w/balloc() */
  1166.     } else {
  1167.         ip->i_size = DIRBLKSIZ;
  1168.         ip->i_flag |= ICHG;
  1169.     }
  1170.     /*
  1171.      * Directory all set up, now
  1172.      * install the entry for it in
  1173.      * the parent directory.
  1174.      */
  1175.     if (error = direnter(ip, ndp)) {
  1176.         dp->i_nlink--;
  1177.         dp->i_flag |= ICHG;
  1178.     }
  1179. bad:
  1180.     /*
  1181.      * No need to do an explicit itrunc here,
  1182.      * vrele will do this for us because we set
  1183.      * the link count to 0.
  1184.      */
  1185.     if (error) {
  1186.         ip->i_nlink = 0;
  1187.         ip->i_flag |= ICHG;
  1188.         iput(ip);
  1189.     } else
  1190.         ndp->ni_vp = ITOV(ip);
  1191.     FREE(ndp->ni_pnbuf, M_NAMEI);
  1192.     iput(dp);
  1193.     return (error);
  1194. }
  1195.  
  1196. /*
  1197.  * Rmdir system call.
  1198.  */
  1199. ufs_rmdir(ndp, p)
  1200.     register struct nameidata *ndp;
  1201.     struct proc *p;
  1202. {
  1203.     register struct inode *ip, *dp;
  1204.     int error = 0;
  1205.  
  1206.     ip = VTOI(ndp->ni_vp);
  1207.     dp = VTOI(ndp->ni_dvp);
  1208.     /*
  1209.      * No rmdir "." please.
  1210.      */
  1211.     if (dp == ip) {
  1212.         vrele(ITOV(dp));
  1213.         iput(ip);
  1214.         return (EINVAL);
  1215.     }
  1216.     /*
  1217.      * Verify the directory is empty (and valid).
  1218.      * (Rmdir ".." won't be valid since
  1219.      *  ".." will contain a reference to
  1220.      *  the current directory and thus be
  1221.      *  non-empty.)
  1222.      */
  1223.     if (ip->i_nlink != 2 || !dirempty(ip, dp->i_number, ndp->ni_cred)) {
  1224.         error = ENOTEMPTY;
  1225.         goto out;
  1226.     }
  1227.     /*
  1228.      * Delete reference to directory before purging
  1229.      * inode.  If we crash in between, the directory
  1230.      * will be reattached to lost+found,
  1231.      */
  1232.     if (error = dirremove(ndp))
  1233.         goto out;
  1234.     dp->i_nlink--;
  1235.     dp->i_flag |= ICHG;
  1236.     cache_purge(ITOV(dp));
  1237.     iput(dp);
  1238.     ndp->ni_dvp = NULL;
  1239.     /*
  1240.      * Truncate inode.  The only stuff left
  1241.      * in the directory is "." and "..".  The
  1242.      * "." reference is inconsequential since
  1243.      * we're quashing it.  The ".." reference
  1244.      * has already been adjusted above.  We've
  1245.      * removed the "." reference and the reference
  1246.      * in the parent directory, but there may be
  1247.      * other hard links so decrement by 2 and
  1248.      * worry about them later.
  1249.      */
  1250.     ip->i_nlink -= 2;
  1251.     error = itrunc(ip, (u_long)0, IO_SYNC);
  1252.     cache_purge(ITOV(ip));
  1253. out:
  1254.     if (ndp->ni_dvp)
  1255.         iput(dp);
  1256.     iput(ip);
  1257.     return (error);
  1258. }
  1259.  
  1260. /*
  1261.  * symlink -- make a symbolic link
  1262.  */
  1263. ufs_symlink(ndp, vap, target, p)
  1264.     struct nameidata *ndp;
  1265.     struct vattr *vap;
  1266.     char *target;
  1267.     struct proc *p;
  1268. {
  1269.     struct inode *ip;
  1270.     int error;
  1271.  
  1272.     error = maknode(IFLNK | vap->va_mode, ndp, &ip);
  1273.     if (error)
  1274.         return (error);
  1275.     error = vn_rdwr(UIO_WRITE, ITOV(ip), target, strlen(target), (off_t)0,
  1276.         UIO_SYSSPACE, IO_NODELOCKED, ndp->ni_cred, (int *)0,
  1277.         (struct proc *)0);
  1278.     iput(ip);
  1279.     return (error);
  1280. }
  1281.  
  1282. /*
  1283.  * Vnode op for read and write
  1284.  */
  1285. ufs_readdir(vp, uio, cred, eofflagp)
  1286.     struct vnode *vp;
  1287.     register struct uio *uio;
  1288.     struct ucred *cred;
  1289.     int *eofflagp;
  1290. {
  1291.     int count, lost, error;
  1292.  
  1293.     count = uio->uio_resid;
  1294.     count &= ~(DIRBLKSIZ - 1);
  1295.     lost = uio->uio_resid - count;
  1296.     if (count < DIRBLKSIZ || (uio->uio_offset & (DIRBLKSIZ -1)))
  1297.         return (EINVAL);
  1298.     uio->uio_resid = count;
  1299.     uio->uio_iov->iov_len = count;
  1300.     error = ufs_read(vp, uio, 0, cred);
  1301.     uio->uio_resid += lost;
  1302.     if ((VTOI(vp)->i_size - uio->uio_offset) <= 0)
  1303.         *eofflagp = 1;
  1304.     else
  1305.         *eofflagp = 0;
  1306.     return (error);
  1307. }
  1308.  
  1309. /*
  1310.  * Return target name of a symbolic link
  1311.  */
  1312. ufs_readlink(vp, uiop, cred)
  1313.     struct vnode *vp;
  1314.     struct uio *uiop;
  1315.     struct ucred *cred;
  1316. {
  1317.  
  1318.     return (ufs_read(vp, uiop, 0, cred));
  1319. }
  1320.  
  1321. /*
  1322.  * Ufs abort op, called after namei() when a CREATE/DELETE isn't actually
  1323.  * done. If a buffer has been saved in anticipation of a CREATE, delete it.
  1324.  */
  1325. /* ARGSUSED */
  1326. ufs_abortop(ndp)
  1327.     struct nameidata *ndp;
  1328. {
  1329.  
  1330.     if ((ndp->ni_nameiop & (HASBUF | SAVESTART)) == HASBUF)
  1331.         FREE(ndp->ni_pnbuf, M_NAMEI);
  1332.     return (0);
  1333. }
  1334.  
  1335. /*
  1336.  * Lock an inode.
  1337.  */
  1338. ufs_lock(vp)
  1339.     struct vnode *vp;
  1340. {
  1341.     register struct inode *ip = VTOI(vp);
  1342.  
  1343.     ILOCK(ip);
  1344.     return (0);
  1345. }
  1346.  
  1347. /*
  1348.  * Unlock an inode.
  1349.  */
  1350. ufs_unlock(vp)
  1351.     struct vnode *vp;
  1352. {
  1353.     register struct inode *ip = VTOI(vp);
  1354.  
  1355.     if (!(ip->i_flag & ILOCKED))
  1356.         panic("ufs_unlock NOT LOCKED");
  1357.     IUNLOCK(ip);
  1358.     return (0);
  1359. }
  1360.  
  1361. /*
  1362.  * Check for a locked inode.
  1363.  */
  1364. ufs_islocked(vp)
  1365.     struct vnode *vp;
  1366. {
  1367.  
  1368.     if (VTOI(vp)->i_flag & ILOCKED)
  1369.         return (1);
  1370.     return (0);
  1371. }
  1372.  
  1373. /*
  1374.  * Get access to bmap
  1375.  */
  1376. ufs_bmap(vp, bn, vpp, bnp)
  1377.     struct vnode *vp;
  1378.     daddr_t bn;
  1379.     struct vnode **vpp;
  1380.     daddr_t *bnp;
  1381. {
  1382.     struct inode *ip = VTOI(vp);
  1383.  
  1384.     if (vpp != NULL)
  1385.         *vpp = ip->i_devvp;
  1386.     if (bnp == NULL)
  1387.         return (0);
  1388.     return (bmap(ip, bn, bnp));
  1389. }
  1390.  
  1391. /*
  1392.  * Calculate the logical to physical mapping if not done already,
  1393.  * then call the device strategy routine.
  1394.  */
  1395. int checkoverlap = 0;
  1396.  
  1397. ufs_strategy(bp)
  1398.     register struct buf *bp;
  1399. {
  1400.     register struct inode *ip = VTOI(bp->b_vp);
  1401.     struct vnode *vp;
  1402.     int error;
  1403.  
  1404.     if (bp->b_vp->v_type == VBLK || bp->b_vp->v_type == VCHR)
  1405.         panic("ufs_strategy: spec");
  1406.     if (bp->b_blkno == bp->b_lblkno) {
  1407.         if (error = bmap(ip, bp->b_lblkno, &bp->b_blkno))
  1408.             return (error);
  1409.         if ((long)bp->b_blkno == -1)
  1410.             clrbuf(bp);
  1411.     }
  1412.     if ((long)bp->b_blkno == -1) {
  1413.         biodone(bp);
  1414.         return (0);
  1415.     }
  1416. #ifdef DIAGNOSTIC
  1417.     if (checkoverlap) {
  1418.         register struct buf *ep;
  1419.         struct buf *ebp;
  1420.         daddr_t start, last;
  1421.  
  1422.         ebp = &buf[nbuf];
  1423.         start = bp->b_blkno;
  1424.         last = start + btodb(bp->b_bcount) - 1;
  1425.         for (ep = buf; ep < ebp; ep++) {
  1426.             if (ep == bp || (ep->b_flags & B_INVAL) ||
  1427.                 ep->b_vp == NULLVP)
  1428.                 continue;
  1429.             if (VOP_BMAP(ep->b_vp, (daddr_t)0, &vp, (daddr_t)0))
  1430.                 continue;
  1431.             if (vp != ip->i_devvp)
  1432.                 continue;
  1433.             /* look for overlap */
  1434.             if (ep->b_bcount == 0 || ep->b_blkno > last ||
  1435.                 ep->b_blkno + btodb(ep->b_bcount) <= start)
  1436.                 continue;
  1437.             vprint("Disk overlap", vp);
  1438.             printf("\tstart %d, end %d overlap start %d, end %d\n",
  1439.                 start, last, ep->b_blkno,
  1440.                 ep->b_blkno + btodb(ep->b_bcount) - 1);
  1441.             panic("Disk buffer overlap");
  1442.         }
  1443.     }
  1444. #endif /* DIAGNOSTIC */
  1445.     vp = ip->i_devvp;
  1446.     bp->b_dev = vp->v_rdev;
  1447.     (*(vp->v_op->vop_strategy))(bp);
  1448.     return (0);
  1449. }
  1450.  
  1451. /*
  1452.  * Print out the contents of an inode.
  1453.  */
  1454. ufs_print(vp)
  1455.     struct vnode *vp;
  1456. {
  1457.     register struct inode *ip = VTOI(vp);
  1458.  
  1459.     printf("tag VT_UFS, ino %d, on dev %d, %d", ip->i_number,
  1460.         major(ip->i_dev), minor(ip->i_dev));
  1461. #ifdef FIFO
  1462.     if (vp->v_type == VFIFO)
  1463.         fifo_printinfo(vp);
  1464. #endif /* FIFO */
  1465.     printf("%s\n", (ip->i_flag & ILOCKED) ? " (LOCKED)" : "");
  1466.     if (ip->i_spare0 == 0)
  1467.         return;
  1468.     printf("\towner pid %d", ip->i_spare0);
  1469.     if (ip->i_spare1)
  1470.         printf(" waiting pid %d", ip->i_spare1);
  1471.     printf("\n");
  1472. }
  1473.  
  1474. /*
  1475.  * Read wrapper for special devices.
  1476.  */
  1477. ufsspec_read(vp, uio, ioflag, cred)
  1478.     struct vnode *vp;
  1479.     struct uio *uio;
  1480.     int ioflag;
  1481.     struct ucred *cred;
  1482. {
  1483.  
  1484.     /*
  1485.      * Set access flag.
  1486.      */
  1487.     VTOI(vp)->i_flag |= IACC;
  1488.     return (spec_read(vp, uio, ioflag, cred));
  1489. }
  1490.  
  1491. /*
  1492.  * Write wrapper for special devices.
  1493.  */
  1494. ufsspec_write(vp, uio, ioflag, cred)
  1495.     struct vnode *vp;
  1496.     struct uio *uio;
  1497.     int ioflag;
  1498.     struct ucred *cred;
  1499. {
  1500.  
  1501.     /*
  1502.      * Set update and change flags.
  1503.      */
  1504.     VTOI(vp)->i_flag |= IUPD|ICHG;
  1505.     return (spec_write(vp, uio, ioflag, cred));
  1506. }
  1507.  
  1508. /*
  1509.  * Close wrapper for special devices.
  1510.  *
  1511.  * Update the times on the inode then do device close.
  1512.  */
  1513. ufsspec_close(vp, fflag, cred, p)
  1514.     struct vnode *vp;
  1515.     int fflag;
  1516.     struct ucred *cred;
  1517.     struct proc *p;
  1518. {
  1519.     register struct inode *ip = VTOI(vp);
  1520.  
  1521.     if (vp->v_usecount > 1 && !(ip->i_flag & ILOCKED))
  1522.         ITIMES(ip, &time, &time);
  1523.     return (spec_close(vp, fflag, cred, p));
  1524. }
  1525.  
  1526. #ifdef FIFO
  1527. /*
  1528.  * Read wrapper for fifo's
  1529.  */
  1530. ufsfifo_read(vp, uio, ioflag, cred)
  1531.     struct vnode *vp;
  1532.     struct uio *uio;
  1533.     int ioflag;
  1534.     struct ucred *cred;
  1535. {
  1536.  
  1537.     /*
  1538.      * Set access flag.
  1539.      */
  1540.     VTOI(vp)->i_flag |= IACC;
  1541.     return (fifo_read(vp, uio, ioflag, cred));
  1542. }
  1543.  
  1544. /*
  1545.  * Write wrapper for fifo's.
  1546.  */
  1547. ufsfifo_write(vp, uio, ioflag, cred)
  1548.     struct vnode *vp;
  1549.     struct uio *uio;
  1550.     int ioflag;
  1551.     struct ucred *cred;
  1552. {
  1553.  
  1554.     /*
  1555.      * Set update and change flags.
  1556.      */
  1557.     VTOI(vp)->i_flag |= IUPD|ICHG;
  1558.     return (fifo_write(vp, uio, ioflag, cred));
  1559. }
  1560.  
  1561. /*
  1562.  * Close wrapper for fifo's.
  1563.  *
  1564.  * Update the times on the inode then do device close.
  1565.  */
  1566. ufsfifo_close(vp, fflag, cred, p)
  1567.     struct vnode *vp;
  1568.     int fflag;
  1569.     struct ucred *cred;
  1570.     struct proc *p;
  1571. {
  1572.     register struct inode *ip = VTOI(vp);
  1573.  
  1574.     if (vp->v_usecount > 1 && !(ip->i_flag & ILOCKED))
  1575.         ITIMES(ip, &time, &time);
  1576.     return (fifo_close(vp, fflag, cred, p));
  1577. }
  1578. #endif /* FIFO */
  1579.  
  1580. /*
  1581.  * Allocate a new inode.
  1582.  */
  1583. maknode(mode, ndp, ipp)
  1584.     int mode;
  1585.     register struct nameidata *ndp;
  1586.     struct inode **ipp;
  1587. {
  1588.     register struct inode *ip;
  1589.     struct inode *tip;
  1590.     register struct inode *pdir = VTOI(ndp->ni_dvp);
  1591.     ino_t ipref;
  1592.     int error;
  1593.  
  1594. #ifdef DIANOSTIC
  1595.     if ((ndp->ni_nameiop & HASBUF) == 0)
  1596.         panic("maknode: no name");
  1597. #endif
  1598.     *ipp = 0;
  1599.     if ((mode & IFMT) == 0)
  1600.         mode |= IFREG;
  1601.     if ((mode & IFMT) == IFDIR)
  1602.         ipref = dirpref(pdir->i_fs);
  1603.     else
  1604.         ipref = pdir->i_number;
  1605.     if (error = ialloc(pdir, ipref, mode, ndp->ni_cred, &tip)) {
  1606.         free(ndp->ni_pnbuf, M_NAMEI);
  1607.         iput(pdir);
  1608.         return (error);
  1609.     }
  1610.     ip = tip;
  1611.     ip->i_uid = ndp->ni_cred->cr_uid;
  1612.     ip->i_gid = pdir->i_gid;
  1613. #ifdef QUOTA
  1614.     if ((error = getinoquota(ip)) ||
  1615.         (error = chkiq(ip, 1, ndp->ni_cred, 0))) {
  1616.         free(ndp->ni_pnbuf, M_NAMEI);
  1617.         ifree(ip, ip->i_number, mode);
  1618.         iput(ip);
  1619.         iput(pdir);
  1620.         return (error);
  1621.     }
  1622. #endif
  1623.     ip->i_flag |= IACC|IUPD|ICHG;
  1624.     ip->i_mode = mode;
  1625.     ITOV(ip)->v_type = IFTOVT(mode);    /* Rest init'd in iget() */
  1626.     ip->i_nlink = 1;
  1627.     if ((ip->i_mode & ISGID) && !groupmember(ip->i_gid, ndp->ni_cred) &&
  1628.         suser(ndp->ni_cred, NULL))
  1629.         ip->i_mode &= ~ISGID;
  1630.  
  1631.     /*
  1632.      * Make sure inode goes to disk before directory entry.
  1633.      */
  1634.     if (error = iupdat(ip, &time, &time, 1))
  1635.         goto bad;
  1636.     if (error = direnter(ip, ndp))
  1637.         goto bad;
  1638.     if ((ndp->ni_nameiop & SAVESTART) == 0)
  1639.         FREE(ndp->ni_pnbuf, M_NAMEI);
  1640.     iput(pdir);
  1641.     *ipp = ip;
  1642.     return (0);
  1643.  
  1644. bad:
  1645.     /*
  1646.      * Write error occurred trying to update the inode
  1647.      * or the directory so must deallocate the inode.
  1648.      */
  1649.     free(ndp->ni_pnbuf, M_NAMEI);
  1650.     iput(pdir);
  1651.     ip->i_nlink = 0;
  1652.     ip->i_flag |= ICHG;
  1653.     iput(ip);
  1654.     return (error);
  1655. }
  1656.  
  1657. /*
  1658.  * Advisory record locking support
  1659.  */
  1660. ufs_advlock(vp, id, op, fl, flags)
  1661.     struct vnode *vp;
  1662.     caddr_t id;
  1663.     int op;
  1664.     register struct flock *fl;
  1665.     int flags;
  1666. {
  1667.     register struct inode *ip = VTOI(vp);
  1668.     register struct lockf *lock;
  1669.     off_t start, end;
  1670.     int error;
  1671.  
  1672.     /*
  1673.      * Avoid the common case of unlocking when inode has no locks.
  1674.      */
  1675.     if (ip->i_lockf == (struct lockf *)0) {
  1676.         if (op != F_SETLK) {
  1677.             fl->l_type = F_UNLCK;
  1678.             return (0);
  1679.         }
  1680.     }
  1681.     /*
  1682.      * Convert the flock structure into a start and end.
  1683.      */
  1684.     switch (fl->l_whence) {
  1685.  
  1686.     case SEEK_SET:
  1687.     case SEEK_CUR:
  1688.         /*
  1689.          * Caller is responsible for adding any necessary offset
  1690.          * when SEEK_CUR is used.
  1691.          */
  1692.         start = fl->l_start;
  1693.         break;
  1694.  
  1695.     case SEEK_END:
  1696.         start = ip->i_size + fl->l_start;
  1697.         break;
  1698.  
  1699.     default:
  1700.         return (EINVAL);
  1701.     }
  1702.     if (start < 0)
  1703.         return (EINVAL);
  1704.     if (fl->l_len == 0)
  1705.         end = -1;
  1706.     else
  1707.         end = start + fl->l_len - 1;
  1708.     /*
  1709.      * Create the lockf structure
  1710.      */
  1711.     MALLOC(lock, struct lockf *, sizeof *lock, M_LOCKF, M_WAITOK);
  1712.     lock->lf_start = start;
  1713.     lock->lf_end = end;
  1714.     lock->lf_id = id;
  1715.     lock->lf_inode = ip;
  1716.     lock->lf_type = fl->l_type;
  1717.     lock->lf_next = (struct lockf *)0;
  1718.     lock->lf_block = (struct lockf *)0;
  1719.     lock->lf_flags = flags;
  1720.     /*
  1721.      * Do the requested operation.
  1722.      */
  1723.     switch(op) {
  1724.     case F_SETLK:
  1725.         return (lf_setlock(lock));
  1726.  
  1727.     case F_UNLCK:
  1728.         error = lf_clearlock(lock);
  1729.         FREE(lock, M_LOCKF);
  1730.         return (error);
  1731.  
  1732.     case F_GETLK:
  1733.         error = lf_getlock(lock, fl);
  1734.         FREE(lock, M_LOCKF);
  1735.         return (error);
  1736.     
  1737.     default:
  1738.         free(lock, M_LOCKF);
  1739.         return (EINVAL);
  1740.     }
  1741.     /* NOTREACHED */
  1742. }
  1743.  
  1744. /*
  1745.  * Global vfs data structures for ufs
  1746.  */
  1747. struct vnodeops ufs_vnodeops = {
  1748.     ufs_lookup,        /* lookup */
  1749.     ufs_create,        /* create */
  1750.     ufs_mknod,        /* mknod */
  1751.     ufs_open,        /* open */
  1752.     ufs_close,        /* close */
  1753.     ufs_access,        /* access */
  1754.     ufs_getattr,        /* getattr */
  1755.     ufs_setattr,        /* setattr */
  1756.     ufs_read,        /* read */
  1757.     ufs_write,        /* write */
  1758.     ufs_ioctl,        /* ioctl */
  1759.     ufs_select,        /* select */
  1760.     ufs_mmap,        /* mmap */
  1761.     ufs_fsync,        /* fsync */
  1762.     ufs_seek,        /* seek */
  1763.     ufs_remove,        /* remove */
  1764.     ufs_link,        /* link */
  1765.     ufs_rename,        /* rename */
  1766.     ufs_mkdir,        /* mkdir */
  1767.     ufs_rmdir,        /* rmdir */
  1768.     ufs_symlink,        /* symlink */
  1769.     ufs_readdir,        /* readdir */
  1770.     ufs_readlink,        /* readlink */
  1771.     ufs_abortop,        /* abortop */
  1772.     ufs_inactive,        /* inactive */
  1773.     ufs_reclaim,        /* reclaim */
  1774.     ufs_lock,        /* lock */
  1775.     ufs_unlock,        /* unlock */
  1776.     ufs_bmap,        /* bmap */
  1777.     ufs_strategy,        /* strategy */
  1778.     ufs_print,        /* print */
  1779.     ufs_islocked,        /* islocked */
  1780.     ufs_advlock,        /* advlock */
  1781. };
  1782.  
  1783. struct vnodeops spec_inodeops = {
  1784.     spec_lookup,        /* lookup */
  1785.     spec_create,        /* create */
  1786.     spec_mknod,        /* mknod */
  1787.     spec_open,        /* open */
  1788.     ufsspec_close,        /* close */
  1789.     ufs_access,        /* access */
  1790.     ufs_getattr,        /* getattr */
  1791.     ufs_setattr,        /* setattr */
  1792.     ufsspec_read,        /* read */
  1793.     ufsspec_write,        /* write */
  1794.     spec_ioctl,        /* ioctl */
  1795.     spec_select,        /* select */
  1796.     spec_mmap,        /* mmap */
  1797.     spec_fsync,        /* fsync */
  1798.     spec_seek,        /* seek */
  1799.     spec_remove,        /* remove */
  1800.     spec_link,        /* link */
  1801.     spec_rename,        /* rename */
  1802.     spec_mkdir,        /* mkdir */
  1803.     spec_rmdir,        /* rmdir */
  1804.     spec_symlink,        /* symlink */
  1805.     spec_readdir,        /* readdir */
  1806.     spec_readlink,        /* readlink */
  1807.     spec_abortop,        /* abortop */
  1808.     ufs_inactive,        /* inactive */
  1809.     ufs_reclaim,        /* reclaim */
  1810.     ufs_lock,        /* lock */
  1811.     ufs_unlock,        /* unlock */
  1812.     spec_bmap,        /* bmap */
  1813.     spec_strategy,        /* strategy */
  1814.     ufs_print,        /* print */
  1815.     ufs_islocked,        /* islocked */
  1816.     spec_advlock,        /* advlock */
  1817. };
  1818.  
  1819. #ifdef FIFO
  1820. struct vnodeops fifo_inodeops = {
  1821.     fifo_lookup,        /* lookup */
  1822.     fifo_create,        /* create */
  1823.     fifo_mknod,        /* mknod */
  1824.     fifo_open,        /* open */
  1825.     ufsfifo_close,        /* close */
  1826.     ufs_access,        /* access */
  1827.     ufs_getattr,        /* getattr */
  1828.     ufs_setattr,        /* setattr */
  1829.     ufsfifo_read,        /* read */
  1830.     ufsfifo_write,        /* write */
  1831.     fifo_ioctl,        /* ioctl */
  1832.     fifo_select,        /* select */
  1833.     fifo_mmap,        /* mmap */
  1834.     fifo_fsync,        /* fsync */
  1835.     fifo_seek,        /* seek */
  1836.     fifo_remove,        /* remove */
  1837.     fifo_link,        /* link */
  1838.     fifo_rename,        /* rename */
  1839.     fifo_mkdir,        /* mkdir */
  1840.     fifo_rmdir,        /* rmdir */
  1841.     fifo_symlink,        /* symlink */
  1842.     fifo_readdir,        /* readdir */
  1843.     fifo_readlink,        /* readlink */
  1844.     fifo_abortop,        /* abortop */
  1845.     ufs_inactive,        /* inactive */
  1846.     ufs_reclaim,        /* reclaim */
  1847.     ufs_lock,        /* lock */
  1848.     ufs_unlock,        /* unlock */
  1849.     fifo_bmap,        /* bmap */
  1850.     fifo_strategy,        /* strategy */
  1851.     ufs_print,        /* print */
  1852.     ufs_islocked,        /* islocked */
  1853.     fifo_advlock,        /* advlock */
  1854. };
  1855. #endif /* FIFO */
  1856.  
  1857. enum vtype iftovt_tab[16] = {
  1858.     VNON, VFIFO, VCHR, VNON, VDIR, VNON, VBLK, VNON,
  1859.     VREG, VNON, VLNK, VNON, VSOCK, VNON, VNON, VBAD,
  1860. };
  1861. int    vttoif_tab[9] = {
  1862.     0, IFREG, IFDIR, IFBLK, IFCHR, IFLNK, IFSOCK, IFIFO, IFMT,
  1863. };
  1864.