Linux Audio

Check our new training course

Yocto / OpenEmbedded training

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