📄 pdcraid.c
字号:
for (i=1 ; i<raid[device].disks; i++) { dist = raid[device].disk[i].last_pos - bh->b_rsector; if (dist<0) dist = -dist; 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_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 pdcraid1_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 pdcraid1_read_request(q,rw,bh); else return pdcraid1_write_request(q,rw,bh);}#include "pdcraid.h"static unsigned long calc_pdcblock_offset (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 / (ideinfo->head*ideinfo->sect)); lba = lba * (ideinfo->head*ideinfo->sect); lba = lba - ideinfo->sect; return lba;}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); unsigned long sb_offset; if (blksize_size[major]==NULL) /* device doesn't exist */ return -EINVAL; /* * Calculate the position of the superblock, * it's at first sector of the last cylinder */ sb_offset = calc_pdcblock_offset(major,minor)/8; /* The /8 transforms sectors into 4Kb blocks */ if (sb_offset==0) return -1; set_blocksize (dev, 4096); bh = bread (dev, sb_offset, 4096); if (bh) { memcpy (buffer, bh->b_data, bufsize); } else { printk(KERN_ERR "pdcraid: Error reading superblock.\n"); goto abort; } ret = 0;abort: if (bh) brelse (bh); return ret;}static unsigned int calc_sb_csum (unsigned int* ptr){ unsigned int sum; int count; sum = 0; for (count=0;count<511;count++) sum += *ptr++; return sum;}static int cookie = 0;static void __init probedisk(int devindex,int device, int raidlevel){ int i; int major, minor; struct promise_raid_conf *prom; static unsigned char block[4096]; struct block_device *bdev; if (devlist[devindex].device!=-1) /* already assigned to another array */ return; major = devlist[devindex].major; minor = devlist[devindex].minor; if (read_disk_sb(major,minor,(unsigned char*)&block,sizeof(block))) return; prom = (struct promise_raid_conf*)&block[512]; /* the checksums must match */ if (prom->checksum != calc_sb_csum((unsigned int*)prom)) return; if (prom->raid.type!=raidlevel) /* different raidlevel */ return; if ((cookie!=0) && (cookie != prom->raid.magic_1)) /* different array */ return; cookie = prom->raid.magic_1; /* This looks evil. But basically, we have to search for our adapternumber in the arraydefinition, both of which are in the superblock */ for (i=0;(i<prom->raid.total_disks)&&(i<8);i++) { if ( (prom->raid.disk[i].channel== prom->raid.channel) && (prom->raid.disk[i].device == prom->raid.device) ) { bdev = bdget(MKDEV(major,minor)); if (bdev && blkdev_get(bdev, FMODE_READ|FMODE_WRITE, 0, BDEV_RAW) == 0) { raid[device].disk[i].bdev = bdev; } raid[device].disk[i].device = MKDEV(major,minor); raid[device].disk[i].sectors = prom->raid.disk_secs; raid[device].stride = (1<<prom->raid.raid0_shift); raid[device].disks = prom->raid.total_disks; raid[device].sectors = prom->raid.total_secs; raid[device].geom.heads = prom->raid.heads+1; raid[device].geom.sectors = prom->raid.sectors; raid[device].geom.cylinders = prom->raid.cylinders+1; devlist[devindex].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 pdcraid_init_one(int device,int raidlevel){ int i, count; for (i=0; i<14; i++) probedisk(i, device, raidlevel); if (raidlevel==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 (%i / %i) \n", i,raid[device].disk[i].sectors/2048,MAJOR(raid[device].disk[i].device),MINOR(raid[device].disk[i].device)); count++; } } if (count) { printk(KERN_INFO "Raid%i array consists of %i drives. \n",raidlevel,count); return 0; } else { return -ENODEV; }}static __init int pdcraid_init(void){ int retval, device, count = 0; do { cookie = 0; device=ataraid_get_device(&pdcraid0_ops); if (device<0) break; retval = pdcraid_init_one(device,0); if (retval) { ataraid_release_device(device); break; } else { count++; } } while (1); do { cookie = 0; device=ataraid_get_device(&pdcraid1_ops); if (device<0) break; retval = pdcraid_init_one(device,1); if (retval) { ataraid_release_device(device); break; } else { count++; } } while (1); if (count) { printk(KERN_INFO "Promise Fasttrak(tm) Softwareraid driver for linux version 0.03beta\n"); return 0; } printk(KERN_DEBUG "Promise Fasttrak(tm) Softwareraid driver 0.03beta: No raid array found\n"); return -ENODEV;}static void __exit pdcraid_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 pdcraid_open(struct inode * inode, struct file * filp) { MOD_INC_USE_COUNT; return 0;}static int pdcraid_release(struct inode * inode, struct file * filp){ MOD_DEC_USE_COUNT; return 0;}module_init(pdcraid_init);module_exit(pdcraid_exit);MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -