Annotation of coherent/d/conf/tboot/diskio.c, revision 1.1.1.1

1.1       root        1: /* diskio.c -- C routines for disk i/o in tertiary boot programs.
                      2:  *
                      3:  * La Monte H. Yarroll <[email protected]>, September 1991
                      4:  */
                      5: 
                      6: #include <sys/types.h>
                      7: #include <canon.h>
                      8: #include <sys/filsys.h>
                      9: #include <sys/ino.h>
                     10: #include <sys/inode.h>
                     11: #include <sys/dir.h>
                     12: #include <sys/buf.h>
                     13: #include <sys/stat.h>
                     14: 
                     15: #include "tboot.h"
                     16: 
                     17: /* Aligning bread.
                     18:  * Reads 1 block into an arbitrary buffer.  The assembly language
                     19:  * routine bread() needs a buffer aligned on a 4K boundary.
                     20:  */
                     21: 
                     22: char bufspace[FOURK+BLOCK];
                     23: char *lbuf = NULL;     /* Buffer for bread.  */
                     24: 
                     25: BUF *
                     26: bread(blockno)
                     27:        daddr_t blockno;        /* Block number.  */
                     28: {
                     29:        BUF *retval = NULL;
                     30: 
                     31:        /* If not already aligned, align buffer on a 4K boundary.  */
                     32:        if (NULL == lbuf) {
                     33:                lbuf = bufspace + FOURK;
                     34:                lbuf = (char *) (((unsigned short) lbuf) & FOURKBOUNDRY);
                     35:        }
                     36: 
                     37:        sanity_check("bread() entry");
                     38:        /*
                     39:         * Get a buffer to cache this in.
                     40:         */
                     41: 
                     42:        retval = bclaim(blockno);
                     43: 
                     44:        sanity_check("bread() returning from bclaim()");
                     45: 
                     46:        /*
                     47:         * If the buffer has the right block number,
                     48:         * we need not go further.
                     49:         */
                     50:        if ((THE_DEV == retval->b_dev) && (blockno == retval->b_bno)) {
                     51:                return(retval);
                     52:        }
                     53: 
                     54:        /* Read the block, ignoring
                     55:         * the return value.
                     56:         */
                     57:        sanity_check("bread() to _bread()");
                     58:        _bread(blockno, lbuf);
                     59:        sanity_check("bread() from _bread()");
                     60: 
                     61:        /* Copy to the unaligned buffer.  */
                     62:        sanity_check("bread() to memcpy()");
                     63:        memcpy((uint16) (retval->b_paddr), lbuf, BLOCK);
                     64:        sanity_check("bread() from memcpy()");
                     65: 
                     66:        retval->b_dev   = THE_DEV;      /* Associate it with a device, */
                     67:        retval->b_bno   = blockno;      /* and block number.  */
                     68: 
                     69:        sanity_check("bread() about to return");
                     70:        /* Return the buffer we just filled in.  */
                     71:        return(retval);
                     72: } /* bread() */
                     73: 
                     74: 
                     75: /*
                     76:  * Inode OPEN: Load the inode for a file into memory.
                     77:  * iopen(struct inode *ip,
                     78:  *      ino_t inode_number)
                     79:  *
                     80:  */  
                     81: 
                     82: int
                     83: iopen(meminode, inode_number)
                     84:        struct inode *meminode;
                     85:        ino_t inode_number;
                     86: {
                     87:        BUF *bp;
                     88:        char *my_block;
                     89: 
                     90:        daddr_t blockno;        /* Physical block the inode lives on.  */
                     91:        uint16 offset;          /* Offset within that block for inode.  */
                     92:        struct dinode *diskinode; /* Pointer into buffer for disk
                     93:                                   * inode structure.
                     94:                                   */
                     95: 
                     96:        /* Read the super block to check the inode_number.
                     97:         * bp = bread(1L);
                     98:         * WRITE ME
                     99:         */
                    100: 
                    101:        /* Convert from inode number to block number.  */
                    102: 
                    103:        /* This code fragment should (but doesn't) examine the
                    104:         * bad block list, to skip over bad blocks in the free list.
                    105:         *
                    106:         * I'm no longer certain of the preceeding comment... :-(
                    107:         */
                    108:        blockno = ((inode_number - 1) / INODES_PER_BLOCK) + 2;
                    109:        
                    110:        offset = ((inode_number - 1) % INODES_PER_BLOCK) *
                    111:                 sizeof(struct dinode);
                    112: 
                    113:        /* Get the inode off disk.  */
                    114:        bp = bread(blockno);
                    115:        
                    116:        /* Point at the actual disk block.  */
                    117:        my_block = (char *) bp->b_paddr;
                    118:        
                    119:        /* Pick out the particular inode we want.  */
                    120:        diskinode = (struct dinode *) (my_block + offset);
                    121:        
                    122:        meminode->i_dev = THE_DEV;      /* We're making something up.  */
                    123:        meminode->i_ino = inode_number;                 /* Inode index */
                    124:        meminode->i_refc = diskinode->di_nlink;
                    125:        meminode->i_gate[0] = 0;                        /* Gate (unused) */
                    126:        meminode->i_gate[1] = 0;                        /* Gate (unused) */
                    127:        meminode->i_flag = 0;                           /* Flags (unused) */
                    128:        meminode->i_mode = diskinode->di_mode;
                    129:        meminode->i_nlink = diskinode->di_nlink;
                    130:        meminode->i_uid = diskinode->di_uid;
                    131:        meminode->i_gid = diskinode->di_gid;
                    132:        meminode->i_size = diskinode->di_size;
                    133:        meminode->i_atime = diskinode->di_atime;
                    134:        meminode->i_mtime = diskinode->di_mtime;
                    135:        meminode->i_ctime = diskinode->di_ctime;
                    136:        meminode->i_lrt = GREATEST(                     /* Last reference time */
                    137:                        meminode->i_atime,
                    138:                        meminode->i_mtime,
                    139:                        meminode->i_ctime);
                    140:        /* Disk addresses */
                    141:        /* Copy all block numbers (10 direct, 3 indirects).  */
                    142:        l3tol(meminode->i_a.i_addr, diskinode->di_a.di_addb, NADDR);
                    143: 
                    144:        /* Translate cannonical form to internal form.  */
                    145:        canshort(meminode->i_nlink);                    /* Reference count */
                    146:        canshort(meminode->i_mode);                     /* Mode and type */
                    147:        canshort(meminode->i_nlink);                    /* Number of links */
                    148:        canshort(meminode->i_uid);                      /* Owner's user id */
                    149:        canshort(meminode->i_gid);                      /* Owner's group id */
                    150:        cansize(meminode->i_size);                      /* Size of file in bytes */
                    151:        cantime(meminode->i_atime);                     /* Last access time */
                    152:        cantime(meminode->i_mtime);                     /* Last modify time */
                    153:        cantime(meminode->i_ctime);                     /* Creation time */
                    154: 
                    155:        
                    156:        sanity_check("iopen() calling brelease()");
                    157:        brelease(bp);
                    158: 
                    159:        return(1);
                    160: } /* iopen() */
                    161: 
                    162: 
                    163: 
                    164: /* Convert a filename to an inode number.  Returns inode number 0 on
                    165:  * failure.
                    166:  */ 
                    167: ino_t
                    168: namei(filename)
                    169:        char *filename;
                    170: {
                    171:        fsize_t i;
                    172:        struct direct dirent;
                    173:        struct inode dir;
                    174: 
                    175:        iopen(&dir, (ino_t) 2); /* Open the root directory.  */
                    176:        
                    177:        /* Read each directory entry one at a time.  */
                    178:        for (i = 0; i < dir.i_size; i += sizeof(struct direct)) {
                    179: 
                    180:                iread(&dir, (char *) &dirent, (fsize_t) i,
                    181:                      (uint16) sizeof(struct direct));
                    182:                
                    183:                /* Canonicalize it.  */
                    184:                canino(dirent.d_ino);
                    185:                if (0 == strncmp(filename, dirent.d_name, DIRSIZ)){
                    186:                        return(dirent.d_ino);
                    187:                }
                    188:        }
                    189:        return((ino_t) 0);
                    190: } /* namei() */
                    191: 
                    192: /*
                    193:  * Inode READ: Load a local buffer from a file.
                    194:  * iread(struct inode *ip,
                    195:  *      char *buffer,
                    196:  *      fsize_t offset,
                    197:  *      uint16 lenarg);
                    198:  */
                    199: void
                    200: iread(ip, buffer, offset, lenarg)
                    201:        struct inode *ip;       /* Read from this file,         */
                    202:        char *buffer;           /* into this buffer,            */
                    203:        fsize_t offset;         /* from here in the file,       */
                    204:        uint16 lenarg;  /* for this many bytes.         */
                    205: {
                    206:        extern uint16 myds;     /* Contents of ds register.  */
                    207: 
                    208:        ifread(ip, myds, buffer, offset, (fsize_t) lenarg);
                    209: } /* iread() */
                    210: 
                    211: /*
                    212:  * Inode to Far READ: Load an arbitrary length from a file into a far address.
                    213:  * ifread(struct inode *ip,
                    214:  *       uint16 toseg,
                    215:  *       uint16 tooffset,
                    216:  *       fsize_t offset,
                    217:  *       fsize_t length);
                    218:  */
                    219: void
                    220: ifread(ip, toseg, tooffset, offset, lenarg)
                    221:        struct inode *ip;       /* Read from this file,         */
                    222:        uint16 toseg;   /* into this far buffer,        */
                    223:        uint16 tooffset;
                    224:        fsize_t offset;         /* from here in the file,       */
                    225:        fsize_t lenarg;         /* for this many bytes.         */
                    226: {
                    227:        BUF *bp;
                    228:        char *my_block;
                    229: 
                    230:        daddr_t fblockno;       /* Block number relative to file.  */
                    231:        daddr_t pblockno;       /* Block number relative to disk.  */
                    232:        uint16 blockoffset;     /* How far into buffer to start or end.  */
                    233:        uint16 blocklen;        /* Size of first fractional block.  */
                    234:        long length;
                    235: 
                    236:        extern uint16 myds;     /* Contents of register ds.  */
                    237: 
                    238:        length = (int32) lenarg;        /* We need something that can go negative.  */
                    239: 
                    240:        /* Calculate the first block of the requested file segment.  */
                    241:        fblockno = (daddr_t) (offset / (fsize_t) BLOCK);
                    242:        /* Look up the physical block number.  */
                    243:        pblockno = vmap(ip, fblockno);
                    244:        /* Calculate starting offset within that block.  */
                    245:        blockoffset = (uint16) (offset % (fsize_t) BLOCK);
                    246:        blocklen =
                    247:         (uint16) LESSER((int32) (BLOCK - blockoffset), length);
                    248: 
                    249:        /* Read the first fraction of a block.  */
                    250:        bp = bread(pblockno);
                    251:        
                    252:        /* Point at the actual data.  */
                    253:        my_block = (char *) bp->b_paddr;
                    254: 
                    255:        /* Copy it in place.  */
                    256:        ffcopy(tooffset, toseg, &(my_block[blockoffset]), myds, blocklen);
                    257:                
                    258:        sanity_check("ifread() calling the first brelease()");
                    259:        brelease(bp);
                    260: 
                    261:        /* Don't bother with the rest if there is nothing more to read.  */
                    262:        if (blocklen == (uint16) length) {
                    263:                return;
                    264:        }
                    265: 
                    266:        ++fblockno;
                    267:        pblockno = vmap(ip, fblockno);
                    268: 
                    269:        length -= (int32) blocklen;
                    270:        seginc(&tooffset, &toseg, blocklen);
                    271: 
                    272:        pac_init();     /* Turn on the pacifier.  */
                    273:        /* Read the middle blocks.  */
                    274:        while (length - (int32) BLOCK > 0L) {
                    275:                sanity_check("ifread() to middle bread()");
                    276:                bp = bread(pblockno);
                    277:                sanity_check("ifread() from middle bread()");
                    278: 
                    279:                /* Point at the actual data.  */
                    280:                my_block = (char *) bp->b_paddr;
                    281: 
                    282:                sanity_check("ifread() to middle ffcopy()");
                    283:                ffcopy(tooffset, toseg, my_block, myds, BLOCK);
                    284:                sanity_check("ifread() from middle ffcopy()");
                    285: 
                    286:                sanity_check("ifread() to middle brelease()");
                    287:                brelease(bp);
                    288:                sanity_check("ifread() from middle brelease()");
                    289: 
                    290:                pacifier(); /* Put something reassuring on the screen.  */
                    291:                ++fblockno;
                    292:                sanity_check("ifread() to middle vmap()");
                    293:                pblockno = vmap(ip, fblockno);
                    294:                sanity_check("ifread() to middle vmap()");
                    295: 
                    296:                length -= (int32) BLOCK;
                    297:                sanity_check("ifread() to middle seginc()");
                    298:                seginc(&tooffset, &toseg, BLOCK);
                    299:                sanity_check("ifread() from middle seginc()");
                    300:        }
                    301:        pac_cleanup();  /* Turn off the pacifier.  */
                    302: 
                    303:        /* Read the last fraction of a block.  */
                    304:        if (length > 0L) {
                    305:                /* ASSERTION: length < BLOCK */
                    306:                bp = bread(pblockno);
                    307: 
                    308:                /* Point at the actual data.  */
                    309:                my_block = (char *) bp->b_paddr;
                    310: 
                    311:                ffcopy(tooffset, toseg, my_block, myds, (uint16)length);
                    312:                sanity_check("ifread() calling the last brelease()");
                    313:                brelease(bp);
                    314:        }
                    315: } /* ifread() */
                    316: 
                    317: 
                    318: /* Aligning xbread.
                    319:  * Disk addresses are relative to the start of the disk, rather than
                    320:  * the start of the partition.
                    321:  * Reads 1 block into an arbitrary buffer.  The assembly language
                    322:  * routine xbread() needs a buffer aligned on a 4K boundary.
                    323:  */
                    324: BUF *
                    325: xbread(blockno)
                    326:        daddr_t blockno;        /* Block number.  */
                    327: {
                    328:        BUF *retval = NULL;
                    329: 
                    330:        /* If not already aligned, align buffer on a 4K boundary.  */
                    331:        if (NULL == lbuf) {
                    332:                lbuf = bufspace + FOURK;
                    333:                lbuf = (char *) (((unsigned short) lbuf) & FOURKBOUNDRY);
                    334:        }
                    335: 
                    336:        sanity_check("xbread() entry");
                    337:        /*
                    338:         * Get a buffer to cache this in.
                    339:         */
                    340: 
                    341:        retval = bclaim(blockno);
                    342: 
                    343:        sanity_check("xbread() returning from bclaim()");
                    344: 
                    345:        /*
                    346:         * If the buffer has the right block number,
                    347:         * we need not go further.
                    348:         */
                    349:        if ((THE_XDEV == retval->b_dev) && (blockno == retval->b_bno)) {
                    350:                return(retval);
                    351:        }
                    352: 
                    353:        /* Read the block, ignoring
                    354:         * the return value.
                    355:         */
                    356:        sanity_check("xbread() to _xbread()");
                    357:        _xbread(blockno, lbuf);
                    358:        sanity_check("xbread() from _xbread()");
                    359: 
                    360:        /* Copy to the unaligned buffer.  */
                    361:        sanity_check("xbread() to memcpy()");
                    362:        memcpy((uint16) (retval->b_paddr), lbuf, BLOCK);
                    363:        sanity_check("xbread() from memcpy()");
                    364: 
                    365:        retval->b_dev   = THE_XDEV;     /* Associate it with a device, */
                    366:        retval->b_bno   = blockno;      /* and block number.  */
                    367: 
                    368:        sanity_check("xbread() about to return");
                    369:        /* Return the buffer we just filled in.  */
                    370:        return(retval);
                    371: } /* xbread() */
                    372: 

unix.superglobalmegacorp.com

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