check.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  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/slab.h>
  16. #include <linux/vmalloc.h>
  17. #include <linux/ctype.h>
  18. #include <linux/genhd.h>
  19. #include "check.h"
  20. #include "acorn.h"
  21. #include "amiga.h"
  22. #include "atari.h"
  23. #include "ldm.h"
  24. #include "mac.h"
  25. #include "msdos.h"
  26. #include "osf.h"
  27. #include "sgi.h"
  28. #include "sun.h"
  29. #include "ibm.h"
  30. #include "ultrix.h"
  31. #include "efi.h"
  32. #include "karma.h"
  33. #include "sysv68.h"
  34. #include "cmdline.h"
  35. int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/
  36. static int (*check_part[])(struct parsed_partitions *) = {
  37. /*
  38. * Probe partition formats with tables at disk address 0
  39. * that also have an ADFS boot block at 0xdc0.
  40. */
  41. #ifdef CONFIG_ACORN_PARTITION_ICS
  42. adfspart_check_ICS,
  43. #endif
  44. #ifdef CONFIG_ACORN_PARTITION_POWERTEC
  45. adfspart_check_POWERTEC,
  46. #endif
  47. #ifdef CONFIG_ACORN_PARTITION_EESOX
  48. adfspart_check_EESOX,
  49. #endif
  50. /*
  51. * Now move on to formats that only have partition info at
  52. * disk address 0xdc0. Since these may also have stale
  53. * PC/BIOS partition tables, they need to come before
  54. * the msdos entry.
  55. */
  56. #ifdef CONFIG_ACORN_PARTITION_CUMANA
  57. adfspart_check_CUMANA,
  58. #endif
  59. #ifdef CONFIG_ACORN_PARTITION_ADFS
  60. adfspart_check_ADFS,
  61. #endif
  62. #ifdef CONFIG_CMDLINE_PARTITION
  63. cmdline_partition,
  64. #endif
  65. #ifdef CONFIG_EFI_PARTITION
  66. efi_partition, /* this must come before msdos */
  67. #endif
  68. #ifdef CONFIG_SGI_PARTITION
  69. sgi_partition,
  70. #endif
  71. #ifdef CONFIG_LDM_PARTITION
  72. ldm_partition, /* this must come before msdos */
  73. #endif
  74. #ifdef CONFIG_MSDOS_PARTITION
  75. msdos_partition,
  76. #endif
  77. #ifdef CONFIG_OSF_PARTITION
  78. osf_partition,
  79. #endif
  80. #ifdef CONFIG_SUN_PARTITION
  81. sun_partition,
  82. #endif
  83. #ifdef CONFIG_AMIGA_PARTITION
  84. amiga_partition,
  85. #endif
  86. #ifdef CONFIG_ATARI_PARTITION
  87. atari_partition,
  88. #endif
  89. #ifdef CONFIG_MAC_PARTITION
  90. mac_partition,
  91. #endif
  92. #ifdef CONFIG_ULTRIX_PARTITION
  93. ultrix_partition,
  94. #endif
  95. #ifdef CONFIG_IBM_PARTITION
  96. ibm_partition,
  97. #endif
  98. #ifdef CONFIG_KARMA_PARTITION
  99. karma_partition,
  100. #endif
  101. #ifdef CONFIG_SYSV68_PARTITION
  102. sysv68_partition,
  103. #endif
  104. NULL
  105. };
  106. static struct parsed_partitions *allocate_partitions(struct gendisk *hd)
  107. {
  108. struct parsed_partitions *state;
  109. int nr;
  110. state = kzalloc(sizeof(*state), GFP_KERNEL);
  111. if (!state)
  112. return NULL;
  113. nr = disk_max_parts(hd);
  114. state->parts = vzalloc(nr * sizeof(state->parts[0]));
  115. if (!state->parts) {
  116. kfree(state);
  117. return NULL;
  118. }
  119. state->limit = nr;
  120. return state;
  121. }
  122. void free_partitions(struct parsed_partitions *state)
  123. {
  124. vfree(state->parts);
  125. kfree(state);
  126. }
  127. struct parsed_partitions *
  128. check_partition(struct gendisk *hd, struct block_device *bdev)
  129. {
  130. struct parsed_partitions *state;
  131. int i, res, err;
  132. state = allocate_partitions(hd);
  133. if (!state)
  134. return NULL;
  135. state->pp_buf = (char *)__get_free_page(GFP_KERNEL);
  136. if (!state->pp_buf) {
  137. free_partitions(state);
  138. return NULL;
  139. }
  140. state->pp_buf[0] = '\0';
  141. state->bdev = bdev;
  142. disk_name(hd, 0, state->name);
  143. snprintf(state->pp_buf, PAGE_SIZE, " %s:", state->name);
  144. if (isdigit(state->name[strlen(state->name)-1]))
  145. sprintf(state->name, "p");
  146. i = res = err = 0;
  147. while (!res && check_part[i]) {
  148. memset(state->parts, 0, state->limit * sizeof(state->parts[0]));
  149. res = check_part[i++](state);
  150. if (res < 0) {
  151. /* We have hit an I/O error which we don't report now.
  152. * But record it, and let the others do their job.
  153. */
  154. err = res;
  155. res = 0;
  156. }
  157. }
  158. if (res > 0) {
  159. printk(KERN_INFO "%s", state->pp_buf);
  160. free_page((unsigned long)state->pp_buf);
  161. return state;
  162. }
  163. if (state->access_beyond_eod)
  164. err = -ENOSPC;
  165. if (err)
  166. /* The partition is unrecognized. So report I/O errors if there were any */
  167. res = err;
  168. if (res) {
  169. if (warn_no_part)
  170. strlcat(state->pp_buf,
  171. " unable to read partition table\n", PAGE_SIZE);
  172. printk(KERN_INFO "%s", state->pp_buf);
  173. }
  174. free_page((unsigned long)state->pp_buf);
  175. free_partitions(state);
  176. return ERR_PTR(res);
  177. }