Source-Changes-HG archive

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

[src/trunk]: src Fixes to the softdep code from Ethan Solomita <ethan@geocast...



details:   https://anonhg.NetBSD.org/src/rev/9a811d22dd25
branches:  trunk
changeset: 482127:9a811d22dd25
user:      fvdl <fvdl%NetBSD.org@localhost>
date:      Mon Feb 14 22:00:21 2000 +0000

description:
Fixes to the softdep code from Ethan Solomita <ethan%geocast.com@localhost>.
* Fix buffer ordering when it has dependencies.
* Alleviate memory problems.
* Deal with some recursive vnode locks (sigh).
* Fix other bugs.

diffstat:

 gnu/sys/ufs/ffs/ffs_softdep.c  |  672 ++++++++++++++++++++++++++--------------
 sys/kern/vfs_vnops.c           |   30 +-
 sys/sys/buf.h                  |    4 +-
 sys/sys/vnode.h                |    4 +-
 sys/ufs/ffs/ffs_alloc.c        |    4 +-
 sys/ufs/ffs/ffs_balloc.c       |   11 +-
 sys/ufs/ffs/ffs_extern.h       |    7 +-
 sys/ufs/ffs/ffs_softdep.stub.c |   13 +-
 sys/ufs/ffs/ffs_vfsops.c       |   10 +-
 sys/ufs/ufs/ufs_extern.h       |    4 +-
 sys/ufs/ufs/ufs_lookup.c       |   27 +-
 sys/ufs/ufs/ufs_vnops.c        |   74 +++-
 12 files changed, 570 insertions(+), 290 deletions(-)

diffs (truncated from 1767 to 300 lines):

diff -r afaf393d418b -r 9a811d22dd25 gnu/sys/ufs/ffs/ffs_softdep.c
--- a/gnu/sys/ufs/ffs/ffs_softdep.c     Mon Feb 14 21:46:26 2000 +0000
+++ b/gnu/sys/ufs/ffs/ffs_softdep.c     Mon Feb 14 22:00:21 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ffs_softdep.c,v 1.5 1999/12/05 20:34:40 fvdl Exp $     */
+/*     $NetBSD: ffs_softdep.c,v 1.6 2000/02/14 22:01:38 fvdl Exp $     */
 
 /*
  * Copyright 1998 Marshall Kirk McKusick. All Rights Reserved.
@@ -54,7 +54,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *     from: @(#)ffs_softdep.c 9.40 (McKusick) 6/15/99
+ *     from: @(#)ffs_softdep.c 9.56 (McKusick) 1/17/00
  */
 
 /*
@@ -117,6 +117,7 @@
  * Finding the current process.
  */
 #define CURPROC curproc
+#define CURPROC_PID (curproc ? curproc->p_pid : 0)
 /*
  * End system adaptaion definitions.
  */
