Annotation of coherent/d/conf/tboot/indirect.c, revision 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.