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