Source-Changes-HG archive

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

[src/trunk]: src/sys/ufs/lfs Make changes that will allow an LFS filesystem t...



details:   https://anonhg.NetBSD.org/src/rev/246a5bf2b345
branches:  trunk
changeset: 476029:246a5bf2b345
user:      perseant <perseant%NetBSD.org@localhost>
date:      Fri Sep 03 22:48:51 1999 +0000

description:
Make changes that will allow an LFS filesystem to be used as the root
filesystem.  In particular,

- Fix mknod deadlock, described in PR 8172.
- Enable lfs_mountroot.
- Make lfs_writevnodes treat filesystems mounted on lfs device nodes properly,
  by flushing that device rather than trying to add blocks to the device inode.

This, in combination with lfs boot blocks, will allow operation of an all-lfs
system.

diffstat:

 sys/ufs/lfs/lfs_alloc.c   |  11 ++++--
 sys/ufs/lfs/lfs_inode.c   |   4 +-
 sys/ufs/lfs/lfs_segment.c |  82 +++++++++++++++++++++++++++++++++++++++++-----
 sys/ufs/lfs/lfs_vfsops.c  |   4 +-
 sys/ufs/lfs/lfs_vnops.c   |  60 +++++++++++++++++++++++++++++----
 5 files changed, 136 insertions(+), 25 deletions(-)

diffs (286 lines):

diff -r 4414a98927ec -r 246a5bf2b345 sys/ufs/lfs/lfs_alloc.c
--- a/sys/ufs/lfs/lfs_alloc.c   Fri Sep 03 22:07:05 1999 +0000
+++ b/sys/ufs/lfs/lfs_alloc.c   Fri Sep 03 22:48:51 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_alloc.c,v 1.24 1999/07/08 01:06:05 wrstuden Exp $  */
+/*     $NetBSD: lfs_alloc.c,v 1.25 1999/09/03 22:48:51 perseant Exp $  */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -150,7 +150,12 @@
        if (ifp->if_daddr != LFS_UNUSED_DADDR)
                panic("lfs_ialloc: inuse inode %d on the free list", new_ino);
        fs->lfs_free = ifp->if_nextfree;
+#ifdef LFS_DEBUG_NEXTFREE
+       ifp->if_nextfree = 0;
+       VOP_BWRITE(bp);
+#else
        brelse(bp);
