static int pd_revalidate(kdev_t dev) { int p, unit, minor; long flags; unit = DEVICE_NR(dev); if ((unit >= PD_UNITS) || (!PD.present)) return -ENODEV; save_flags(flags); cli(); if (PD.access > 1) { restore_flags(flags); return -EBUSY; } pd_valid = 0; restore_flags(flags); for (p=(PD_PARTNS-1);p>=0;p--) { minor = p + unit*PD_PARTNS; invalidate_device(MKDEV(MAJOR_NR, minor), 1); pd_hd[minor].start_sect = 0; pd_hd[minor].nr_sects = 0; } if (pd_identify(unit)) grok_partitions(&pd_gendisk,unit,1<<PD_BITS,PD.capacity); pd_valid = 1; wake_up(&pd_wait_open); return 0; }
/* xd_reread_partitions: rereads the partition table from a drive */ static int xd_reread_partitions(kdev_t dev) { int target; int start; int partition; target = DEVICE_NR(dev); start = target << xd_gendisk.minor_shift; cli(); xd_valid[target] = (xd_access[target] != 1); sti(); if (xd_valid[target]) return -EBUSY; for (partition = xd_gendisk.max_p - 1; partition >= 0; partition--) { int minor = (start | partition); invalidate_device(MKDEV(MAJOR_NR, minor), 1); xd_gendisk.part[minor].start_sect = 0; xd_gendisk.part[minor].nr_sects = 0; }; grok_partitions(&xd_gendisk, target, 1<<6, xd_info[target].heads * xd_info[target].cylinders * xd_info[target].sectors); xd_valid[target] = 1; wake_up(&xd_wait_open); return 0; }
static int nftl_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg) { struct NFTLrecord *nftl; int p; nftl = NFTLs[MINOR(inode->i_rdev) >> NFTL_PARTN_BITS]; if (!nftl) return -EINVAL; switch (cmd) { case HDIO_GETGEO: { struct hd_geometry g; g.heads = nftl->heads; g.sectors = nftl->sectors; g.cylinders = nftl->cylinders; g.start = part_table[MINOR(inode->i_rdev)].start_sect; return copy_to_user((void *)arg, &g, sizeof g) ? -EFAULT : 0; } case BLKGETSIZE: /* Return device size */ return put_user(part_table[MINOR(inode->i_rdev)].nr_sects, (unsigned long *) arg); #ifdef BLKGETSIZE64 case BLKGETSIZE64: return put_user((u64)part_table[MINOR(inode->i_rdev)].nr_sects << 9, (u64 *)arg); #endif case BLKFLSBUF: if (!capable(CAP_SYS_ADMIN)) return -EACCES; fsync_dev(inode->i_rdev); invalidate_buffers(inode->i_rdev); if (nftl->mtd->sync) nftl->mtd->sync(nftl->mtd); return 0; case BLKRRPART: if (!capable(CAP_SYS_ADMIN)) return -EACCES; if (nftl->usecount > 1) return -EBUSY; /* * We have to flush all buffers and invalidate caches, * or we won't be able to re-use the partitions, * if there was a change and we don't want to reboot */ p = (1<<NFTL_PARTN_BITS) - 1; while (p-- > 0) { kdev_t devp = MKDEV(MAJOR(inode->i_dev), MINOR(inode->i_dev)+p); if (part_table[p].nr_sects > 0) invalidate_device (devp, 1); part_table[MINOR(inode->i_dev)+p].start_sect = 0; part_table[MINOR(inode->i_dev)+p].nr_sects = 0; } #if LINUX_VERSION_CODE < 0x20328 resetup_one_dev(&nftl_gendisk, MINOR(inode->i_rdev) >> NFTL_PARTN_BITS); #else grok_partitions(&nftl_gendisk, MINOR(inode->i_rdev) >> NFTL_PARTN_BITS, 1<<NFTL_PARTN_BITS, nftl->nr_sects); #endif return 0; #if (LINUX_VERSION_CODE < 0x20303) RO_IOCTLS(inode->i_rdev, arg); /* ref. linux/blk.h */ #else case BLKROSET: case BLKROGET: case BLKSSZGET: return blk_ioctl(inode->i_rdev, cmd, arg); #endif default: return -EINVAL; } }