new queue structure
[unix-history] / usr / src / sys / ufs / ffs / ffs_inode.c
index dc8e31c..91a5ea7 100644 (file)
@@ -1,10 +1,10 @@
 /*
 /*
- * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
- * All rights reserved.
+ * Copyright (c) 1982, 1986, 1989, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
  * %sccs.include.redist.c%
  *
  *
  * %sccs.include.redist.c%
  *
- *     @(#)ffs_inode.c 7.69 (Berkeley) %G%
+ *     @(#)ffs_inode.c 8.5 (Berkeley) %G%
  */
 
 #include <sys/param.h>
  */
 
 #include <sys/param.h>
@@ -39,44 +39,46 @@ ffs_init()
 }
 
 /*
 }
 
 /*
- * Update the access, modified, and inode change times as specified
- * by the IACC, IUPD, and ICHG flags respectively. The IMOD flag
- * is used to specify that the inode needs to be updated but that
- * the times have already been set. The access and modified times
- * are taken from the second and third parameters; the inode change
- * time is always taken from the current time. If waitfor is set,
- * then wait for the disk write of the inode to complete.
+ * Update the access, modified, and inode change times as specified by the
+ * IACCESS, IUPDATE, and ICHANGE flags respectively. The IMODIFIED flag is
+ * used to specify that the inode needs to be updated but that the times have
+ * already been set. The access and modified times are taken from the second
+ * and third parameters; the inode change time is always taken from the current
+ * time. If waitfor is set, then wait for the disk write of the inode to
+ * complete.
  */
 int
 ffs_update(ap)
        struct vop_update_args /* {
                struct vnode *a_vp;
  */
 int
 ffs_update(ap)
        struct vop_update_args /* {
                struct vnode *a_vp;
-               struct timeval *a_ta;
-               struct timeval *a_tm;
+               struct timeval *a_access;
+               struct timeval *a_modify;
                int a_waitfor;
        } */ *ap;
 {
                int a_waitfor;
        } */ *ap;
 {
+       register struct fs *fs;
        struct buf *bp;
        struct inode *ip;
        struct buf *bp;
        struct inode *ip;
-       struct dinode *dp;
        register struct fs *fs;
 
        ip = VTOI(ap->a_vp);
        if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY) {
        register struct fs *fs;
 
        ip = VTOI(ap->a_vp);
        if (ap->a_vp->v_mount->mnt_flag & MNT_RDONLY) {
-               ip->i_flag &= ~(IUPD|IACC|ICHG|IMOD);
+               ip->i_flag &=
+                   ~(IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE);
                return (0);
        }
                return (0);
        }
-       if ((ip->i_flag & (IUPD|IACC|ICHG|IMOD)) == 0)
+       if ((ip->i_flag &
+           (IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0)
                return (0);
                return (0);
-       if (ip->i_flag&IACC)
-               ip->i_atime.ts_sec = ap->a_ta->tv_sec;
-       if (ip->i_flag&IUPD) {
-               ip->i_mtime.ts_sec = ap->a_tm->tv_sec;
+       if (ip->i_flag & IN_ACCESS)
+               ip->i_atime.ts_sec = ap->a_access->tv_sec;
+       if (ip->i_flag & IN_UPDATE) {
+               ip->i_mtime.ts_sec = ap->a_modify->tv_sec;
                ip->i_modrev++;
        }
                ip->i_modrev++;
        }
-       if (ip->i_flag&ICHG)
+       if (ip->i_flag & IN_CHANGE)
                ip->i_ctime.ts_sec = time.tv_sec;
                ip->i_ctime.ts_sec = time.tv_sec;
-       ip->i_flag &= ~(IUPD|IACC|ICHG|IMOD);
+       ip->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE);
        fs = ip->i_fs;
        /*
         * Ensure that uid and gid are correct. This is a temporary
        fs = ip->i_fs;
        /*
         * Ensure that uid and gid are correct. This is a temporary
@@ -86,13 +88,14 @@ ffs_update(ap)
                ip->i_din.di_ouid = ip->i_uid;          /* XXX */
                ip->i_din.di_ogid = ip->i_gid;          /* XXX */
        }                                               /* XXX */
                ip->i_din.di_ouid = ip->i_uid;          /* XXX */
                ip->i_din.di_ogid = ip->i_gid;          /* XXX */
        }                                               /* XXX */
-       if (error = bread(ip->i_devvp, fsbtodb(fs, itod(fs, ip->i_number)),
+       if (error = bread(ip->i_devvp,
+           fsbtodb(fs, ino_to_fsba(fs, ip->i_number)),
                (int)fs->fs_bsize, NOCRED, &bp)) {
                brelse(bp);
                return (error);
        }
                (int)fs->fs_bsize, NOCRED, &bp)) {
                brelse(bp);
                return (error);
        }
