check.c 4.2 KB

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