blob: 4dcfded373aaab10ab0d84a1d5b2ec902edee1aa [file] [log] [blame]
Mike Frysinger1fd98e02005-05-09 22:10:42 +00001/*
2 * brel_ma.c
Tim Rikerc1ef7bd2006-01-25 00:08:53 +00003 *
Mike Frysinger1fd98e02005-05-09 22:10:42 +00004 * 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;
Tim Rikerc1ef7bd2006-01-25 00:08:53 +000051 struct brel_ma *ma = 0;
Mike Frysinger1fd98e02005-05-09 22:10:42 +000052 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 &brel);
61 if (retval)
62 goto errout;
63 memset(brel, 0, sizeof(struct ext2_block_relocation_table));
Tim Rikerc1ef7bd2006-01-25 00:08:53 +000064
Mike Frysinger1fd98e02005-05-09 22:10:42 +000065 retval = ext2fs_get_mem(strlen(name)+1, &brel->name);
66 if (retval)
67 goto errout;
68 strcpy(brel->name, name);
Tim Rikerc1ef7bd2006-01-25 00:08:53 +000069
Mike Frysinger1fd98e02005-05-09 22:10:42 +000070 retval = ext2fs_get_mem(sizeof(struct brel_ma), &ma);
71 if (retval)
72 goto errout;
73 memset(ma, 0, sizeof(struct brel_ma));
74 brel->priv_data = ma;
Tim Rikerc1ef7bd2006-01-25 00:08:53 +000075
Mike Frysinger1fd98e02005-05-09 22:10:42 +000076 size = (size_t) (sizeof(struct ext2_block_relocate_entry) *
77 (max_block+1));
78 retval = ext2fs_get_mem(size, &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;
Tim Rikerc1ef7bd2006-01-25 00:08:53 +000094
Mike Frysinger1fd98e02005-05-09 22:10:42 +000095 *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{
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000106 struct brel_ma *ma;
Mike Frysinger1fd98e02005-05-09 22:10:42 +0000107
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{
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000118 struct brel_ma *ma;
Mike Frysinger1fd98e02005-05-09 22:10:42 +0000119
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{
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000138 struct brel_ma *ma;
Mike Frysinger1fd98e02005-05-09 22:10:42 +0000139
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{
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000154 struct brel_ma *ma;
Mike Frysinger1fd98e02005-05-09 22:10:42 +0000155
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{
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000168 struct brel_ma *ma;
Mike Frysinger1fd98e02005-05-09 22:10:42 +0000169
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{
Tim Rikerc1ef7bd2006-01-25 00:08:53 +0000181 struct brel_ma *ma;
Mike Frysinger1fd98e02005-05-09 22:10:42 +0000182
183 if (!brel)
184 return 0;
185
186 ma = brel->priv_data;
187
188 if (ma) {
189 if (ma->entries)
190 ext2fs_free_mem(&ma->entries);
191 ext2fs_free_mem(&ma);
192 }
193 if (brel->name)
194 ext2fs_free_mem(&brel->name);
195 ext2fs_free_mem(&brel);
196 return 0;
197}