Source-Changes-HG archive

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

[src/netbsd-1-5]: src/sys/ufs Pull up recent LFS kernel changes (approved by ...



details:   https://anonhg.NetBSD.org/src/rev/45141c0d4f2b
branches:  netbsd-1-5
changeset: 489464:45141c0d4f2b
user:      perseant <perseant%NetBSD.org@localhost>
date:      Thu Sep 14 18:50:15 2000 +0000

description:
Pull up recent LFS kernel changes (approved by thorpej):

ufs/ufs/inode.h, 1.20--1.22      (add i_lfs_effnblks extension ;
                                 make ITIMES aware of LFS_ITIMES;
                                 _LKM protection so userland progs
                                 compile)
ufs/ufs/ufs_vnops.c, 1.69, 1.71  (remove IN_ADIROP;
                                 use ITIMES instead of FFS_ITIMES)
ufs/ufs/ufs_readwrite.c, 1.27    (use lfs_reserve in lfs_write)
ufs/lfs/lfs.h, 1.26--1.32        (define LFS_EST_* macros ;
                                 change MIN_FREE_SEGS to lfs_minfreesegs ;
                                 add avail and bfree to CLEANERINFO ;
                                 change lfs_uinodes to signed ;
                                 change lfs_dmeta to signed ;
                                 add whitespace to line up structure
                                 members ;
                                 explicit cast to int32_t in LFS_EST_*
                                 macros)
ufs/lfs/lfs_alloc.c, back out 1.34.2.3 (pullups of 1.39, 1.40);
then pull up         1.38        (clean up on error)
                     1.39--1.43  (restore fvdl's ufs_hashlock fix ;
                                 restore fvdl's ufs_hashlock fix ;
                                 set i_lfs_effnblks ;
                                 use UINO macros ;
                                 add comments and fix long lines)
ufs/lfs/lfs_balloc.c, 1.19       (don't succeed halfway)
                      1.21--1.25 (use i_lfs_effnblks ;
                                 fix i_lfs_effnblks computation and
                                 quieten ;
                                 fix i_ffs_blocks in unwritten fragment ;
                                 remove useless debugging check ;
                                 add comments and (c) 2000)
ufs/lfs/lfs_bio.c, 1.24--1.30    (cleanup and make lfs_flush_fs take
                                   "struct lfs *" instead of "struct
                                 mount *" ;
                                 use lfs_minfreeseg instead of
                                 MIN_FREE_SEGS ;
                                 use UINO macros, and copy bfree/avail
                                   to CLEANERINFO ;
                                 add lfs_reserve function ;
                                 1.28--1.30 fix printf formatting)
ufs/lfs/lfs_cksum.c, 1.13        (add (c) 2000)
ufs/lfs/lfs_debug.c, 1.11        (use btodb instead of DEV_BSIZE)
ufs/lfs/lfs_extern.h, 1.18, 1.20--1.21 (function prototype changes)
ufs/lfs/lfs_inode.c, 1.38        (rewrite lfs_truncate from
                                 ffs_truncate)
                     1.40--1.44  (count written and unwritten blocks
                                   seperately ;
                                 use disk block units instead of bytes ;
                                 remove unnecessary "mod" variable ;
                                 correct B_DELWRI to avoid bawrite panic ;
                                 use lfs_reserve)
ufs/lfs/lfs_segment.c, 1.52-1.59 (use lfs_dmeta to note used summaries ;
                                 check for UNWRITTEN in indirect blocks ;
                                 more debugging stuff inside #ifdef
                                 DEBUG_LFS ;
                                 use LK_CANRECURSE ;
                                 don't drop dirty indirect blocks ;
                                 use UINO macros ;
                                 don't hose the free list ;
                                 use btodb() instead of DEV_BSIZE ;
                                 make it compile again (oops))
ufs/lfs/lfs_subr.c, 1.16--1.17   (check for locked inodes before
                                 changing ;
                                 use btodb() instead of DEV_BSIZE, (c)
                                 2000)
ufs/lfs/lfs_syscalls.c, back out 1.41.4.2 (fvdl's ufs_hashlock fix);
then pull up          1.43       (use lfs_dmeta)
                      1.44--1.45 (restore fvdl's ufs_hashlock fix)
                      1.46--1.47 (fix lfs_avail leakage from sblock
                                 segments ;
                                 use UINO macros)
                      1.49       (bounds-check inode numbers in
                                 lfs_markv)
ufs/lfs/lfs_vfsops.c, 1.53       (use LFS_EST_* macros in lfs_statfs)
                      1.56--1.58 (initialize lfs_minfreeseg, lfs_effnblk ;
                                 initialize lfs_uinodes ;
                                 initialize lfs_ravail)
ufs/lfs/lfs_vnops.c, 1.40        (remove VDIROP from removed files)
                     1.42--1.44  (move SET_ENDOP below the removal of
                                 VDIROP ;
                                 use UINO macros and add lfs_itimes
                                 function ;
                                 use lfs_reserve in dirops)

diffstat:

 sys/ufs/lfs/lfs.h           |  107 ++++-
 sys/ufs/lfs/lfs_alloc.c     |   81 ++-
 sys/ufs/lfs/lfs_balloc.c    |  240 ++++++------
 sys/ufs/lfs/lfs_bio.c       |  173 ++++++--
 sys/ufs/lfs/lfs_cksum.c     |    4 +-
 sys/ufs/lfs/lfs_debug.c     |    6 +-
 sys/ufs/lfs/lfs_extern.h    |   15 +-
 sys/ufs/lfs/lfs_inode.c     |  830 +++++++++++++++++++++++++------------------
 sys/ufs/lfs/lfs_segment.c   |  485 ++++++++++++++-----------
 sys/ufs/lfs/lfs_subr.c      |   16 +-
 sys/ufs/lfs/lfs_syscalls.c  |   97 ++--
 sys/ufs/lfs/lfs_vfsops.c    |   45 +-
 sys/ufs/lfs/lfs_vnops.c     |  159 ++++++--
 sys/ufs/ufs/inode.h         |   29 +-
 sys/ufs/ufs/ufs_readwrite.c |    6 +-
 sys/ufs/ufs/ufs_vnops.c     |   14 +-
 16 files changed, 1396 insertions(+), 911 deletions(-)

diffs (truncated from 3867 to 300 lines):

diff -r 21c7001d3640 -r 45141c0d4f2b sys/ufs/lfs/lfs.h
--- a/sys/ufs/lfs/lfs.h Thu Sep 14 16:20:01 2000 +0000
+++ b/sys/ufs/lfs/lfs.h Thu Sep 14 18:50:15 2000 +0000
@@ -1,7 +1,7 @@
-/*     $NetBSD: lfs.h,v 1.25 2000/06/06 20:19:14 perseant Exp $        */
+/*     $NetBSD: lfs.h,v 1.25.2.1 2000/09/14 18:50:17 perseant Exp $    */
 
 /*-
- * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -85,28 +85,70 @@
  * Parameters and generic definitions
  */
 #define BW_CLEAN       1
-#define MIN_FREE_SEGS  4
+#define MIN_FREE_SEGS  2
 #define LFS_MAX_ACTIVE 10
 #define LFS_MAXDIROP   (desiredvnodes>>2)
 
 /* For convenience */
 #define IN_ALLMOD (IN_MODIFIED|IN_ACCESS|IN_CHANGE|IN_UPDATE|IN_ACCESSED|IN_CLEANING)
+#define LFS_SET_UINO(ip, flags) do {                                    \
+        if (((flags) & IN_ACCESSED) && !((ip)->i_flag & IN_ACCESSED))   \
+                ++(ip)->i_lfs->lfs_uinodes;                             \
+        if (((flags) & IN_CLEANING) && !((ip)->i_flag & IN_CLEANING))   \
+                ++(ip)->i_lfs->lfs_uinodes;                             \
+        if (((flags) & IN_MODIFIED) && !((ip)->i_flag & IN_MODIFIED))   \
+                ++(ip)->i_lfs->lfs_uinodes;                             \
+        (ip)->i_flag |= (flags);                                        \
+} while(0)
+
+#define LFS_CLR_UINO(ip, flags) do {                                    \
+        if (((flags) & IN_ACCESSED) && ((ip)->i_flag & IN_ACCESSED))    \
+                --(ip)->i_lfs->lfs_uinodes;                             \
+        if (((flags) & IN_CLEANING) && ((ip)->i_flag & IN_CLEANING))    \
+                --(ip)->i_lfs->lfs_uinodes;                             \
+        if (((flags) & IN_MODIFIED) && ((ip)->i_flag & IN_MODIFIED))    \
+                --(ip)->i_lfs->lfs_uinodes;                             \
+        (ip)->i_flag &= ~(flags);                                       \
+       if ((ip)->i_lfs->lfs_uinodes < 0) {                             \
+               panic("lfs_uinodes < 0");                               \
+       }                                                               \
+} while(0)
+
 
 #ifndef LFS_ATIME_IFILE
-# define LFS_ITIMES(ip, acc, mod, cre) FFS_ITIMES((ip),(acc),(mod),(cre))
+#define        LFS_ITIMES(ip, acc, mod, cre) {                                 \
+       if ((ip)->i_flag & IN_ACCESS) {                                 \
+               (ip)->i_ffs_atime = (acc)->tv_sec;                      \
+               (ip)->i_ffs_atimensec = (acc)->tv_nsec;                 \
+               LFS_SET_UINO(ip, IN_ACCESSED);                          \
+       }                                                               \
+       if ((ip)->i_flag & (IN_CHANGE | IN_UPDATE)) {                   \
+               if ((ip)->i_flag & IN_UPDATE) {                         \
+                       (ip)->i_ffs_mtime = (mod)->tv_sec;              \
+                       (ip)->i_ffs_mtimensec = (mod)->tv_nsec;         \
+                       (ip)->i_modrev++;                               \
+               }                                                       \
+               if ((ip)->i_flag & IN_CHANGE) {                         \
+                       (ip)->i_ffs_ctime = (cre)->tv_sec;              \
+                       (ip)->i_ffs_ctimensec = (cre)->tv_nsec;         \
+               }                                                       \
+               LFS_SET_UINO(ip, IN_MODIFIED);                          \
+       }                                                               \
+       (ip)->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE);           \
+}
 #else
 # define LFS_ITIMES(ip, acc, mod, cre) {                                \ 
        struct buf *ibp;                                                \
        IFILE *ifp;                                                     \
                                                                        \
         if ((ip)->i_flag & IN_ACCESS) {                                \
-       LFS_IENTRY(ifp, ip->i_lfs, ip->i_number, ibp);                  \
+               LFS_IENTRY(ifp, ip->i_lfs, ip->i_number, ibp);          \
                        ifp->if_atime = (mod);                                  \
                        VOP_BWRITE(bp);                                         \
                (ip)->i_flag &= ~IN_ACCESS;                             \
         }                                                              \
         if ((ip)->i_flag & (IN_CHANGE | IN_UPDATE)) {                  \
-                (ip)->i_flag |= IN_MODIFIED;                            \
+               LFS_SET_UINO(ip, IN_MODIFIED);                          \
                 if ((ip)->i_flag & IN_UPDATE) {                         \
                         (ip)->i_ffs_mtime = (mod)->tv_sec;             \
                         (ip)->i_ffs_mtimensec = (mod)->tv_nsec;         \
@@ -121,7 +163,7 @@
 }
 #endif
 
-#define WRITEINPROG(vp) (vp->v_dirtyblkhd.lh_first && !(VTOI(vp)->i_flag & (IN_MODIFIED|IN_CLEANING)))
+#define WRITEINPROG(vp) (vp->v_dirtyblkhd.lh_first && !(VTOI(vp)->i_flag & (IN_MODIFIED|IN_ACCESSED|IN_CLEANING)))
 
 /* Here begins the berkeley code */
 
@@ -139,6 +181,7 @@
 #define        SEGUSE_ACTIVE           0x01    /* segment is currently being written */
 #define        SEGUSE_DIRTY            0x02    /* segment has data in it */
 #define        SEGUSE_SUPERBLOCK       0x04    /* segment contains a superblock */
+#define SEGUSE_ERROR            0x08    /* cleaner: do not clean segment */
        u_int32_t su_flags;
 };
 