+#endif
        
        /* Extend IFILE so that the next lfs_valloc will succeed. */
        if (fs->lfs_free == LFS_UNUSED_INUM) {
@@ -318,13 +323,11 @@
        
        if (ip->i_flag & IN_CLEANING) {
                --fs->lfs_uinodes;
-               ip->i_flag &= ~IN_CLEANING;
        }
        if (ip->i_flag & IN_MODIFIED) {
                --fs->lfs_uinodes;
-               ip->i_flag &=
-                       ~(IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE);
        }
+       ip->i_flag &= ~(IN_CLEANING | IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE);
 #ifdef DEBUG_LFS       
        if((int32_t)fs->lfs_uinodes<0) {
                printf("U1");
diff -r 4414a98927ec -r 246a5bf2b345 sys/ufs/lfs/lfs_inode.c
--- a/sys/ufs/lfs/lfs_inode.c   Fri Sep 03 22:07:05 1999 +0000
+++ b/sys/ufs/lfs/lfs_inode.c   Fri Sep 03 22:48:51 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_inode.c,v 1.26 1999/06/15 22:25:41 perseant Exp $  */
+/*     $NetBSD: lfs_inode.c,v 1.27 1999/09/03 22:48:51 perseant Exp $  */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -168,7 +168,7 @@
                        printf("lfs_update: sleeping on inode %d (dirops)\n",ip->i_number);
 #endif
                        if(fs->lfs_dirops==0)
-                               lfs_flush_fs(vp->v_mount,0);
+                               lfs_flush_fs(vp->v_mount,SEGM_SYNC);
                        else
                                tsleep(&fs->lfs_writer, PRIBIO+1, "lfs_fsync", 0);
                        /* XXX KS - by falling out here, are we writing the vn
diff -r 4414a98927ec -r 246a5bf2b345 sys/ufs/lfs/lfs_segment.c
--- a/sys/ufs/lfs/lfs_segment.c Fri Sep 03 22:07:05 1999 +0000
+++ b/sys/ufs/lfs/lfs_segment.c Fri Sep 03 22:48:51 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_segment.c,v 1.29 1999/07/08 01:06:06 wrstuden Exp $        */
+/*     $NetBSD: lfs_segment.c,v 1.30 1999/09/03 22:48:51 perseant Exp $        */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -72,6 +72,7 @@
 
 #define ivndebug(vp,str) printf("ino %d: %s\n",VTOI(vp)->i_number,(str))
 
+#include "opt_ddb.h"
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/namei.h>
@@ -186,7 +187,8 @@
        struct inode *ip;
        struct lfs *fs;
        struct segment *sp;
-       int error;
+       struct buf *bp, *nbp;
+       int error, s;
 
        ip = VTOI(vp);
        fs = VFSTOUFS(vp->v_mount)->um_lfs;
@@ -212,6 +214,40 @@
 
        /* Protect against VXLOCK deadlock in vinvalbuf() */
        lfs_seglock(fs, SEGM_SYNC);
+
+       /* If we're supposed to flush a freed inode, just toss it */
+       /* XXX - seglock, so these buffers can't be gathered, right? */
+       if(ip->i_ffs_mode == 0) {
+               printf("lfs_vflush: ino %d is freed, not flushing\n",
+                       ip->i_number);
+               s = splbio();
+               for(bp=vp->v_dirtyblkhd.lh_first; bp; bp=nbp) {
+                       nbp = bp->b_vnbufs.le_next;
+                       /* Copied from lfs_writeseg */
+                       if (bp->b_flags & B_CALL) {
+                               /* if B_CALL, it was created with newbuf */
+                               lfs_freebuf(bp);
+                       } else {
+                               bremfree(bp);
+                               bp->b_flags &= ~(B_ERROR | B_READ | B_DELWRI |
+                                         B_LOCKED | B_GATHERED);
+                               bp->b_flags |= B_DONE;
+                               reassignbuf(bp, vp);
+                               brelse(bp);  
+                       }
+               }
+               splx(s);
+               if(ip->i_flag & IN_CLEANING)
+                       fs->lfs_uinodes--;
+               if(ip->i_flag & IN_MODIFIED)
+                       fs->lfs_uinodes--;
+               ip->i_flag &= ~(IN_MODIFIED|IN_UPDATE|IN_ACCESS|IN_CHANGE|IN_CLEANING);
+               printf("lfs_vflush: done not flushing ino %d\n",
+                       ip->i_number);
+               lfs_segunlock(fs);
+               return 0;
+       }
+
        SET_FLUSHING(fs,vp);
        if (fs->lfs_nactive > LFS_MAX_ACTIVE) {
                error = lfs_segwrite(vp->v_mount, SEGM_SYNC|SEGM_CKP);
@@ -721,6 +757,13 @@
                LFS_IENTRY(ifp, fs, ino, ibp);
                daddr = ifp->if_daddr;
                ifp->if_daddr = bp->b_blkno;
+#ifdef LFS_DEBUG_NEXTFREE
+               if(ino > 3 && ifp->if_nextfree) {
+                       vprint("lfs_writeinode",ITOV(ip));
+                       printf("lfs_writeinode: updating free ino %d\n",
+                               ip->i_number);
+               }
+#endif
                error = VOP_BWRITE(ibp);
        }
        
@@ -831,18 +874,39 @@
 #endif /* LFS_NO_BACKBUF_HACK */
                if ((bp->b_flags & (B_BUSY|B_GATHERED)) || !match(fs, bp))
                        continue;
+               if(vp->v_type == VBLK) {
+                       /* For block devices, just write the blocks. */
+                       /* XXX Do we really need to even do this? */
+#ifdef DEBUG_LFS
+                       if(count==0)
+                               printf("BLK(");
+                       printf(".");
+#endif
+                       /* Get the block before bwrite, so we don't corrupt the free list */
+                       bp->b_flags |= B_BUSY;
+                       bremfree(bp);
+                       bwrite(bp);
+               } else {
 #ifdef DIAGNOSTIC
-               if (!(bp->b_flags & B_DELWRI))
-                       panic("lfs_gather: bp not B_DELWRI");
-               if (!(bp->b_flags & B_LOCKED))
-                       panic("lfs_gather: bp not B_LOCKED");
+                       if (!(bp->b_flags & B_DELWRI))
+                               panic("lfs_gather: bp not B_DELWRI");
+                       if (!(bp->b_flags & B_LOCKED)) {
+                               printf("lfs_gather: lbn %d blk %d not B_LOCKED\n", bp->b_lblkno, bp->b_blkno);
+                               VOP_PRINT(bp->b_vp);
+                               panic("lfs_gather: bp not B_LOCKED");
+                       }
 #endif
+                       if (lfs_gatherblock(sp, bp, &s)) {
+                               goto loop;
+                       }
+               }
                count++;
-               if (lfs_gatherblock(sp, bp, &s)) {
-                       goto loop;
-               }
        }
        splx(s);
+#ifdef DEBUG_LFS
+       if(vp->v_type == VBLK && count)
+               printf(")\n");
+#endif
        lfs_updatemeta(sp);
        sp->vp = NULL;
        return count;
diff -r 4414a98927ec -r 246a5bf2b345 sys/ufs/lfs/lfs_vfsops.c
--- a/sys/ufs/lfs/lfs_vfsops.c  Fri Sep 03 22:07:05 1999 +0000
+++ b/sys/ufs/lfs/lfs_vfsops.c  Fri Sep 03 22:48:51 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_vfsops.c,v 1.35 1999/07/17 01:08:30 wrstuden Exp $ */
+/*     $NetBSD: lfs_vfsops.c,v 1.36 1999/09/03 22:48:51 perseant Exp $ */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -130,7 +130,7 @@
        lfs_vptofh,
        lfs_init,
        lfs_sysctl,
-       NULL,
+       lfs_mountroot,
        ufs_check_export,
        lfs_vnodeopv_descs,
 };