@@ -143,7 +144,7 @@
 static void handle_workitem_freefile __P((struct freefile *));
 static void handle_workitem_remove __P((struct dirrem *));
 static struct dirrem *newdirrem __P((struct buf *, struct inode *,
-           struct inode *, int));
+           struct inode *, int, struct dirrem **));
 static void free_diradd __P((struct diradd *));
 static void free_allocindir __P((struct allocindir *, struct inodedep *));
 static int indir_trunc __P((struct inode *, ufs_daddr_t, int, ufs_lbn_t,
@@ -151,6 +152,7 @@
 static void deallocate_dependencies __P((struct buf *, struct inodedep *));
 static void free_allocdirect __P((struct allocdirectlst *,
            struct allocdirect *, int));
+static int check_inode_unwritten __P((struct inodedep *));
 static int free_inodedep __P((struct inodedep *));
 static void handle_workitem_freeblocks __P((struct freeblks *));
 static void merge_inode_lists __P((struct inodedep *));
@@ -175,12 +177,22 @@
 /*
  * Exported softdep operations.
  */
+static void softdep_disk_io_initiation __P((struct buf *));
+static void softdep_disk_write_complete __P((struct buf *));
+static void softdep_deallocate_dependencies __P((struct buf *));
+static int softdep_fsync __P((struct vnode *));
+static int softdep_process_worklist __P((struct mount *));
+static void softdep_move_dependencies __P((struct buf *, struct buf *));
+static int softdep_count_dependencies __P((struct buf *bp, int));
+
 struct bio_ops bioops = {
        softdep_disk_io_initiation,             /* io_start */
        softdep_disk_write_complete,            /* io_complete */
        softdep_deallocate_dependencies,        /* io_deallocate */
        softdep_fsync,                          /* io_fsync */
        softdep_process_worklist,               /* io_sync */
+       softdep_move_dependencies,              /* io_movedeps */
+       softdep_count_dependencies,             /* io_countdeps */
 };
 
 /*
@@ -204,8 +216,8 @@
 } lk = { 0 };
 #define ACQUIRE_LOCK(lk)               (lk)->lkt_spl = splbio()
 #define FREE_LOCK(lk)                  splx((lk)->lkt_spl)
-#define ACQUIRE_LOCK_INTERLOCKED(lk)
-#define FREE_LOCK_INTERLOCKED(lk)
+#define ACQUIRE_LOCK_INTERLOCKED(lk, s)        (lk)->lkt_spl = s
+#define FREE_LOCK_INTERLOCKED(lk)      (lk)->lkt_spl
 
 #else /* DEBUG */
 static struct lockit {
@@ -216,27 +228,26 @@
 
 static void acquire_lock __P((struct lockit *));
 static void free_lock __P((struct lockit *));
-static void acquire_lock_interlocked __P((struct lockit *));
-static void free_lock_interlocked __P((struct lockit *));
+static void acquire_lock_interlocked __P((struct lockit *, int));
+static int  free_lock_interlocked __P((struct lockit *));
 
 #define ACQUIRE_LOCK(lk)               acquire_lock(lk)
 #define FREE_LOCK(lk)                  free_lock(lk)
-#define ACQUIRE_LOCK_INTERLOCKED(lk)   acquire_lock_interlocked(lk)
+#define ACQUIRE_LOCK_INTERLOCKED(lk, s)        acquire_lock_interlocked(lk, s)
 #define FREE_LOCK_INTERLOCKED(lk)      free_lock_interlocked(lk)
 
 static void
 acquire_lock(lk)
        struct lockit *lk;
 {
-
        if (lk->lkt_held != -1) {
-               if (lk->lkt_held == CURPROC->p_pid)
+               if (lk->lkt_held == CURPROC_PID)
                        panic("softdep_lock: locking against myself");
                else
                        panic("softdep_lock: lock held by %d", lk->lkt_held);
        }
        lk->lkt_spl = splbio();
-       lk->lkt_held = CURPROC->p_pid;
+       lk->lkt_held = CURPROC_PID;
        lockcnt++;
 }
 
@@ -252,29 +263,30 @@
 }
 
 static void
-acquire_lock_interlocked(lk)
+acquire_lock_interlocked(lk, s)
        struct lockit *lk;
+       int s;
 {
-
        if (lk->lkt_held != -1) {
-               if (lk->lkt_held == CURPROC->p_pid)
+               if (lk->lkt_held == CURPROC_PID)
                        panic("softdep_lock_interlocked: locking against self");
                else
                        panic("softdep_lock_interlocked: lock held by %d",
                            lk->lkt_held);
        }
-       lk->lkt_held = CURPROC->p_pid;
+       lk->lkt_spl = s;
+       lk->lkt_held = CURPROC_PID;
        lockcnt++;
 }
 
-static void
+static int
 free_lock_interlocked(lk)
        struct lockit *lk;
 {
-
        if (lk->lkt_held == -1)
                panic("softdep_unlock_interlocked: lock not held");
        lk->lkt_held = -1;
+       return lk->lkt_spl;
 }
 #endif /* DEBUG */
 
@@ -311,18 +323,19 @@
        struct sema *semap;
        struct lockit *interlock;
 {
-
+       int s;
+       
        if (semap->value++ > 0) {
                if (interlock != NULL)
-                       FREE_LOCK_INTERLOCKED(interlock);
+                       s = FREE_LOCK_INTERLOCKED(interlock);
                tsleep((caddr_t)semap, semap->prio, semap->name, semap->timo);
                if (interlock != NULL) {
-                       ACQUIRE_LOCK_INTERLOCKED(interlock);
+                       ACQUIRE_LOCK_INTERLOCKED(interlock, s);
                        FREE_LOCK(interlock);
                }
                return (0);
        }
-       semap->holder = CURPROC->p_pid;
+       semap->holder = CURPROC_PID;
        if (interlock != NULL)
                FREE_LOCK(interlock);
        return (1);
@@ -333,7 +346,7 @@
        struct sema *semap;
 {
 
-       if (semap->value <= 0 || semap->holder != CURPROC->p_pid)
+       if (semap->value <= 0 || semap->holder != CURPROC_PID)
                panic("sema_release: not held");
        if (--semap->value > 0) {
                semap->value = 0;
@@ -478,7 +491,7 @@
  * ordering ensures that no new <vfsid, inum, lbn> triples will be generated
  * until all the old ones have been purged from the dependency lists.
  */
-int 
+static int 
 softdep_process_worklist(matchmnt)
        struct mount *matchmnt;
 {
@@ -486,7 +499,6 @@
        struct worklist *wk;
        struct fs *matchfs;
        int matchcnt;
-
        /*
         * Record the process identifier of our caller so that we can give
         * this process preferential treatment in request_cleanup below.
@@ -578,6 +590,31 @@
 }
 
 /*
+ * Move dependencies from one buffer to another.
+ */
+static void
+softdep_move_dependencies(oldbp, newbp)
+       struct buf *oldbp;
+       struct buf *newbp;
+{
+       struct worklist *wk, *wktail;
+
+       if (LIST_FIRST(&newbp->b_dep) != NULL)
+               panic("softdep_move_dependencies: need merge code");
+       wktail = 0;
+       ACQUIRE_LOCK(&lk);
+       while ((wk = LIST_FIRST(&oldbp->b_dep)) != NULL) {
+               LIST_REMOVE(wk, wk_list);
+               if (wktail == 0)
+                       LIST_INSERT_HEAD(&newbp->b_dep, wk, wk_list);
+               else
+                       LIST_INSERT_AFTER(wktail, wk, wk_list);
+               wktail = wk;
+       }
+       FREE_LOCK(&lk);
+}
+
+/*
  * Purge the work list of all items associated with a particular mount point.
  */
 int
@@ -606,8 +643,9 @@
         * but we give it a few extra just to be sure.
         */
        devvp = VFSTOUFS(oldmnt)->um_devvp;
-       for (loopcnt = 10; loopcnt > 0; loopcnt--) {
+       for (loopcnt = 10; loopcnt > 0; ) {
                if (softdep_process_worklist(oldmnt) == 0) {
+                       loopcnt--;
                        /*
                         * Do another flush in case any vnodes were brought in
                         * as part of the cleanup operations.
@@ -1492,6 +1530,7 @@
                }
                newindirdep->ir_savebp =
                    getblk(ip->i_devvp, bp->b_blkno, bp->b_bcount, 0, 0);
+               newindirdep->ir_savebp->b_flags |= B_ASYNC;
                bcopy(bp->b_data, newindirdep->ir_savebp->b_data, bp->b_bcount);
        }
 }
@@ -1525,7 +1564,6 @@
  * later release and zero the inode so that the calling routine
  * can release it.
  */
-static long num_freeblks;      /* number of freeblks allocated */
 void
 softdep_setup_freeblocks(ip, length)
        struct inode *ip;       /* The inode whose length is to be reduced */
@@ -1542,12 +1580,6 @@
 
        if (length != 0)
                panic("softdep_setup_freeblocks: non-zero length");
-       /*
-        * If we are over our limit, try to improve the situation.
-        */
-       if (num_freeblks > max_softdeps / 2 && speedup_syncer() == 0)
-               (void) request_cleanup(FLUSH_REMOVE, 0);
-       num_freeblks += 1;
        MALLOC(freeblks, struct freeblks *, sizeof(struct freeblks),
                M_FREEBLKS, M_WAITOK);
        bzero(freeblks, sizeof(struct freeblks));
@@ -1592,11 +1624,6 @@
        if ((inodedep->id_state & IOSTARTED) != 0)
                panic("softdep_setup_freeblocks: inode busy");
        /*
-        * Add the freeblks structure to the list of operations that
-        * must await the zero'ed inode being written to disk.
-        */
-       WORKLIST_INSERT(&inodedep->id_bufwait, &freeblks->fb_list);
-       /*
         * Because the file length has been truncated to zero, any
         * pending block allocation dependency structures associated
         * with this inode are obsolete and can simply be de-allocated.
@@ -1627,11 +1654,22 @@
                ACQUIRE_LOCK(&lk);
        }
        /*
-        * Try freeing the inodedep in case that was the last dependency.
+        * Add the freeblks structure to the list of operations that
+        * must await the zero'ed inode being written to disk. If we
+        * still have a bitmap dependency, then the inode has never been
+        * written to disk, so we can process the freeblks immediately.
+        * If the inodedep does not exist, then the zero'ed inode has
+        * been written and we can also proceed.
         */
-       if ((inodedep_lookup(fs, ip->i_number, 0, &inodedep)) != 0)
-               (void) free_inodedep(inodedep);
-       FREE_LOCK(&lk);
+       if (inodedep_lookup(fs, ip->i_number, 0, &inodedep) == 0 ||
+           free_inodedep(inodedep) ||
+           (inodedep->id_state & DEPCOMPLETE) == 0) {
+               FREE_LOCK(&lk);



Home | Main Index | Thread Index | Old Index