check.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497
  1. /*
  2. * fs/partitions/check.c
  3. *
  4. * Code extracted from drivers/block/genhd.c
  5. * Copyright (C) 1991-1998 Linus Torvalds
  6. * Re-organised Feb 1998 Russell King
  7. *
  8. * We now have independent partition support from the
  9. * block drivers, which allows all the partition code to
  10. * be grouped in one location, and it to be mostly self
  11. * contained.
  12. *
  13. * Added needed MAJORS for new pairs, {hdi,hdj}, {hdk,hdl}
  14. */
  15. #include <linux/init.h>
  16. #include <linux/module.h>
  17. #include <linux/fs.h>
  18. #include <linux/kmod.h>
  19. #include <linux/ctype.h>
  20. #include <linux/devfs_fs_kernel.h>
  21. #include "check.h"
  22. #include "devfs.h"
  23. #include "acorn.h"
  24. #include "amiga.h"
  25. #include "atari.h"
  26. #include "ldm.h"
  27. #include "mac.h"
  28. #include "msdos.h"
  29. #include "osf.h"
  30. #include "sgi.h"
  31. #include "sun.h"
  32. #include "ibm.h"
  33. #include "ultrix.h"
  34. #include "efi.h"
  35. #include "karma.h"
  36. #ifdef CONFIG_BLK_DEV_MD
  37. extern void md_autodetect_dev(dev_t dev);
  38. #endif
  39. int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/
  40. static int (*check_part[])(struct parsed_partitions *, struct block_device *) = {
  41. /*
  42. * Probe partition formats with tables at disk address 0
  43. * that also have an ADFS boot block at 0xdc0.
  44. */
  45. #ifdef CONFIG_ACORN_PARTITION_ICS
  46. adfspart_check_ICS,
  47. #endif
  48. #ifdef CONFIG_ACORN_PARTITION_POWERTEC
  49. adfspart_check_POWERTEC,
  50. #endif
  51. #ifdef CONFIG_ACORN_PARTITION_EESOX
  52. adfspart_check_EESOX,
  53. #endif
  54. /*
  55. * Now move on to formats that only have partition info at
  56. * disk address 0xdc0. Since these may also have stale
  57. * PC/BIOS partition tables, they need to come before
  58. * the msdos entry.
  59. */
  60. #ifdef CONFIG_ACORN_PARTITION_CUMANA
  61. adfspart_check_CUMANA,
  62. #endif
  63. #ifdef CONFIG_ACORN_PARTITION_ADFS
  64. adfspart_check_ADFS,
  65. #endif
  66. #ifdef CONFIG_EFI_PARTITION
  67. efi_partition, /* this must come before msdos */
  68. #endif
  69. #ifdef CONFIG_SGI_PARTITION
  70. sgi_partition,
  71. #endif
  72. #ifdef CONFIG_LDM_PARTITION
  73. ldm_partition, /* this must come before msdos */
  74. #endif
  75. #ifdef CONFIG_MSDOS_PARTITION
  76. msdos_partition,
  77. #endif
  78. #ifdef CONFIG_OSF_PARTITION
  79. osf_partition,
  80. #endif
  81. #ifdef CONFIG_SUN_PARTITION
  82. sun_partition,
  83. #endif
  84. #ifdef CONFIG_AMIGA_PARTITION
  85. amiga_partition,
  86. #endif
  87. #ifdef CONFIG_ATARI_PARTITION
  88. atari_partition,
  89. #endif
  90. #ifdef CONFIG_MAC_PARTITION
  91. mac_partition,
  92. #endif
  93. #ifdef CONFIG_ULTRIX_PARTITION
  94. ultrix_partition,
  95. #endif
  96. #ifdef CONFIG_IBM_PARTITION
  97. ibm_partition,
  98. #endif
  99. #ifdef CONFIG_KARMA_PARTITION
  100. karma_partition,
  101. #endif
  102. NULL
  103. };
  104. /*
  105. * disk_name() is used by partition check code and the genhd driver.
  106. * It formats the devicename of the indicated disk into
  107. * the supplied buffer (of size at least 32), and returns
  108. * a pointer to that same buffer (for convenience).
  109. */
  110. char *disk_name(struct gendisk *hd, int part, char *buf)
  111. {
  112. if (!part)
  113. snprintf(buf, BDEVNAME_SIZE, "%s", hd->disk_name);
  114. else if (isdigit(hd->disk_name[strlen(hd->disk_name)-1]))
  115. snprintf(buf, BDEVNAME_SIZE, "%sp%d", hd->disk_name, part);
  116. else
  117. snprintf(buf, BDEVNAME_SIZE, "%s%d", hd->disk_name, part);
  118. return buf;
  119. }
  120. const char *bdevname(struct block_device *bdev, char *buf)
  121. {
  122. int part = MINOR(bdev->bd_dev) - bdev->bd_disk->first_minor;
  123. return disk_name(bdev->bd_disk, part, buf);
  124. }
  125. EXPORT_SYMBOL(bdevname);
  126. /*
  127. * There's very little reason to use this, you should really
  128. * have a struct block_device just about everywhere and use
  129. * bdevname() instead.
  130. */
  131. const char *__bdevname(dev_t dev, char *buffer)
  132. {
  133. scnprintf(buffer, BDEVNAME_SIZE, "unknown-block(%u,%u)",
  134. MAJOR(dev), MINOR(dev));
  135. return buffer;
  136. }
  137. EXPORT_SYMBOL(__bdevname);
  138. static struct parsed_partitions *
  139. check_partition(struct gendisk *hd, struct block_device *bdev)
  140. {
  141. struct parsed_partitions *state;
  142. int i, res;
  143. state = kmalloc(sizeof(struct parsed_partitions), GFP_KERNEL);
  144. if (!state)
  145. return NULL;
  146. #ifdef CONFIG_DEVFS_FS
  147. if (hd->devfs_name[0] != '\0') {
  148. printk(KERN_INFO " /dev/%s:", hd->devfs_name);
  149. sprintf(state->name, "p");
  150. }
  151. #endif
  152. else {
  153. disk_name(hd, 0, state->name);
  154. printk(KERN_INFO " %s:", state->name);
  155. if (isdigit(state->name[strlen(state->name)-1]))
  156. sprintf(state->name, "p");
  157. }
  158. state->limit = hd->minors;
  159. i = res = 0;
  160. while (!res && check_part[i]) {
  161. memset(&state->parts, 0, sizeof(state->parts));
  162. res = check_part[i++](state, bdev);
  163. }
  164. if (res > 0)
  165. return state;
  166. if (!res)
  167. printk(" unknown partition table\n");
  168. else if (warn_no_part)
  169. printk(" unable to read partition table\n");
  170. kfree(state);
  171. return NULL;
  172. }
  173. /*
  174. * sysfs bindings for partitions
  175. */
  176. struct part_attribute {
  177. struct attribute attr;
  178. ssize_t (*show)(struct hd_struct *,char *);
  179. ssize_t (*store)(struct hd_struct *,const char *, size_t);
  180. };
  181. static ssize_t
  182. part_attr_show(struct kobject * kobj, struct attribute * attr, char * page)
  183. {
  184. struct hd_struct * p = container_of(kobj,struct hd_struct,kobj);
  185. struct part_attribute * part_attr = container_of(attr,struct part_attribute,attr);
  186. ssize_t ret = 0;
  187. if (part_attr->show)
  188. ret = part_attr->show(p, page);
  189. return ret;
  190. }
  191. static ssize_t
  192. part_attr_store(struct kobject * kobj, struct attribute * attr,
  193. const char *page, size_t count)
  194. {
  195. struct hd_struct * p = container_of(kobj,struct hd_struct,kobj);
  196. struct part_attribute * part_attr = container_of(attr,struct part_attribute,attr);
  197. ssize_t ret = 0;
  198. if (part_attr->store)
  199. ret = part_attr->store(p, page, count);
  200. return ret;
  201. }
  202. static struct sysfs_ops part_sysfs_ops = {
  203. .show = part_attr_show,
  204. .store = part_attr_store,
  205. };
  206. static ssize_t part_uevent_store(struct hd_struct * p,
  207. const char *page, size_t count)
  208. {
  209. kobject_uevent(&p->kobj, KOBJ_ADD);
  210. return count;
  211. }
  212. static ssize_t part_dev_read(struct hd_struct * p, char *page)
  213. {
  214. struct gendisk *disk = container_of(p->kobj.parent,struct gendisk,kobj);
  215. dev_t dev = MKDEV(disk->major, disk->first_minor + p->partno);
  216. return print_dev_t(page, dev);
  217. }
  218. static ssize_t part_start_read(struct hd_struct * p, char *page)
  219. {
  220. return sprintf(page, "%llu\n",(unsigned long long)p->start_sect);
  221. }
  222. static ssize_t part_size_read(struct hd_struct * p, char *page)
  223. {
  224. return sprintf(page, "%llu\n",(unsigned long long)p->nr_sects);
  225. }
  226. static ssize_t part_stat_read(struct hd_struct * p, char *page)
  227. {
  228. return sprintf(page, "%8u %8llu %8u %8llu\n",
  229. p->ios[0], (unsigned long long)p->sectors[0],
  230. p->ios[1], (unsigned long long)p->sectors[1]);
  231. }
  232. static struct part_attribute part_attr_uevent = {
  233. .attr = {.name = "uevent", .mode = S_IWUSR },
  234. .store = part_uevent_store
  235. };
  236. static struct part_attribute part_attr_dev = {
  237. .attr = {.name = "dev", .mode = S_IRUGO },
  238. .show = part_dev_read
  239. };
  240. static struct part_attribute part_attr_start = {
  241. .attr = {.name = "start", .mode = S_IRUGO },
  242. .show = part_start_read
  243. };
  244. static struct part_attribute part_attr_size = {
  245. .attr = {.name = "size", .mode = S_IRUGO },
  246. .show = part_size_read
  247. };
  248. static struct part_attribute part_attr_stat = {
  249. .attr = {.name = "stat", .mode = S_IRUGO },
  250. .show = part_stat_read
  251. };
  252. static struct attribute * default_attrs[] = {
  253. &part_attr_uevent.attr,
  254. &part_attr_dev.attr,
  255. &part_attr_start.attr,
  256. &part_attr_size.attr,
  257. &part_attr_stat.attr,
  258. NULL,
  259. };
  260. extern struct subsystem block_subsys;
  261. static void part_release(struct kobject *kobj)
  262. {
  263. struct hd_struct * p = container_of(kobj,struct hd_struct,kobj);
  264. kfree(p);
  265. }
  266. struct kobj_type ktype_part = {
  267. .release = part_release,
  268. .default_attrs = default_attrs,
  269. .sysfs_ops = &part_sysfs_ops,
  270. };
  271. void delete_partition(struct gendisk *disk, int part)
  272. {
  273. struct hd_struct *p = disk->part[part-1];
  274. if (!p)
  275. return;
  276. if (!p->nr_sects)
  277. return;
  278. disk->part[part-1] = NULL;
  279. p->start_sect = 0;
  280. p->nr_sects = 0;
  281. p->ios[0] = p->ios[1] = 0;
  282. p->sectors[0] = p->sectors[1] = 0;
  283. devfs_remove("%s/part%d", disk->devfs_name, part);
  284. kobject_unregister(&p->kobj);
  285. }
  286. void add_partition(struct gendisk *disk, int part, sector_t start, sector_t len)
  287. {
  288. struct hd_struct *p;
  289. p = kmalloc(sizeof(*p), GFP_KERNEL);
  290. if (!p)
  291. return;
  292. memset(p, 0, sizeof(*p));
  293. p->start_sect = start;
  294. p->nr_sects = len;
  295. p->partno = part;
  296. devfs_mk_bdev(MKDEV(disk->major, disk->first_minor + part),
  297. S_IFBLK|S_IRUSR|S_IWUSR,
  298. "%s/part%d", disk->devfs_name, part);
  299. if (isdigit(disk->kobj.name[strlen(disk->kobj.name)-1]))
  300. snprintf(p->kobj.name,KOBJ_NAME_LEN,"%sp%d",disk->kobj.name,part);
  301. else
  302. snprintf(p->kobj.name,KOBJ_NAME_LEN,"%s%d",disk->kobj.name,part);
  303. p->kobj.parent = &disk->kobj;
  304. p->kobj.ktype = &ktype_part;
  305. kobject_register(&p->kobj);
  306. disk->part[part-1] = p;
  307. }
  308. static char *make_block_name(struct gendisk *disk)
  309. {
  310. char *name;
  311. static char *block_str = "block:";
  312. int size;
  313. size = strlen(block_str) + strlen(disk->disk_name) + 1;
  314. name = kmalloc(size, GFP_KERNEL);
  315. if (!name)
  316. return NULL;
  317. strcpy(name, block_str);
  318. strcat(name, disk->disk_name);
  319. return name;
  320. }
  321. static void disk_sysfs_symlinks(struct gendisk *disk)
  322. {
  323. struct device *target = get_device(disk->driverfs_dev);
  324. if (target) {
  325. char *disk_name = make_block_name(disk);
  326. sysfs_create_link(&disk->kobj,&target->kobj,"device");
  327. if (disk_name) {
  328. sysfs_create_link(&target->kobj,&disk->kobj,disk_name);
  329. kfree(disk_name);
  330. }
  331. }
  332. }
  333. /* Not exported, helper to add_disk(). */
  334. void register_disk(struct gendisk *disk)
  335. {
  336. struct block_device *bdev;
  337. char *s;
  338. int err;
  339. strlcpy(disk->kobj.name,disk->disk_name,KOBJ_NAME_LEN);
  340. /* ewww... some of these buggers have / in name... */
  341. s = strchr(disk->kobj.name, '/');
  342. if (s)
  343. *s = '!';
  344. if ((err = kobject_add(&disk->kobj)))
  345. return;
  346. disk_sysfs_symlinks(disk);
  347. kobject_uevent(&disk->kobj, KOBJ_ADD);
  348. /* No minors to use for partitions */
  349. if (disk->minors == 1) {
  350. if (disk->devfs_name[0] != '\0')
  351. devfs_add_disk(disk);
  352. return;
  353. }
  354. /* always add handle for the whole disk */
  355. devfs_add_partitioned(disk);
  356. /* No such device (e.g., media were just removed) */
  357. if (!get_capacity(disk))
  358. return;
  359. bdev = bdget_disk(disk, 0);
  360. if (!bdev)
  361. return;
  362. bdev->bd_invalidated = 1;
  363. if (blkdev_get(bdev, FMODE_READ, 0) < 0)
  364. return;
  365. blkdev_put(bdev);
  366. }
  367. int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
  368. {
  369. struct parsed_partitions *state;
  370. int p, res;
  371. if (bdev->bd_part_count)
  372. return -EBUSY;
  373. res = invalidate_partition(disk, 0);
  374. if (res)
  375. return res;
  376. bdev->bd_invalidated = 0;
  377. for (p = 1; p < disk->minors; p++)
  378. delete_partition(disk, p);
  379. if (disk->fops->revalidate_disk)
  380. disk->fops->revalidate_disk(disk);
  381. if (!get_capacity(disk) || !(state = check_partition(disk, bdev)))
  382. return 0;
  383. for (p = 1; p < state->limit; p++) {
  384. sector_t size = state->parts[p].size;
  385. sector_t from = state->parts[p].from;
  386. if (!size)
  387. continue;
  388. add_partition(disk, p, from, size);
  389. #ifdef CONFIG_BLK_DEV_MD
  390. if (state->parts[p].flags)
  391. md_autodetect_dev(bdev->bd_dev+p);
  392. #endif
  393. }
  394. kfree(state);
  395. return 0;
  396. }
  397. unsigned char *read_dev_sector(struct block_device *bdev, sector_t n, Sector *p)
  398. {
  399. struct address_space *mapping = bdev->bd_inode->i_mapping;
  400. struct page *page;
  401. page = read_cache_page(mapping, (pgoff_t)(n >> (PAGE_CACHE_SHIFT-9)),
  402. (filler_t *)mapping->a_ops->readpage, NULL);
  403. if (!IS_ERR(page)) {
  404. wait_on_page_locked(page);
  405. if (!PageUptodate(page))
  406. goto fail;
  407. if (PageError(page))
  408. goto fail;
  409. p->v = page;
  410. return (unsigned char *)page_address(page) + ((n & ((1 << (PAGE_CACHE_SHIFT - 9)) - 1)) << 9);
  411. fail:
  412. page_cache_release(page);
  413. }
  414. p->v = NULL;
  415. return NULL;
  416. }
  417. EXPORT_SYMBOL(read_dev_sector);
  418. void del_gendisk(struct gendisk *disk)
  419. {
  420. int p;
  421. /* invalidate stuff */
  422. for (p = disk->minors - 1; p > 0; p--) {
  423. invalidate_partition(disk, p);
  424. delete_partition(disk, p);
  425. }
  426. invalidate_partition(disk, 0);
  427. disk->capacity = 0;
  428. disk->flags &= ~GENHD_FL_UP;
  429. unlink_gendisk(disk);
  430. disk_stat_set_all(disk, 0);
  431. disk->stamp = 0;
  432. devfs_remove_disk(disk);
  433. if (disk->driverfs_dev) {
  434. char *disk_name = make_block_name(disk);
  435. sysfs_remove_link(&disk->kobj, "device");
  436. if (disk_name) {
  437. sysfs_remove_link(&disk->driverfs_dev->kobj, disk_name);
  438. kfree(disk_name);
  439. }
  440. put_device(disk->driverfs_dev);
  441. }
  442. kobject_uevent(&disk->kobj, KOBJ_REMOVE);
  443. kobject_del(&disk->kobj);
  444. }