1 /* vim: set noexpandtab tabstop=4 shiftwidth=4:
2 *----------------------------------------------------------------------------
4 *----------------------------------------------------------------------------
5 * This file is part of emufs.
7 * emufs is free software; you can redistribute it and/or modify it under the
8 * terms of the GNU General Public License as published by the Free Software
9 * Foundation; either version 2 of the License, or (at your option) any later
12 * emufs is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public License along
18 * with emufs; if not, write to the Free Software Foundation, Inc., 59 Temple
19 * Place, Suite 330, Boston, MA 02111-1307 USA
20 *----------------------------------------------------------------------------
21 * Creado: vie abr 9 16:17:50 ART 2004
22 * Autores: Nicolás Dimov <sagardua@uolsinectis.com.ar>
23 * Leandro Lucarella <llucare@fi.uba.ar>
24 *----------------------------------------------------------------------------
32 * Archivo para administrar el espacio libre disponible.
34 * Implementación del archivo para administrar el espacio libre disponible.
42 /* Crea un archivo de Gaps o Espacio Libre en Bloque */
43 int emufs_fsc_crear(EMUFS* efs)
45 return emufs_crear_archivo_auxiliar(efs->nombre, EMUFS_FSC_EXT);
48 /* Agrega un registro al archivo de espacio libre en bloque. */
49 int emufs_fsc_agregar(EMUFS *emu, EMUFS_BLOCK_ID marker, EMUFS_FREE freespace)
55 strcpy(name_f_fsc,emu->nombre);
56 strcat(name_f_fsc, EMUFS_FSC_EXT);
58 /* Cargo el registro */
60 reg.freespace = freespace;
62 /* Lo guardo en el archivo al final "a+"*/
63 if ( (f_fsc = fopen(name_f_fsc,"a+"))==NULL ) return -1;
64 fwrite(®,sizeof(EMUFS_FSC),1,f_fsc);
69 /* Agrega un GAP en el archivo de Gaps para Filetype 2 */
70 int emufs_fsc_agregar_gap(EMUFS *emu, EMUFS_OFFSET marker, EMUFS_FREE freespace)
73 EMUFS_FSC gap_aux,gap_before,gap_after,gap_new;
75 EMUFS_REG_ID pos_gap_before = 0, pos_gap_after = 0;
76 unsigned long source,destination,file_size,reg_count = 0,cant_moved = 0;
78 strcpy(name_f_fsc,emu->nombre);
79 strcat(name_f_fsc, EMUFS_FSC_EXT);
81 gap_before.marker = -1;
82 gap_after.marker = -1;
84 /* Busco si hay un GAP por delante y/o por detras del que se esta por crear */
85 /* para en dicho caso realizar un merge! */
86 if ( (f_fsc = fopen(name_f_fsc,"r+")) == NULL) return -1;
87 while ( !feof(f_fsc) ){
88 if ( fread(&gap_aux,sizeof(EMUFS_FSC),1,f_fsc) != 1) continue;
90 /* Chequeo si es un gap justo anterior al nuestro */
91 if (gap_aux.marker+gap_aux.freespace == marker) {
92 gap_before.marker = gap_aux.marker;
93 gap_before.freespace = gap_aux.freespace;
94 pos_gap_before = reg_count;
97 /* Chequeo si es un gap justo posterior al nuestro */
98 if (gap_aux.marker == marker+freespace) {
99 gap_after.marker = gap_aux.marker;
100 gap_after.freespace = gap_aux.freespace;
101 pos_gap_after = reg_count;
106 /* Si no encontre gaps ni por delante ni por detras */
107 if ((gap_before.marker == -1) && (gap_after.marker == -1)) {
108 /* Lo guardo en el archivo al final */
109 gap_new.marker = marker;
110 gap_new.freespace = freespace;
111 fseek(f_fsc,0,SEEK_END);
112 fwrite(&gap_new,sizeof(EMUFS_FSC),1,f_fsc);
116 /* Si encuentro un GAP Justo por delante pero no por detras */
117 if ((gap_before.marker != -1) && (gap_after.marker == -1))
119 /* Me posiciono en el registro que indica dicho gap y lo reescribo con */
120 /* la suma de los espacios libres */
121 fseek(f_fsc,sizeof(EMUFS_FSC)*pos_gap_before,0);
122 gap_new.marker = gap_before.marker;
123 gap_new.freespace = gap_before.freespace + freespace;
124 fwrite(&gap_new,sizeof(EMUFS_FSC),1,f_fsc);
128 /* Si encuentro un GAP Justo por detras pero no por delante */
129 if ((gap_before.marker == -1) && (gap_after.marker != -1))
131 /* Me posiciono en el registro que indica dicho gap y lo reescribo con */
132 /* los datos actualizados de offset y espacio */
133 fseek(f_fsc,sizeof(EMUFS_FSC)*pos_gap_after,0);
134 gap_new.marker = gap_after.marker - freespace;
135 gap_new.freespace = gap_after.freespace + freespace;
136 fwrite(&gap_new,sizeof(EMUFS_FSC),1,f_fsc);
140 /* Finalmente, si encuentro Justo por delante y por detras..*/
141 if ((gap_before.marker != -1) && (gap_after.marker != -1))
143 /* Guardo el nuevo GAP que posee los tres espacios sumados */
144 if (pos_gap_before < pos_gap_after) {
145 fseek(f_fsc,sizeof(EMUFS_FSC)*pos_gap_before,0);
146 destination = sizeof(EMUFS_FSC)*pos_gap_after;
149 fseek(f_fsc,sizeof(EMUFS_FSC)*pos_gap_after,0);
150 destination = sizeof(EMUFS_FSC)*pos_gap_before;
152 gap_new.marker = gap_before.marker;
153 gap_new.freespace = gap_before.freespace + freespace + gap_after.freespace;
154 fwrite(&gap_new,sizeof(EMUFS_FSC),1,f_fsc);
156 /* Preparo el escenario para la movida de registros */
157 source = destination+sizeof(EMUFS_FSC); /* Salteo el gap que elimino! */
158 fseek(f_fsc,0,SEEK_END);
159 file_size = ftell(f_fsc);
160 reg_count = (file_size - source) / sizeof(EMUFS_FSC);
162 /* Comienzo a mover */
163 while (cant_moved < reg_count) {
164 fseek(f_fsc,source,0);
165 fread(&gap_new,sizeof(EMUFS_FSC),1,f_fsc);
166 fseek(f_fsc,-sizeof(EMUFS_FSC)*2,SEEK_CUR);
167 fwrite(&gap_new,sizeof(EMUFS_FSC),1,f_fsc);
168 source += sizeof(EMUFS_FSC);
172 truncate(name_f_fsc, file_size - sizeof(EMUFS_FSC));
178 /* Elimina un registro GAP del archivo de espacios libres (gaps) */
179 int emufs_fsc_remove_gap(EMUFS *emu, EMUFS_OFFSET marker)
183 char name_f_fsc[255];
184 unsigned long source,destination,file_size,reg_count = 0,cant_moved = 0;
186 strcpy(name_f_fsc,emu->nombre);
187 strcat(name_f_fsc, EMUFS_FSC_EXT);
189 /* Busco el Gap en el .fsc */
190 if ((f_fsc = fopen(name_f_fsc,"r+")) == NULL) return -1;
191 while ( !feof(f_fsc) ){
192 if ( fread(&gap_aux,sizeof(EMUFS_FSC),1,f_fsc) != 1) continue;
193 if ( gap_aux.marker == marker ) break;
196 /* Preparo el escenario para la movida de registros */
197 fseek(f_fsc,-sizeof(EMUFS_FSC),SEEK_CUR);
198 destination = ftell(f_fsc);
199 source = destination+sizeof(EMUFS_FSC); /* Salteo el gap a eliminar! */
200 fseek(f_fsc,0,SEEK_END);
201 file_size = ftell(f_fsc);
202 reg_count = (file_size - source) / sizeof(EMUFS_FSC);
204 /* Comienzo a mover */
205 while (cant_moved < reg_count) {
206 fseek(f_fsc,source,0);
207 fread(&gap_aux,sizeof(EMUFS_FSC),1,f_fsc);
208 fseek(f_fsc,-sizeof(EMUFS_FSC)*2,SEEK_CUR);
209 fwrite(&gap_aux,sizeof(EMUFS_FSC),1,f_fsc);
210 source += sizeof(EMUFS_FSC);
214 truncate(name_f_fsc, file_size - sizeof(EMUFS_FSC));
219 /* Objetivo: Actualiza un registro de espacio libre de acorde al FType */
220 int emufs_fsc_actualizar(EMUFS *emu, EMUFS_BLOCK_ID marker, EMUFS_FREE freespace)
224 char name_f_fsc[255];
226 strcpy(name_f_fsc,emu->nombre);
227 strcat(name_f_fsc, EMUFS_FSC_EXT);
229 /*busco el bloque o gap que modifique*/
230 if ( (f_fsc = fopen(name_f_fsc,"r+")) == NULL) return -1;
231 while ( !feof(f_fsc) ){
232 if ( fread(®,sizeof(EMUFS_FSC),1,f_fsc) != 1) continue;
233 if ( reg.marker == marker ){
234 reg.freespace = freespace;
235 fseek(f_fsc,-sizeof(EMUFS_FSC),SEEK_CUR);
236 fwrite(®,sizeof(EMUFS_FSC),1,f_fsc);
244 /* Actualiza un registro de gap, en el archivo de Gaps en Disco */
245 int emufs_fsc_actualizar_gap(EMUFS *emu, EMUFS_OFFSET marker, EMUFS_FREE freespace)
249 char name_f_fsc[255];
251 strcpy(name_f_fsc,emu->nombre);
252 strcat(name_f_fsc, EMUFS_FSC_EXT);
254 /*busco el bloque o gap que modifique*/
255 if ( (f_fsc = fopen(name_f_fsc,"r+")) == NULL) return -1;
256 while ( !feof(f_fsc) ){
257 if ( fread(&gap_aux,sizeof(EMUFS_FSC),1,f_fsc) != 1) continue;
258 if ( gap_aux.marker == marker ){
259 gap_aux.marker = marker + gap_aux.freespace - freespace;
260 gap_aux.freespace = freespace;
261 fseek(f_fsc,-sizeof(EMUFS_FSC),SEEK_CUR);
262 fwrite(&gap_aux,sizeof(EMUFS_FSC),1,f_fsc);
270 /* Me devuelve el ID del bloque u Offset del Gap donde quepa un registro, y guarda en n_freespace el espacio libre actualizado */
271 EMUFS_BLOCK_ID emufs_fsc_buscar_lugar(EMUFS *emu, EMUFS_FREE reg_size, EMUFS_FREE *freespace)
275 char name_f_fsc[255];
278 strcpy(name_f_fsc,emu->nombre);
279 strcat(name_f_fsc, EMUFS_FSC_EXT);
281 if ( (f_fsc = fopen(name_f_fsc,"r"))==NULL ) return EMUFS_NOT_FOUND;
283 /* Inicializamos la estructura para devolver algun valor en concreto */
284 /* en caso de que no se halle un espacio libre apropiado */
286 if (fread(®,sizeof(EMUFS_FSC),1,f_fsc) != 1) continue;
287 if (reg.freespace >= reg_size) {
293 /* Si salio por error o por fin de archivo y no encontro space... */
295 reg.marker = EMUFS_NOT_FOUND;
296 *freespace = emu->tam_bloque;
298 else *freespace = reg.freespace;
304 /* Devuelve el espacio libre de un Bloque o Gap dado */
305 EMUFS_FREE emufs_fsc_get_fs(EMUFS *emu, EMUFS_BLOCK_ID marker)
309 char name_f_fsc[255];
311 strcpy(name_f_fsc,emu->nombre);
312 strcat(name_f_fsc, EMUFS_FSC_EXT);
314 /* Busco el Bloque o Gap pedido y obtengo su espacio libre */
315 if ( (f_fsc = fopen(name_f_fsc,"r"))==NULL ) return -1;
316 while ( !feof(f_fsc) ){
317 if ( fread(®,sizeof(EMUFS_FSC),1,f_fsc) != 1 ) continue;
318 if ( reg.marker == marker )
323 return reg.freespace;
326 EMUFS_FREE emufs_fsc_get_total_fs(EMUFS *emu)
330 char name_f_fsc[255];
333 strcpy(name_f_fsc,emu->nombre);
334 strcat(name_f_fsc, EMUFS_FSC_EXT);
336 if ( (f_fsc = fopen(name_f_fsc,"r"))==NULL ) return -1;
338 while ( !feof(f_fsc) ){
339 if ( fread(®, sizeof(EMUFS_FSC), 1, f_fsc) != 1) continue;
340 total += reg.freespace;