@@ -175,7 +218,7 @@
         u_int32_t dlfs_bfree;     /* 36: number of free disk blocks */
         u_int32_t dlfs_nfiles;    /* 40: number of allocated inodes */
         int32_t   dlfs_avail;     /* 44: blocks available for writing */
-        u_int32_t dlfs_uinodes;   /* 48: inodes in cache not yet on disk */
+        int32_t   dlfs_uinodes;   /* 48: inodes in cache not yet on disk */
         ufs_daddr_t  dlfs_idaddr; /* 52: inode file disk address */
         u_int32_t dlfs_ifile;     /* 56: inode file inode number */
         ufs_daddr_t  dlfs_lastseg; /* 60: address of last segment written */
@@ -220,9 +263,11 @@
        u_char    dlfs_fsmnt[MNAMELEN];  /* 232: name mounted on */
        /* XXX this is 2 bytes only to pad to a quad boundary */
        u_int16_t dlfs_clean;     /* 322: file system is clean flag */
-        int8_t    dlfs_pad[184];  /* 324: round to 512 bytes */
+       int32_t   dlfs_dmeta;     /* 324: total number of dirty summaries */
+       u_int32_t dlfs_minfreeseg; /* 328: segs reserved for cleaner */
+        int8_t    dlfs_pad[176];  /* 332: round to 512 bytes */
 /* Checksum -- last valid disk field. */
