Annotation of Net2/ufs/ufs_disksubr.c, revision 1.1.1.3

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.