Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/ufs in both paths that can cause fragments to be expande...
details: https://anonhg.NetBSD.org/src/rev/13dda8d181c9
branches: trunk
changeset: 517169:13dda8d181c9
user: chs <chs%NetBSD.org@localhost>
date: Thu Nov 08 05:24:52 2001 +0000
description:
in both paths that can cause fragments to be expanded (write and truncate-up),
deal with the fragment expansion separately before the rest of the operation.
this allows us to simplify ufs_balloc_range() by not worrying about implicit
fragment expansion.
call VOP_PUTPAGES() directly for vnodes instead of
going through the UVM pager "put" vector.
diffstat:
sys/ufs/ffs/ffs_inode.c | 38 ++++++++++---
sys/ufs/ufs/ufs_inode.c | 119 +++++++++++--------------------------------
sys/ufs/ufs/ufs_readwrite.c | 24 +++++---
3 files changed, 74 insertions(+), 107 deletions(-)
diffs (truncated from 323 to 300 lines):
diff -r 92422018d00d -r 13dda8d181c9 sys/ufs/ffs/ffs_inode.c
--- a/sys/ufs/ffs/ffs_inode.c Thu Nov 08 05:00:51 2001 +0000
+++ b/sys/ufs/ffs/ffs_inode.c Thu Nov 08 05:24:52 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ffs_inode.c,v 1.47 2001/11/06 06:59:06 simonb Exp $ */
+/* $NetBSD: ffs_inode.c,v 1.48 2001/11/08 05:24:52 chs Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ffs_inode.c,v 1.47 2001/11/06 06:59:06 simonb Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ffs_inode.c,v 1.48 2001/11/08 05:24:52 chs Exp $");
#if defined(_KERNEL_OPT)
#include "opt_ffs.h"
@@ -180,7 +180,7 @@
struct fs *fs;
int offset, size, level;
long count, nblocks, blocksreleased = 0;
- int i;
+ int i, ioflag, aflag;
int error, allerror = 0;
off_t osize;
@@ -210,6 +210,7 @@
return (EFBIG);
osize = oip->i_ffs_size;
+ ioflag = ap->a_flags;
/*
* Lengthen the size of the file. We must ensure that the
@@ -218,9 +219,28 @@
*/
if (osize < length) {
+ aflag = ioflag & IO_SYNC ? B_SYNC : 0;
+ if (lblkno(fs, osize) < NDADDR &&
+ lblkno(fs, osize) != lblkno(fs, length) &&
+ blkroundup(fs, osize) != osize) {
+ error = ufs_balloc_range(ovp, osize,
+ blkroundup(fs, osize) - osize, ap->a_cred, aflag);
+ if (error) {
+ return error;
+ }
+ if (ioflag & IO_SYNC) {
+ ovp->v_size = blkroundup(fs, osize);
+ simple_lock(&ovp->v_interlock);
+ VOP_PUTPAGES(ovp, osize & ~(fs->fs_bsize - 1),
+ round_page(ovp->v_size),
+ PGO_CLEANIT | PGO_SYNCIO);
+ }
+ }
error = ufs_balloc_range(ovp, length - 1, 1, ap->a_cred,
- ap->a_flags & IO_SYNC ? B_SYNC : 0);
+ aflag);
if (error) {
+ (void) VOP_TRUNCATE(ovp, osize, ioflag & IO_SYNC,
+ ap->a_cred, ap->a_p);
return error;
}
uvm_vnp_setsize(ovp, length);
@@ -235,7 +255,7 @@
* We must synchronously flush the zeroed pages to disk
* since the new pages will be invalidated as soon as we
* inform the VM system of the new, smaller size.
- * We must to this before acquiring the GLOCK, since fetching
+ * We must do this before acquiring the GLOCK, since fetching
* the pages will acquire the GLOCK internally.
* So there is a window where another thread could see a whole
* zeroed page past EOF, but that's life.
@@ -243,16 +263,14 @@
offset = blkoff(fs, length);
if (ovp->v_type == VREG && length < osize && offset != 0) {
- struct uvm_object *uobj;
voff_t eoz;
size = blksize(fs, oip, lblkno(fs, length));
eoz = MIN(lblktosize(fs, lblkno(fs, length)) + size, osize);
uvm_vnp_zerorange(ovp, length, eoz - length);
- uobj = &ovp->v_uobj;
- simple_lock(&uobj->vmobjlock);
- error = (uobj->pgops->pgo_put)(uobj, trunc_page(length),
- round_page(eoz), PGO_CLEANIT|PGO_DEACTIVATE|PGO_SYNCIO);
+ simple_lock(&ovp->v_interlock);
+ error = VOP_PUTPAGES(ovp, trunc_page(length), round_page(eoz),
+ PGO_CLEANIT | PGO_DEACTIVATE | PGO_SYNCIO);
if (error) {
return error;
}
diff -r 92422018d00d -r 13dda8d181c9 sys/ufs/ufs/ufs_inode.c
--- a/sys/ufs/ufs/ufs_inode.c Thu Nov 08 05:00:51 2001 +0000
+++ b/sys/ufs/ufs/ufs_inode.c Thu Nov 08 05:24:52 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ufs_inode.c,v 1.28 2001/11/08 02:39:16 lukem Exp $ */
+/* $NetBSD: ufs_inode.c,v 1.29 2001/11/08 05:24:52 chs Exp $ */
/*
* Copyright (c) 1991, 1993
@@ -41,7 +41,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ufs_inode.c,v 1.28 2001/11/08 02:39:16 lukem Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ufs_inode.c,v 1.29 2001/11/08 05:24:52 chs Exp $");
#include "opt_quota.h"
@@ -169,14 +169,14 @@
struct ucred *cred;
int flags;
{
- off_t tmpeof, oldeof, neweof, oldeob, neweob, oldpagestart, pagestart;
+ off_t oldeof, neweof, oldeob, neweob, pagestart;
struct uvm_object *uobj;
struct genfs_node *gp = VTOG(vp);
- int i, delta, error, npages1, npages2;
+ int i, delta, error, npages;
int bshift = vp->v_mount->mnt_fs_bshift;
int bsize = 1 << bshift;
int ppb = MAX(bsize >> PAGE_SHIFT, 1);
- struct vm_page *pgs1[ppb], *pgs2[ppb];
+ struct vm_page *pgs[ppb];
UVMHIST_FUNC("ufs_balloc_range"); UVMHIST_CALLED(ubchist);
UVMHIST_LOG(ubchist, "vp %p off 0x%x len 0x%x u_size 0x%x",
vp, off, len, vp->v_size);
@@ -189,67 +189,34 @@
error = 0;
uobj = &vp->v_uobj;
- pgs1[0] = pgs2[0] = NULL;
+ pgs[0] = NULL;
/*
- * if the last block in the file is not a full block (ie. it is a
- * fragment), and this allocation is causing the fragment to change
- * size (either to expand the fragment or promote it to a full block),
- * cache the old last block (at its new size).
- */
-
- oldpagestart = trunc_page(oldeof) & ~(bsize - 1);
- if ((oldeob & (bsize - 1)) != 0 && oldeob != neweob) {
- npages1 = MIN(ppb, (round_page(neweob) - oldpagestart) >>
- PAGE_SHIFT);
- memset(pgs1, 0, npages1 * sizeof(struct vm_page *));
- simple_lock(&uobj->vmobjlock);
- error = VOP_GETPAGES(vp, oldpagestart, pgs1, &npages1,
- 0, VM_PROT_READ, 0, PGO_SYNCIO|PGO_PASTEOF);
- if (error) {
- goto out;
- }
- simple_lock(&uobj->vmobjlock);
- uvm_lock_pageq();
- for (i = 0; i < npages1; i++) {
- UVMHIST_LOG(ubchist, "got pgs1[%d] %p", i, pgs1[i],0,0);
- KASSERT((pgs1[i]->flags & PG_RELEASED) == 0);
- pgs1[i]->flags &= ~PG_CLEAN;
- uvm_pageactivate(pgs1[i]);
- }
- uvm_unlock_pageq();
- simple_unlock(&uobj->vmobjlock);
- }
-
- /*
- * cache the new range as well. this will create zeroed pages
- * where the new block will be and keep them locked until the
- * new block is allocated, so there will be no window where
- * the old contents of the new block is visible to racing threads.
+ * read or create pages covering the range of the allocation and
+ * keep them locked until the new block is allocated, so there
+ * will be no window where the old contents of the new block are
+ * visible to racing threads.
*/
pagestart = trunc_page(off) & ~(bsize - 1);
- if (pagestart != oldpagestart || pgs1[0] == NULL) {
- npages2 = MIN(ppb, (round_page(neweob) - pagestart) >>
- PAGE_SHIFT);
- memset(pgs2, 0, npages2 * sizeof(struct vm_page *));
- simple_lock(&uobj->vmobjlock);
- error = VOP_GETPAGES(vp, pagestart, pgs2, &npages2, 0,
- VM_PROT_READ, 0, PGO_SYNCIO|PGO_PASTEOF);
- if (error) {
- goto out;
- }
- simple_lock(&uobj->vmobjlock);
- uvm_lock_pageq();
- for (i = 0; i < npages2; i++) {
- UVMHIST_LOG(ubchist, "got pgs2[%d] %p", i, pgs2[i],0,0);
- KASSERT((pgs2[i]->flags & PG_RELEASED) == 0);
- pgs2[i]->flags &= ~PG_CLEAN;
- uvm_pageactivate(pgs2[i]);
- }
- uvm_unlock_pageq();
- simple_unlock(&uobj->vmobjlock);
+ npages = MIN(ppb, (round_page(neweob) - pagestart) >> PAGE_SHIFT);
+ memset(pgs, 0, npages * sizeof(struct vm_page *));
+ simple_lock(&uobj->vmobjlock);
+ error = VOP_GETPAGES(vp, pagestart, pgs, &npages, 0,
+ VM_PROT_READ, 0, PGO_SYNCIO|PGO_PASTEOF);
+ if (error) {
+ goto out;
}
+ simple_lock(&uobj->vmobjlock);
+ uvm_lock_pageq();
+ for (i = 0; i < npages; i++) {
+ UVMHIST_LOG(ubchist, "got pgs[%d] %p", i, pgs[i],0,0);
+ KASSERT((pgs[i]->flags & PG_RELEASED) == 0);
+ pgs[i]->flags &= ~PG_CLEAN;
+ uvm_pageactivate(pgs[i]);
+ }
+ uvm_unlock_pageq();
+ simple_unlock(&uobj->vmobjlock);
/*
* adjust off to be block-aligned.
@@ -270,39 +237,17 @@
/*
* clear PG_RDONLY on any pages we are holding
* (since they now have backing store) and unbusy them.
- * if we got an error, the pages covering the new block
- * were already unbusied down in ffs_balloc() to make
- * things work out for softdep.
*/
out:
simple_lock(&uobj->vmobjlock);
- if (pgs1[0] != NULL) {
- for (i = 0; i < npages1; i++) {
- pgs1[i]->flags &= ~PG_RDONLY;
- }
- uvm_page_unbusy(pgs1, npages1);
-
- /*
- * The data in the frag might be moving to a new disk location.
- * We need to flush pages to the new disk locations.
- */
-
- if (flags & B_SYNC) {
- tmpeof = MIN(neweof,
- (oldeof + bsize - 1) & ~(bsize - 1));
- vp->v_size = tmpeof;
- (uobj->pgops->pgo_put)(uobj, oldeof & ~(bsize - 1),
- round_page(tmpeof), PGO_CLEANIT | PGO_SYNCIO);
- simple_lock(&uobj->vmobjlock);
+ for (i = 0; i < npages; i++) {
+ pgs[i]->flags &= ~PG_RDONLY;
+ if (error) {
+ pgs[i]->flags |= PG_RELEASED;
}
}
- if (pgs2[0] != NULL && !error) {
- for (i = 0; i < npages2; i++) {
- pgs2[i]->flags &= ~PG_RDONLY;
- }
- uvm_page_unbusy(pgs2, npages2);
- }
+ uvm_page_unbusy(pgs, npages);
simple_unlock(&uobj->vmobjlock);
return error;
}
diff -r 92422018d00d -r 13dda8d181c9 sys/ufs/ufs/ufs_readwrite.c
--- a/sys/ufs/ufs/ufs_readwrite.c Thu Nov 08 05:00:51 2001 +0000
+++ b/sys/ufs/ufs/ufs_readwrite.c Thu Nov 08 05:24:52 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: ufs_readwrite.c,v 1.37 2001/11/08 02:42:31 lukem Exp $ */
+/* $NetBSD: ufs_readwrite.c,v 1.38 2001/11/08 05:24:52 chs Exp $ */
/*-
* Copyright (c) 1993
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(1, "$NetBSD: ufs_readwrite.c,v 1.37 2001/11/08 02:42:31 lukem Exp $");
+__KERNEL_RCSID(1, "$NetBSD: ufs_readwrite.c,v 1.38 2001/11/08 05:24:52 chs Exp $");
#ifdef LFS_READWRITE
#define BLKSIZE(a, b, c) blksize(a, b, c)
@@ -295,6 +295,12 @@
if (error) {
goto out;
}
+ if (flags & B_SYNC) {
+ vp->v_size = blkroundup(fs, osize);
+ simple_lock(&vp->v_interlock);
+ VOP_PUTPAGES(vp, osize & ~(bsize - 1),
+ round_page(vp->v_size), PGO_CLEANIT | PGO_SYNCIO);
+ }
}
ubc_alloc_flags = UBC_WRITE;
@@ -358,20 +364,18 @@
*/
if (!async && oldoff >> 16 != uio->uio_offset >> 16) {
Home |
Main Index |
Thread Index |
Old Index