-        u_int32_t dlfs_cksum;     /* 328: checksum for superblock checking */
+        u_int32_t dlfs_cksum;     /* 508: checksum for superblock checking */
 };
 
 /* Maximum number of io's we can have pending at once */
@@ -279,6 +324,9 @@
 #define lfs_clean lfs_dlfs.dlfs_clean
 #define lfs_fsmnt lfs_dlfs.dlfs_fsmnt
 #define lfs_nclean lfs_dlfs.dlfs_nclean
+#define lfs_dmeta lfs_dlfs.dlfs_dmeta
+#define lfs_minfreeseg lfs_dlfs.dlfs_minfreeseg
+
 /* These fields are set at mount time and are meaningless on disk. */
        struct segment *lfs_sp;         /* current segment being written */
        struct vnode *lfs_ivnode;       /* vnode for the ifile */
@@ -306,6 +354,7 @@
        struct lock lfs_freelock;
        pid_t lfs_rfpid;                /* Process ID of roll-forward agent */
        int       lfs_nadirop;          /* number of active dirop nodes */
+       long      lfs_ravail;           /* blocks pre-reserved for writing */
 };
 
 /*
@@ -347,8 +396,10 @@
  * to pass information between the cleaner and the kernel.
  */
 typedef struct _cleanerinfo {
-       u_int32_t clean;                /* K: number of clean segments */
-       u_int32_t dirty;                /* K: number of dirty segments */
+       u_int32_t clean;                /* number of clean segments */
+       u_int32_t dirty;                /* number of dirty segments */
+       u_int32_t bfree;                /* disk blocks free */
+       int32_t   avail;                /* disk blocks available */
 } CLEANERINFO;
 
 #define        CLEANSIZE_SU(fs)                                                \
