Annotation of linux/kernel/blk_drv/genhd.c, revision 1.1.1.2

1.1       root        1: /*
                      2:  *  Code extracted from
                      3:  *  linux/kernel/hd.c
                      4:  *
                      5:  *  Copyright (C) 1991, 1992  Linus Torvalds
                      6:  */
                      7: 
                      8: /*
                      9:  *  Thanks to Branko Lankester, [email protected], who found a bug
                     10:  *  in the early extended-partition checks and added DM partitions
                     11:  */
                     12: 
                     13: #include <linux/config.h>
                     14: #include <linux/fs.h>
                     15: #include <linux/genhd.h>
                     16: #include <linux/kernel.h>
                     17: struct gendisk *gendisk_head = NULL;
                     18: 
                     19: static int current_minor = 0;
                     20: extern int *blk_size[];
                     21: /*
                     22:  * Create devices for each logical partition in an extended partition.
                     23:  * The logical partitions form a linked list, with each entry being
                     24:  * a partition table with two entries.  The first entry
                     25:  * is the real data partition (with a start relative to the partition
                     26:  * table start).  The second is a pointer to the next logical partition
                     27:  * (with a start relative to the entire extended partition).
                     28:  * We do not create a Linux partition for the partition tables, but
                     29:  * only for the actual data partitions.
                     30:  */
                     31: 
                     32: static void extended_partition(struct gendisk *hd, int dev)
                     33: {
                     34:        struct buffer_head *bh;
                     35:        struct partition *p;
                     36:        unsigned long first_sector, this_sector;
                     37:        int mask = (1 << hd->minor_shift) - 1;
                     38: 
                     39:        first_sector = hd->part[MINOR(dev)].start_sect;
                     40:        this_sector = first_sector;
                     41: 
                     42:        while (1) {
                     43:                if ((current_minor & mask) >= (4 + hd->max_p))
                     44:                        return;
                     45:                if (!(bh = bread(dev,0,1024))) {
                     46:                        printk("Unable to read partition table of device %04x\n",dev);
                     47:                        return;
                     48:                }
                     49:          /*
                     50:           * This block is from a device that we're about to stomp on.
                     51:           * So make sure nobody thinks this block is usable.
                     52:           */
                     53:                bh->b_dirt=0;
                     54:                bh->b_uptodate=0;
                     55:                if (*(unsigned short *) (bh->b_data+510) == 0xAA55) {
                     56:                        p = 0x1BE + (void *)bh->b_data;
                     57:                /*
                     58:                 * Process the first entry, which should be the real
                     59:                 * data partition.
                     60:                 */
                     61:                        if (p->sys_ind == EXTENDED_PARTITION ||
                     62:                            !(hd->part[current_minor].nr_sects = p->nr_sects))
                     63:                                goto done;  /* shouldn't happen */
                     64:                        hd->part[current_minor].start_sect = this_sector + p->start_sect;
                     65:                        printk("  Logical part %d start %d size %d end %d\n\r", 
1.1.1.2 ! root       66:                               mask & current_minor, hd->part[current_minor].start_sect, 
1.1       root       67:                               hd->part[current_minor].nr_sects,
                     68:                               hd->part[current_minor].start_sect + 
                     69:                               hd->part[current_minor].nr_sects - 1);
                     70:                        current_minor++;
                     71:                        p++;
                     72:                /*
                     73:                 * Process the second entry, which should be a link
                     74:                 * to the next logical partition.  Create a minor
                     75:                 * for this just long enough to get the next partition
                     76:                 * table.  The minor will be reused for the real
                     77:                 * data partition.
                     78:                 */
                     79:                        if (p->sys_ind != EXTENDED_PARTITION ||
                     80:                            !(hd->part[current_minor].nr_sects = p->nr_sects))
                     81:                                goto done;  /* no more logicals in this partition */
                     82:                        hd->part[current_minor].start_sect = first_sector + p->start_sect;
                     83:                        this_sector = first_sector + p->start_sect;
                     84:                        dev = ((hd->major) << 8) | current_minor;
                     85:                        brelse(bh);
                     86:                } else
                     87:                        goto done;
                     88:        }
                     89: done:
                     90:        brelse(bh);
                     91: }
                     92: 
                     93: static void check_partition(struct gendisk *hd, unsigned int dev)
                     94: {
                     95:        int i, minor = current_minor;
                     96:        struct buffer_head *bh;
                     97:        struct partition *p;
                     98:        unsigned long first_sector;
1.1.1.2 ! root       99:        int mask = (1 << hd->minor_shift) - 1;
1.1       root      100: 
                    101:        first_sector = hd->part[MINOR(dev)].start_sect;
                    102: 
                    103:        if (!(bh = bread(dev,0,1024))) {
                    104:                printk("Unable to read partition table of device %04x\n",dev);
                    105:                return;
                    106:        }
1.1.1.2 ! root      107:        printk("%s%c :\n\r", hd->major_name, 'a'+(minor >> hd->minor_shift));
1.1       root      108:        current_minor += 4;  /* first "extra" minor */
                    109:        if (*(unsigned short *) (bh->b_data+510) == 0xAA55) {
                    110:                p = 0x1BE + (void *)bh->b_data;
                    111:                for (i=1 ; i<=4 ; minor++,i++,p++) {
                    112:                        if (!(hd->part[minor].nr_sects = p->nr_sects))
                    113:                                continue;
                    114:                        hd->part[minor].start_sect = first_sector + p->start_sect;
                    115:                        printk(" part %d start %d size %d end %d \n\r", i, 
                    116:                               hd->part[minor].start_sect, hd->part[minor].nr_sects, 
                    117:                               hd->part[minor].start_sect + hd->part[minor].nr_sects - 1);
                    118:                        if ((current_minor & 0x3f) >= 60)
                    119:                                continue;
                    120:                        if (p->sys_ind == EXTENDED_PARTITION) {
                    121:                                extended_partition(hd, (hd->major << 8) | minor);
                    122:                        }
                    123:                }
                    124:                /*
                    125:                 * check for Disk Manager partition table
                    126:                 */
                    127:                if (*(unsigned short *) (bh->b_data+0xfc) == 0x55AA) {
                    128:                        p = 0x1BE + (void *)bh->b_data;
                    129:                        for (i = 4 ; i < 16 ; i++, current_minor++) {
                    130:                                p--;
1.1.1.2 ! root      131:                                if ((current_minor & mask) >= mask-2)
1.1       root      132:                                        break;
                    133:                                if (!(p->start_sect && p->nr_sects))
                    134:                                        continue;
                    135:                                hd->part[current_minor].start_sect = p->start_sect;
                    136:                                hd->part[current_minor].nr_sects = p->nr_sects;
                    137:                                printk(" DM part %d start %d size %d end %d\n\r",
1.1.1.2 ! root      138:                                       current_minor & mask,
1.1       root      139:                                       hd->part[current_minor].start_sect, 
                    140:                                       hd->part[current_minor].nr_sects,
                    141:                                       hd->part[current_minor].start_sect + 
                    142:                                       hd->part[current_minor].nr_sects - 1);
                    143:                        }
                    144:                }
                    145:        } else
                    146:                printk("Bad partition table on dev %04x\n",dev);
                    147:        brelse(bh);
                    148: }
                    149: 
                    150: static void setup_dev(struct gendisk *dev)
                    151: {
                    152:        int i;
                    153:        int j = dev->max_nr * dev->max_p;
                    154:        int major = dev->major << 8;
                    155:        int drive;
                    156:        
                    157: 
                    158:        for (i = 0 ; i < j; i++)  {
                    159:                dev->part[i].start_sect = 0;
                    160:                dev->part[i].nr_sects = 0;
                    161:        }
                    162:        dev->init();    
                    163:        for (drive=0 ; drive<dev->nr_real ; drive++) {
                    164:                current_minor = 1+(drive<<dev->minor_shift);
                    165:                check_partition(dev, major+(drive<<dev->minor_shift));
                    166:        }
                    167:        for (i=0 ; i < j ; i++)
                    168:                dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9);
                    169:        blk_size[dev->major] = dev->sizes;
                    170: }
                    171:        
                    172: /* This may be used only once, enforced by 'static int callable' */
                    173: int sys_setup(void * BIOS)
                    174: {
                    175:        static int callable = 1;
                    176:        struct gendisk *p;
                    177:        int nr=0;
                    178: 
                    179:        if (!callable)
                    180:                return -1;
                    181:        callable = 0;
                    182: 
                    183:        for (p = gendisk_head ; p ; p=p->next) {
                    184:                setup_dev(p);
                    185:                nr += p->nr_real;
                    186:        }
                    187:                
                    188:        if (nr)
                    189:                printk("Partition table%s ok.\n\r",(nr>1)?"s":"");
                    190: 
                    191: #ifdef RAMDISK
                    192:        rd_load();
                    193: #endif
                    194:        mount_root();
                    195:        return (0);
                    196: }

unix.superglobalmegacorp.com

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