direct-io.hg
changeset 224:b05b1796e256
bitkeeper revision 1.82 (3e562a3eivWgqJ6O9wH-OFGq-YzJ5w)
.del-msdos.c~f31e5a4d337da875:
Delete: xenolinux-2.4.16-sparse/fs/partitions/msdos.c
.del-check.c~ebcaa3de1bfb8ad8:
Delete: xenolinux-2.4.16-sparse/fs/partitions/check.c
.del-msdos.c~f31e5a4d337da875:
Delete: xenolinux-2.4.16-sparse/fs/partitions/msdos.c
.del-check.c~ebcaa3de1bfb8ad8:
Delete: xenolinux-2.4.16-sparse/fs/partitions/check.c
author | kaf24@labyrinth.cl.cam.ac.uk |
---|---|
date | Fri Feb 21 13:31:42 2003 +0000 (2003-02-21) |
parents | 81ac00c13385 |
children | 0fd36a1adb1d |
files | .rootkeys xenolinux-2.4.16-sparse/fs/partitions/check.c xenolinux-2.4.16-sparse/fs/partitions/msdos.c |
line diff
1.1 --- a/.rootkeys Fri Feb 21 12:46:51 2003 +0000 1.2 +++ b/.rootkeys Fri Feb 21 13:31:42 2003 +0000 1.3 @@ -329,8 +329,6 @@ 3ddb79bbx682YH6vR2zbVOXwg73ULg xenolinux 1.4 3ddb79bcJfHdwrPsjqgI33_OsGdVCg xenolinux-2.4.16-sparse/drivers/block/rd.c 1.5 3ddb79bcpVu-IbnqwQqpRqsEbLpsuw xenolinux-2.4.16-sparse/drivers/char/tty_io.c 1.6 3e15d5273gfR2fbcYe05kqBSAvCX_w xenolinux-2.4.16-sparse/fs/exec.c 1.7 -3e4a8cb7kqfJTMeOpPcYxqxv7N18DA xenolinux-2.4.16-sparse/fs/partitions/check.c 1.8 -3e4a8cb7p079Xxly4uNcouacMSjJLw xenolinux-2.4.16-sparse/fs/partitions/msdos.c 1.9 3ddb79b8VFtfWSCrXKPN2K21zd_vtw xenolinux-2.4.16-sparse/include/asm-xeno/a.out.h 1.10 3ddb79b8Zzi13p3OAPV25QgiC3THAQ xenolinux-2.4.16-sparse/include/asm-xeno/apic.h 1.11 3ddb79baZDlsdV_m6C5CXnWMl15p1g xenolinux-2.4.16-sparse/include/asm-xeno/apicdef.h
2.1 --- a/xenolinux-2.4.16-sparse/fs/partitions/check.c Fri Feb 21 12:46:51 2003 +0000 2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 2.3 @@ -1,443 +0,0 @@ 2.4 -/* 2.5 - * Code extracted from drivers/block/genhd.c 2.6 - * Copyright (C) 1991-1998 Linus Torvalds 2.7 - * Re-organised Feb 1998 Russell King 2.8 - * 2.9 - * We now have independent partition support from the 2.10 - * block drivers, which allows all the partition code to 2.11 - * be grouped in one location, and it to be mostly self 2.12 - * contained. 2.13 - * 2.14 - * Added needed MAJORS for new pairs, {hdi,hdj}, {hdk,hdl} 2.15 - */ 2.16 - 2.17 -#include <linux/config.h> 2.18 -#include <linux/fs.h> 2.19 -#include <linux/genhd.h> 2.20 -#include <linux/kernel.h> 2.21 -#include <linux/major.h> 2.22 -#include <linux/blk.h> 2.23 -#include <linux/init.h> 2.24 -#include <linux/raid/md.h> 2.25 - 2.26 -#include "check.h" 2.27 - 2.28 -#include "acorn.h" 2.29 -#include "amiga.h" 2.30 -#include "atari.h" 2.31 -#include "ldm.h" 2.32 -#include "mac.h" 2.33 -#include "msdos.h" 2.34 -#include "osf.h" 2.35 -#include "sgi.h" 2.36 -#include "sun.h" 2.37 -#include "ibm.h" 2.38 -#include "ultrix.h" 2.39 - 2.40 -extern int *blk_size[]; 2.41 - 2.42 -#define CHECK_DEBUG 0 2.43 - 2.44 -int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/ 2.45 - 2.46 -static int (*check_part[])(struct gendisk *hd, struct block_device *bdev, unsigned long first_sect, int first_minor) = { 2.47 -#ifdef CONFIG_ACORN_PARTITION 2.48 - acorn_partition, 2.49 -#endif 2.50 -#ifdef CONFIG_LDM_PARTITION 2.51 - ldm_partition, /* this must come before msdos */ 2.52 -#endif 2.53 -#ifdef CONFIG_MSDOS_PARTITION 2.54 - msdos_partition, 2.55 -#endif 2.56 -#ifdef CONFIG_OSF_PARTITION 2.57 - osf_partition, 2.58 -#endif 2.59 -#ifdef CONFIG_SUN_PARTITION 2.60 - sun_partition, 2.61 -#endif 2.62 -#ifdef CONFIG_AMIGA_PARTITION 2.63 - amiga_partition, 2.64 -#endif 2.65 -#ifdef CONFIG_ATARI_PARTITION 2.66 - atari_partition, 2.67 -#endif 2.68 -#ifdef CONFIG_MAC_PARTITION 2.69 - mac_partition, 2.70 -#endif 2.71 -#ifdef CONFIG_SGI_PARTITION 2.72 - sgi_partition, 2.73 -#endif 2.74 -#ifdef CONFIG_ULTRIX_PARTITION 2.75 - ultrix_partition, 2.76 -#endif 2.77 -#ifdef CONFIG_IBM_PARTITION 2.78 - ibm_partition, 2.79 -#endif 2.80 - NULL 2.81 -}; 2.82 - 2.83 -/* 2.84 - * This is ucking fugly but its probably the best thing for 2.4.x 2.85 - * Take it as a clear reminder than we should put the device name 2.86 - * generation in the object kdev_t points to in 2.5. 2.87 - */ 2.88 - 2.89 -#ifdef CONFIG_ARCH_S390 2.90 -int (*genhd_dasd_name)(char*,int,int,struct gendisk*) = NULL; 2.91 -EXPORT_SYMBOL(genhd_dasd_name); 2.92 -#endif 2.93 - 2.94 -/* 2.95 - * disk_name() is used by partition check code and the md driver. 2.96 - * It formats the devicename of the indicated disk into 2.97 - * the supplied buffer (of size at least 32), and returns 2.98 - * a pointer to that same buffer (for convenience). 2.99 - */ 2.100 - 2.101 -char *disk_name (struct gendisk *hd, int minor, char *buf) 2.102 -{ 2.103 - const char *maj = hd->major_name; 2.104 - unsigned int unit = (minor >> hd->minor_shift); 2.105 - unsigned int part = (minor & ((1 << hd->minor_shift) -1 )); 2.106 - 2.107 - if ((unit < hd->nr_real) && hd->part[minor].de) { 2.108 - int pos; 2.109 - 2.110 - pos = devfs_generate_path (hd->part[minor].de, buf, 64); 2.111 - if (pos >= 0) 2.112 - return buf + pos; 2.113 - } 2.114 - 2.115 -#ifdef CONFIG_ARCH_S390 2.116 - if (genhd_dasd_name 2.117 - && genhd_dasd_name (buf, unit, part, hd) == 0) 2.118 - return buf; 2.119 -#endif 2.120 - /* 2.121 - * IDE devices use multiple major numbers, but the drives 2.122 - * are named as: {hda,hdb}, {hdc,hdd}, {hde,hdf}, {hdg,hdh}.. 2.123 - * This requires special handling here. 2.124 - */ 2.125 - switch (hd->major) { 2.126 - case IDE9_MAJOR: 2.127 - unit += 2; 2.128 - case IDE8_MAJOR: 2.129 - unit += 2; 2.130 - case IDE7_MAJOR: 2.131 - unit += 2; 2.132 - case IDE6_MAJOR: 2.133 - unit += 2; 2.134 - case IDE5_MAJOR: 2.135 - unit += 2; 2.136 - case IDE4_MAJOR: 2.137 - unit += 2; 2.138 - case IDE3_MAJOR: 2.139 - unit += 2; 2.140 - case IDE2_MAJOR: 2.141 - unit += 2; 2.142 - case IDE1_MAJOR: 2.143 - unit += 2; 2.144 - case IDE0_MAJOR: 2.145 - maj = "hd"; 2.146 - break; 2.147 - case MD_MAJOR: 2.148 - sprintf(buf, "%s%d", maj, unit); 2.149 - return buf; 2.150 - } 2.151 - if (hd->major >= SCSI_DISK1_MAJOR && hd->major <= SCSI_DISK7_MAJOR) { 2.152 - unit = unit + (hd->major - SCSI_DISK1_MAJOR + 1) * 16; 2.153 - if (unit+'a' > 'z') { 2.154 - unit -= 26; 2.155 - sprintf(buf, "sd%c%c", 'a' + unit / 26, 'a' + unit % 26); 2.156 - if (part) 2.157 - sprintf(buf + 4, "%d", part); 2.158 - return buf; 2.159 - } 2.160 - } 2.161 - if (hd->major >= COMPAQ_SMART2_MAJOR && hd->major <= COMPAQ_SMART2_MAJOR+7) { 2.162 - int ctlr = hd->major - COMPAQ_SMART2_MAJOR; 2.163 - if (part == 0) 2.164 - sprintf(buf, "%s/c%dd%d", maj, ctlr, unit); 2.165 - else 2.166 - sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, unit, part); 2.167 - return buf; 2.168 - } 2.169 - if (hd->major >= COMPAQ_CISS_MAJOR && hd->major <= COMPAQ_CISS_MAJOR+7) { 2.170 - int ctlr = hd->major - COMPAQ_CISS_MAJOR; 2.171 - if (part == 0) 2.172 - sprintf(buf, "%s/c%dd%d", maj, ctlr, unit); 2.173 - else 2.174 - sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, unit, part); 2.175 - return buf; 2.176 - } 2.177 - if (hd->major >= DAC960_MAJOR && hd->major <= DAC960_MAJOR+7) { 2.178 - int ctlr = hd->major - DAC960_MAJOR; 2.179 - if (part == 0) 2.180 - sprintf(buf, "%s/c%dd%d", maj, ctlr, unit); 2.181 - else 2.182 - sprintf(buf, "%s/c%dd%dp%d", maj, ctlr, unit, part); 2.183 - return buf; 2.184 - } 2.185 - if (hd->major == ATARAID_MAJOR) { 2.186 - int disk = minor >> hd->minor_shift; 2.187 - int part = minor & (( 1 << hd->minor_shift) - 1); 2.188 - if (part == 0) 2.189 - sprintf(buf, "%s/d%d", maj, disk); 2.190 - else 2.191 - sprintf(buf, "%s/d%dp%d", maj, disk, part); 2.192 - return buf; 2.193 - } 2.194 - if (part) 2.195 - sprintf(buf, "%s%c%d", maj, unit+'a', part); 2.196 - else 2.197 - sprintf(buf, "%s%c", maj, unit+'a'); 2.198 - return buf; 2.199 -} 2.200 - 2.201 -/* 2.202 - * Add a partitions details to the devices partition description. 2.203 - */ 2.204 -void add_gd_partition(struct gendisk *hd, int minor, int start, int size) 2.205 -{ 2.206 -#ifndef CONFIG_DEVFS_FS 2.207 - char buf[40]; 2.208 -#endif 2.209 - 2.210 - hd->part[minor].start_sect = start; 2.211 - hd->part[minor].nr_sects = size; 2.212 -#ifdef CONFIG_DEVFS_FS 2.213 - printk(" p%d", (minor & ((1 << hd->minor_shift) - 1))); 2.214 -#else 2.215 - if ((hd->major >= COMPAQ_SMART2_MAJOR+0 && hd->major <= COMPAQ_SMART2_MAJOR+7) || 2.216 - (hd->major >= COMPAQ_CISS_MAJOR+0 && hd->major <= COMPAQ_CISS_MAJOR+7)) 2.217 - printk(" p%d", (minor & ((1 << hd->minor_shift) - 1))); 2.218 - else 2.219 - printk(" %s", disk_name(hd, minor, buf)); 2.220 -#endif 2.221 -} 2.222 - 2.223 -static void check_partition(struct gendisk *hd, kdev_t dev, int first_part_minor) 2.224 -{ 2.225 - devfs_handle_t de = NULL; 2.226 - static int first_time = 1; 2.227 - unsigned long first_sector; 2.228 - struct block_device *bdev; 2.229 - char buf[64]; 2.230 - int i; 2.231 - 2.232 - if (CHECK_DEBUG) printk (KERN_ALERT "check.c::check_partition\n"); 2.233 - 2.234 - if (first_time) 2.235 - printk(KERN_INFO "Partition check:\n"); 2.236 - first_time = 0; 2.237 - first_sector = hd->part[MINOR(dev)].start_sect; 2.238 - 2.239 - /* 2.240 - * This is a kludge to allow the partition check to be 2.241 - * skipped for specific drives (e.g. IDE CD-ROM drives) 2.242 - */ 2.243 - if ((int)first_sector == -1) { 2.244 - hd->part[MINOR(dev)].start_sect = 0; 2.245 - return; 2.246 - } 2.247 - 2.248 - if (hd->de_arr) 2.249 - de = hd->de_arr[MINOR(dev) >> hd->minor_shift]; 2.250 - i = devfs_generate_path (de, buf, sizeof buf); 2.251 - if (i >= 0) 2.252 - printk(KERN_INFO " /dev/%s:", buf + i); 2.253 - else 2.254 - printk(KERN_INFO " %s:", disk_name(hd, MINOR(dev), buf)); 2.255 - bdev = bdget(kdev_t_to_nr(dev)); 2.256 - bdev->bd_inode->i_size = (loff_t)hd->part[MINOR(dev)].nr_sects << 9; 2.257 - bdev->bd_inode->i_blkbits = blksize_bits(block_size(dev)); 2.258 - for (i = 0; check_part[i]; i++) { 2.259 - int res; 2.260 - res = check_part[i](hd, bdev, first_sector, first_part_minor); 2.261 - if (res) { 2.262 - if (res < 0 && warn_no_part) 2.263 - printk(" unable to read partition table\n"); 2.264 - goto setup_devfs; 2.265 - } 2.266 - } 2.267 - 2.268 - printk(" unknown partition table\n"); 2.269 -setup_devfs: 2.270 - invalidate_bdev(bdev, 1); 2.271 - truncate_inode_pages(bdev->bd_inode->i_mapping, 0); 2.272 - bdput(bdev); 2.273 - i = first_part_minor - 1; 2.274 - devfs_register_partitions (hd, i, hd->sizes ? 0 : 1); 2.275 -} 2.276 - 2.277 -#ifdef CONFIG_DEVFS_FS 2.278 -static void devfs_register_partition (struct gendisk *dev, int minor, int part) 2.279 -{ 2.280 - int devnum = minor >> dev->minor_shift; 2.281 - devfs_handle_t dir; 2.282 - unsigned int devfs_flags = DEVFS_FL_DEFAULT; 2.283 - char devname[16]; 2.284 - 2.285 - if (dev->part[minor + part].de) return; 2.286 - dir = devfs_get_parent (dev->part[minor].de); 2.287 - if (!dir) return; 2.288 - if ( dev->flags && (dev->flags[devnum] & GENHD_FL_REMOVABLE) ) 2.289 - devfs_flags |= DEVFS_FL_REMOVABLE; 2.290 - sprintf (devname, "part%d", part); 2.291 - dev->part[minor + part].de = 2.292 - devfs_register (dir, devname, devfs_flags, 2.293 - dev->major, minor + part, 2.294 - S_IFBLK | S_IRUSR | S_IWUSR, 2.295 - dev->fops, NULL); 2.296 -} 2.297 - 2.298 -static struct unique_numspace disc_numspace = UNIQUE_NUMBERSPACE_INITIALISER; 2.299 - 2.300 -static void devfs_register_disc (struct gendisk *dev, int minor) 2.301 -{ 2.302 - int pos = 0; 2.303 - int devnum = minor >> dev->minor_shift; 2.304 - devfs_handle_t dir, slave; 2.305 - unsigned int devfs_flags = DEVFS_FL_DEFAULT; 2.306 - char dirname[64], symlink[16]; 2.307 - static devfs_handle_t devfs_handle; 2.308 - 2.309 - if (dev->part[minor].de) return; 2.310 - if ( dev->flags && (dev->flags[devnum] & GENHD_FL_REMOVABLE) ) 2.311 - devfs_flags |= DEVFS_FL_REMOVABLE; 2.312 - if (dev->de_arr) { 2.313 - dir = dev->de_arr[devnum]; 2.314 - if (!dir) /* Aware driver wants to block disc management */ 2.315 - return; 2.316 - pos = devfs_generate_path (dir, dirname + 3, sizeof dirname-3); 2.317 - if (pos < 0) return; 2.318 - strncpy (dirname + pos, "../", 3); 2.319 - } 2.320 - else { 2.321 - /* Unaware driver: construct "real" directory */ 2.322 - sprintf (dirname, "../%s/disc%d", dev->major_name, devnum); 2.323 - dir = devfs_mk_dir (NULL, dirname + 3, NULL); 2.324 - } 2.325 - if (!devfs_handle) 2.326 - devfs_handle = devfs_mk_dir (NULL, "discs", NULL); 2.327 - dev->part[minor].number = devfs_alloc_unique_number (&disc_numspace); 2.328 - sprintf (symlink, "disc%d", dev->part[minor].number); 2.329 - devfs_mk_symlink (devfs_handle, symlink, DEVFS_FL_DEFAULT, 2.330 - dirname + pos, &slave, NULL); 2.331 - dev->part[minor].de = 2.332 - devfs_register (dir, "disc", devfs_flags, dev->major, minor, 2.333 - S_IFBLK | S_IRUSR | S_IWUSR, dev->fops, NULL); 2.334 - devfs_auto_unregister (dev->part[minor].de, slave); 2.335 - if (!dev->de_arr) 2.336 - devfs_auto_unregister (slave, dir); 2.337 -} 2.338 -#endif /* CONFIG_DEVFS_FS */ 2.339 - 2.340 -void devfs_register_partitions (struct gendisk *dev, int minor, int unregister) 2.341 -{ 2.342 -#ifdef CONFIG_DEVFS_FS 2.343 - int part; 2.344 - 2.345 - if (!unregister) 2.346 - devfs_register_disc (dev, minor); 2.347 - for (part = 1; part < dev->max_p; part++) { 2.348 - if ( unregister || (dev->part[part + minor].nr_sects < 1) ) { 2.349 - devfs_unregister (dev->part[part + minor].de); 2.350 - dev->part[part + minor].de = NULL; 2.351 - continue; 2.352 - } 2.353 - devfs_register_partition (dev, minor, part); 2.354 - } 2.355 - if (unregister) { 2.356 - devfs_unregister (dev->part[minor].de); 2.357 - dev->part[minor].de = NULL; 2.358 - devfs_dealloc_unique_number (&disc_numspace, 2.359 - dev->part[minor].number); 2.360 - } 2.361 -#endif /* CONFIG_DEVFS_FS */ 2.362 -} 2.363 - 2.364 -/* 2.365 - * This function will re-read the partition tables for a given device, 2.366 - * and set things back up again. There are some important caveats, 2.367 - * however. You must ensure that no one is using the device, and no one 2.368 - * can start using the device while this function is being executed. 2.369 - * 2.370 - * Much of the cleanup from the old partition tables should have already been 2.371 - * done 2.372 - */ 2.373 - 2.374 -void register_disk(struct gendisk *gdev, kdev_t dev, unsigned minors, 2.375 - struct block_device_operations *ops, long size) 2.376 -{ 2.377 - if (CHECK_DEBUG) 2.378 - { 2.379 - if (gdev != NULL) 2.380 - printk (KERN_ALERT 2.381 - "check.c::register_disk gdev:%p dev:%d min:%u ops:%p sz:%ld\n", 2.382 - gdev, dev, minors, ops, size); 2.383 - } 2.384 - 2.385 - if (!gdev) 2.386 - return; 2.387 - 2.388 - grok_partitions(gdev, MINOR(dev)>>gdev->minor_shift, minors, size); 2.389 -} 2.390 - 2.391 -void grok_partitions(struct gendisk *dev, int drive, unsigned minors, long size) 2.392 -{ 2.393 - int i; 2.394 - int first_minor = drive << dev->minor_shift; 2.395 - int end_minor = first_minor + dev->max_p; 2.396 - 2.397 - if (CHECK_DEBUG) printk (KERN_ALERT "check.c::grok_partitions\n"); 2.398 - 2.399 - if(!dev->sizes) 2.400 - blk_size[dev->major] = NULL; 2.401 - 2.402 - dev->part[first_minor].nr_sects = size; 2.403 - /* No such device or no minors to use for partitions */ 2.404 - if (!size || minors == 1) 2.405 - return; 2.406 - 2.407 - if (dev->sizes) { 2.408 - dev->sizes[first_minor] = size >> (BLOCK_SIZE_BITS - 9); 2.409 - for (i = first_minor + 1; i < end_minor; i++) 2.410 - dev->sizes[i] = 0; 2.411 - } 2.412 - blk_size[dev->major] = dev->sizes; 2.413 - check_partition(dev, MKDEV(dev->major, first_minor), 1 + first_minor); 2.414 - 2.415 - /* 2.416 - * We need to set the sizes array before we will be able to access 2.417 - * any of the partitions on this device. 2.418 - */ 2.419 - if (dev->sizes != NULL) { /* optional safeguard in ll_rw_blk.c */ 2.420 - for (i = first_minor; i < end_minor; i++) 2.421 - dev->sizes[i] = dev->part[i].nr_sects >> (BLOCK_SIZE_BITS - 9); 2.422 - } 2.423 -} 2.424 - 2.425 -unsigned char *read_dev_sector(struct block_device *bdev, unsigned long n, Sector *p) 2.426 -{ 2.427 - struct address_space *mapping = bdev->bd_inode->i_mapping; 2.428 - int sect = PAGE_CACHE_SIZE / 512; 2.429 - struct page *page; 2.430 - 2.431 - page = read_cache_page(mapping, n/sect, 2.432 - (filler_t *)mapping->a_ops->readpage, NULL); 2.433 - if (!IS_ERR(page)) { 2.434 - wait_on_page(page); 2.435 - if (!Page_Uptodate(page)) 2.436 - goto fail; 2.437 - if (PageError(page)) 2.438 - goto fail; 2.439 - p->v = page; 2.440 - return (unsigned char *)page_address(page) + 512 * (n % sect); 2.441 -fail: 2.442 - page_cache_release(page); 2.443 - } 2.444 - p->v = NULL; 2.445 - return NULL; 2.446 -}
3.1 --- a/xenolinux-2.4.16-sparse/fs/partitions/msdos.c Fri Feb 21 12:46:51 2003 +0000 3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 3.3 @@ -1,642 +0,0 @@ 3.4 -/* 3.5 - * fs/partitions/msdos.c 3.6 - * 3.7 - * Code extracted from drivers/block/genhd.c 3.8 - * Copyright (C) 1991-1998 Linus Torvalds 3.9 - * 3.10 - * Thanks to Branko Lankester, lankeste@fwi.uva.nl, who found a bug 3.11 - * in the early extended-partition checks and added DM partitions 3.12 - * 3.13 - * Support for DiskManager v6.0x added by Mark Lord, 3.14 - * with information provided by OnTrack. This now works for linux fdisk 3.15 - * and LILO, as well as loadlin and bootln. Note that disks other than 3.16 - * /dev/hda *must* have a "DOS" type 0x51 partition in the first slot (hda1). 3.17 - * 3.18 - * More flexible handling of extended partitions - aeb, 950831 3.19 - * 3.20 - * Check partition table on IDE disks for common CHS translations 3.21 - * 3.22 - * Re-organised Feb 1998 Russell King 3.23 - */ 3.24 - 3.25 -#include <linux/config.h> 3.26 -#include <linux/fs.h> 3.27 -#include <linux/genhd.h> 3.28 -#include <linux/kernel.h> 3.29 -#include <linux/major.h> 3.30 -#include <linux/string.h> 3.31 -#include <linux/blk.h> 3.32 - 3.33 -#ifdef CONFIG_BLK_DEV_IDE 3.34 -#include <linux/ide.h> /* IDE xlate */ 3.35 -#endif /* CONFIG_BLK_DEV_IDE */ 3.36 - 3.37 -#define MSDOS_DEBUG 0 3.38 - 3.39 -#include <asm/system.h> 3.40 - 3.41 -#include "check.h" 3.42 -#include "msdos.h" 3.43 - 3.44 -#if CONFIG_BLK_DEV_MD 3.45 -extern void md_autodetect_dev(kdev_t dev); 3.46 -#endif 3.47 - 3.48 -/* 3.49 - * Many architectures don't like unaligned accesses, which is 3.50 - * frequently the case with the nr_sects and start_sect partition 3.51 - * table entries. 3.52 - */ 3.53 -#include <asm/unaligned.h> 3.54 - 3.55 -#define SYS_IND(p) (get_unaligned(&p->sys_ind)) 3.56 -#define NR_SECTS(p) ({ __typeof__(p->nr_sects) __a = \ 3.57 - get_unaligned(&p->nr_sects); \ 3.58 - le32_to_cpu(__a); \ 3.59 - }) 3.60 - 3.61 -#define START_SECT(p) ({ __typeof__(p->start_sect) __a = \ 3.62 - get_unaligned(&p->start_sect); \ 3.63 - le32_to_cpu(__a); \ 3.64 - }) 3.65 - 3.66 -static inline int is_extended_partition(struct partition *p) 3.67 -{ 3.68 - return (SYS_IND(p) == DOS_EXTENDED_PARTITION || 3.69 - SYS_IND(p) == WIN98_EXTENDED_PARTITION || 3.70 - SYS_IND(p) == LINUX_EXTENDED_PARTITION); 3.71 -} 3.72 - 3.73 -/* 3.74 - * partition_name() formats the short partition name into the supplied 3.75 - * buffer, and returns a pointer to that buffer. 3.76 - * Used by several partition types which makes conditional inclusion messy, 3.77 - * use __attribute__ ((unused)) instead. 3.78 - */ 3.79 -static char __attribute__ ((unused)) 3.80 - *partition_name (struct gendisk *hd, int minor, char *buf) 3.81 -{ 3.82 -#ifdef CONFIG_DEVFS_FS 3.83 - sprintf(buf, "p%d", (minor & ((1 << hd->minor_shift) - 1))); 3.84 - return buf; 3.85 -#else 3.86 - return disk_name(hd, minor, buf); 3.87 -#endif 3.88 -} 3.89 - 3.90 -#define MSDOS_LABEL_MAGIC1 0x55 3.91 -#define MSDOS_LABEL_MAGIC2 0xAA 3.92 - 3.93 -static inline int 3.94 -msdos_magic_present(unsigned char *p) 3.95 -{ 3.96 - return (p[0] == MSDOS_LABEL_MAGIC1 && p[1] == MSDOS_LABEL_MAGIC2); 3.97 -} 3.98 - 3.99 -/* 3.100 - * Create devices for each logical partition in an extended partition. 3.101 - * The logical partitions form a linked list, with each entry being 3.102 - * a partition table with two entries. The first entry 3.103 - * is the real data partition (with a start relative to the partition 3.104 - * table start). The second is a pointer to the next logical partition 3.105 - * (with a start relative to the entire extended partition). 3.106 - * We do not create a Linux partition for the partition tables, but 3.107 - * only for the actual data partitions. 3.108 - */ 3.109 - 3.110 -static void extended_partition(struct gendisk *hd, struct block_device *bdev, 3.111 - int minor, unsigned long first_size, int *current_minor) 3.112 -{ 3.113 - struct partition *p; 3.114 - Sector sect; 3.115 - unsigned char *data; 3.116 - unsigned long first_sector, this_sector, this_size; 3.117 - int mask = (1 << hd->minor_shift) - 1; 3.118 - int sector_size = get_hardsect_size(to_kdev_t(bdev->bd_dev)) / 512; 3.119 - int loopct = 0; /* number of links followed 3.120 - without finding a data partition */ 3.121 - int i; 3.122 - 3.123 - this_sector = first_sector = hd->part[minor].start_sect; 3.124 - this_size = first_size; 3.125 - 3.126 - while (1) { 3.127 - if (++loopct > 100) 3.128 - return; 3.129 - if ((*current_minor & mask) == 0) 3.130 - return; 3.131 - data = read_dev_sector(bdev, this_sector, §); 3.132 - if (!data) 3.133 - return; 3.134 - 3.135 - if (!msdos_magic_present(data + 510)) 3.136 - goto done; 3.137 - 3.138 - p = (struct partition *) (data + 0x1be); 3.139 - 3.140 - /* 3.141 - * Usually, the first entry is the real data partition, 3.142 - * the 2nd entry is the next extended partition, or empty, 3.143 - * and the 3rd and 4th entries are unused. 3.144 - * However, DRDOS sometimes has the extended partition as 3.145 - * the first entry (when the data partition is empty), 3.146 - * and OS/2 seems to use all four entries. 3.147 - */ 3.148 - 3.149 - /* 3.150 - * First process the data partition(s) 3.151 - */ 3.152 - for (i=0; i<4; i++, p++) { 3.153 - unsigned long offs, size, next; 3.154 - if (!NR_SECTS(p) || is_extended_partition(p)) 3.155 - continue; 3.156 - 3.157 - /* Check the 3rd and 4th entries - 3.158 - these sometimes contain random garbage */ 3.159 - offs = START_SECT(p)*sector_size; 3.160 - size = NR_SECTS(p)*sector_size; 3.161 - next = this_sector + offs; 3.162 - if (i >= 2) { 3.163 - if (offs + size > this_size) 3.164 - continue; 3.165 - if (next < first_sector) 3.166 - continue; 3.167 - if (next + size > first_sector + first_size) 3.168 - continue; 3.169 - } 3.170 - 3.171 - add_gd_partition(hd, *current_minor, next, size); 3.172 -#if CONFIG_BLK_DEV_MD 3.173 - if (SYS_IND(p) == LINUX_RAID_PARTITION) { 3.174 - md_autodetect_dev(MKDEV(hd->major,*current_minor)); 3.175 - } 3.176 -#endif 3.177 - 3.178 - (*current_minor)++; 3.179 - loopct = 0; 3.180 - if ((*current_minor & mask) == 0) 3.181 - goto done; 3.182 - } 3.183 - /* 3.184 - * Next, process the (first) extended partition, if present. 3.185 - * (So far, there seems to be no reason to make 3.186 - * extended_partition() recursive and allow a tree 3.187 - * of extended partitions.) 3.188 - * It should be a link to the next logical partition. 3.189 - * Create a minor for this just long enough to get the next 3.190 - * partition table. The minor will be reused for the next 3.191 - * data partition. 3.192 - */ 3.193 - p -= 4; 3.194 - for (i=0; i<4; i++, p++) 3.195 - if (NR_SECTS(p) && is_extended_partition(p)) 3.196 - break; 3.197 - if (i == 4) 3.198 - goto done; /* nothing left to do */ 3.199 - 3.200 - this_sector = first_sector + START_SECT(p) * sector_size; 3.201 - this_size = NR_SECTS(p) * sector_size; 3.202 - minor = *current_minor; 3.203 - put_dev_sector(sect); 3.204 - } 3.205 -done: 3.206 - put_dev_sector(sect); 3.207 -} 3.208 - 3.209 -/* james@bpgc.com: Solaris has a nasty indicator: 0x82 which also 3.210 - indicates linux swap. Be careful before believing this is Solaris. */ 3.211 - 3.212 -static void 3.213 -solaris_x86_partition(struct gendisk *hd, struct block_device *bdev, 3.214 - int minor, int *current_minor) 3.215 -{ 3.216 - 3.217 -#ifdef CONFIG_SOLARIS_X86_PARTITION 3.218 - long offset = hd->part[minor].start_sect; 3.219 - Sector sect; 3.220 - struct solaris_x86_vtoc *v; 3.221 - struct solaris_x86_slice *s; 3.222 - int mask = (1 << hd->minor_shift) - 1; 3.223 - int i; 3.224 - char buf[40]; 3.225 - 3.226 - v = (struct solaris_x86_vtoc *)read_dev_sector(bdev, offset+1, §); 3.227 - if (!v) 3.228 - return; 3.229 - if (le32_to_cpu(v->v_sanity) != SOLARIS_X86_VTOC_SANE) { 3.230 - put_dev_sector(sect); 3.231 - return; 3.232 - } 3.233 - printk(" %s: <solaris:", partition_name(hd, minor, buf)); 3.234 - if (le32_to_cpu(v->v_version) != 1) { 3.235 - printk(" cannot handle version %d vtoc>\n", 3.236 - le32_to_cpu(v->v_version)); 3.237 - put_dev_sector(sect); 3.238 - return; 3.239 - } 3.240 - for (i=0; i<SOLARIS_X86_NUMSLICE; i++) { 3.241 - if ((*current_minor & mask) == 0) 3.242 - break; 3.243 - s = &v->v_slice[i]; 3.244 - 3.245 - if (s->s_size == 0) 3.246 - continue; 3.247 - printk(" [s%d]", i); 3.248 - /* solaris partitions are relative to current MS-DOS 3.249 - * one but add_gd_partition starts relative to sector 3.250 - * zero of the disk. Therefore, must add the offset 3.251 - * of the current partition */ 3.252 - add_gd_partition(hd, *current_minor, 3.253 - le32_to_cpu(s->s_start)+offset, 3.254 - le32_to_cpu(s->s_size)); 3.255 - (*current_minor)++; 3.256 - } 3.257 - put_dev_sector(sect); 3.258 - printk(" >\n"); 3.259 -#endif 3.260 -} 3.261 - 3.262 -#ifdef CONFIG_BSD_DISKLABEL 3.263 -static void 3.264 -check_and_add_bsd_partition(struct gendisk *hd, struct bsd_partition *bsd_p, 3.265 - int minor, int *current_minor) 3.266 -{ 3.267 - struct hd_struct *lin_p; 3.268 - /* check relative position of partitions. */ 3.269 - for (lin_p = hd->part + 1 + minor; 3.270 - lin_p - hd->part - minor < *current_minor; lin_p++) { 3.271 - /* no relationship -> try again */ 3.272 - if (lin_p->start_sect + lin_p->nr_sects <= le32_to_cpu(bsd_p->p_offset) || 3.273 - lin_p->start_sect >= le32_to_cpu(bsd_p->p_offset) + le32_to_cpu(bsd_p->p_size)) 3.274 - continue; 3.275 - /* equal -> no need to add */ 3.276 - if (lin_p->start_sect == le32_to_cpu(bsd_p->p_offset) && 3.277 - lin_p->nr_sects == le32_to_cpu(bsd_p->p_size)) 3.278 - return; 3.279 - /* bsd living within dos partition */ 3.280 - if (lin_p->start_sect <= le32_to_cpu(bsd_p->p_offset) && lin_p->start_sect 3.281 - + lin_p->nr_sects >= le32_to_cpu(bsd_p->p_offset) + le32_to_cpu(bsd_p->p_size)) { 3.282 -#ifdef DEBUG_BSD_DISKLABEL 3.283 - printk("w: %d %ld+%ld,%d+%d", 3.284 - lin_p - hd->part, 3.285 - lin_p->start_sect, lin_p->nr_sects, 3.286 - le32_to_cpu(bsd_p->p_offset), 3.287 - le32_to_cpu(bsd_p->p_size)); 3.288 -#endif 3.289 - break; 3.290 - } 3.291 - /* ouch: bsd and linux overlap. Don't even try for that partition */ 3.292 -#ifdef DEBUG_BSD_DISKLABEL 3.293 - printk("???: %d %ld+%ld,%d+%d", 3.294 - lin_p - hd->part, lin_p->start_sect, lin_p->nr_sects, 3.295 - le32_to_cpu(bsd_p->p_offset), le32_to_cpu(bsd_p->p_size)); 3.296 -#endif 3.297 - printk("???"); 3.298 - return; 3.299 - } /* if the bsd partition is not currently known to linux, we end 3.300 - * up here 3.301 - */ 3.302 - add_gd_partition(hd, *current_minor, le32_to_cpu(bsd_p->p_offset), 3.303 - le32_to_cpu(bsd_p->p_size)); 3.304 - (*current_minor)++; 3.305 -} 3.306 - 3.307 -/* 3.308 - * Create devices for BSD partitions listed in a disklabel, under a 3.309 - * dos-like partition. See extended_partition() for more information. 3.310 - */ 3.311 -static void do_bsd_partition(struct gendisk *hd, struct block_device *bdev, 3.312 - int minor, int *current_minor, char *name, int max_partitions) 3.313 -{ 3.314 - long offset = hd->part[minor].start_sect; 3.315 - Sector sect; 3.316 - struct bsd_disklabel *l; 3.317 - struct bsd_partition *p; 3.318 - int mask = (1 << hd->minor_shift) - 1; 3.319 - char buf[40]; 3.320 - 3.321 - l = (struct bsd_disklabel *)read_dev_sector(bdev, offset+1, §); 3.322 - if (!l) 3.323 - return; 3.324 - if (le32_to_cpu(l->d_magic) != BSD_DISKMAGIC) { 3.325 - put_dev_sector(sect); 3.326 - return; 3.327 - } 3.328 - printk(" %s: <%s", partition_name(hd, minor, buf), name); 3.329 - 3.330 - if (le16_to_cpu(l->d_npartitions) < max_partitions) 3.331 - max_partitions = le16_to_cpu(l->d_npartitions); 3.332 - for (p = l->d_partitions; p - l->d_partitions < max_partitions; p++) { 3.333 - if ((*current_minor & mask) == 0) 3.334 - break; 3.335 - if (p->p_fstype == BSD_FS_UNUSED) 3.336 - continue; 3.337 - check_and_add_bsd_partition(hd, p, minor, current_minor); 3.338 - } 3.339 - put_dev_sector(sect); 3.340 - printk(" >\n"); 3.341 -} 3.342 -#endif 3.343 - 3.344 -static void bsd_partition(struct gendisk *hd, struct block_device *bdev, 3.345 - int minor, int *current_minor) 3.346 -{ 3.347 -#ifdef CONFIG_BSD_DISKLABEL 3.348 - do_bsd_partition(hd, bdev, minor, current_minor, "bsd", 3.349 - BSD_MAXPARTITIONS); 3.350 -#endif 3.351 -} 3.352 - 3.353 -static void netbsd_partition(struct gendisk *hd, struct block_device *bdev, 3.354 - int minor, int *current_minor) 3.355 -{ 3.356 -#ifdef CONFIG_BSD_DISKLABEL 3.357 - do_bsd_partition(hd, bdev, minor, current_minor, "netbsd", 3.358 - BSD_MAXPARTITIONS); 3.359 -#endif 3.360 -} 3.361 - 3.362 -static void openbsd_partition(struct gendisk *hd, struct block_device *bdev, 3.363 - int minor, int *current_minor) 3.364 -{ 3.365 -#ifdef CONFIG_BSD_DISKLABEL 3.366 - do_bsd_partition(hd, bdev, minor, current_minor, 3.367 - "openbsd", OPENBSD_MAXPARTITIONS); 3.368 -#endif 3.369 -} 3.370 - 3.371 -/* 3.372 - * Create devices for Unixware partitions listed in a disklabel, under a 3.373 - * dos-like partition. See extended_partition() for more information. 3.374 - */ 3.375 -static void unixware_partition(struct gendisk *hd, struct block_device *bdev, 3.376 - int minor, int *current_minor) 3.377 -{ 3.378 -#ifdef CONFIG_UNIXWARE_DISKLABEL 3.379 - long offset = hd->part[minor].start_sect; 3.380 - Sector sect; 3.381 - struct unixware_disklabel *l; 3.382 - struct unixware_slice *p; 3.383 - int mask = (1 << hd->minor_shift) - 1; 3.384 - char buf[40]; 3.385 - 3.386 - l = (struct unixware_disklabel *)read_dev_sector(bdev, offset+29, §); 3.387 - if (!l) 3.388 - return; 3.389 - if (le32_to_cpu(l->d_magic) != UNIXWARE_DISKMAGIC || 3.390 - le32_to_cpu(l->vtoc.v_magic) != UNIXWARE_DISKMAGIC2) { 3.391 - put_dev_sector(sect); 3.392 - return; 3.393 - } 3.394 - printk(" %s: <unixware:", partition_name(hd, minor, buf)); 3.395 - p = &l->vtoc.v_slice[1]; 3.396 - /* I omit the 0th slice as it is the same as whole disk. */ 3.397 - while (p - &l->vtoc.v_slice[0] < UNIXWARE_NUMSLICE) { 3.398 - if ((*current_minor & mask) == 0) 3.399 - break; 3.400 - 3.401 - if (p->s_label != UNIXWARE_FS_UNUSED) { 3.402 - add_gd_partition(hd, *current_minor, START_SECT(p), 3.403 - NR_SECTS(p)); 3.404 - (*current_minor)++; 3.405 - } 3.406 - p++; 3.407 - } 3.408 - put_dev_sector(sect); 3.409 - printk(" >\n"); 3.410 -#endif 3.411 -} 3.412 - 3.413 -/* 3.414 - * Minix 2.0.0/2.0.2 subpartition support. 3.415 - * Anand Krishnamurthy <anandk@wiproge.med.ge.com> 3.416 - * Rajeev V. Pillai <rajeevvp@yahoo.com> 3.417 - */ 3.418 -static void minix_partition(struct gendisk *hd, struct block_device *bdev, 3.419 - int minor, int *current_minor) 3.420 -{ 3.421 -#ifdef CONFIG_MINIX_SUBPARTITION 3.422 - long offset = hd->part[minor].start_sect; 3.423 - Sector sect; 3.424 - unsigned char *data; 3.425 - struct partition *p; 3.426 - int mask = (1 << hd->minor_shift) - 1; 3.427 - int i; 3.428 - char buf[40]; 3.429 - 3.430 - data = read_dev_sector(bdev, offset, §); 3.431 - if (!data) 3.432 - return; 3.433 - 3.434 - p = (struct partition *)(data + 0x1be); 3.435 - 3.436 - /* The first sector of a Minix partition can have either 3.437 - * a secondary MBR describing its subpartitions, or 3.438 - * the normal boot sector. */ 3.439 - if (msdos_magic_present (data + 510) && 3.440 - SYS_IND(p) == MINIX_PARTITION) { /* subpartition table present */ 3.441 - 3.442 - printk(" %s: <minix:", partition_name(hd, minor, buf)); 3.443 - for (i = 0; i < MINIX_NR_SUBPARTITIONS; i++, p++) { 3.444 - if ((*current_minor & mask) == 0) 3.445 - break; 3.446 - /* add each partition in use */ 3.447 - if (SYS_IND(p) == MINIX_PARTITION) { 3.448 - add_gd_partition(hd, *current_minor, 3.449 - START_SECT(p), NR_SECTS(p)); 3.450 - (*current_minor)++; 3.451 - } 3.452 - } 3.453 - printk(" >\n"); 3.454 - } 3.455 - put_dev_sector(sect); 3.456 -#endif /* CONFIG_MINIX_SUBPARTITION */ 3.457 -} 3.458 - 3.459 -static struct { 3.460 - unsigned char id; 3.461 - void (*parse)(struct gendisk *, struct block_device *, int, int *); 3.462 -} subtypes[] = { 3.463 - {BSD_PARTITION, bsd_partition}, 3.464 - {NETBSD_PARTITION, netbsd_partition}, 3.465 - {OPENBSD_PARTITION, openbsd_partition}, 3.466 - {MINIX_PARTITION, minix_partition}, 3.467 - {UNIXWARE_PARTITION, unixware_partition}, 3.468 - {SOLARIS_X86_PARTITION, solaris_x86_partition}, 3.469 - {0, NULL}, 3.470 -}; 3.471 -/* 3.472 - * Look for various forms of IDE disk geometry translation 3.473 - */ 3.474 -static int handle_ide_mess(struct block_device *bdev) 3.475 -{ 3.476 -#ifdef CONFIG_BLK_DEV_IDE 3.477 - Sector sect; 3.478 - unsigned char *data; 3.479 - kdev_t dev = to_kdev_t(bdev->bd_dev); 3.480 - unsigned int sig; 3.481 - int heads = 0; 3.482 - struct partition *p; 3.483 - int i; 3.484 - 3.485 - if (MSDOS_DEBUG) 3.486 - printk (KERN_ALERT "handle_ide_mess ------------\n"); 3.487 - 3.488 - /* 3.489 - * The i386 partition handling programs very often 3.490 - * make partitions end on cylinder boundaries. 3.491 - * There is no need to do so, and Linux fdisk doesnt always 3.492 - * do this, and Windows NT on Alpha doesnt do this either, 3.493 - * but still, this helps to guess #heads. 3.494 - */ 3.495 - data = read_dev_sector(bdev, 0, §); 3.496 - if (!data) 3.497 - return -1; 3.498 - if (!msdos_magic_present(data + 510)) { 3.499 - put_dev_sector(sect); 3.500 - return 0; 3.501 - } 3.502 - sig = le16_to_cpu(*(unsigned short *)(data + 2)); 3.503 - p = (struct partition *) (data + 0x1be); 3.504 - for (i = 0; i < 4; i++) { 3.505 - struct partition *q = &p[i]; 3.506 - if (NR_SECTS(q)) { 3.507 - if ((q->sector & 63) == 1 && 3.508 - (q->end_sector & 63) == 63) 3.509 - heads = q->end_head + 1; 3.510 - break; 3.511 - } 3.512 - } 3.513 - if (SYS_IND(p) == EZD_PARTITION) { 3.514 - /* 3.515 - * Accesses to sector 0 must go to sector 1 instead. 3.516 - */ 3.517 - if (ide_xlate_1024(dev, -1, heads, " [EZD]")) 3.518 - goto reread; 3.519 - } else if (SYS_IND(p) == DM6_PARTITION) { 3.520 - 3.521 - /* 3.522 - * Everything on the disk is offset by 63 sectors, 3.523 - * including a "new" MBR with its own partition table. 3.524 - */ 3.525 - if (ide_xlate_1024(dev, 1, heads, " [DM6:DDO]")) 3.526 - goto reread; 3.527 - } else if (sig <= 0x1ae && 3.528 - data[sig] == 0xAA && data[sig+1] == 0x55 && 3.529 - (data[sig+2] & 1)) { 3.530 - /* DM6 signature in MBR, courtesy of OnTrack */ 3.531 - (void) ide_xlate_1024 (dev, 0, heads, " [DM6:MBR]"); 3.532 - } else if (SYS_IND(p) == DM6_AUX1PARTITION || 3.533 - SYS_IND(p) == DM6_AUX3PARTITION) { 3.534 - /* 3.535 - * DM6 on other than the first (boot) drive 3.536 - */ 3.537 - (void) ide_xlate_1024(dev, 0, heads, " [DM6:AUX]"); 3.538 - } else { 3.539 - (void) ide_xlate_1024(dev, 2, heads, " [PTBL]"); 3.540 - } 3.541 - put_dev_sector(sect); 3.542 - 3.543 - if (MSDOS_DEBUG) 3.544 - printk (KERN_ALERT "handle_ide_mess -------- %d\n", heads); 3.545 - return 1; 3.546 - 3.547 -reread: 3.548 - put_dev_sector(sect); 3.549 - /* Flush the cache */ 3.550 - invalidate_bdev(bdev, 1); 3.551 - truncate_inode_pages(bdev->bd_inode->i_mapping, 0); 3.552 -#endif /* CONFIG_BLK_DEV_IDE */ 3.553 - return 1; 3.554 -} 3.555 - 3.556 -int msdos_partition(struct gendisk *hd, struct block_device *bdev, 3.557 - unsigned long first_sector, int first_part_minor) 3.558 -{ 3.559 - int i, minor = first_part_minor; 3.560 - Sector sect; 3.561 - struct partition *p; 3.562 - unsigned char *data; 3.563 - int mask = (1 << hd->minor_shift) - 1; 3.564 - int sector_size = get_hardsect_size(to_kdev_t(bdev->bd_dev)) / 512; 3.565 - int current_minor = first_part_minor; 3.566 - int err; 3.567 - 3.568 - if (MSDOS_DEBUG) printk (KERN_ALERT "msdos.c::msdos_partition\n"); 3.569 - err = handle_ide_mess(bdev); 3.570 - if (err <= 0) 3.571 - return err; 3.572 - data = read_dev_sector(bdev, 0, §); 3.573 - if (!data) 3.574 - return -1; 3.575 - if (!msdos_magic_present(data + 510)) { 3.576 - put_dev_sector(sect); 3.577 - return 0; 3.578 - } 3.579 - p = (struct partition *) (data + 0x1be); 3.580 - 3.581 - /* 3.582 - * Look for partitions in two passes: 3.583 - * First find the primary and DOS-type extended partitions. 3.584 - * On the second pass look inside *BSD, Unixware and Solaris partitions. 3.585 - */ 3.586 - 3.587 - current_minor += 4; 3.588 - for (i=1 ; i<=4 ; minor++,i++,p++) { 3.589 - if (!NR_SECTS(p)) 3.590 - continue; 3.591 - add_gd_partition(hd, minor, 3.592 - first_sector+START_SECT(p)*sector_size, 3.593 - NR_SECTS(p)*sector_size); 3.594 -#if CONFIG_BLK_DEV_MD 3.595 - if (SYS_IND(p) == LINUX_RAID_PARTITION) { 3.596 - md_autodetect_dev(MKDEV(hd->major,minor)); 3.597 - } 3.598 -#endif 3.599 - if (is_extended_partition(p)) { 3.600 - unsigned long size = hd->part[minor].nr_sects; 3.601 - printk(" <"); 3.602 - /* prevent someone doing mkfs or mkswap on an 3.603 - extended partition, but leave room for LILO */ 3.604 - if (size > 2) 3.605 - hd->part[minor].nr_sects = 2; 3.606 - extended_partition(hd, bdev, minor, size, ¤t_minor); 3.607 - printk(" >"); 3.608 - } 3.609 - } 3.610 - 3.611 - /* 3.612 - * Check for old-style Disk Manager partition table 3.613 - */ 3.614 - if (msdos_magic_present(data + 0xfc)) { 3.615 - p = (struct partition *) (0x1be + data); 3.616 - for (i = 4 ; i < 16 ; i++, current_minor++) { 3.617 - p--; 3.618 - if ((current_minor & mask) == 0) 3.619 - break; 3.620 - if (!(START_SECT(p) && NR_SECTS(p))) 3.621 - continue; 3.622 - add_gd_partition(hd, current_minor, START_SECT(p), NR_SECTS(p)); 3.623 - } 3.624 - } 3.625 - printk("\n"); 3.626 - 3.627 - /* second pass - output for each on a separate line */ 3.628 - minor -= 4; 3.629 - p = (struct partition *) (0x1be + data); 3.630 - for (i=1 ; i<=4 ; minor++,i++,p++) { 3.631 - unsigned char id = SYS_IND(p); 3.632 - int n; 3.633 - 3.634 - if (!NR_SECTS(p)) 3.635 - continue; 3.636 - 3.637 - for (n = 0; subtypes[n].parse && id != subtypes[n].id; n++) 3.638 - ; 3.639 - 3.640 - if (subtypes[n].parse) 3.641 - subtypes[n].parse(hd, bdev, minor, ¤t_minor); 3.642 - } 3.643 - put_dev_sector(sect); 3.644 - return 1; 3.645 -}