@@ -494,15 +545,35 @@
        u_int16_t seg_flags;            /* run-time flags for this segment */
 };
 
+/*
+ * Macros for determining free space on the disk, with the variable metadata
+ * of segment summaries and inode blocks taken into account.
+ */
+/* Estimate number of clean blocks not available for writing */
+#define LFS_EST_CMETA(F) (int32_t)((((F)->lfs_dmeta *                        \
+                                    (int64_t)(F)->lfs_nclean) /             \
+                                     ((F)->lfs_nseg - (F)->lfs_nclean)))
+
+/* Estimate total size of the disk not including metadata */
+#define LFS_EST_NONMETA(F) ((F)->lfs_dsize - (F)->lfs_dmeta - LFS_EST_CMETA(F))
+
+/* Estimate number of blocks actually available for writing */
+#define LFS_EST_BFREE(F) ((F)->lfs_bfree - LFS_EST_CMETA(F) - (F)->lfs_dmeta)
+
+/* Amount of non-meta space not available to mortal man */
+#define LFS_EST_RSVD(F) (int32_t)((LFS_EST_NONMETA(F) *                      \
+                                   (u_int64_t)(F)->lfs_minfree) /            \
+                                 100)
+
+/* Can credential C write BB blocks */
 #define ISSPACE(F, BB, C)                                              \
-       (((C)->cr_uid == 0 && (F)->lfs_bfree >= (BB)) ||                \
-       ((C)->cr_uid != 0 && IS_FREESPACE(F, BB)))
+       ((((C) == NOCRED || (C)->cr_uid == 0) &&                        \
+          LFS_EST_BFREE(F) >= (BB)) ||                                 \
+        ((C)->cr_uid != 0 && IS_FREESPACE(F, BB)))
 
+/* Can an ordinary user write BB blocks */
 #define IS_FREESPACE(F, BB)                                            \
