|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
26: /*
27: * Copyright (c) 1982, 1986, 1988, 1993
28: * The Regents of the University of California. All rights reserved.
29: * (c) UNIX System Laboratories, Inc.
30: * All or some portions of this file are derived from material licensed
31: * to the University of California by American Telephone and Telegraph
32: * Co. or Unix System Laboratories, Inc. and are reproduced herein with
33: * the permission of UNIX System Laboratories, Inc.
34: *
35: * Redistribution and use in source and binary forms, with or without
36: * modification, are permitted provided that the following conditions
37: * are met:
38: * 1. Redistributions of source code must retain the above copyright
39: * notice, this list of conditions and the following disclaimer.
40: * 2. Redistributions in binary form must reproduce the above copyright
41: * notice, this list of conditions and the following disclaimer in the
42: * documentation and/or other materials provided with the distribution.
43: * 3. All advertising materials mentioning features or use of this software
44: * must display the following acknowledgement:
45: * This product includes software developed by the University of
46: * California, Berkeley and its contributors.
47: * 4. Neither the name of the University nor the names of its contributors
48: * may be used to endorse or promote products derived from this software
49: * without specific prior written permission.
50: *
51: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
52: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
53: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
54: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
55: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
56: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
57: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
58: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
59: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
60: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
61: * SUCH DAMAGE.
62: *
63: * @(#)ufs_disksubr.c 8.5 (Berkeley) 1/21/94
64: */
65:
66: #include <sys/param.h>
67: #include <sys/systm.h>
68: #include <sys/buf.h>
69: #include <sys/disklabel.h>
70: #include <sys/syslog.h>
71:
72: /*
73: * Seek sort for disks. We depend on the driver which calls us using b_resid
74: * as the current cylinder number.
75: *
76: * The argument ap structure holds a b_actf activity chain pointer on which we
77: * keep two queues, sorted in ascending cylinder order. The first queue holds
78: * those requests which are positioned after the current cylinder (in the first
79: * request); the second holds requests which came in after their cylinder number
80: * was passed. Thus we implement a one way scan, retracting after reaching the
81: * end of the drive to the first request on the second queue, at which time it
82: * becomes the first queue.
83: *
84: * A one-way scan is natural because of the way UNIX read-ahead blocks are
85: * allocated.
86: */
87:
88: /*
89: * For portability with historic industry practice, the
90: * cylinder number has to be maintained in the `b_resid'
91: * field.
92: */
93: #define b_cylinder b_resid
94:
95: void
96: disksort(ap, bp)
97: register struct buf *ap, *bp;
98: {
99: register struct buf *bq;
100:
101: /* If the queue is empty, then it's easy. */
102: if (ap->b_actf == NULL) {
103: bp->b_actf = NULL;
104: ap->b_actf = bp;
105: return;
106: }
107:
108: /*
109: * If we lie after the first (currently active) request, then we
110: * must locate the second request list and add ourselves to it.
111: */
112: bq = ap->b_actf;
113: if (bp->b_cylinder < bq->b_cylinder) {
114: while (bq->b_actf) {
115: /*
116: * Check for an ``inversion'' in the normally ascending
117: * cylinder numbers, indicating the start of the second
118: * request list.
119: */
120: if (bq->b_actf->b_cylinder < bq->b_cylinder) {
121: /*
122: * Search the second request list for the first
123: * request at a larger cylinder number. We go
124: * before that; if there is no such request, we
125: * go at end.
126: */
127: do {
128: if (bp->b_cylinder <
129: bq->b_actf->b_cylinder)
130: goto insert;
131: if (bp->b_cylinder ==
132: bq->b_actf->b_cylinder &&
133: bp->b_blkno < bq->b_actf->b_blkno)
134: goto insert;
135: bq = bq->b_actf;
136: } while (bq->b_actf);
137: goto insert; /* after last */
138: }
139: bq = bq->b_actf;
140: }
141: /*
142: * No inversions... we will go after the last, and
143: * be the first request in the second request list.
144: */
145: goto insert;
146: }
147: /*
148: * Request is at/after the current request...
149: * sort in the first request list.
150: */
151: while (bq->b_actf) {
152: /*
153: * We want to go after the current request if there is an
154: * inversion after it (i.e. it is the end of the first
155: * request list), or if the next request is a larger cylinder
156: * than our request.
157: */
158: if (bq->b_actf->b_cylinder < bq->b_cylinder ||
159: bp->b_cylinder < bq->b_actf->b_cylinder ||
160: (bp->b_cylinder == bq->b_actf->b_cylinder &&
161: bp->b_blkno < bq->b_actf->b_blkno))
162: goto insert;
163: bq = bq->b_actf;
164: }
165: /*
166: * Neither a second list nor a larger request... we go at the end of
167: * the first list, which is the same as the end of the whole schebang.
168: */
169: insert: bp->b_actf = bq->b_actf;
170: bq->b_actf = bp;
171: }
172:
173: /* encoding of disk minor numbers, should be elsewhere... */
174: #define dkunit(dev) (minor(dev) >> 3)
175: #define dkpart(dev) (minor(dev) & 07)
176: #define dkminor(unit, part) (((unit) << 3) | (part))
177:
178: /*
179: * Compute checksum for disk label.
180: */
181: u_int
182: dkcksum(lp)
183: register struct disklabel *lp;
184: {
185: register u_short *start, *end;
186: register u_short sum = 0;
187:
188: start = (u_short *)lp;
189: end = (u_short *)&lp->d_partitions[lp->d_npartitions];
190: while (start < end)
191: sum ^= *start++;
192: return (sum);
193: }
194:
195: /*
196: * Disk error is the preface to plaintive error messages
197: * about failing disk transfers. It prints messages of the form
198:
199: hp0g: hard error reading fsbn 12345 of 12344-12347 (hp0 bn %d cn %d tn %d sn %d)
200:
201: * if the offset of the error in the transfer and a disk label
202: * are both available. blkdone should be -1 if the position of the error
203: * is unknown; the disklabel pointer may be null from drivers that have not
204: * been converted to use them. The message is printed with printf
205: * if pri is LOG_PRINTF, otherwise it uses log at the specified priority.
206: * The message should be completed (with at least a newline) with printf
207: * or addlog, respectively. There is no trailing space.
208: */
209: void
210: diskerr(bp, dname, what, pri, blkdone, lp)
211: register struct buf *bp;
212: char *dname, *what;
213: int pri, blkdone;
214: register struct disklabel *lp;
215: {
216: int unit = dkunit(bp->b_dev), part = dkpart(bp->b_dev);
217: register void (*pr) __P((const char *, ...));
218: char partname = 'a' + part;
219: int sn;
220:
221: if (pri != LOG_PRINTF) {
222: log(pri, "");
223: pr = addlog;
224: } else
225: pr = printf;
226: (*pr)("%s%d%c: %s %sing fsbn ", dname, unit, partname, what,
227: bp->b_flags & B_READ ? "read" : "writ");
228: sn = bp->b_blkno;
229: if (bp->b_bcount <= DEV_BSIZE)
230: (*pr)("%d", sn);
231: else {
232: if (blkdone >= 0) {
233: sn += blkdone;
234: (*pr)("%d of ", sn);
235: }
236: (*pr)("%d-%d", bp->b_blkno,
237: bp->b_blkno + (bp->b_bcount - 1) / DEV_BSIZE);
238: }
239: if (lp && (blkdone >= 0 || bp->b_bcount <= lp->d_secsize)) {
240: #ifdef tahoe
241: sn *= DEV_BSIZE / lp->d_secsize; /* XXX */
242: #endif
243: sn += lp->d_partitions[part].p_offset;
244: (*pr)(" (%s%d bn %d; cn %d", dname, unit, sn,
245: sn / lp->d_secpercyl);
246: sn %= lp->d_secpercyl;
247: (*pr)(" tn %d sn %d)", sn / lp->d_nsectors, sn % lp->d_nsectors);
248: }
249: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.