|
|
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.