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

4.104.115
Last change on this file since e682fffd was 6780829, checked in by Sebastian Huber <sebastian.huber@…>, on 04/30/10 at 08:42:13

2010-04-30 Sebastian Huber <sebastian.huber@…>

  • libblock/src/bdpart.c: Removed file.
  • libblock/src/bdpart-create.c, libblock/src/bdpart-dump.c, libblock/src/bdpart-mount.c, libblock/src/bdpart-read.c, libblock/src/bdpart-register.c, libblock/src/bdpart-sort.c, libblock/src/bdpart-write.c: New files.
  • libblock/include/rtems/bdpart.h: Moved some definitions from bdpart.c.
  • libblock/Makefile.am: Update for file changes.
  • Property mode set to 100644
File size: 3.5 KB
Line 
1/**
2 * @file
3 *
4 * @ingroup rtems_bdpart
5 *
6 * Block device partition management.
7 */
8
9/*
10 * Copyright (c) 2009, 2010
11 * embedded brains GmbH
12 * Obere Lagerstr. 30
13 * D-82178 Puchheim
14 * Germany
15 * <rtems@embedded-brains.de>
16 *
17 * The license and distribution terms for this file may be
18 * found in the file LICENSE in this distribution or at
19 * http://www.rtems.com/license/LICENSE.
20 */
21
22#ifdef HAVE_CONFIG_H
23#include "config.h"
24#endif
25
26#include <rtems.h>
27#include <rtems/bdpart.h>
28
29rtems_status_code rtems_bdpart_create(
30  const char *disk_name,
31  const rtems_bdpart_format *format,
32  rtems_bdpart_partition *pt,
33  const unsigned *dist,
34  size_t count
35)
36{
37  rtems_status_code sc = RTEMS_SUCCESSFUL;
38  bool dos_compatibility = format != NULL
39    && format->type == RTEMS_BDPART_FORMAT_MBR
40    && format->mbr.dos_compatibility;
41  rtems_blkdev_bnum disk_end = 0;
42  rtems_blkdev_bnum pos = 0;
43  rtems_blkdev_bnum dist_sum = 0;
44  rtems_blkdev_bnum record_space =
45    dos_compatibility ? RTEMS_BDPART_MBR_CYLINDER_SIZE : 1;
46  rtems_blkdev_bnum overhead = 0;
47  rtems_blkdev_bnum free_space = 0;
48  dev_t disk = 0;
49  size_t i = 0;
50
51  /* Check if we have something to do */
52  if (count == 0) {
53    /* Nothing to do */
54    return RTEMS_SUCCESSFUL;
55  }
56
57  /* Check parameter */
58  if (format == NULL || pt == NULL || dist == NULL) {
59    return RTEMS_INVALID_ADDRESS;
60  }
61
62  /* Get disk data */
63  sc = rtems_bdpart_get_disk_data( disk_name, &disk, &disk_end);
64  if (sc != RTEMS_SUCCESSFUL) {
65    return sc;
66  }
67
68  /* Get distribution sum and check for overflow */
69  for (i = 0; i < count; ++i) {
70    unsigned prev_sum = dist_sum;
71
72    dist_sum += dist [i];
73
74    if (dist_sum < prev_sum) {
75      return RTEMS_INVALID_NUMBER;
76    }
77
78    if (dist [i] == 0) {
79      return RTEMS_INVALID_NUMBER;
80    }
81  }
82
83  /* Check format */
84  if (format->type != RTEMS_BDPART_FORMAT_MBR) {
85    return RTEMS_NOT_IMPLEMENTED;
86  }
87
88  /* Align end of disk on cylinder boundary if necessary */
89  if (dos_compatibility) {
90    disk_end -= (disk_end % record_space);
91  }
92
93  /*
94   * We need at least space for the MBR and the compatibility space for the
95   * first primary partition.
96   */
97  overhead += record_space;
98
99  /*
100   * In case we need an extended partition and logical partitions we have to
101   * account for the space of each EBR.
102   */
103  if (count > 4) {
104    overhead += (count - 3) * record_space;
105  }
106
107  /*
108   * Account space to align every partition on cylinder boundaries if
109   * necessary.
110   */
111  if (dos_compatibility) {
112    overhead += (count - 1) * record_space;
113  }
114
115  /* Check disk space */
116  if ((overhead + count) > disk_end) {
117    return RTEMS_IO_ERROR;
118  }
119
120  /* Begin of first primary partition */
121  pos = record_space;
122
123  /* Space for partitions */
124  free_space = disk_end - overhead;
125
126  for (i = 0; i < count; ++i) {
127    rtems_bdpart_partition *p = pt + i;
128
129    /* Partition size */
130    rtems_blkdev_bnum s = free_space * dist [i];
131    if (s < free_space || s < dist [i]) {
132      /* TODO: Calculate without overflow */
133      return RTEMS_INVALID_NUMBER;
134    }
135    s /= dist_sum;
136
137    /* Ensure that the partition is not empty */
138    if (s == 0) {
139      s = 1;
140    }
141
142    /* Align partition upwards */
143    s += record_space - (s % record_space);
144
145    /* Partition begin and end */
146    p->begin = pos;
147    pos += s;
148    p->end = pos;
149
150    /* Reserve space for the EBR if necessary */
151    if (count > 4 && i > 2) {
152      p->begin += record_space;
153    }
154  }
155
156  /* Expand the last partition to the disk end */
157  pt [count - 1].end = disk_end;
158
159  return RTEMS_SUCCESSFUL;
160}
Note: See TracBrowser for help on using the repository browser.