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

1.1       root        1: /*
                      2:  * Handle the indirections in Unix-style file system.
                      3:  *
                      4:  * Uses a recursive scheme to follow up indirections.
                      5:  *
                      6:  * Needs optimization.  A good place to start would be caching of
                      7:  * lookup tables.
                      8:  *
                      9:  * La Monte H. Yarroll <[email protected]>, September 1991
                     10:  */
                     11: 
                     12: #include <sys/types.h>
                     13: #include <sys/buf.h>
                     14: #include <sys/ino.h>
                     15: #include <sys/inode.h>
                     16: #include <canon.h>
                     17: #include <sys/ptypes.h>
                     18: 
                     19: extern BUF *bread();
                     20: daddr_t vmap();
                     21: daddr_t indirect();
                     22: daddr_t ind_lookup();
                     23: uint16 ind_index();
                     24: 
                     25: /* Convert the given virtual block to a physical block for the given inode.
                     26:  * ip points to the in-core inode for a file.
                     27:  * vblockno is a block number relative to the start of that file.
                     28:  */
                     29: daddr_t
                     30: vmap(ip, vblockno)
                     31:        struct inode *ip;
                     32:        daddr_t vblockno;
                     33: {
                     34:        uint16 ind_level;
                     35:        daddr_t ind_table;
                     36:        daddr_t vbno;
                     37: 
                     38:        if (vblockno < (daddr_t) ND){
                     39:                /* Direct block.  */
                     40:                return(ip->i_a.i_addr[vblockno]);
                     41:        } else if (vblockno < (daddr_t) (ND + NBN)) {
                     42:                /* Single indirect block.  */
                     43:                ind_level = 1;
                     44:                ind_table = ip->i_a.i_addr[ND];
                     45:                vbno = vblockno - ND;   /* Skip over direct blocks.  */
                     46:        } else if (vblockno < (daddr_t) (ND + (NBN*NBN))) {
                     47:                /* Double indirect block.  */
                     48:                ind_level = 2;
                     49:                ind_table = ip->i_a.i_addr[ND+1];
                     50:                vbno = vblockno - (ND + NBN);   /* Skip over direct
                     51:                                                 * and indirect blocks.
                     52:                                                 */
                     53:                
                     54:        } else {
                     55:                /* Triple indirect block.  */
                     56:                ind_level = 3;
                     57:                ind_table = ip->i_a.i_addr[ND+2];
                     58:                /* Skip over direct, indirect blocks,
                     59:                 * and double indirect blocks.
                     60:                 */
                     61:                vbno = vblockno - (ND + NBN + NBN*NBN);
                     62:        }
                     63: 
                     64:        return(indirect(ind_level, ind_table, vbno));
                     65: } /* vmap() */
                     66: 
                     67: /* indirect(uint16 ind_level, daddr_t ind_table_ptr, daddr_t vblockno)
                     68:  * Recursively follow an indirection for a given virtual block number
                     69:  * vblockno.
                     70:  * ind_level must be the level of indirection still un-resolved.
                     71:  * ind_table is the physical block number of the next indirection.
                     72:  */
                     73: daddr_t
                     74: indirect(ind_level, ind_table_ptr, vblockno)
                     75:        uint16 ind_level;
                     76:        daddr_t ind_table_ptr;
                     77:        daddr_t vblockno;
                     78: {
                     79:        BUF *bp;
                     80:        daddr_t *my_block;
                     81:        daddr_t next_ptr;
                     82: 
                     83:        /* Base case.  Direct block.  */
                     84:        if (0 == ind_level) {
                     85:                /* At this point, the block number in ind_table_ptr
                     86:                 * is exactly the physical block number we've been
                     87:                 * looking for.
                     88:                 */
                     89:                return(ind_table_ptr);
                     90:        }
                     91: 
                     92:        /* Recursive case.  Some level of indirection.  */
                     93: 
                     94:        /* Read the next table.  */
                     95:        bp = bread(ind_table_ptr);
                     96:        
                     97:        /* Pick out the actual disk block.  */
                     98:        my_block = (daddr_t *) bp->b_paddr;
                     99:        
                    100:        /* Fetch the next indirection.  */
                    101:        next_ptr = ind_lookup(ind_level, my_block, vblockno);
                    102: 
                    103:        /* Canonicalize it.  */
                    104:        candaddr(next_ptr);
                    105: 
                    106: #if 0
                    107:        /* Normally, buffers containing indirection blocks should not
                    108:         * be brelease()'d.  This is how we try to assure that they
                    109:         * do not need to be read off of disk too often.
                    110:         */
                    111:        sanity_check("indirect() about to brelease() and recurse");
                    112:        brelease(bp);   /* DEBUG */
                    113: #endif
                    114: 
                    115:        indirect(ind_level - 1,
                    116:                 next_ptr,
                    117:                 vblockno);
                    118: } /* indirect() */
                    119: 
                    120: /* ind_lookup(uint16 ind_level, daddr_t *ind_table, daddr_t vblockno)
                    121:  * Look up the next level of block in table ind_table, for virtual
                    122:  * block number vblockno.
                    123:  * Note that this table is in DISK CANNONICAL format.  If the local
                    124:  * notion of daddr_t is a different size from DISK CANONICAL daddr_t
                    125:  */
                    126: daddr_t
                    127: ind_lookup(ind_level, ind_table, vblockno)
                    128:        uint16 ind_level;
                    129:        daddr_t *ind_table;
                    130:        daddr_t vblockno;
                    131: {
                    132:        return(ind_table[ind_index(ind_level, vblockno)]);
                    133: }
                    134: 
                    135: /* uint16 ind_index(uint16 ind_level, daddr_t vblockno);
                    136:  * Calculate the index needed for virtual block vblockno into
                    137:  * a table of the given indirection level.
                    138:  */
                    139: #define SEVENONES 0x7f /* Mask of address bits for table lookups.
                    140:                         * NBN = 128 entries = 7 bit address.
                    141:                         */
                    142: uint16
                    143: ind_index(ind_level, vblockno)
                    144:        uint16 ind_level;
                    145:        daddr_t vblockno;
                    146: {
                    147:        /* Move the appropriate 7 bits to the lowest position,
                    148:         * and return them.
                    149:         */
                    150:        return((vblockno >> (7 * (ind_level - 1))) & SEVENONES);
                    151: }

unix.superglobalmegacorp.com

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