📄 hptraid.c
字号:
if (dist>4095) dist=4095; if (bestdist==dist) { /* it's a tie; try to do some read balancing */ if ((previous>bestsofar)&&(previous<=i)) bestsofar = i; previous = (previous + 1) % raid[device].disks; } else if (bestdist>dist) { bestdist = dist; bestsofar = i; } } bh->b_rsector += bestsofar?10:0; bh->b_rdev = raid[device].disk[bestsofar].device; raid[device].disk[bestsofar].last_pos = bh->b_rsector+(bh->b_size>>9); /* * Let the main block layer submit the IO and resolve recursion: */ return 1;}static int hptraid1_write_request(request_queue_t *q, int rw, struct buffer_head * bh){ struct buffer_head *bh1; struct ataraid_bh_private *private; int device; int i; device = (bh->b_rdev >> SHIFT)&MAJOR_MASK; private = ataraid_get_private(); if (private==NULL) BUG(); private->parent = bh; atomic_set(&private->count,raid[device].disks); for (i = 0; i< raid[device].disks; i++) { bh1=ataraid_get_bhead(); /* If this ever fails we're doomed */ if (!bh1) BUG(); /* dupe the bufferhead and update the parts that need to be different */ memcpy(bh1, bh, sizeof(*bh)); bh1->b_end_io = ataraid_end_request; bh1->b_private = private; bh1->b_rsector += ataraid_gendisk.part[MINOR(bh->b_rdev)].start_sect+(i==0?0:10); /* partition offset */ bh1->b_rdev = raid[device].disk[i].device; /* update the last known head position for the drive */ raid[device].disk[i].last_pos = bh1->b_rsector+(bh1->b_size>>9); generic_make_request(rw,bh1); } return 0;}static int hptraid1_make_request (request_queue_t *q, int rw, struct buffer_head * bh) { /* Read and Write are totally different cases; split them totally here */ if (rw==READA) rw = READ; if (rw==READ) return hptraid1_read_request(q,rw,bh); else return hptraid1_write_request(q,rw,bh);}#include "hptraid.h"static int read_disk_sb (int major, int minor, unsigned char *buffer,int bufsize){ int ret = -EINVAL; struct buffer_head *bh = NULL; kdev_t dev = MKDEV(major,minor); if (blksize_size[major]==NULL) /* device doesn't exist */ return -EINVAL; /* Superblock is at 4096+412 bytes */ set_blocksize (dev, 4096); bh = bread (dev, 1, 4096); if (bh) { memcpy (buffer, bh->b_data, bufsize); } else { printk(KERN_ERR "hptraid: Error reading superblock.\n"); goto abort; } ret = 0;abort: if (bh) brelse (bh); return ret;}static unsigned long maxsectors (int major,int minor){ unsigned long lba = 0; kdev_t dev; ide_drive_t *ideinfo; dev = MKDEV(major,minor); ideinfo = get_info_ptr (dev); if (ideinfo==NULL) return 0; /* first sector of the last cluster */ if (ideinfo->head==0) return 0; if (ideinfo->sect==0) return 0; lba = (ideinfo->capacity); return lba;}static void __init probedisk(struct hptraid_dev *disk, int device, u_int8_t type){ int i; struct highpoint_raid_conf *prom; static unsigned char block[4096]; struct block_device *bdev; if (disk->device != -1) /* disk is occupied? */ return; if (maxsectors(disk->major,disk->minor)==0) return; if (read_disk_sb(disk->major,disk->minor,(unsigned char*)&block,sizeof(block))) return; prom = (struct highpoint_raid_conf*)&block[512]; if (prom->magic!= 0x5a7816f0) return; switch (prom->type) { case HPT_T_SPAN: case HPT_T_RAID_0: case HPT_T_RAID_1: if(prom->type != type) return; break; default: printk(KERN_INFO "hptraid: only SPAN, RAID0 and RAID1 is currently supported \n"); return; } /* disk from another array? */ if(raid[device].disks && prom->magic_0 != raid[device].magic_0) return; i = prom->disk_number; if (i<0) return; if (i>8) return; bdev = bdget(MKDEV(disk->major,disk->minor)); if (bdev && blkdev_get(bdev,FMODE_READ|FMODE_WRITE,0,BDEV_RAW) == 0) { int j=0; struct gendisk *gd; raid[device].disk[i].bdev = bdev; /* This is supposed to prevent others from stealing our underlying disks */ /* now blank the /proc/partitions table for the wrong partition table, so that scripts don't accidentally mount it and crash the kernel */ /* XXX: the 0 is an utter hack --hch */ gd=get_gendisk(MKDEV(disk->major, 0)); if (gd!=NULL) { if (gd->major==disk->major) for (j=1+(disk->minor<<gd->minor_shift); j<((disk->minor+1)<<gd->minor_shift); j++) gd->part[j].nr_sects=0; } } raid[device].disk[i].device = MKDEV(disk->major,disk->minor); raid[device].disk[i].sectors = maxsectors(disk->major,disk->minor); raid[device].stride = (1<<prom->raid0_shift); raid[device].disks = prom->raid_disks; raid[device].sectors = prom->total_secs-(prom->total_secs%(255*63)); raid[device].sectors += raid[device].sectors&1?1:0; raid[device].magic_0=prom->magic_0; disk->device=device; }static void __init fill_cutoff(int device){ int i,j; unsigned long smallest; unsigned long bar; int count; bar = 0; for (i=0;i<8;i++) { smallest = ~0; for (j=0;j<8;j++) if ((raid[device].disk[j].sectors < smallest) && (raid[device].disk[j].sectors>bar)) smallest = raid[device].disk[j].sectors; count = 0; for (j=0;j<8;j++) if (raid[device].disk[j].sectors >= smallest) count++; smallest = smallest * count; bar = smallest; raid[device].cutoff[i] = smallest; raid[device].cutoff_disks[i] = count; }}static __init int hptraid_init_one(int device, u_int8_t type){ int i,count; memset(raid+device, 0, sizeof(struct hptraid)); for(i=0; i < 14; i++) { probedisk(devlist+i, device, type); } if(type == HPT_T_RAID_0) fill_cutoff(device); /* Initialize the gendisk structure */ ataraid_register_disk(device,raid[device].sectors); count=0; for (i=0;i<8;i++) { if (raid[device].disk[i].device!=0) { printk(KERN_INFO "Drive %i is %li Mb \n", i,raid[device].disk[i].sectors/2048); count++; } } if (count) { printk(KERN_INFO "Raid array consists of %i drives. \n",count); return 0; } else { printk(KERN_INFO "No raid array found\n"); return -ENODEV; } }static __init int hptraid_init(void){ int retval,device,count=0; printk(KERN_INFO "Highpoint HPT370 Softwareraid driver for linux version 0.01-ww1\n"); do { device=ataraid_get_device(&hptraid0_ops); if (device<0) return (count?0:-ENODEV); retval = hptraid_init_one(device, HPT_T_RAID_0); if (retval) ataraid_release_device(device); else count++; } while(!retval); do { device=ataraid_get_device(&hptraid1_ops); if (device<0) return (count?0:-ENODEV); retval = hptraid_init_one(device, HPT_T_RAID_1); if (retval) ataraid_release_device(device); else count++; } while(!retval); do { device=ataraid_get_device(&hptraidspan_ops); if (device<0) return (count?0:-ENODEV); retval = hptraid_init_one(device, HPT_T_SPAN); if (retval) ataraid_release_device(device); else count++; } while(!retval); return (count?0:retval);}static void __exit hptraid_exit (void){ int i,device; for (device = 0; device<16; device++) { for (i=0;i<8;i++) { struct block_device *bdev = raid[device].disk[i].bdev; raid[device].disk[i].bdev = NULL; if (bdev) blkdev_put(bdev, BDEV_RAW); } if (raid[device].sectors) ataraid_release_device(device); }}static int hptraid_open(struct inode * inode, struct file * filp) { MOD_INC_USE_COUNT; return 0;}static int hptraid_release(struct inode * inode, struct file * filp){ MOD_DEC_USE_COUNT; return 0;}module_init(hptraid_init);module_exit(hptraid_exit);MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -