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