source: rtems/cpukit/libblock/src/bdpart-create.c @ f381e9b

Last change on this file since f381e9b was f381e9b, checked in by Joel Sherrill <joel@…>, on 02/17/22 at 15:47:33

cpukit/libblock: Change license to BSD-2

Updates #3053.

  • Property mode set to 100644
File size: 4.6 KB
Line 
1/* SPDX-License-Identifier: BSD-2-Clause */
2
3/**
4 * @file
5 *
6 * @ingroup rtems_bdpart
7 *
8 * @brief Manage Partitions of a Disk Device
9 */
10
11/*
12 * Copyright (c) 2009, 2010
13 * embedded brains GmbH
14 * Obere Lagerstr. 30
15 * D-82178 Puchheim
16 * Germany
17 * <rtems@embedded-brains.de>
18 *
19 * Redistribution and use in source and binary forms, with or without
20 * modification, are permitted provided that the following conditions
21 * are met:
22 * 1. Redistributions of source code must retain the above copyright
23 *    notice, this list of conditions and the following disclaimer.
24 * 2. Redistributions in binary form must reproduce the above copyright
25 *    notice, this list of conditions and the following disclaimer in the
26 *    documentation and/or other materials provided with the distribution.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
29 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
32 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
33 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38 * POSSIBILITY OF SUCH DAMAGE.
39 */
40
41#ifdef HAVE_CONFIG_H
42#include "config.h"
43#endif
44
45#include <rtems.h>
46#include <rtems/bdpart.h>
47
48rtems_status_code rtems_bdpart_create(
49  const char *disk_name,
50  const rtems_bdpart_format *format,
51  rtems_bdpart_partition *pt,
52  const unsigned *dist,
53  size_t count
54)
55{
56  rtems_status_code sc = RTEMS_SUCCESSFUL;
57  bool dos_compatibility = format != NULL
58    && format->type == RTEMS_BDPART_FORMAT_MBR
59    && format->mbr.dos_compatibility;
60  rtems_blkdev_bnum disk_end = 0;
61  rtems_blkdev_bnum pos = 0;
62  rtems_blkdev_bnum dist_sum = 0;
63  rtems_blkdev_bnum record_space =
64    dos_compatibility ? RTEMS_BDPART_MBR_CYLINDER_SIZE : 1;
65  rtems_blkdev_bnum overhead = 0;
66  rtems_blkdev_bnum free_space = 0;
67  size_t i = 0;
68
69  /* Check if we have something to do */
70  if (count == 0) {
71    /* Nothing to do */
72    return RTEMS_SUCCESSFUL;
73  }
74
75  /* Check parameter */
76  if (format == NULL || pt == NULL || dist == NULL) {
77    return RTEMS_INVALID_ADDRESS;
78  }
79
80  /* Get disk data */
81  sc = rtems_bdpart_get_disk_data( disk_name, NULL, NULL, &disk_end);
82  if (sc != RTEMS_SUCCESSFUL) {
83    return sc;
84  }
85
86  /* Get distribution sum and check for overflow */
87  for (i = 0; i < count; ++i) {
88    unsigned prev_sum = dist_sum;
89
90    dist_sum += dist [i];
91
92    if (dist_sum < prev_sum) {
93      return RTEMS_INVALID_NUMBER;
94    }
95
96    if (dist [i] == 0) {
97      return RTEMS_INVALID_NUMBER;
98    }
99  }
100
101  /* Check format */
102  if (format->type != RTEMS_BDPART_FORMAT_MBR) {
103    return RTEMS_NOT_IMPLEMENTED;
104  }
105
106  /* Align end of disk on cylinder boundary if necessary */
107  if (dos_compatibility) {
108    disk_end -= (disk_end % record_space);
109  }
110
111  /*
112   * We need at least space for the MBR and the compatibility space for the
113   * first primary partition.
114   */
115  overhead += record_space;
116
117  /*
118   * In case we need an extended partition and logical partitions we have to
119   * account for the space of each EBR.
120   */
121  if (count > 4) {
122    overhead += (count - 3) * record_space;
123  }
124
125  /*
126   * Account space to align every partition on cylinder boundaries if
127   * necessary.
128   */
129  if (dos_compatibility) {
130    overhead += (count - 1) * record_space;
131  }
132
133  /* Check disk space */
134  if ((overhead + count) > disk_end) {
135    return RTEMS_IO_ERROR;
136  }
137
138  /* Begin of first primary partition */
139  pos = record_space;
140
141  /* Space for partitions */
142  free_space = disk_end - overhead;
143
144  for (i = 0; i < count; ++i) {
145    rtems_bdpart_partition *p = pt + i;
146
147    /* Partition size */
148    rtems_blkdev_bnum s = free_space * dist [i];
149    if (s < free_space || s < dist [i]) {
150      /* TODO: Calculate without overflow */
151      return RTEMS_INVALID_NUMBER;
152    }
153    s /= dist_sum;
154
155    /* Ensure that the partition is not empty */
156    if (s == 0) {
157      s = 1;
158    }
159
160    /* Align partition upwards */
161    s += record_space - (s % record_space);
162
163    /* Reserve space for the EBR if necessary */
164    if (count > 4 && i > 2) {
165      pos += record_space;
166    }
167
168    /* Partition begin and end */
169    p->begin = pos;
170    pos += s;
171    p->end = pos;
172  }
173
174  /* Expand the last partition to the disk end */
175  pt [count - 1].end = disk_end;
176
177  return RTEMS_SUCCESSFUL;
178}
Note: See TracBrowser for help on using the repository browser.