diff -r 4414a98927ec -r 246a5bf2b345 sys/ufs/lfs/lfs_vnops.c
--- a/sys/ufs/lfs/lfs_vnops.c   Fri Sep 03 22:07:05 1999 +0000
+++ b/sys/ufs/lfs/lfs_vnops.c   Fri Sep 03 22:48:51 1999 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: lfs_vnops.c,v 1.27 1999/08/03 20:19:22 wrstuden Exp $  */
+/*     $NetBSD: lfs_vnops.c,v 1.28 1999/09/03 22:48:51 perseant Exp $  */
 
 /*-
  * Copyright (c) 1999 The NetBSD Foundation, Inc.
@@ -199,7 +199,7 @@
        { &vop_vfree_desc, lfs_vfree },                 /* vfree */
        { &vop_truncate_desc, spec_truncate },          /* truncate */
        { &vop_update_desc, lfs_update },               /* update */
-       { &vop_bwrite_desc, lfs_bwrite },               /* bwrite */
+       { &vop_bwrite_desc, vn_bwrite },                /* bwrite */
        { (struct vnodeop_desc*)NULL, (int(*) __P((void *)))NULL }
 };
 struct vnodeopv_desc lfs_specop_opv_desc =
@@ -374,15 +374,59 @@
                struct componentname *a_cnp;
                struct vattr *a_vap;
                } */ *ap = v;
-       int ret;
+        struct vattr *vap = ap->a_vap;
+        struct vnode **vpp = ap->a_vpp;
+        struct inode *ip;
+        int error;
 
-       if((ret=SET_DIROP(VTOI(ap->a_dvp)->i_lfs))!=0)
-               return ret;
+       if((error=SET_DIROP(VTOI(ap->a_dvp)->i_lfs))!=0)
+               return error;
        MARK_VNODE(ap->a_dvp);
-       ret = ufs_mknod(ap);
-       MAYBE_INACTIVE(VTOI(ap->a_dvp)->i_lfs,*(ap->a_vpp)); /* XXX KS */
+       error = ufs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode),
+            ap->a_dvp, vpp, ap->a_cnp);
+
+       /* Either way we're done with the dirop at this point */
        SET_ENDOP(VTOI(ap->a_dvp)->i_lfs,ap->a_dvp,"mknod");
-       return (ret);
+
+        if (error)
+               return (error);
+
+        ip = VTOI(*vpp);
+        ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
+        if (vap->va_rdev != VNOVAL) {
+                /*
+                 * Want to be able to use this to make badblock
+                 * inodes, so don't truncate the dev number.
+                 */
+#if 0
+                ip->i_ffs_rdev = ufs_rw32(vap->va_rdev,
+                    UFS_MPNEEDSWAP((*vpp)->v_mount));
+#else
+                ip->i_ffs_rdev = vap->va_rdev;
+#endif
+        }
+       /*
+        * Call fsync to write the vnode so that we don't have to deal with
+        * flushing it when it's marked VDIROP|VXLOCK.
+        *
+        * XXX KS - If we can't flush we also can't call vgone(), so must
+        * return.  But, that leaves this vnode in limbo, also not good.
+        * Can this ever happen (barring hardware failure)?
+        */
+       if ((error = VOP_FSYNC(*vpp, NOCRED, FSYNC_WAIT, curproc)) != 0)
+               return (error);
+        /*
+         * Remove inode so that it will be reloaded by VFS_VGET and
+         * checked to see if it is an alias of an existing entry in
+         * the inode cache.
+         */
+       /* Used to be vput, but that causes us to call VOP_INACTIVE twice. */
+       VOP_UNLOCK(*vpp,0);
+       lfs_vunref(*vpp);
+        (*vpp)->v_type = VNON;
+        vgone(*vpp);
+        *vpp = 0;
+        return (0);
 }
 
 int



Home | Main Index | Thread Index | Old Index