Changeset e27b89a in mainline for uspace/srv/part/mbr_part/mbr_part.c


Ignore:
Timestamp:
2009-09-01T21:27:41Z (15 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0712ff2, 9aa54d4a
Parents:
440b0ce
Message:

Remove fixed limitation on partition count.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/part/mbr_part/mbr_part.c

    r440b0ce re27b89a  
    5959#include <bool.h>
    6060#include <byteorder.h>
     61#include <assert.h>
    6162#include <macros.h>
    6263#include <task.h>
     
    7071        /** Boot record signature */
    7172        BR_SIGNATURE    = 0xAA55,
    72 
    73         /** Maximum number of partitions */
    74         MAX_PART        = 64
    7573};
    7674
     
    8179
    8280/** Partition */
    83 typedef struct {
     81typedef struct part {
    8482        /** Primary partition entry is in use */
    8583        bool present;
     
    9088        /** Device representing the partition (outbound device) */
    9189        dev_handle_t dev;
     90        /** Points to next partition structure. */
     91        struct part *next;
    9292} part_t;
    9393
     
    130130static dev_handle_t indev_handle;
    131131
    132 static part_t primary[MAX_PART];
     132/** List of partitions. This structure is an empty head. */
     133static part_t plist_head;
    133134
    134135static int mbr_init(const char *dev_name);
    135136static int mbr_part_read(void);
     137static part_t *mbr_part_new(void);
    136138static void mbr_pte_to_part(uint32_t base, const pt_entry_t *pte, part_t *part);
    137139static void mbr_connection(ipc_callid_t iid, ipc_call_t *icall);
     
    140142static int mbr_bsa_translate(part_t *p, uint64_t ba, size_t cnt, uint64_t *gba);
    141143
    142 /** Total number of partitions entries in @c primary (including non-present). */
    143 static int total_part;
    144 
    145144int main(int argc, char **argv)
    146145{
     
    170169        dev_handle_t dev;
    171170        uint64_t size_mb;
     171        part_t *part;
    172172
    173173        rc = devmap_device_get_handle(dev_name, &indev_handle, 0);
     
    208208        }
    209209
    210         /* Create partition devices. */
    211         for (i = 0; i < total_part; ++i) {
     210        /*
     211         * Create partition devices.
     212         */
     213        i = 0;
     214        part = plist_head.next;
     215
     216        while (part != NULL) {
    212217                /* Skip absent partitions. */
    213                 if (!primary[i].present)
     218                if (!part->present) {
     219                        part = part->next;
     220                        ++i;
    214221                        continue;
     222                }
    215223
    216224                asprintf(&name, "%sp%d", dev_name, i);
     
    225233                }
    226234
    227                 size_mb = (primary[i].length * block_size + 1024 * 1024 - 1)
     235                size_mb = (part->length * block_size + 1024 * 1024 - 1)
    228236                    / (1024 * 1024);
    229237                printf(NAME ": Registered device %s: %llu blocks %llu MB.\n",
    230                     name, primary[i].length, size_mb);
    231 
    232                 primary[i].dev = dev;
     238                    name, part->length, size_mb);
     239
     240                part->dev = dev;
    233241                free(name);
     242
     243                part = part->next;
     244                ++i;
    234245        }
    235246
     
    246257        part_t *ext_part, cp;
    247258        uint32_t base;
     259        part_t *prev, *p;
    248260
    249261        brb = malloc(sizeof(br_block_t));
     
    270282
    271283        ext_part = NULL;
     284        plist_head.next = NULL;
     285        prev = &plist_head;
    272286
    273287        for (i = 0; i < N_PRIMARY; ++i) {
    274                 mbr_pte_to_part(0, &brb->pte[i], &primary[i]);
     288                p = mbr_part_new();
     289                if (p == NULL)
     290                        return ENOMEM;
     291
     292                mbr_pte_to_part(0, &brb->pte[i], p);
     293                prev->next = p;
     294                prev = p;
    275295
    276296                if (brb->pte[i].ptype == PT_EXTENDED) {
    277                         primary[i].present = false;
    278                         ext_part = &primary[i];
     297                        p->present = false;
     298                        ext_part = p;
    279299                }
    280300        }
     
    312332                }
    313333
     334                p = mbr_part_new();
     335                if (p == NULL)
     336                        return ENOMEM;
     337
    314338                /* First PTE is the logical partition itself. */
    315                 mbr_pte_to_part(base, &brb->pte[0], &primary[i]);
    316                 ++i;
     339                mbr_pte_to_part(base, &brb->pte[0], p);
     340                prev->next = p;
     341                prev = p;
    317342
    318343                /* Second PTE describes next chain element. */
    319344                mbr_pte_to_part(base, &brb->pte[1], &cp);
    320         } while (cp.present && i < MAX_PART);
    321 
    322         total_part = i;
     345        } while (cp.present);
    323346
    324347        return EOK;
     348}
     349
     350/** Allocate a new @c part_t structure. */
     351static part_t *mbr_part_new(void)
     352{
     353        return malloc(sizeof(part_t));
    325354}
    326355
     
    338367        part->present = (sa != 0 || len != 0) ? true : false;
    339368        part->dev = 0;
     369        part->next = NULL;
    340370}
    341371
     
    352382        uint64_t ba;
    353383        size_t cnt;
    354         int pidx, i;
    355384        part_t *part;
    356385
     
    358387        dh = IPC_GET_ARG1(*icall);
    359388
    360         /* Determine which partition device is the client connecting to. */
    361         pidx = -1;
    362         for (i = 0; i < total_part; i++)
    363                 if (primary[i].dev == dh)
    364                         pidx = i;
    365 
    366         if (pidx < 0/* || disk[disk_id].present == false*/) {
     389        /*
     390         * Determine which partition device is the client connecting to.
     391         * A linear search is not terribly fast, but we only do this
     392         * once for each connection.
     393         */
     394        part = plist_head.next;
     395        while (part != NULL && part->dev != dh)
     396                part = part->next;
     397
     398        if (part == NULL) {
    367399                ipc_answer_0(iid, EINVAL);
    368400                return;
    369401        }
    370402
    371         part = &primary[pidx];
     403        assert(part->present == true);
    372404
    373405        /* Answer the IPC_M_CONNECT_ME_TO call. */
Note: See TracChangeset for help on using the changeset viewer.