示例#1
0
void partitioning<Grid>::read_partition(std::istream& in)
{ 
 int p;
 partial_mapping<int,int> part_nums(-1);
 CellIterator C = TheGrid().FirstCell();
 
 
 char c;
 in >> c;
 in.putback(c);
 if(isdigit(c)) {
   while(in && ! C.IsDone()) {
     in >> p;
     int np = ranges.size()-1; //NumOfPartitions();
     for( int pp = 0; pp <= p - np; ++pp)
       add_partition();
     // if( part_nums(p) == -1) {
     //  part_nums[p] = add_partition();
     // }
     add_cell(p,*C);
     ++C;
   }
   if(!in && ! C.IsDone()) {
     std::cerr << "partitioning<Grid>::read_partition(): input ended prematurely!\n"
	       << "creating new partition for the remaining cells.\n";
     p = add_partition();
     while(! C.IsDone()) {
       add_cell(p,*C);
       ++C;
     }
   }
 }
 else {
示例#2
0
static void key_callback(GLFWwindow* window, int key, int scancode, int action, int mods)
{
    // Get render_state from GLFW user pointer
    render_t *render_state = glfwGetWindowUserPointer(window);

    if(action == GLFW_PRESS || action == GLFW_REPEAT)
    {

        // Let renderer know of activity
        set_activity_time(render_state);

        switch(key)
        { 
            case GLFW_KEY_ESCAPE:
                toggle_quit_mode(render_state);              
	        break;
            case GLFW_KEY_RIGHT:
                increase_parameter(render_state);
                break;
            case GLFW_KEY_LEFT:
                decrease_parameter(render_state);
                break;
            case GLFW_KEY_UP:
                move_parameter_up(render_state);
                break;
            case GLFW_KEY_DOWN:
                move_parameter_down(render_state);
                break;
            case GLFW_KEY_LEFT_BRACKET:
                remove_partition(render_state);
                break;
            case GLFW_KEY_RIGHT_BRACKET:
                add_partition(render_state);
                break;
            case GLFW_KEY_X:
                set_fluid_x(render_state);
                break;
            case GLFW_KEY_Y:
                set_fluid_y(render_state);
                break;
            case GLFW_KEY_A:
                if(render_state->quit_mode)
                    exit_with_selected_program(render_state, window);
                set_fluid_a(render_state);
                break;
            case GLFW_KEY_B:
                set_fluid_b(render_state);
                break;
            case GLFW_KEY_D:
                toggle_dividers(render_state);
                break;
            case GLFW_KEY_P:
                toggle_pause(render_state);
                break;
            case GLFW_KEY_L:
                toggle_liquid(render_state);
                break;
        }
    }
}
示例#3
0
文件: genhd.c 项目: andreiw/mkunity
/* 
 * Create devices for BSD partitions listed in a disklabel, under a
 * dos-like partition. See extended_partition() for more information.
 */
static void bsd_disklabel_partition(struct gendisk *hd, kdev_t dev)
{
	struct buffer_head *bh;
	struct bsd_disklabel *l;
	struct bsd_partition *p;
	int mask = (1 << hd->minor_shift) - 1;

	if (!(bh = bread(dev,0,1024)))
		return;
	bh->b_state = 0;
	l = (struct bsd_disklabel *) (bh->b_data+512);
	if (l->d_magic != BSD_DISKMAGIC) {
		brelse(bh);
		return;
	}

	p = &l->d_partitions[0];
	while (p - &l->d_partitions[0] <= BSD_MAXPARTITIONS) {
		if ((current_minor & mask) >= (4 + hd->max_p))
			break;

		if (p->p_fstype != BSD_FS_UNUSED) {
			add_partition(hd, current_minor, p->p_offset, p->p_size);
			current_minor++;
		}
		p++;
	}
	brelse(bh);

}
示例#4
0
int do_spi_create (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
#if defined (CONFIG_APP_IN_SPI)
    unsigned int size=0;
    int ret=0;
    UBOOT_TRACE("IN\n");
    if(argc!=CREATE_PARTITION_INPUT_LEN)
    {
        cmd_usage(cmdtp);
        return -1;
    }
    size=simple_strtol(argv[2], NULL,16);
    ret=add_partition(argv[1],size);
    if(ret==0)
    {
        UBOOT_TRACE("OK\n");    
    }
    else
    {
        UBOOT_ERROR("create partition fail\n");
    }
    return ret;
#else
    UBOOT_TRACE("IN\n");
    UBOOT_ERROR("This function doesn't support\n");
    return -1;
#endif
}
/**
 * add_card_partition : add card partition , refer to 
 * board-****.c  inand_partition_info[]
 * @disk: add partitions in which disk
 * @part: partition table
 * @nr_part: partition numbers
 */
int add_card_partition(struct memory_card* card, struct gendisk * disk,
                              struct mtd_partition * part, unsigned int nr_part)
{
	unsigned int i;
	struct hd_struct * ret=NULL;
	uint64_t cur_offset=0;
	uint64_t offset, size;
	
	if(!part)
		return 0;

	for(i=0; i<nr_part; i++){
		offset = part[i].offset>>9;
		size = part[i].size>>9;
		if (part[i].offset== MTDPART_OFS_APPEND)
			offset = cur_offset;
		if (part[i].size == MTDPART_SIZ_FULL)
		{
			size = disk->part0.nr_sects - offset;
#ifdef CONFIG_INAND_LP
			printk("[%s%d] %20s  offset 0x%012llx, len 0x%012llx %s\n",
					disk->disk_name, 1+i, part[i].name, offset<<9, size<<9,
					IS_ERR(ret) ? "add fail":"");
			break;
#endif
		}
		ret = add_partition(disk, 1+i, offset, size, 0,NULL);//change by leo
		printk("[%s%d] %20s  offset 0x%012llx, len 0x%012llx %s\n",
				disk->disk_name, 1+i, part[i].name, offset<<9, size<<9,
				IS_ERR(ret) ? "add fail":"");

		//if(IS_ERR(ret)){
		//	printk("errno = %d, offset = %x, size = %x, disk->part0.nr_sects = %x\n", ret, offset, size);
		//	return ERR_PTR(ret);
		//}
		cur_offset = offset + size;
		
		card_table[i] = &part[i];
		card_table[i]->offset = offset<<9;
		card_table[i]->size = size<<9;
	}

#ifdef CONFIG_PROC_FS
	if (!proc_card && (proc_card = create_proc_entry( "inand", 0, NULL )))
		proc_card->read_proc = card_read_proc;
#endif /* CONFIG_PROC_FS */

	return 0;
}
示例#6
0
void get_partition(unsigned char * data, unsigned disk, unsigned MBROffset)
{
	if(data[MBROffset] != 0){
		uint32_t startSector = *((uint32_t *)&data[MBROffset + 8]);
		uint32_t sectors = *((uint32_t *)&data[MBROffset + 12]);
		if((startSector + sectors) <= hdd_devices[disk].sectorCount){
			struct PARTITION p;
			p.disk = disk;
			p.startSector = startSector;
			p.sectors = sectors;
			p.fileSystem = 0;
			
			add_partition(&p);
		}
	}
}
示例#7
0
void partition_manager_init()
{
	for(unsigned i = 0; i < (sizeof(struct PARTITION) * MAX_PARTITIONS); i++){
		((char *)&partitions)[i] = 0;
	}
	
	for(int i = 0; i < HDD_MAX_DEVICES; i++){
		if(hdd_devices[i].exists){
			unsigned char bootSector[512];
			int err = hdd_read_sectors((uint16_t *) &bootSector[0], 1, i, 0);
			if(err != 0) continue;// Abandon Drive!
			if(!is_mbr(&bootSector[0])){
				struct PARTITION p;
				p.disk = i;
				p.startSector = 0;
				p.sectors = hdd_devices[i].sectorCount;
				p.fileSystem = 0;
			
				add_partition(&p);
			} else {
				get_partitions(&bootSector[0], i);
			}
			
		}
	}
	
	for(int i = 0; i < MAX_PARTITIONS; i++){
		if (partitions[i].present){
			unsigned char bootSector[512];
			int err = hdd_read_sectors((uint16_t *) &bootSector[0], 1, partitions[i].disk, partitions[i].startSector);
			if (err == 0){
				if(is_fat_boot_sector(&bootSector[0])){
					// FAT
				} else if(is_ext_file_system(&partitions[i])){
					// EXT
				}
			}
		}
	}
	
}
示例#8
0
文件: fdisk.c 项目: HarryR/sanos
int main(int argc, char *argv[]) {
  int rc;
  int cmd;
  int done = 0;

  // Check arguments
  if (argc == 1) {
    devname = "/dev/hd0";
  } else if (argc == 2) {
    devname = argv[1];
  } else {
    printf("usage: fdisk <device>\n");
    return 1;
  }

  // Open device
  hdev = open(devname, O_RDWR | O_BINARY);
  if (hdev < 0) {
    printf("%s: error %d opening device\n", devname, errno);
    return 1;
  }

  // Get disk geometry
  rc = ioctl(hdev, IOCTL_GETGEOMETRY, &geom , sizeof(struct geometry));
  if (rc < 0) {
    printf("%s: error %d determining disk geometry\n", devname, errno);
    close(hdev);
    return 1;
  }

  // Read master boot record
  rc = read_mbr();
  if (rc < 0 && errno != EINVAL) {
    printf("%s: error %d reading master boot record\n", devname, errno);
    close(hdev);
    return 1;
  }

  // Ask to create new master boot record if the existing is invalid
  if (rc < 0 && errno == EINVAL) {
    printf("%s: invalid master boot record\n", devname);
    if (ask("create new master boot record (y/n)? ", "yn") == 'y') {
      memcpy(&mbr, bootrecord, sizeof(mbr));
    }
  }

  // Read commands
  printf("(a)dd (b)oot (c)ommit (d)elete (l)ist (m)br (h)elp e(x)it\n");
  while (!done) {
    cmd = ask("fdisk> ", "abcdlmhx?");

    switch (cmd) {
      case 'a':
        add_partition();
        break;

      case 'b':
        set_boot_part();
        break;

      case 'c':
        commit_mbr();
        break;

      case 'd':
        delete_partition();
        break;

      case 'l':
        list_partitions();
        break;

      case 'm':
        clear_mbr();
        break;

      case 'h':
      case '?':
        help();
        break;

      case 'x':
        done = 1;
        break;
    }
  }

  // Close device
  close(hdev);
  return 0;
}
示例#9
0
文件: genhd.c 项目: andreiw/mkunity
static int
amiga_partition(struct gendisk *hd, unsigned int dev, unsigned long first_sector)
{
	struct buffer_head	*bh;
	struct RigidDiskBlock	*rdb;
	struct PartitionBlock	*pb;
	int			 start_sect;
	int			 nr_sects;
	int			 blk;
	int			 part, res;

	set_blocksize(dev,512);
	res = 0;

	for (blk = 0; blk < RDB_ALLOCATION_LIMIT; blk++) {
		if(!(bh = bread(dev,blk,512))) {
			printk("Dev %d: unable to read RDB block %d\n",dev,blk);
			goto rdb_done;
		}
		if (*(__u32 *)bh->b_data == htonl(IDNAME_RIGIDDISK)) {
			rdb = (struct RigidDiskBlock *)bh->b_data;
			if (checksum_block((__u32 *)bh->b_data,htonl(rdb->rdb_SummedLongs) & 0x7F)) {
				printk("Dev %d: RDB in block %d has bad checksum\n",dev,blk);
				brelse(bh);
				continue;
			}
			printk(" RDSK");
			blk = htonl(rdb->rdb_PartitionList);
			brelse(bh);
			for (part = 1; blk > 0 && part <= 16; part++) {
				if (!(bh = bread(dev,blk,512))) {
					printk("Dev %d: unable to read partition block %d\n",
						       dev,blk);
					goto rdb_done;
				}
				pb  = (struct PartitionBlock *)bh->b_data;
				blk = htonl(pb->pb_Next);
				if (pb->pb_ID == htonl(IDNAME_PARTITION) && checksum_block(
				    (__u32 *)pb,htonl(pb->pb_SummedLongs) & 0x7F) == 0 ) {
					
					/* Tell Kernel about it */

					if (!(nr_sects = (htonl(pb->pb_Environment[10]) + 1 -
							  htonl(pb->pb_Environment[9])) *
							 htonl(pb->pb_Environment[3]) *
							 htonl(pb->pb_Environment[5]))) {
						continue;
					}
					start_sect = htonl(pb->pb_Environment[9]) *
						     htonl(pb->pb_Environment[3]) *
						     htonl(pb->pb_Environment[5]);
					add_partition(hd,current_minor,start_sect,nr_sects);
					current_minor++;
					res = 1;
				}
				brelse(bh);
			}
			printk("\n");
			break;
		}
	}

rdb_done:
	set_blocksize(dev,BLOCK_SIZE);
	return res;
}
示例#10
0
文件: genhd.c 项目: andreiw/mkunity
static int sun_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector)
{
	int i, csum;
	unsigned short *ush;
	struct buffer_head *bh;
	struct sun_disklabel {
		unsigned char info[128];   /* Informative text string */
		unsigned char spare[292];  /* Boot information etc. */
		unsigned short rspeed;     /* Disk rotational speed */
		unsigned short pcylcount;  /* Physical cylinder count */
		unsigned short sparecyl;   /* extra sects per cylinder */
		unsigned char spare2[4];   /* More magic... */
		unsigned short ilfact;     /* Interleave factor */
		unsigned short ncyl;       /* Data cylinder count */
		unsigned short nacyl;      /* Alt. cylinder count */
		unsigned short ntrks;      /* Tracks per cylinder */
		unsigned short nsect;      /* Sectors per track */
		unsigned char spare3[4];   /* Even more magic... */
		struct sun_partition {
			__u32 start_cylinder;
			__u32 num_sectors;
		} partitions[8];
		unsigned short magic;      /* Magic number */
		unsigned short csum;       /* Label xor'd checksum */
	} * label;		
	struct sun_partition *p;
	int other_endian;
	unsigned long spc;
#define SUN_LABEL_MAGIC          0xDABE
#define SUN_LABEL_MAGIC_SWAPPED  0xBEDA
/* No need to optimize these macros since they are called only when reading
 * the partition table. This occurs only at each disk change. */
#define SWAP16(x)  (other_endian ? (((__u16)(x) & 0xFF) << 8) \
				 | (((__u16)(x) & 0xFF00) >> 8) \
				 : (__u16)(x))
#define SWAP32(x)  (other_endian ? (((__u32)(x) & 0xFF) << 24) \
				 | (((__u32)(x) & 0xFF00) << 8) \
				 | (((__u32)(x) & 0xFF0000) >> 8) \
				 | (((__u32)(x) & 0xFF000000) >> 24) \
				 : (__u32)(x))

	if(!(bh = bread(dev, 0, 1024))) {
		printk("Dev %s: unable to read partition table\n",
		       kdevname(dev));
		return -1;
	}
	label = (struct sun_disklabel *) bh->b_data;
	p = label->partitions;
	if (label->magic != SUN_LABEL_MAGIC && label->magic != SUN_LABEL_MAGIC_SWAPPED) {
		printk("Dev %s Sun disklabel: bad magic %04x\n",
		       kdevname(dev), label->magic);
		brelse(bh);
		return 0;
	}
	other_endian = (label->magic == SUN_LABEL_MAGIC_SWAPPED);
	/* Look at the checksum */
	ush = ((unsigned short *) (label+1)) - 1;
	for(csum = 0; ush >= ((unsigned short *) label);)
		csum ^= *ush--;
	if(csum) {
		printk("Dev %s Sun disklabel: Csum bad, label corrupted\n",
		       kdevname(dev));
		brelse(bh);
		return 0;
	}
	/* All Sun disks have 8 partition entries */
	spc = SWAP16(label->ntrks) * SWAP16(label->nsect);
	for(i=0; i < 8; i++, p++) {
		unsigned long st_sector;

		/* We register all partitions, even if zero size, so that
		 * the minor numbers end up ok as per SunOS interpretation.
		 */
		st_sector = first_sector + SWAP32(p->start_cylinder) * spc;
		add_partition(hd, current_minor, st_sector, SWAP32(p->num_sectors));
		current_minor++;
	}
	printk("\n");
	brelse(bh);
	return 1;
