Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/ufs/lfs Fix problems outlined in PR#9926:



details:   https://anonhg.NetBSD.org/src/rev/c617e80f8ee7
branches:  trunk
changeset: 485280:c617e80f8ee7
user:      perseant <perseant%NetBSD.org@localhost>
date:      Sun Apr 23 21:10:26 2000 +0000

description:
Fix problems outlined in PR#9926:
        - lfs_truncate extends the file if called with length > i_ffs_size;
    - lfs_truncate errors out if called with length < 0;
        - lfs_balloc block accounting corrected for the case of blocks read
          into the cache before they exist on disk;
        - mp->mnt_stat.f_iosize is initialized in lfs_mountfs.

diffstat:

 sys/ufs/lfs/lfs_balloc.c |  39 ++++++++++++++++++++++++---------------
 sys/ufs/lfs/lfs_debug.c  |  15 ++++++++-------
 sys/ufs/lfs/lfs_inode.c  |  26 +++++++++++++++++++++++---
 sys/ufs/lfs/lfs_vfsops.c |   3 ++-
 4 files changed, 57 insertions(+), 26 deletions(-)

diffs (165 lines):

diff -r 8bdf7bcd376a -r c617e80f8ee7 sys/ufs/lfs/lfs_balloc.c
--- a/sys/ufs/lfs/lfs_balloc.c  Sun Apr 23 21:04:02 2000 +0000
+++ b/sys/ufs/lfs/lfs_balloc.c  Sun Apr 23 21:10:26 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_balloc.c,v 1.14 1999/11/15 18:49:14 fvdl Exp $     */
+/*     $NetBSD: lfs_balloc.c,v 1.15 2000/04/23 21:10:26 perseant Exp $ */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -237,23 +237,32 @@
         * The block we are writing may be a brand new block
         * in which case we need to do accounting (i.e. check
         * for free space and update the inode number of blocks.
+        *
+        * We can tell a truly new block because (1) ufs_bmaparray
+        * will say it is UNASSIGNED; and (2) it will not be marked
+        * with B_DELWRI.  (It might be marked B_DONE, if it was
+        * read into the cache before it existed on disk.)
         */
-       if (!(bp->b_flags & (B_DONE | B_DELWRI))) {
-               if (daddr == UNASSIGNED)
-                       if (!ISSPACE(fs, bb, curproc->p_ucred)) {
-                               bp->b_flags |= B_INVAL;
-                               brelse(bp);
-                               return(ENOSPC);
-                       } else {
-                               ip->i_ffs_blocks += bb;
-                               ip->i_lfs->lfs_bfree -= bb;
-                               if (iosize != fs->lfs_bsize)
-                                       clrbuf(bp);
-                       }
-               else if (iosize == fs->lfs_bsize)
+       if ((!(bp->b_flags & B_DELWRI)) && daddr == UNASSIGNED) {
+               if (!ISSPACE(fs, bb, curproc->p_ucred)) {
+                       bp->b_flags |= B_INVAL;
+                       brelse(bp);
+                       return(ENOSPC);
+               } else {
+                       ip->i_ffs_blocks += bb;
+                       ip->i_lfs->lfs_bfree -= bb;
+                       if (iosize != fs->lfs_bsize)
+                               clrbuf(bp);
+               }
+       } else if (!(bp->b_flags & (B_DONE|B_DELWRI))) {
+               /*
+                * Not a brand new block, also not in the cache;
+                * read it in from disk.
+                */
+               if (iosize == fs->lfs_bsize)
                        /* Optimization: I/O is unnecessary. */
                        bp->b_blkno = daddr;
-               else  {
+               else {
                        /*
                         * We need to read the block to preserve the
                         * existing bytes.
diff -r 8bdf7bcd376a -r c617e80f8ee7 sys/ufs/lfs/lfs_debug.c
--- a/sys/ufs/lfs/lfs_debug.c   Sun Apr 23 21:04:02 2000 +0000
+++ b/sys/ufs/lfs/lfs_debug.c   Sun Apr 23 21:10:26 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_debug.c,v 1.9 1999/03/10 00:20:00 perseant Exp $   */
+/*     $NetBSD: lfs_debug.c,v 1.10 2000/04/23 21:10:26 perseant Exp $  */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -155,12 +155,13 @@
 {
        int i;
        
-       printf("%s%u\t%s%d\t%s%u\t%s%u\t%s%qu\n",
-              "mode  ", dip->di_mode,
-              "nlink ", dip->di_nlink,
-              "uid   ", dip->di_uid,
-              "gid   ", dip->di_gid,
-              "size  ", (long long)dip->di_size);
+       printf("%s%u\t%s%d\t%s%u\t%s%u\t%s%qu\t%s%d\n",
+              "mode   ", dip->di_mode,
+              "nlink  ", dip->di_nlink,
+              "uid    ", dip->di_uid,
+              "gid    ", dip->di_gid,
+              "size   ", (long long)dip->di_size,
+              "blocks ", dip->di_blocks);
        printf("inum  %d\n", dip->di_inumber);
        printf("Direct Addresses\n");
        for (i = 0; i < NDADDR; i++) {
diff -r 8bdf7bcd376a -r c617e80f8ee7 sys/ufs/lfs/lfs_inode.c
--- a/sys/ufs/lfs/lfs_inode.c   Sun Apr 23 21:04:02 2000 +0000
+++ b/sys/ufs/lfs/lfs_inode.c   Sun Apr 23 21:10:26 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_inode.c,v 1.32 2000/03/30 12:41:13 augustss Exp $  */
+/*     $NetBSD: lfs_inode.c,v 1.33 2000/04/23 21:10:27 perseant Exp $  */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -227,6 +227,7 @@
        } */ *ap = v;
        struct indir *inp;
        int i;
+        int error, aflags;
        ufs_daddr_t *daddrp;
        struct vnode *vp = ap->a_vp;
        off_t length = ap->a_length;
@@ -241,7 +242,12 @@
        long off, a_released, fragsreleased, i_released;
        int e1, e2, depth, lastseg, num, offset, seg, freesize, s;
        
+       if (length < 0)
+               return (EINVAL);
+
        ip = VTOI(vp);
+       if (length == ip->i_ffs_size) /* XXX don't update times */
+               return 0;
 
        if (vp->v_type == VLNK &&
           (ip->i_ffs_size < vp->v_mount->mnt_maxsymlinklen ||
@@ -256,16 +262,30 @@
                ip->i_flag |= IN_CHANGE | IN_UPDATE;
                return (VOP_UPDATE(vp, NULL, NULL, 0));
        }
-       uvm_vnp_setsize(vp, length);
        
        fs = ip->i_lfs;
        lfs_imtime(fs);
        
        /* If length is larger than the file, just update the times. */
-       if (ip->i_ffs_size <= length) {
+       if (ip->i_ffs_size < length) {
+               if (length > fs->lfs_maxfilesize)
+                       return (EFBIG);
+               /*
+                * Allocate the new last block to ensure that any previously
+                * existing fragments get extended.  (XXX Adding the new
+                * block is not really necessary.)
+                */
+               error = VOP_BALLOC(vp, length - 1, 1, ap->a_cred, aflags, &bp);
+               if (error)
+                       return (error);
+               VOP_BWRITE(bp);
+               ip->i_ffs_size = length;
+               uvm_vnp_setsize(vp, length);
+               (void) uvm_vnp_uncache(vp);
                ip->i_flag |= IN_CHANGE | IN_UPDATE;
                return (VOP_UPDATE(vp, NULL, NULL, 0));
        }
+       uvm_vnp_setsize(vp, length);
 
        /*
         * Make sure no writes happen while we're truncating.
diff -r 8bdf7bcd376a -r c617e80f8ee7 sys/ufs/lfs/lfs_vfsops.c
--- a/sys/ufs/lfs/lfs_vfsops.c  Sun Apr 23 21:04:02 2000 +0000
+++ b/sys/ufs/lfs/lfs_vfsops.c  Sun Apr 23 21:10:26 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_vfsops.c,v 1.48 2000/03/30 12:41:13 augustss Exp $ */
+/*     $NetBSD: lfs_vfsops.c,v 1.49 2000/04/23 21:10:27 perseant Exp $ */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -437,6 +437,7 @@
        mp->mnt_data = (qaddr_t)ump;
        mp->mnt_stat.f_fsid.val[0] = (long)dev;
        mp->mnt_stat.f_fsid.val[1] = makefstype(MOUNT_LFS);
+       mp->mnt_stat.f_iosize = fs->lfs_bsize;
        mp->mnt_maxsymlinklen = fs->lfs_maxsymlinklen;
        mp->mnt_flag |= MNT_LOCAL;
        ump->um_flags = 0;



Home | Main Index | Thread Index | Old Index