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