Index: e2fsprogs-1.41.1/misc/base_device.c =================================================================== --- e2fsprogs-1.41.1.orig/misc/base_device.c 2008-08-28 16:26:31.000000000 +0200 +++ e2fsprogs-1.41.1/misc/base_device.c 2008-09-04 15:08:22.000000000 +0200 @@ -31,125 +31,169 @@ #include "fsck.h" /* - * Required for the uber-silly devfs /dev/ide/host1/bus2/target3/lun3 - * pathames. + * Same version as above but returns the devicenumber of + * base device. Saner, no strings to free, works with everything. */ -static const char *devfs_hier[] = { - "host", "bus", "target", "lun", 0 -}; - -char *base_device(const char *device) +dev_t base_devt(const char *device) { - char *str, *cp; - const char **hier, *disk; - int len; - - str = malloc(strlen(device)+1); - if (!str) - return NULL; - strcpy(str, device); - cp = str; - - /* Skip over /dev/; if it's not present, give up. */ - if (strncmp(cp, "/dev/", 5) != 0) - goto errout; - cp += 5; - - /* Skip over /dev/dsk/... */ - if (strncmp(cp, "dsk/", 4) == 0) - cp += 4; - - /* - * For md devices, we treat them all as if they were all - * on one disk, since we don't know how to parallelize them. - */ - if (cp[0] == 'm' && cp[1] == 'd') { - *(cp+2) = 0; - return str; + struct stat statbuf; + unsigned int dev_major, dev_minor, disk_minor; + + if (stat(device, &statbuf) < 0) { + fprintf(stderr,"error on stat() %s: %s\n", + device, strerror(errno)); + return 0; + } + + if (!S_ISBLK(statbuf.st_mode)) + return 0; + + dev_major = major(statbuf.st_mode); + dev_minor = minor(statbuf.st_mode); + + switch (dev_major) { + case 3: /* IDE / ATAPI disks */ + case 13: /* PC MFM disks */ + case 14: /* BIOS HD disks */ + case 21: /* Acorn MFM disks */ + case 22: /* 2nd IDE / ATAPI controller */ + case 33: /* 3rd IDE / ATAPI controller */ + case 34: /* 4th IDE / ATAPI controller */ + case 56: /* 5th IDE / ATAPI controller */ + case 57: /* 6th IDE / ATAPI controller */ + case 88: /* 7th IDE / ATAPI controller */ + case 89: /* 8th IDE / ATAPI controller */ + case 90: /* 9th IDE / ATAPI controller */ + case 91: /* 10th IDE / ATAPI controller */ + case 36: /* MCA ESDI disks */ + disk_minor = dev_minor - (dev_minor % 64); + break; + case 160: /* Carmel 8-port SATA disks, 1st controller */ + case 161: /* Carmel 8-port SATA disks, 2nd controller */ + disk_minor = dev_minor - (dev_minor % 32); + break; + case 8: /* SCSI devices */ + case 28: /* Atari ASCI disks */ + case 44: /* FTL disks */ + case 45: /* Parallel port IDE disks */ + case 65: /* SCSI devices */ + case 66: /* SCSI devices */ + case 67: /* SCSI devices */ + case 68: /* SCSI devices */ + case 69: /* SCSI devices */ + case 70: /* SCSI devices */ + case 71: /* SCSI devices */ + case 72: /* Compaq IDA, 1st controller */ + case 73: /* Compaq IDA, 2nd controller */ + case 74: /* Compaq IDA, 3rd controller */ + case 75: /* Compaq IDA, 4th controller */ + case 76: /* Compaq IDA, 5th controller */ + case 77: /* Compaq IDA, 6th controller */ + case 78: /* Compaq IDA, 7th controller */ + case 79: /* Compaq IDA, 8th controller */ + case 80: /* I2O disks */ + case 81: /* I2O disks */ + case 82: /* I2O disks */ + case 83: /* I2O disks */ + case 84: /* I2O disks */ + case 85: /* I2O disks */ + case 86: /* I2O disks */ + case 87: /* I2O disks */ + case 93: /* NAND FTL disks */ + case 96: /* Inverse NAND FTL disks */ + case 98: /* User-mode Virtual disks */ + case 101: /* AMI RAID controller */ + case 102: /* Compressed block device */ + case 104: /* Compaq CCISS, 1st controller */ + case 105: /* Compaq CCISS, 2nd controller */ + case 106: /* Compaq CCISS, 3rd controller */ + case 107: /* Compaq CCISS, 4th controller */ + case 108: /* Compaq CCISS, 5th controller */ + case 109: /* Compaq CCISS, 6th controller */ + case 110: /* Compaq CCISS, 7th controller */ + case 111: /* Compaq CCISS, 8th controller */ + case 114: /* ATARAID devices */ + case 128: /* SCSI disks */ + case 129: /* SCSI disks */ + case 130: /* SCSI disks */ + case 131: /* SCSI disks */ + case 132: /* SCSI disks */ + case 133: /* SCSI disks */ + case 134: /* SCSI disks */ + case 135: /* SCSI disks */ + case 153: /* Enhanced Metadisk RAID */ + disk_minor = dev_minor - (dev_minor % 16); + break; + case 48: /* Mylex DAC960 RAID, 1st controller */ + case 49: /* Mylex DAC960 RAID, 2nd controller */ + case 50: /* Mylex DAC960 RAID, 3rd controller */ + case 51: /* Mylex DAC960 RAID, 4th controller */ + case 52: /* Mylex DAC960 RAID, 5th controller */ + case 53: /* Mylex DAC960 RAID, 6th controller */ + case 54: /* Mylex DAC960 RAID, 7th controller */ + case 55: /* Mylex DAC960 RAID, 8th controller */ + case 112: /* IBM iSeries virtual disks */ + case 136: /* Mylex DAC960 RAID, 9th controller */ + case 137: /* Mylex DAC960 RAID, 10th controller */ + case 138: /* Mylex DAC960 RAID, 11th controller */ + case 139: /* Mylex DAC960 RAID, 12th controller */ + case 140: /* Mylex DAC960 RAID, 13th controller */ + case 141: /* Mylex DAC960 RAID, 14th controller */ + case 142: /* Mylex DAC960 RAID, 15th controller */ + case 143: /* Mylex DAC960 RAID, 16th controller */ + case 180: /* USB Block devices */ + disk_minor = dev_minor - (dev_minor % 8); + break; + case 94: /* IBM S/390 DASD */ + disk_minor = dev_minor - (dev_minor % 4); + break; + default: + disk_minor = dev_minor; + break; } + + return makedev(dev_major,disk_minor); +} + +/* + * Check whether two given devices match. + * Rather then check for the device names + * (which wouldn't work with udev anyway) + * check whether the device numbers are + * identical. + */ +int match_device(const char *dev1, const char *dev2) +{ + struct stat statbuf; + dev_t saved_devt; + int ret = 0; - /* Handle DAC 960 devices */ - if (strncmp(cp, "rd/", 3) == 0) { - cp += 3; - if (cp[0] != 'c' || cp[2] != 'd' || - !isdigit(cp[1]) || !isdigit(cp[3])) - goto errout; - *(cp+4) = 0; - return str; + if (stat(dev1, &statbuf) < 0) { + return 0; } - /* Now let's handle /dev/hd* and /dev/sd* devices.... */ - if ((cp[0] == 'h' || cp[0] == 's') && (cp[1] == 'd')) { - cp += 2; - /* If there's a single number after /dev/hd, skip it */ - if (isdigit(*cp)) - cp++; - /* What follows must be an alpha char, or give up */ - if (!isalpha(*cp)) - goto errout; - *(cp + 1) = 0; - return str; - } + if (!S_ISBLK(statbuf.st_mode)) + return 0; - /* Now let's handle devfs (ugh) names */ - len = 0; - if (strncmp(cp, "ide/", 4) == 0) - len = 4; - if (strncmp(cp, "scsi/", 5) == 0) - len = 5; - if (len) { - cp += len; - /* - * Now we proceed down the expected devfs hierarchy. - * i.e., .../host1/bus2/target3/lun4/... - * If we don't find the expected token, followed by - * some number of digits at each level, abort. - */ - for (hier = devfs_hier; *hier; hier++) { - len = strlen(*hier); - if (strncmp(cp, *hier, len) != 0) - goto errout; - cp += len; - while (*cp != '/' && *cp != 0) { - if (!isdigit(*cp)) - goto errout; - cp++; - } - cp++; - } - *(cp - 1) = 0; - return str; - } + saved_devt = statbuf.st_rdev; - /* Now handle devfs /dev/disc or /dev/disk names */ - disk = 0; - if (strncmp(cp, "discs/", 6) == 0) - disk = "disc"; - else if (strncmp(cp, "disks/", 6) == 0) - disk = "disk"; - if (disk) { - cp += 6; - if (strncmp(cp, disk, 4) != 0) - goto errout; - cp += 4; - while (*cp != '/' && *cp != 0) { - if (!isdigit(*cp)) - goto errout; - cp++; - } - *cp = 0; - return str; + if (stat(dev2, &statbuf) < 0) { + return 0; } -errout: - free(str); - return NULL; + if (!S_ISBLK(statbuf.st_mode)) + return 0; + + if (saved_devt == statbuf.st_rdev) + ret = 1; + + return ret; } #ifdef DEBUG int main(int argc, char** argv) { - const char *base; + dev_t base; char buf[256], *cp; while (1) { @@ -161,8 +205,8 @@ int main(int argc, char** argv) cp = strchr(buf, '\t'); if (cp) *cp = 0; - base = base_device(buf); - printf("%s\t%s\n", buf, base ? base : "NONE"); + base = base_devt(buf); + printf("%s\t0x%04x\n", buf, base); } exit(0); } Index: e2fsprogs-1.41.1/misc/fsck.c =================================================================== --- e2fsprogs-1.41.1.orig/misc/fsck.c 2008-08-28 16:26:31.000000000 +0200 +++ e2fsprogs-1.41.1/misc/fsck.c 2008-09-04 15:23:38.000000000 +0200 @@ -237,8 +237,6 @@ static void free_instance(struct fsck_in free(i->prog); if (i->device) free(i->device); - if (i->base_device) - free(i->base_device); free(i); return; } @@ -390,7 +388,7 @@ static struct fs_info *lookup(char *file return NULL; for (fs = filesys_info; fs; fs = fs->next) { - if (!strcmp(filesys, fs->device) || + if (match_device(filesys, fs->device) || (fs->mountpt && !strcmp(filesys, fs->mountpt))) break; } @@ -514,7 +512,7 @@ static int execute(const char *type, con inst->prog = string_copy(prog); inst->type = string_copy(type); inst->device = string_copy(device); - inst->base_device = base_device(device); + inst->base_devt = base_devt(device); inst->start_time = time(0); inst->next = NULL; @@ -927,7 +925,7 @@ static int ignore(struct fs_info *fs) static int device_already_active(char *device) { struct fsck_instance *inst; - char *base; + dev_t disk_devt; if (force_all_parallel) return 0; @@ -940,20 +938,18 @@ static int device_already_active(char *d return 1; #endif - base = base_device(device); + disk_devt = base_devt(device); /* * If we don't know the base device, assume that the device is * already active if there are any fsck instances running. */ - if (!base) + if (!disk_devt) return (instance_list != 0); for (inst = instance_list; inst; inst = inst->next) { - if (!inst->base_device || !strcmp(base, inst->base_device)) { - free(base); + if (!inst->base_devt || disk_devt == inst->base_devt) { return 1; } } - free(base); return 0; } Index: e2fsprogs-1.41.1/misc/fsck.h =================================================================== --- e2fsprogs-1.41.1.orig/misc/fsck.h 2008-08-28 05:07:00.000000000 +0200 +++ e2fsprogs-1.41.1/misc/fsck.h 2008-09-04 14:57:13.000000000 +0200 @@ -62,12 +62,12 @@ struct fsck_instance { char * prog; char * type; char * device; - char * base_device; + dev_t base_devt; struct fsck_instance *next; }; -extern char *base_device(const char *device); -extern const char *identify_fs(const char *fs_name, const char *fs_types); +extern dev_t base_devt(const char *device); +extern int match_device(const char *dev1, const char *dev2); /* ismounted.h */ extern int is_mounted(const char *file);