brel_ma.c revision d1154eb460efe588eaed3d439c1caaca149fa362
156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson/*
256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * brel_ma.c
356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson *
456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * Copyright (C) 1996, 1997 Theodore Ts'o.
556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson *
656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * TODO: rewrite to not use a direct array!!!  (Fortunately this
756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * module isn't really used yet.)
856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson *
956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * %Begin-Header%
1056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * This file may be redistributed under the terms of the GNU Library
1156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * General Public License, version 2.
1256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson * %End-Header%
1356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson */
1456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
1556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#include "config.h"
1656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#include <fcntl.h>
1756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#include <stdio.h>
1856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#include <string.h>
1956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#if HAVE_UNISTD_H
2056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#include <unistd.h>
2156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#endif
2256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#if HAVE_ERRNO_H
2356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#include <errno.h>
2456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#endif
2556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
2656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#include "ext2_fs.h"
2756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#include "ext2fs.h"
2856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson#include "brel.h"
2956ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson
3056ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonstatic errcode_t bma_put(ext2_brel brel, blk_t old,
3156ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson			struct ext2_block_relocate_entry *ent);
3256ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonstatic errcode_t bma_get(ext2_brel brel, blk_t old,
3356ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson			struct ext2_block_relocate_entry *ent);
3456ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonstatic errcode_t bma_start_iter(ext2_brel brel);
3556ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonstatic errcode_t bma_next(ext2_brel brel, blk_t *old,
3656ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodson			 struct ext2_block_relocate_entry *ent);
3756ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonstatic errcode_t bma_move(ext2_brel brel, blk_t old, blk_t new);
3856ed4167b942ec265f9cee70ac4d71d10b3835ceBen Dodsonstatic errcode_t bma_delete(ext2_brel brel, blk_t old);
39static errcode_t bma_free(ext2_brel brel);
40
41struct brel_ma {
42	__u32 magic;
43	blk_t max_block;
44	struct ext2_block_relocate_entry *entries;
45};
46
47errcode_t ext2fs_brel_memarray_create(char *name, blk_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
100errout:
101	bma_free(brel);
102	return retval;
103}
104
105static errcode_t bma_put(ext2_brel brel, blk_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
117static errcode_t bma_get(ext2_brel brel, blk_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
131static errcode_t bma_start_iter(ext2_brel brel)
132{
133	brel->current = 0;
134	return 0;
135}
136
137static errcode_t bma_next(ext2_brel brel, blk_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
154static errcode_t bma_move(ext2_brel brel, blk_t old, blk_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
168static errcode_t bma_delete(ext2_brel brel, blk_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
181static 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