-       dp = bp->b_un.b_dino + itoo(fs, ip->i_number);
-       *dp = ip->i_din;
+       *((struct dinode *)bp->b_data +
+           ino_to_fsbo(fs, ip->i_number)) = ip->i_din;
        if (ap->a_waitfor)
                return (bwrite(bp));
        else {
        if (ap->a_waitfor)
                return (bwrite(bp));
        else {
@@ -105,8 +108,8 @@ ffs_update(ap)
 #define        DOUBLE  1       /* index of double indirect block */
 #define        TRIPLE  2       /* index of triple indirect block */
 /*
 #define        DOUBLE  1       /* index of double indirect block */
 #define        TRIPLE  2       /* index of triple indirect block */
 /*
- * Truncate the inode oip to at most length size.  Free affected disk
- * blocks -- the blocks of the file are removed in reverse order.
+ * Truncate the inode oip to at most length size, freeing the
+ * disk blocks.
  */
 ffs_truncate(ap)
        struct vop_truncate_args /* {
  */
 ffs_truncate(ap)
        struct vop_truncate_args /* {
@@ -142,34 +145,50 @@ ffs_truncate(ap)
 #endif
                bzero((char *)&oip->i_shortlink, (u_int)oip->i_size);
                oip->i_size = 0;
 #endif
                bzero((char *)&oip->i_shortlink, (u_int)oip->i_size);
                oip->i_size = 0;
-               oip->i_flag |= ICHG|IUPD;
+               oip->i_flag |= IN_CHANGE | IN_UPDATE;
                return (VOP_UPDATE(ovp, &tv, &tv, 1));
        }
                return (VOP_UPDATE(ovp, &tv, &tv, 1));
        }
-       if (oip->i_size <= length) {
-               oip->i_flag |= ICHG|IUPD;
+       if (oip->i_size == length) {
+               oip->i_flag |= IN_CHANGE | IN_UPDATE;
                return (VOP_UPDATE(ovp, &tv, &tv, 0));
        }
                return (VOP_UPDATE(ovp, &tv, &tv, 0));
        }
+#ifdef QUOTA
+       if (error = getinoquota(oip))
+               return (error);
+#endif
        vnode_pager_setsize(ovp, (u_long)length);
        vnode_pager_setsize(ovp, (u_long)length);
+       fs = oip->i_fs;
+       osize = oip->i_size;
        /*
        /*
-        * Calculate index into inode's block list of
-        * last direct and indirect blocks (if any)
-        * which we want to keep.  Lastblock is -1 when
-        * the file is truncated to 0.
+        * Lengthen the size of the file. We must ensure that the
+        * last byte of the file is allocated. Since the smallest
+        * value of oszie is 0, length will be at least 1.
         */
         */
-       fs = oip->i_fs;
-       lastblock = lblkno(fs, length + fs->fs_bsize - 1) - 1;
-       lastiblock[SINGLE] = lastblock - NDADDR;
-       lastiblock[DOUBLE] = lastiblock[SINGLE] - NINDIR(fs);
-       lastiblock[TRIPLE] = lastiblock[DOUBLE] - NINDIR(fs) * NINDIR(fs);
-       nblocks = btodb(fs->fs_bsize);
+       if (osize < length) {
+               offset = blkoff(fs, length - 1);
+               lbn = lblkno(fs, length - 1);
+               aflags = B_CLRBUF;
+               if (ap->a_flags & IO_SYNC)
+                       aflags |= B_SYNC;
+               if (error = ffs_balloc(oip, lbn, offset + 1, ap->a_cred, &bp,
+                   aflags))
+                       return (error);
+               oip->i_size = length;
+               (void) vnode_pager_uncache(ovp);
+               if (aflags & IO_SYNC)
+                       bwrite(bp);
+               else
+                       bawrite(bp);
+               oip->i_flag |= IN_CHANGE | IN_UPDATE;
+               return (VOP_UPDATE(ovp, &tv, &tv, 1));
+       }
        /*
        /*
-        * Update the size of the file. If the file is not being
+        * Shorten the size of the file. If the file is not being
         * truncated to a block boundry, the contents of the
         * partial block following the end of the file must be
         * zero'ed in case it ever become accessable again because
         * of subsequent file growth.
         */
         * truncated to a block boundry, the contents of the
         * partial block following the end of the file must be
         * zero'ed in case it ever become accessable again because
         * of subsequent file growth.
         */
-       osize = oip->i_size;
        offset = blkoff(fs, length);
        if (offset == 0) {
                oip->i_size = length;
        offset = blkoff(fs, length);
        if (offset == 0) {
                oip->i_size = length;
@@ -178,22 +197,30 @@ ffs_truncate(ap)
                aflags = B_CLRBUF;
                if (ap->a_flags & IO_SYNC)
                        aflags |= B_SYNC;
                aflags = B_CLRBUF;
                if (ap->a_flags & IO_SYNC)
                        aflags |= B_SYNC;
-#ifdef QUOTA
-               if (error = getinoquota(oip))
-                       return (error);
-#endif
-               if (error = ffs_balloc(oip, lbn, offset, ap->a_cred, &bp, aflags))
+               if (error = ffs_balloc(oip, lbn, offset, ap->a_cred, &bp,
+                   aflags))
                        return (error);
                oip->i_size = length;
                size = blksize(fs, oip, lbn);
                (void) vnode_pager_uncache(ovp);
                        return (error);
                oip->i_size = length;
                size = blksize(fs, oip, lbn);
                (void) vnode_pager_uncache(ovp);
-               bzero(bp->b_un.b_addr + offset, (unsigned)(size - offset));
+               bzero((char *)bp->b_data + offset, (u_int)(size - offset));
                allocbuf(bp, size);
                allocbuf(bp, size);
-               if (ap->a_flags & IO_SYNC)
+               if (aflags & IO_SYNC)
                        bwrite(bp);
                else
                        bawrite(bp);
        }
                        bwrite(bp);
                else
                        bawrite(bp);
        }
+       /*
+        * Calculate index into inode's block list of
+        * last direct and indirect blocks (if any)
+        * which we want to keep.  Lastblock is -1 when
+        * the file is truncated to 0.
+        */
+       lastblock = lblkno(fs, length + fs->fs_bsize - 1) - 1;
+       lastiblock[SINGLE] = lastblock - NDADDR;
+       lastiblock[DOUBLE] = lastiblock[SINGLE] - NINDIR(fs);
+       lastiblock[TRIPLE] = lastiblock[DOUBLE] - NINDIR(fs) * NINDIR(fs);
+       nblocks = btodb(fs->fs_bsize);
        /*
         * Update file and block pointers on disk before we start freeing
         * blocks.  If we crash before free'ing blocks below, the blocks
        /*
         * Update file and block pointers on disk before we start freeing
         * blocks.  If we crash before free'ing blocks below, the blocks
@@ -208,7 +235,7 @@ ffs_truncate(ap)
                }
        for (i = NDADDR - 1; i > lastblock; i--)
                oip->i_db[i] = 0;
                }
        for (i = NDADDR - 1; i > lastblock; i--)
                oip->i_db[i] = 0;
-       oip->i_flag |= ICHG|IUPD;
+       oip->i_flag |= IN_CHANGE | IN_UPDATE;
        if (error = VOP_UPDATE(ovp, &tv, &tv, MNT_WAIT))
                allerror = error;
        /*
        if (error = VOP_UPDATE(ovp, &tv, &tv, MNT_WAIT))
                allerror = error;
        /*
@@ -301,7 +328,7 @@ done:
                if (newblks[i] != oip->i_db[i])
                        panic("itrunc2");
        if (length == 0 &&
                if (newblks[i] != oip->i_db[i])
                        panic("itrunc2");
        if (length == 0 &&
-           (ovp->v_dirtyblkhd.le_next || ovp->v_cleanblkhd.le_next))
+           (ovp->v_dirtyblkhd.lh_first || ovp->v_cleanblkhd.lh_first))
                panic("itrunc3");
 #endif /* DIAGNOSTIC */
        /*
                panic("itrunc3");
 #endif /* DIAGNOSTIC */
        /*
@@ -311,10 +338,9 @@ done:
        oip->i_blocks -= blocksreleased;
        if (oip->i_blocks < 0)                  /* sanity */
                oip->i_blocks = 0;
        oip->i_blocks -= blocksreleased;
        if (oip->i_blocks < 0)                  /* sanity */
                oip->i_blocks = 0;
-       oip->i_flag |= ICHG;
+       oip->i_flag |= IN_CHANGE;
 #ifdef QUOTA
 #ifdef QUOTA
-       if (!getinoquota(oip))
-               (void) chkdq(oip, -blocksreleased, NOCRED, 0);
+       (void) chkdq(oip, -blocksreleased, NOCRED, 0);
 #endif
        return (allerror);
 }
 #endif
        return (allerror);
 }
@@ -391,7 +417,7 @@ ffs_indirtrunc(ip, lbn, dbn, lastbn, level, countp)
                return (error);
        }
 
                return (error);
        }
 
-       bap = bp->b_un.b_daddr;
+       bap = (daddr_t *)bp->b_data;
        MALLOC(copy, daddr_t *, fs->fs_bsize, M_TEMP, M_WAITOK);
        bcopy((caddr_t)bap, (caddr_t)copy, (u_int)fs->fs_bsize);
        bzero((caddr_t)&bap[last + 1],
        MALLOC(copy, daddr_t *, fs->fs_bsize, M_TEMP, M_WAITOK);
        bcopy((caddr_t)bap, (caddr_t)copy, (u_int)fs->fs_bsize);
        bzero((caddr_t)&bap[last + 1],