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