-       ((F)->lfs_bfree > ((F)->lfs_dsize * (F)->lfs_minfree / 100 + (BB)))
-
-#define ISSPACE_XXX(F, BB)                                             \
-       ((F)->lfs_bfree >= (BB))
+          (LFS_EST_BFREE(F) >= (BB) + LFS_EST_RSVD(F))
 
 /* Statistics Counters */
 struct lfs_stats {
diff -r 21c7001d3640 -r 45141c0d4f2b sys/ufs/lfs/lfs_alloc.c
--- a/sys/ufs/lfs/lfs_alloc.c   Thu Sep 14 16:20:01 2000 +0000
+++ b/sys/ufs/lfs/lfs_alloc.c   Thu Sep 14 18:50:15 2000 +0000
@@ -1,7 +1,7 @@
-/*     $NetBSD: lfs_alloc.c,v 1.34.2.3 2000/07/03 18:33:55 fvdl Exp $  */
+/*     $NetBSD: lfs_alloc.c,v 1.34.2.4 2000/09/14 18:50:17 perseant Exp $      */
 
 /*-
- * Copyright (c) 1999 The NetBSD Foundation, Inc.
+ * Copyright (c) 1999, 2000 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -94,10 +94,12 @@
 #include <ufs/lfs/lfs.h>
 #include <ufs/lfs/lfs_extern.h>
 
+extern int lfs_dirvcount;
 extern struct lock ufs_hashlock;
 
 /* Allocate a new inode. */
 /* ARGSUSED */
+/* VOP_BWRITE 2i times */
 int
 lfs_valloc(v)
        void *v;
@@ -121,6 +123,9 @@
        extern int lfs_dirvcount;
 
        fs = VTOI(ap->a_pvp)->i_lfs;
+       if (fs->lfs_ronly)
+               return EROFS;
+       *ap->a_vpp = NULL;
        
        /*
         * Use lfs_seglock here, instead of fs->lfs_freelock, to ensure that
@@ -158,7 +163,7 @@
        new_gen = ifp->if_version; /* version was updated by vfree */
 #ifdef LFS_DEBUG_NEXTFREE
        ifp->if_nextfree = 0;
-       VOP_BWRITE(bp);
+       (void) VOP_BWRITE(bp); /* Ifile */
 #else
        brelse(bp);
 #endif
@@ -166,17 +171,21 @@
        /* Extend IFILE so that the next lfs_valloc will succeed. */
        if (fs->lfs_free == LFS_UNUSED_INUM) {
                vp = fs->lfs_ivnode;
-               VOP_LOCK(vp,LK_EXCLUSIVE);
+               (void)lfs_vref(vp);
+               vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
                ip = VTOI(vp);
                blkno = lblkno(fs, ip->i_ffs_size);
                if ((error = VOP_BALLOC(vp, ip->i_ffs_size, fs->lfs_bsize,
-                   NULL, 0, &bp)) != 0) {
+                                       ap->a_cred, 0, &bp)) != 0) {
+                       VOP_UNLOCK(vp, 0);
                        lfs_segunlock(fs);
+                       fs->lfs_free = new_ino;
                        return (error);
                }
                ip->i_ffs_size += fs->lfs_bsize;
                uvm_vnp_setsize(vp, ip->i_ffs_size);
                (void)uvm_vnp_uncache(vp);
+               VOP_UNLOCK(vp, 0);
 
                i = (blkno - fs->lfs_segtabsz - fs->lfs_cleansz) *
                        fs->lfs_ifpb;
@@ -193,11 +202,8 @@
                }
                ifp--;
                ifp->if_nextfree = LFS_UNUSED_INUM;
-               VOP_UNLOCK(vp,0);
-               if ((error = VOP_BWRITE(bp)) != 0) {
-                       lfs_segunlock(fs);
-                       return (error);
-               }
+               (void) VOP_BWRITE(bp); /* Ifile */
+               lfs_vunref(vp);
        }
 #ifdef DIAGNOSTIC
        if(fs->lfs_free == LFS_UNUSED_INUM)
@@ -208,7 +214,7 @@
 
        if ((error = getnewvnode(VT_LFS, ap->a_pvp->v_mount,
            lfs_vnodeop_p, &vp)) != 0)
-               return (error);
+               goto errout;
 
        lockmgr(&ufs_hashlock, LK_EXCLUSIVE, 0);
        /* Create an inode to associate with the vnode. */
@@ -229,26 +235,38 @@
        error = ufs_vinit(vp->v_mount, lfs_specop_p, lfs_fifoop_p, &vp);
        if (error) {
                vput(vp);
-               *ap->a_vpp = NULL;
-               return (error);
+               goto errout;



Home | Main Index | Thread Index | Old Index