Home | History | Annotate | Download | only in ext2fs
      1 /*
      2  * brel_ma.c
      3  *
      4  * Copyright (C) 1996, 1997 Theodore Ts'o.
      5  *
      6  * TODO: rewrite to not use a direct array!!!  (Fortunately this
      7  * module isn't really used yet.)
      8  *
      9  * %Begin-Header%
     10  * This file may be redistributed under the terms of the GNU Library
     11  * General Public License, version 2.
     12  * %End-Header%
     13  */
     14 
     15 #include "config.h"
     16 #include <fcntl.h>
     17 #include <stdio.h>
     18 #include <string.h>
     19 #if HAVE_UNISTD_H
     20 #include <unistd.h>
     21 #endif
     22 #if HAVE_ERRNO_H
     23 #include <errno.h>
     24 #endif
     25 
     26 #include "ext2_fs.h"
     27 #include "ext2fs.h"
     28 #include "brel.h"
     29 
     30 static errcode_t bma_put(ext2_brel brel, blk64_t old,
     31 			struct ext2_block_relocate_entry *ent);
     32 static errcode_t bma_get(ext2_brel brel, blk64_t old,
     33 			struct ext2_block_relocate_entry *ent);
     34 static errcode_t bma_start_iter(ext2_brel brel);
     35 static errcode_t bma_next(ext2_brel brel, blk64_t *old,
     36 			 struct ext2_block_relocate_entry *ent);
     37 static errcode_t bma_move(ext2_brel brel, blk64_t old, blk64_t new);
     38 static errcode_t bma_delete(ext2_brel brel, blk64_t old);
     39 static errcode_t bma_free(ext2_brel brel);
     40 
     41 struct brel_ma {
     42 	__u32 magic;
     43 	blk64_t max_block;
     44 	struct ext2_block_relocate_entry *entries;
     45 };
     46 
     47 errcode_t ext2fs_brel_memarray_create(char *name, blk64_t max_block,
     48 				      ext2_brel *new_brel)
     49 {
     50 	ext2_brel		brel = 0;
     51 	errcode_t	retval;
     52 	struct brel_ma 	*ma = 0;
     53 	size_t		size;
     54 
     55 	*new_brel = 0;
     56 
     57 	/*
     58 	 * Allocate memory structures
     59 	 */
     60 	retval = ext2fs_get_mem(sizeof(struct ext2_block_relocation_table),
     61 				&brel);
     62 	if (retval)
     63 		goto errout;
     64 	memset(brel, 0, sizeof(struct ext2_block_relocation_table));
     65 
     66 	retval = ext2fs_get_mem(strlen(name)+1, &brel->name);
     67 	if (retval)
     68 		goto errout;
     69 	strcpy(brel->name, name);
     70 
     71 	retval = ext2fs_get_mem(sizeof(struct brel_ma), &ma);
     72 	if (retval)
     73 		goto errout;
     74 	memset(ma, 0, sizeof(struct brel_ma));
     75 	brel->priv_data = ma;
     76 
     77 	size = (size_t) (sizeof(struct ext2_block_relocate_entry) *
     78 			 (max_block+1));
     79 	retval = ext2fs_get_array(max_block+1,
     80 		sizeof(struct ext2_block_relocate_entry), &ma->entries);
     81 	if (retval)
     82 		goto errout;
     83 	memset(ma->entries, 0, size);
     84 	ma->max_block = max_block;
     85 
     86 	/*
     87 	 * Fill in the brel data structure
     88 	 */
     89 	brel->put = bma_put;
     90 	brel->get = bma_get;
     91 	brel->start_iter = bma_start_iter;
     92 	brel->next = bma_next;
     93 	brel->move = bma_move;
     94 	brel->delete = bma_delete;
     95 	brel->free = bma_free;
     96 
     97 	*new_brel = brel;
     98 	return 0;
     99 
    100 errout:
    101 	bma_free(brel);
    102 	return retval;
    103 }
    104 
    105 static errcode_t bma_put(ext2_brel brel, blk64_t old,
    106 			struct ext2_block_relocate_entry *ent)
    107 {
    108 	struct brel_ma 	*ma;
    109 
    110 	ma = brel->priv_data;
    111 	if (old > ma->max_block)
    112 		return EXT2_ET_INVALID_ARGUMENT;
    113 	ma->entries[(unsigned)old] = *ent;
    114 	return 0;
    115 }
    116 
    117 static errcode_t bma_get(ext2_brel brel, blk64_t old,
    118 			struct ext2_block_relocate_entry *ent)
    119 {
    120 	struct brel_ma 	*ma;
    121 
    122 	ma = brel->priv_data;
    123 	if (old > ma->max_block)
    124 		return EXT2_ET_INVALID_ARGUMENT;
    125 	if (ma->entries[(unsigned)old].new == 0)
    126 		return ENOENT;
    127 	*ent = ma->entries[old];
    128 	return 0;
    129 }
    130 
    131 static errcode_t bma_start_iter(ext2_brel brel)
    132 {
    133 	brel->current = 0;
    134 	return 0;
    135 }
    136 
    137 static errcode_t bma_next(ext2_brel brel, blk64_t *old,
    138 			  struct ext2_block_relocate_entry *ent)
    139 {
    140 	struct brel_ma 	*ma;
    141 
    142 	ma = brel->priv_data;
    143 	while (++brel->current < ma->max_block) {
    144 		if (ma->entries[(unsigned)brel->current].new == 0)
    145 			continue;
    146 		*old = brel->current;
    147 		*ent = ma->entries[(unsigned)brel->current];
    148 		return 0;
    149 	}
    150 	*old = 0;
    151 	return 0;
    152 }
    153 
    154 static errcode_t bma_move(ext2_brel brel, blk64_t old, blk64_t new)
    155 {
    156 	struct brel_ma 	*ma;
    157 
    158 	ma = brel->priv_data;
    159 	if ((old > ma->max_block) || (new > ma->max_block))
    160 		return EXT2_ET_INVALID_ARGUMENT;
    161 	if (ma->entries[(unsigned)old].new == 0)
    162 		return ENOENT;
    163 	ma->entries[(unsigned)new] = ma->entries[old];
    164 	ma->entries[(unsigned)old].new = 0;
    165 	return 0;
    166 }
    167 
    168 static errcode_t bma_delete(ext2_brel brel, blk64_t old)
    169 {
    170 	struct brel_ma 	*ma;
    171 
    172 	ma = brel->priv_data;
    173 	if (old > ma->max_block)
    174 		return EXT2_ET_INVALID_ARGUMENT;
    175 	if (ma->entries[(unsigned)old].new == 0)
    176 		return ENOENT;
    177 	ma->entries[(unsigned)old].new = 0;
    178 	return 0;
    179 }
    180 
    181 static errcode_t bma_free(ext2_brel brel)
    182 {
    183 	struct brel_ma 	*ma;
    184 
    185 	if (!brel)
    186 		return 0;
    187 
    188 	ma = brel->priv_data;
    189 
    190 	if (ma) {
    191 		if (ma->entries)
    192 			ext2fs_free_mem(&ma->entries);
    193 		ext2fs_free_mem(&ma);
    194 	}
    195 	if (brel->name)
    196 		ext2fs_free_mem(&brel->name);
    197 	ext2fs_free_mem(&brel);
    198 	return 0;
    199 }
    200