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