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