Annotation of researchv10no/cmd/rarepl/rarepl.c, revision 1.1.1.1

1.1       root        1: /*% cc -O -o rarepl %
                      2:  *
                      3:  * replace a bad sector on an RA disk
                      4:  */
                      5: 
                      6: #include <stdio.h>
                      7: #include <sys/param.h>
                      8: #include <sys/udaioc.h>
                      9: #include "rct.h"
                     10: 
                     11: struct ud_unit ud_unit;
                     12: int primblk;           /* ugh */
                     13: int notprim;           /* never primary replacement */
                     14: 
                     15: #define        BADRBN  (-1L)
                     16: 
                     17: main(argc, argv)
                     18: int argc;
                     19: char **argv;
                     20: {
                     21:        int fd;
                     22:        int errs = 0;
                     23: 
                     24:        if (argc < 3) {
                     25:                fprintf(stderr, "usage: %s dev lbn ...\n", argv[0]);
                     26:                exit(1);
                     27:        }
                     28:        if ((fd = open(argv[1], 2)) < 0) {
                     29:                perror(argv[1]);
                     30:                exit(1);
                     31:        }
                     32:        online(fd);
                     33:        if (ioctl(fd, UIOCHAR, &ud_unit) < 0) {
                     34:                perror("unit info");
                     35:                exit(1);
                     36:        }
                     37:        argc--;
                     38:        argv++;
                     39:        while (--argc > 0)
                     40:                errs += repl(fd, atol(*++argv));
                     41:        exit(errs);
                     42: }
                     43: 
                     44: /*
                     45:  * read a block from the disk,
                     46:  * just to make the driver bring it online
                     47:  */
                     48: 
                     49: online(fd)
                     50: int fd;
                     51: {
                     52:        char buf[RBNSEC];
                     53: 
                     54:        read(fd, buf, RBNSEC);          /* ignore error; might be bad sector */
                     55: }
                     56: 
                     57: /*
                     58:  * replace a block
                     59:  */
                     60: 
                     61: repl(fd, bad)
                     62: int fd;
                     63: daddr_t bad;
                     64: {
                     65:        struct ud_repl r;
                     66:        char block[RBNSEC];
                     67:        struct rbd rct[RBNPB];
                     68:        daddr_t rctb;
                     69:        int rctoff;
                     70:        daddr_t rbn;
                     71:        daddr_t pickrbn();
                     72: 
                     73:        if (bad >= ud_unit.radsize) {
                     74:                fprintf(stderr, "%ld: out of range\n", bad);
                     75:                return (1);
                     76:        }
                     77:        clrbuf(block);
                     78:        lseek(fd, (off_t)(bad * RBNSEC), 0);
                     79:        read(fd, block, RBNSEC);        /* ignore error on purpose */
                     80:        if ((rbn = pickrbn(fd, bad)) == BADRBN) {
                     81:                fprintf(stderr, "can't find replacement for %ld\n", bad);
                     82:                return (1);
                     83:        }
                     84:        rctb = (rbn / RBNPB) + RCTTAB;
                     85:        rctoff = rbn % RBNPB;
                     86:        if (rdrct(fd, rctb, (char *)rct) == 0)
                     87:                return (1);
                     88:        if (rct[rctoff].rb_code) {
                     89:                fprintf(stderr, "rbn %ld in use or bad\n", rbn);
                     90:                return (1);
                     91:        }
                     92:        rct[rctoff].rb_code = primblk ? RALLOC : RALLOC | RALT;
                     93:        rct[rctoff].rb_lbn = bad;
                     94:        if (wrrct(fd, rctb, (char *)rct) == 0)
                     95:                return (1);
                     96:        r.lbn = bad;
                     97:        r.replbn = rbn;
                     98:        r.prim = primblk;
                     99:        if (ioctl(fd, UIOREPL, &r) < 0) {
                    100:                perror("replace ioctl");
                    101:                return (1);
                    102:        }
                    103:        lseek(fd, (off_t)(bad * RBNSEC), 0);
                    104:        if (write(fd, block, RBNSEC) != RBNSEC) {
                    105:                perror("write back");
                    106:                return (1);
                    107:        }
                    108:        return (0);
                    109: }
                    110: 
                    111: /*
                    112:  * find a replacement block
                    113:  * remember in primblk whether it's the primary replacement
                    114:  */
                    115: 
                    116: daddr_t
                    117: pickrbn(fd, lbn)
                    118: int fd;
                    119: daddr_t lbn;
                    120: {
                    121:        struct rbd rct[RBNPB];
                    122:        daddr_t bno, rbn, prbn;
                    123:        daddr_t low, high;
                    124:        register int i;
                    125:        daddr_t size;
                    126:        daddr_t rctmax(), primrbn();
                    127: 
                    128:        size = rctmax();
                    129:        prbn = primrbn(lbn);
                    130:        low = high = BADRBN;
                    131:        for (bno = RCTTAB, rbn = 0L; bno < size; bno++) {
                    132:                if (rdrct(fd, bno, (char *)rct) == 0) {
                    133:                        rbn += RBNPB;
                    134:                        continue;
                    135:                }
                    136:                for (i = 0; i < RBNPB; i++, rbn++) {
                    137:                        if (rct[i].rb_code == RFREE) {
                    138:                                if (rbn < prbn)
                    139:                                        low = rbn;
                    140:                                else if (high == BADRBN)
                    141:                                        high = rbn;
                    142:                        }
                    143:                        else if (rct[i].rb_lbn == lbn
                    144:                             &&  rct[i].rb_code != RNULL
                    145:                             &&  rct[i].rb_code != RBAD) {
                    146:                                rct[i].rb_code = RBAD;
                    147:                                wrrct(fd, bno, (char *)rct);
                    148:                        }
                    149:                }
                    150:        }
                    151:        if (low == BADRBN && high == BADRBN)
                    152:                return (BADRBN);
                    153:        else if (low == BADRBN)
                    154:                rbn = high;
                    155:        else if (high == BADRBN)
                    156:                rbn = low;
                    157:        else if (prbn - low < high - prbn)
                    158:                rbn = low;
                    159:        else
                    160:                rbn = high;
                    161:        if (notprim)
                    162:                primblk = 0;
                    163:        else
                    164:                primblk = (rbn == prbn);
                    165:        return (rbn);
                    166: }
                    167: 
                    168: daddr_t
                    169: rctmax()
                    170: {
                    171:        register daddr_t nrbns;
                    172: 
                    173:        nrbns = (ud_unit.radsize / ud_unit.tracksz) * ud_unit.rbns;
                    174:        nrbns = ((nrbns+RBNPB-1) / RBNPB) + RCTTAB;
                    175:        if (nrbns >= ud_unit.rctsize) {
                    176:                notprim = 1;
                    177:                return ((daddr_t)ud_unit.rctsize);
                    178:        }
                    179:        return (nrbns);
                    180: }
                    181: 
                    182: /*
                    183:  * figure out the primary RBN
                    184:  * if notprim == 0, we understand what to do
                    185:  * otherwise it's not really the primary RBN (and we won't tell the
                    186:  * controller so), but make a guess about a preferred RBN anyway
                    187:  */
                    188: daddr_t
                    189: primrbn(lbn)
                    190: daddr_t lbn;
                    191: {
                    192:        daddr_t q, csize;
                    193: 
                    194:        if (notprim == 0)
                    195:                return ((lbn/ud_unit.tracksz) * ud_unit.rbns);
                    196:        /*
                    197:         * try for one in the same cylinder,
                    198:         * or multiple thereof
                    199:         */
                    200:        q = (ud_unit.rctsize - RCTTAB)*RBNPB;   /* max possible rbns */
                    201:        q /= ud_unit.rbns;              /* max rbn quantum */
                    202:        q = ud_unit.radsize/q;          /* max LBNs per RBN */
                    203:        csize = ud_unit.tracksz*ud_unit.groupsz*ud_unit.cylsz;
                    204:        q = (q + csize - 1)/csize;      /* cylinders per RBN */
                    205:        q *= csize;                     /* probably real LBNs per RBN */
                    206:        return ((lbn + csize - 1)/q);
                    207: }
                    208: 
                    209: rdrct(fd, bno, buf)
                    210: int fd;
                    211: daddr_t bno;
                    212: char *buf;
                    213: {
                    214:        struct ud_rctbuf b;
                    215: 
                    216:        b.buf = buf;
                    217:        b.lbn = bno;
                    218:        if (ioctl(fd, UIORRCT, &b) < 0) {
                    219:                perror("rrct");
                    220:                fprintf(stderr, "can't read block %ld of rct\n", bno);
                    221:                return (0);
                    222:        }
                    223:        return (1);
                    224: }
                    225: 
                    226: wrrct(fd, bno, buf)
                    227: int fd;
                    228: daddr_t bno;
                    229: char *buf;
                    230: {
                    231:        struct ud_rctbuf b;
                    232: 
                    233:        b.buf = buf;
                    234:        b.lbn = bno;
                    235:        if (ioctl(fd, UIOWRCT, &b) < 0) {
                    236:                perror("wrct");
                    237:                fprintf(stderr, "can't write block %ld of rct\n", bno);
                    238:                return (0);
                    239:        }
                    240:        return (1);
                    241: }
                    242: 
                    243: clrbuf(b)
                    244: register char *b;
                    245: {
                    246:        register int i;
                    247: 
                    248:        for (i = 0; i < RBNSEC; i++)
                    249:                *b++ = 0;
                    250: }

unix.superglobalmegacorp.com

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