#undef SWAP16
#undef SWAP32
}
示例#11
0
文件: genhd.c 项目: andreiw/mkunity
static int osf_partition(struct gendisk *hd, unsigned int dev, unsigned long first_sector)
{
	int i;
	int mask = (1 << hd->minor_shift) - 1;
	struct buffer_head *bh;
	struct disklabel {
		u32 d_magic;
		u16 d_type,d_subtype;
		u8 d_typename[16];
		u8 d_packname[16];
		u32 d_secsize;
		u32 d_nsectors;
		u32 d_ntracks;
		u32 d_ncylinders;
		u32 d_secpercyl;
		u32 d_secprtunit;
		u16 d_sparespertrack;
		u16 d_sparespercyl;
		u32 d_acylinders;
		u16 d_rpm, d_interleave, d_trackskew, d_cylskew;
		u32 d_headswitch, d_trkseek, d_flags;
		u32 d_drivedata[5];
		u32 d_spare[5];
		u32 d_magic2;
		u16 d_checksum;
		u16 d_npartitions;
		u32 d_bbsize, d_sbsize;
		struct d_partition {
			u32 p_size;
			u32 p_offset;
			u32 p_fsize;
			u8  p_fstype;
			u8  p_frag;
			u16 p_cpg;
		} d_partitions[8];
	} * label;
	struct d_partition * partition;
#define DISKLABELMAGIC (0x82564557UL)

	if (!(bh = bread(dev,0,1024))) {
		printk("unable to read partition table\n");
		return -1;
	}
	label = (struct disklabel *) (bh->b_data+64);
	partition = label->d_partitions;
	if (label->d_magic != DISKLABELMAGIC) {
		printk("magic: %08x\n", label->d_magic);
		brelse(bh);
		return 0;
	}
	if (label->d_magic2 != DISKLABELMAGIC) {
		printk("magic2: %08x\n", label->d_magic2);
		brelse(bh);
		return 0;
	}
	for (i = 0 ; i < label->d_npartitions; i++, partition++) {
		if ((current_minor & mask) == 0)
		        break;
		if (partition->p_size)
			add_partition(hd, current_minor,
				first_sector+partition->p_offset,
				partition->p_size);
		current_minor++;
	}
	printk("\n");
	brelse(bh);
	return 1;
}
示例#12
0
文件: genhd.c 项目: andreiw/mkunity
static int msdos_partition(struct gendisk *hd, kdev_t dev, unsigned long first_sector)
{
	int i, minor = current_minor;
	struct buffer_head *bh;
	struct partition *p;
	unsigned char *data;
	int mask = (1 << hd->minor_shift) - 1;
#ifdef CONFIG_BLK_DEV_IDE
	int tested_for_xlate = 0;

read_mbr:
#endif
	if (!(bh = bread(dev,0,1024))) {
		printk(" unable to read partition table\n");
		return -1;
	}
	data = bh->b_data;
	/* In some cases we modify the geometry    */
	/*  of the drive (below), so ensure that   */
	/*  nobody else tries to re-use this data. */
	bh->b_state = 0;
#ifdef __powerpc__
	if (*(unsigned short *) (bh->b_data+510) == 0x55AA)
	{ /* Little-endian partition table - adjust in place */
		p = (struct partition *) (0x1BE + bh->b_data);
		for (i=1 ; i<=4 ; i++,p++)
		{
			if (!p->nr_sects)
				continue;
			p->start_sect = _LE_to_BE_long(p->start_sect);
			p->nr_sects = _LE_to_BE_long(p->nr_sects);
		}
		*(unsigned short *) (bh->b_data+510) = 0xAA55;
	}
#endif	
#ifdef CONFIG_BLK_DEV_IDE
check_table:
#endif
	if (*(unsigned short *)  (0x1fe + data) != 0xAA55) {
		brelse(bh);
		return 0;
	}
	p = (struct partition *) (0x1be + data);

#ifdef CONFIG_BLK_DEV_IDE
	if (!tested_for_xlate++) {	/* Do this only once per disk */
		/*
		 * Look for various forms of IDE disk geometry translation
		 */
		extern int ide_xlate_1024(kdev_t, int, const char *);
		unsigned int sig = *(unsigned short *)(data + 2);
		if (SYS_IND(p) == EZD_PARTITION) {
			/*
			 * The remainder of the disk must be accessed using
			 * a translated geometry that reduces the number of 
			 * apparent cylinders to less than 1024 if possible.
			 *
			 * ide_xlate_1024() will take care of the necessary
			 * adjustments to fool fdisk/LILO and partition check.
			 */
			if (ide_xlate_1024(dev, -1, " [EZD]")) {
				data += 512;
				goto check_table;
			}
		} else if (SYS_IND(p) == DM6_PARTITION) {

			/*
			 * Everything on the disk is offset by 63 sectors,
			 * including a "new" MBR with its own partition table,
			 * and the remainder of the disk must be accessed using
			 * a translated geometry that reduces the number of 
			 * apparent cylinders to less than 1024 if possible.
			 *
			 * ide_xlate_1024() will take care of the necessary
			 * adjustments to fool fdisk/LILO and partition check.
			 */
			if (ide_xlate_1024(dev, 1, " [DM6:DDO]")) {
				brelse(bh);
				goto read_mbr;	/* start over with new MBR */
			}
		} else if (sig <= 0x1ae && *(unsigned short *)(data + sig) == 0x55AA
			 && (1 & *(unsigned char *)(data + sig + 2)) ) 
		{
			/*
			 * DM6 signature in MBR, courtesy of OnTrack
			 */
			(void) ide_xlate_1024 (dev, 0, " [DM6:MBR]");
		} else if (SYS_IND(p) == DM6_AUX1PARTITION || SYS_IND(p) == DM6_AUX3PARTITION) {
			/*
			 * DM6 on other than the first (boot) drive
			 */
			(void) ide_xlate_1024(dev, 0, " [DM6:AUX]");
		} else {
			/*
			 * Examine the partition table for common translations.
			 * This is necessary for drives for situations where
			 * the translated geometry is unavailable from the BIOS.
			 */
			for (i = 0; i < 4 ; i++) {
				struct partition *q = &p[i];
				if (NR_SECTS(q)
				   && (q->sector & 63) == 1
				   && (q->end_sector & 63) == 63) {
					unsigned int heads = q->end_head + 1;
					if (heads == 32 || heads == 64 || heads == 128 || heads == 255) {

						(void) ide_xlate_1024(dev, heads, " [PTBL]");
						break;
					}
				}
			}
		}
	}
#endif	/* CONFIG_BLK_DEV_IDE */

	current_minor += 4;  /* first "extra" minor (for extended partitions) */
	for (i=1 ; i<=4 ; minor++,i++,p++) {
		if (!NR_SECTS(p))
			continue;
		add_partition(hd, minor, first_sector+START_SECT(p), NR_SECTS(p));
		if (is_extended_partition(p)) {
			printk(" <");
			/*
			 * If we are rereading the partition table, we need
			 * to set the size of the partition so that we will
			 * be able to bread the block containing the extended
			 * partition info.
			 */
			hd->sizes[minor] = hd->part[minor].nr_sects 
			  	>> (BLOCK_SIZE_BITS - 9);
			extended_partition(hd, MKDEV(hd->major, minor));
			printk(" >");
			/* prevent someone doing mkfs or mkswap on an
			   extended partition, but leave room for LILO */
			if (hd->part[minor].nr_sects > 2)
				hd->part[minor].nr_sects = 2;
		}
#ifdef CONFIG_BSD_DISKLABEL
		if (SYS_IND(p) == BSD_PARTITION) {
			printk(" <");
			bsd_disklabel_partition(hd, MKDEV(hd->major, minor));
			printk(" >");
		}
#endif
	}
	/*
	 *  Check for old-style Disk Manager partition table
	 */
	if (*(unsigned short *) (data+0xfc) == 0x55AA) {
		p = (struct partition *) (0x1be + data);
		for (i = 4 ; i < 16 ; i++, current_minor++) {
			p--;
			if ((current_minor & mask) == 0)
				break;
			if (!(START_SECT(p) && NR_SECTS(p)))
				continue;
			add_partition(hd, current_minor, START_SECT(p), NR_SECTS(p));
		}
	}
	printk("\n");
	brelse(bh);
	return 1;
}
示例#13
0
文件: genhd.c 项目: andreiw/mkunity
static void extended_partition(struct gendisk *hd, kdev_t dev)
{
	struct buffer_head *bh;
	struct partition *p;
	unsigned long first_sector, first_size, this_sector, this_size;
	int mask = (1 << hd->minor_shift) - 1;
	int i;

	first_sector = hd->part[MINOR(dev)].start_sect;
	first_size = hd->part[MINOR(dev)].nr_sects;
	this_sector = first_sector;

	while (1) {
		if ((current_minor & mask) == 0)
			return;
		if (!(bh = bread(dev,0,1024)))
			return;
	  /*
	   * This block is from a device that we're about to stomp on.
	   * So make sure nobody thinks this block is usable.
	   */
		bh->b_state = 0;

		if (*(unsigned short *) (bh->b_data+510) != 0xAA55)
			goto done;

		p = (struct partition *) (0x1BE + bh->b_data);

		this_size = hd->part[MINOR(dev)].nr_sects;

		/*
		 * Usually, the first entry is the real data partition,
		 * the 2nd entry is the next extended partition, or empty,
		 * and the 3rd and 4th entries are unused.
		 * However, DRDOS sometimes has the extended partition as
		 * the first entry (when the data partition is empty),
		 * and OS/2 seems to use all four entries.
		 */

		/* 
		 * First process the data partition(s)
		 */
		for (i=0; i<4; i++, p++) {
		    if (!NR_SECTS(p) || is_extended_partition(p))
		      continue;

		    /* Check the 3rd and 4th entries -
		       these sometimes contain random garbage */
		    if (i >= 2
			&& START_SECT(p) + NR_SECTS(p) > this_size
			&& (this_sector + START_SECT(p) < first_sector ||
			    this_sector + START_SECT(p) + NR_SECTS(p) >
			     first_sector + first_size))
		      continue;

		    add_partition(hd, current_minor, this_sector+START_SECT(p), NR_SECTS(p));
		    current_minor++;
		    if ((current_minor & mask) == 0)
		      goto done;
		}
		/*
		 * Next, process the (first) extended partition, if present.
		 * (So far, there seems to be no reason to make
		 *  extended_partition()  recursive and allow a tree
		 *  of extended partitions.)
		 * It should be a link to the next logical partition.
		 * Create a minor for this just long enough to get the next
		 * partition table.  The minor will be reused for the next
		 * data partition.
		 */
		p -= 4;
		for (i=0; i<4; i++, p++)
		  if(NR_SECTS(p) && is_extended_partition(p))
		    break;
		if (i == 4)
		  goto done;	 /* nothing left to do */

		hd->part[current_minor].nr_sects = NR_SECTS(p);
		hd->part[current_minor].start_sect = first_sector + START_SECT(p);
		this_sector = first_sector + START_SECT(p);
		dev = MKDEV(hd->major, current_minor);
		brelse(bh);
	}
done:
	brelse(bh);
}
示例#14
0
/**
* @brief 	Add partition function.
* @param 	disk[in]: General disk structure.
* @param 	partno[in]: Partition number.
* @param 	start[in]: Start sector.
* @param 	len[in]: Partition size.
* @param	flags[in]: Control flag.
* @return 	ERROR_ID(<0).
*/ 
struct hd_struct *gp_add_partition(struct gendisk *disk, int partno, sector_t start, sector_t len, int flags)
{
	return add_partition(disk, partno, start, len, flags);
}