Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:14

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup rtems_bdpart
0007  *
0008  * @brief Block Device Partition Management
0009  */
0010 
0011 /*
0012  * Copyright (C) 2009, 2012 embedded brains GmbH & Co. KG
0013  *
0014  * Redistribution and use in source and binary forms, with or without
0015  * modification, are permitted provided that the following conditions
0016  * are met:
0017  * 1. Redistributions of source code must retain the above copyright
0018  *    notice, this list of conditions and the following disclaimer.
0019  * 2. Redistributions in binary form must reproduce the above copyright
0020  *    notice, this list of conditions and the following disclaimer in the
0021  *    documentation and/or other materials provided with the distribution.
0022  *
0023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0033  * POSSIBILITY OF SUCH DAMAGE.
0034  */
0035 
0036 #ifdef HAVE_CONFIG_H
0037 #include "config.h"
0038 #endif
0039 
0040 #include <stdio.h>
0041 #include <stdlib.h>
0042 #include <string.h>
0043 #include <unistd.h>
0044 
0045 #include <rtems.h>
0046 #include <rtems/bdpart.h>
0047 
0048 static char *create_logical_disk_name( const char *disk_name, char **marker)
0049 {
0050   size_t disk_name_size = strlen( disk_name);
0051   char *logical_disk_name = malloc( disk_name_size + RTEMS_BDPART_NUMBER_SIZE);
0052 
0053   if (logical_disk_name != NULL) {
0054     /* The string is NUL terminated by (A) ... */
0055     memcpy( logical_disk_name, disk_name, disk_name_size);
0056     *marker = logical_disk_name + disk_name_size;
0057   }
0058 
0059   return logical_disk_name;
0060 }
0061 
0062 static rtems_status_code update_logical_disk_name(
0063   char *logical_disk_marker,
0064   size_t i
0065 )
0066 {
0067   rtems_status_code sc = RTEMS_SUCCESSFUL;
0068   int rv = 0;
0069 
0070   /* ... (A) */
0071   rv = snprintf( logical_disk_marker, RTEMS_BDPART_NUMBER_SIZE, "%zu", i + 1);
0072   if (rv >= RTEMS_BDPART_NUMBER_SIZE) {
0073     sc = RTEMS_INVALID_NAME;
0074   }
0075 
0076   return sc;
0077 }
0078 
0079 rtems_status_code rtems_bdpart_register(
0080   const char *disk_name,
0081   const rtems_bdpart_partition *pt,
0082   size_t count
0083 )
0084 {
0085   rtems_status_code sc = RTEMS_SUCCESSFUL;
0086   rtems_status_code esc = RTEMS_SUCCESSFUL;
0087   rtems_blkdev_bnum disk_end = 0;
0088   char *logical_disk_name = NULL;
0089   char *logical_disk_marker = NULL;
0090   size_t i = 0;
0091   int fd = -1;
0092   rtems_disk_device *dd = NULL;
0093 
0094   /* Get disk data */
0095   sc = rtems_bdpart_get_disk_data( disk_name, &fd, &dd, &disk_end);
0096   if (sc != RTEMS_SUCCESSFUL) {
0097     return sc;
0098   }
0099 
0100   /* Create logical disk name */
0101   logical_disk_name = create_logical_disk_name(
0102     disk_name,
0103     &logical_disk_marker
0104   );
0105   if (logical_disk_name == NULL) {
0106     esc = sc;
0107     goto cleanup;
0108   }
0109 
0110   /* Create a logical disk for each partition */
0111   for (i = 0; i < count; ++i) {
0112     const rtems_bdpart_partition *p = pt + i;
0113 
0114     /* Set partition number for logical disk name */
0115     sc = update_logical_disk_name( logical_disk_marker, i);
0116     if (sc != RTEMS_SUCCESSFUL) {
0117       esc = sc;
0118       goto cleanup;
0119     }
0120 
0121     /* Create logical disk */
0122     sc = rtems_blkdev_create_partition(
0123       logical_disk_name,
0124       disk_name,
0125       p->begin,
0126       p->end - p->begin
0127     );
0128     if (sc != RTEMS_SUCCESSFUL) {
0129       esc = sc;
0130       goto cleanup;
0131     }
0132   }
0133 
0134 cleanup:
0135 
0136   free( logical_disk_name);
0137   close( fd);
0138 
0139   return esc;
0140 }
0141 
0142 rtems_status_code rtems_bdpart_register_from_disk( const char *disk_name)
0143 {
0144   rtems_status_code sc = RTEMS_SUCCESSFUL;
0145   rtems_bdpart_format format;
0146   rtems_bdpart_partition pt [RTEMS_BDPART_PARTITION_NUMBER_HINT];
0147   size_t count = RTEMS_BDPART_PARTITION_NUMBER_HINT;
0148 
0149   /* Read partitions */
0150   sc = rtems_bdpart_read( disk_name, &format, pt, &count);
0151   if (sc != RTEMS_SUCCESSFUL) {
0152     return sc;
0153   }
0154 
0155   /* Register partitions */
0156   return rtems_bdpart_register( disk_name, pt, count);
0157 }
0158 
0159 rtems_status_code rtems_bdpart_unregister(
0160   const char *disk_name,
0161   const rtems_bdpart_partition *pt RTEMS_UNUSED,
0162   size_t count
0163 )
0164 {
0165   rtems_status_code sc = RTEMS_SUCCESSFUL;
0166   rtems_status_code esc = RTEMS_SUCCESSFUL;
0167   rtems_blkdev_bnum disk_end = 0;
0168   char *logical_disk_name = NULL;
0169   char *logical_disk_marker = NULL;
0170   size_t i = 0;
0171   int fd = -1;
0172   rtems_disk_device *dd = NULL;
0173 
0174   /* Get disk data */
0175   sc = rtems_bdpart_get_disk_data( disk_name, &fd, &dd, &disk_end);
0176   if (sc != RTEMS_SUCCESSFUL) {
0177     return sc;
0178   }
0179 
0180   /* Create logical disk name */
0181   logical_disk_name = create_logical_disk_name(
0182     disk_name,
0183     &logical_disk_marker
0184   );
0185   if (logical_disk_name == NULL) {
0186     esc = sc;
0187     goto cleanup;
0188   }
0189 
0190   /* Delete the logical disk for each partition */
0191   for (i = 0; i < count; ++i) {
0192     int rv = 0;
0193 
0194     /* Set partition number for logical disk name */
0195     sc = update_logical_disk_name( logical_disk_marker, i);
0196     if (sc != RTEMS_SUCCESSFUL) {
0197       esc = sc;
0198       goto cleanup;
0199     }
0200 
0201     /* Delete logical disk */
0202     rv = unlink( logical_disk_name);
0203     if (rv != 0) {
0204       esc = sc;
0205       goto cleanup;
0206     }
0207   }
0208 
0209 cleanup:
0210 
0211   /*
0212    * When we get here, logical_disk_name is guaranteed to be non-NULL
0213    * but fd may be -1. Coverity flagged passing a bad value to close().
0214    */
0215   free( logical_disk_name);
0216   if (fd >= 0) {
0217     close( fd);
0218   }
0219 
0220   return esc;
0221 }