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