check.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * fs/partitions/check.c
  4. *
  5. * Code extracted from drivers/block/genhd.c
  6. * Copyright (C) 1991-1998 Linus Torvalds
  7. * Re-organised Feb 1998 Russell King
  8. *
  9. * We now have independent partition support from the
  10. * block drivers, which allows all the partition code to
  11. * be grouped in one location, and it to be mostly self
  12. * contained.
  13. *
  14. * Added needed MAJORS for new pairs, {hdi,hdj}, {hdk,hdl}
  15. */
  16. #include <linux/slab.h>
  17. #include <linux/vmalloc.h>
  18. #include <linux/ctype.h>
  19. #include <linux/genhd.h>
  20. #include "check.h"
  21. #include "acorn.h"
  22. #include "amiga.h"
  23. #include "atari.h"
  24. #include "ldm.h"
  25. #include "mac.h"
  26. #include "msdos.h"
  27. #include "osf.h"
  28. #include "sgi.h"
  29. #include "sun.h"
  30. #include "ibm.h"
  31. #include "ultrix.h"
  32. #include "efi.h"
  33. #include "karma.h"
  34. #include "sysv68.h"
  35. #include "cmdline.h"
  36. int warn_no_part = 1; /*This is ugly: should make genhd removable media aware*/
  37. static int (*check_part[])(struct parsed_partitions *) = {
  38. /*
  39. * Probe partition formats with tables at disk address 0
  40. * that also have an ADFS boot block at 0xdc0.
  41. */
  42. #ifdef CONFIG_ACORN_PARTITION_ICS
  43. adfspart_check_ICS,
  44. #endif
  45. #ifdef CONFIG_ACORN_PARTITION_POWERTEC
  46. adfspart_check_POWERTEC,
  47. #endif
  48. #ifdef CONFIG_ACORN_PARTITION_EESOX
  49. adfspart_check_EESOX,
  50. #endif
  51. /*
  52. * Now move on to formats that only have partition info at
  53. * disk address 0xdc0. Since these may also have stale
  54. * PC/BIOS partition tables, they need to come before
  55. * the msdos entry.
  56. */
  57. #ifdef CONFIG_ACORN_PARTITION_CUMANA
  58. adfspart_check_CUMANA,
  59. #endif
  60. #ifdef CONFIG_ACORN_PARTITION_ADFS
  61. adfspart_check_ADFS,
  62. #endif
  63. #ifdef CONFIG_CMDLINE_PARTITION
  64. cmdline_partition,
  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. #ifdef CONFIG_SYSV68_PARTITION
  103. sysv68_partition,
  104. #endif
  105. NULL
  106. };
  107. static struct parsed_partitions *allocate_partitions(struct gendisk *hd)
  108. {
  109. struct parsed_partitions *state;
  110. int nr;
  111. state = kzalloc(sizeof(*state), GFP_KERNEL);
  112. if (!state)
  113. return NULL;
  114. nr = disk_max_parts(hd);
  115. state->parts = vzalloc(array_size(nr, sizeof(state->parts[0])));
  116. if (!state->parts) {
  117. kfree(state);
  118. return NULL;
  119. }
  120. state->limit = nr;
  121. return state;
  122. }
  123. void free_partitions(struct parsed_partitions *state)
  124. {
  125. vfree(state->parts);
  126. kfree(state);
  127. }
  128. struct parsed_partitions *
  129. check_partition(struct gendisk *hd, struct block_device *bdev)
  130. {
  131. struct parsed_partitions *state;
  132. int i, res, err;
  133. state = allocate_partitions(hd);
  134. if (!state)
  135. return NULL;
  136. state->pp_buf = (char *)__get_free_page(GFP_KERNEL);
  137. if (!state->pp_buf) {
  138. free_partitions(state);
  139. return NULL;
  140. }
  141. state->pp_buf[0] = '\0';
  142. state->bdev = bdev;
  143. disk_name(hd, 0, state->name);
  144. snprintf(state->pp_buf, PAGE_SIZE, " %s:", state->name);
  145. if (isdigit(state->name[strlen(state->name)-1]))
  146. sprintf(state->name, "p");
  147. i = res = err = 0;
  148. while (!res && check_part[i]) {
  149. memset(state->parts, 0, state->limit * sizeof(state->parts[0]));
  150. res = check_part[i++](state);
  151. if (res < 0) {
  152. /* We have hit an I/O error which we don't report now.
  153. * But record it, and let the others do their job.
  154. */
  155. err = res;
  156. res = 0;
  157. }
  158. }
  159. if (res > 0) {
  160. printk(KERN_INFO "%s", state->pp_buf);
  161. free_page((unsigned long)state->pp_buf);
  162. return state;
  163. }
  164. if (state->access_beyond_eod)
  165. err = -ENOSPC;
  166. if (err)
  167. /* The partition is unrecognized. So report I/O errors if there were any */
  168. res = err;
  169. if (res) {
  170. if (warn_no_part)
  171. strlcat(state->pp_buf,
  172. " unable to read partition table\n", PAGE_SIZE);
  173. printk(KERN_INFO "%s", state->pp_buf);
  174. }
  175. free_page((unsigned long)state->pp_buf);
  176. free_partitions(state);
  177. return ERR_PTR(res);
  178. }