1 /* $NetBSD: pass5.c,v 1.23 2007/10/08 21:39:49 ad Exp $ */
4 * Copyright (c) 2000, 2003 The NetBSD Foundation, Inc.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Konrad E. Schroder <perseant@hhhh.org>.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
32 #include <sys/types.h>
33 #include <sys/param.h>
36 #include <sys/mount.h>
38 #include <ufs/ufs/ufsmount.h>
39 #include <ufs/ufs/inode.h>
40 #include <ufs/ufs/dir.h>
42 #include <ufs/lfs/lfs.h>
55 extern SEGUSE
*seg_table
;
56 extern off_t locked_queue_bytes
;
64 unsigned long bb
; /* total number of used blocks (lower bound) */
65 unsigned long ubb
; /* upper bound number of used blocks */
66 unsigned long avail
; /* blocks available for writing */
67 unsigned long dmeta
; /* blocks in segsums and inodes */
68 int nclean
; /* clean segments */
73 * Check segment holdings against actual holdings. Check for
74 * "clean" segments that contain live data. If we are only
75 * rolling forward, we can't check the segment holdings, but
76 * we can still check the cleanerinfo data.
82 for (i
= 0; i
< fs
->lfs_nseg
; i
++) {
84 LFS_SEGENTRY(su
, fs
, i
, bp
);
85 if (!preen
&& !(su
->su_flags
& SEGUSE_DIRTY
) &&
86 seg_table
[i
].su_nbytes
> 0) {
87 pwarn("CLEAN SEGMENT %d CONTAINS %d BYTES\n",
88 i
, seg_table
[i
].su_nbytes
);
89 if (reply("MARK SEGMENT DIRTY")) {
90 su
->su_flags
|= SEGUSE_DIRTY
;
94 if (!preen
&& su
->su_nbytes
!= seg_table
[i
].su_nbytes
) {
95 pwarn("SEGMENT %d CLAIMS %d BYTES BUT HAS %d",
96 i
, su
->su_nbytes
, seg_table
[i
].su_nbytes
);
97 if ((int32_t)su
->su_nbytes
>
98 (int32_t)seg_table
[i
].su_nbytes
)
99 pwarn(" (HIGH BY %d)\n", su
->su_nbytes
-
100 seg_table
[i
].su_nbytes
);
102 pwarn(" (LOW BY %d)\n", -su
->su_nbytes
+
103 seg_table
[i
].su_nbytes
);
105 su
->su_nbytes
= seg_table
[i
].su_nbytes
;
109 if (su
->su_flags
& SEGUSE_DIRTY
) {
110 bb
+= btofsb(fs
, su
->su_nbytes
+
111 su
->su_nsums
* fs
->lfs_sumsize
);
112 ubb
+= btofsb(fs
, su
->su_nbytes
+
113 su
->su_nsums
* fs
->lfs_sumsize
+
114 su
->su_ninos
* fs
->lfs_ibsize
);
116 fs
->lfs_sumsize
* su
->su_nsums
);
118 fs
->lfs_ibsize
* su
->su_ninos
);
121 avail
+= segtod(fs
, 1);
122 if (su
->su_flags
& SEGUSE_SUPERBLOCK
)
123 avail
-= btofsb(fs
, LFS_SBPAD
);
124 if (i
== 0 && fs
->lfs_version
> 1 &&
125 fs
->lfs_start
< btofsb(fs
, LFS_LABELPAD
))
126 avail
-= btofsb(fs
, LFS_LABELPAD
) -
135 /* Also may be available bytes in current seg */
136 i
= dtosn(fs
, fs
->lfs_offset
);
137 avail
+= sntod(fs
, i
+ 1) - fs
->lfs_offset
;
138 /* But do not count minfreesegs */
139 avail
-= segtod(fs
, (fs
->lfs_minfreeseg
-
140 (fs
->lfs_minfreeseg
/ 2)));
141 /* Note we may have bytes to write yet */
142 avail
-= btofsb(fs
, locked_queue_bytes
);
145 pwarn("NOTE: when using -i, expect discrepancies in dmeta,"
146 " avail, nclean, bfree\n");
147 if (dmeta
!= fs
->lfs_dmeta
) {
148 pwarn("DMETA GIVEN AS %d, SHOULD BE %ld\n", fs
->lfs_dmeta
,
150 if (preen
|| reply("FIX")) {
151 fs
->lfs_dmeta
= dmeta
;
155 if (avail
!= fs
->lfs_avail
) {
156 pwarn("AVAIL GIVEN AS %d, SHOULD BE %ld\n", fs
->lfs_avail
,
158 if (preen
|| reply("FIX")) {
159 fs
->lfs_avail
= avail
;
163 if (nclean
!= fs
->lfs_nclean
) {
164 pwarn("NCLEAN GIVEN AS %d, SHOULD BE %d\n", fs
->lfs_nclean
,
166 if (preen
|| reply("FIX")) {
167 fs
->lfs_nclean
= nclean
;
173 if (fs
->lfs_version
> 1 &&
174 fs
->lfs_start
< btofsb(fs
, LFS_LABELPAD
))
175 labelskew
= btofsb(fs
, LFS_LABELPAD
);
176 if (fs
->lfs_bfree
> fs
->lfs_dsize
- bb
- labelskew
||
177 fs
->lfs_bfree
< fs
->lfs_dsize
- ubb
- labelskew
) {
178 pwarn("BFREE GIVEN AS %d, SHOULD BE BETWEEN %ld AND %ld\n",
179 fs
->lfs_bfree
, (fs
->lfs_dsize
- ubb
- labelskew
),
180 fs
->lfs_dsize
- bb
- labelskew
);
181 if (preen
|| reply("FIX")) {
183 ((fs
->lfs_dsize
- labelskew
- ubb
) +
184 fs
->lfs_dsize
- labelskew
- bb
) / 2;