root/block/partitions/check.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. allocate_partitions
  2. free_partitions
  3. check_partition

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

/* [<][>][^][v][top][bottom][index][help] */