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 n_marker, EMUFS_FREE n_freespace)
55 strcpy(name_f_fsc,emu->nombre);
56 strcat(name_f_fsc, EMUFS_FSC_EXT);
58 /* Cargo el registro */
59 reg.n_marker = n_marker;
60 reg.n_freespace = n_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 n_marker, EMUFS_FREE n_freespace)
73 EMUFS_FSC gap_aux,gap_before,gap_after,gap_new;
75 EMUFS_REG_ID n_gap_before = 0, n_gap_after = 0;
76 unsigned long n_source,n_destination,n_filesize,n_reg_count = 0,n_moved = 0;
78 strcpy(name_f_fsc,emu->nombre);
79 strcat(name_f_fsc, EMUFS_FSC_EXT);
81 gap_before.n_marker = -1;
82 gap_after.n_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.n_marker+gap_aux.n_freespace == n_marker) {
92 gap_before.n_marker = gap_aux.n_marker;
93 gap_before.n_freespace = gap_aux.n_freespace;
94 n_gap_before = n_reg_count;
97 /* Chequeo si es un gap justo posterior al nuestro */
98 if (gap_aux.n_marker == n_marker+n_freespace) {
99 gap_after.n_marker = gap_aux.n_marker;
100 gap_after.n_freespace = gap_aux.n_freespace;
101 n_gap_after = n_reg_count;
106 /* Si no encontre gaps ni por delante ni por detras */
107 if ((gap_before.n_marker == -1) && (gap_after.n_marker == -1)) {
108 /* Lo guardo en el archivo al final */
109 gap_new.n_marker = n_marker;
110 gap_new.n_freespace = n_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.n_marker != -1) && (gap_after.n_marker == -1))
119 printf("fsc.c >> Found GAP justo por Delante pero no por Detras!!\n");
120 printf("fsc.c >> Gap found is reg number %lu in .fsc file\n",n_gap_before);
121 /* Me posiciono en el registro que indica dicho gap y lo reescribo con */
122 /* la suma de los espacios libres */
123 fseek(f_fsc,sizeof(EMUFS_FSC)*n_gap_before,0);
124 gap_new.n_marker = gap_before.n_marker;
125 gap_new.n_freespace = gap_before.n_freespace + n_freespace;
126 fwrite(&gap_new,sizeof(EMUFS_FSC),1,f_fsc);
130 /* Si encuentro un GAP Justo por detras pero no por delante */
131 if ((gap_before.n_marker == -1) && (gap_after.n_marker != -1))
133 printf("fsc.c >> Found GAP justo por Detras pero no por Delante!!\n");
134 printf("fsc.c >> Gap found is reg number %lu in .fsc file\n",n_gap_after);
135 /* Me posiciono en el registro que indica dicho gap y lo reescribo con */
136 /* los datos actualizados de offset y espacio */
137 fseek(f_fsc,sizeof(EMUFS_FSC)*n_gap_after,0);
138 gap_new.n_marker = gap_after.n_marker - n_freespace;
139 gap_new.n_freespace = gap_after.n_freespace + n_freespace;
140 fwrite(&gap_new,sizeof(EMUFS_FSC),1,f_fsc);
144 /* Finalmente, si encuentro Justo por delante y por detras..*/
145 if ((gap_before.n_marker != -1) && (gap_after.n_marker != -1))
147 printf("fsc.c >> Found GAP justo por Delante y por Detras!!\n");
148 printf("fsc.c >> Pre Gap found is reg number %lu in .fsc file\n",n_gap_before);
149 printf("fsc.c >> Post Gap found is reg number %lu in .fsc file\n",n_gap_after);
150 /* Guardo el nuevo GAP que posee los tres espacios sumados */
151 if (n_gap_before < n_gap_after) {
152 fseek(f_fsc,sizeof(EMUFS_FSC)*n_gap_before,0);
153 n_destination = sizeof(EMUFS_FSC)*n_gap_after;
156 fseek(f_fsc,sizeof(EMUFS_FSC)*n_gap_after,0);
157 n_destination = sizeof(EMUFS_FSC)*n_gap_before;
159 gap_new.n_marker = gap_before.n_marker;
160 gap_new.n_freespace = gap_before.n_freespace + n_freespace + gap_after.n_freespace;
161 fwrite(&gap_new,sizeof(EMUFS_FSC),1,f_fsc);
163 /* Preparo el escenario para la movida de registros */
164 n_source = n_destination+sizeof(EMUFS_FSC); /* Salteo el gap que elimino! */
165 fseek(f_fsc,0,SEEK_END);
166 n_filesize = ftell(f_fsc);
167 n_reg_count = (n_filesize - n_source) / sizeof(EMUFS_FSC);
168 printf("Destination: %lu Source: %lu Cant Regs a Mover: %lu\n",n_destination,n_source,n_reg_count);
170 /* Comienzo a mover */
171 while (n_moved < n_reg_count) {
172 fseek(f_fsc,n_source,0);
173 fread(&gap_new,sizeof(EMUFS_FSC),1,f_fsc);
174 fseek(f_fsc,-sizeof(EMUFS_FSC)*2,SEEK_CUR);
175 fwrite(&gap_new,sizeof(EMUFS_FSC),1,f_fsc);
176 n_source += sizeof(EMUFS_FSC);
180 truncate(name_f_fsc, n_filesize - sizeof(EMUFS_FSC));
186 /* Elimina un registro GAP del archivo de espacios libres (gaps) */
187 int emufs_fsc_remove_gap(EMUFS *emu, EMUFS_OFFSET n_marker)
191 char name_f_fsc[255];
192 unsigned long n_source,n_destination,n_filesize,n_reg_count = 0,n_moved = 0;
194 strcpy(name_f_fsc,emu->nombre);
195 strcat(name_f_fsc, EMUFS_FSC_EXT);
197 /* Busco el Gap en el .fsc */
198 if ((f_fsc = fopen(name_f_fsc,"r+")) == NULL) return -1;
199 while ( !feof(f_fsc) ){
200 if ( fread(&gap_aux,sizeof(EMUFS_FSC),1,f_fsc) != 1) continue;
201 if ( gap_aux.n_marker == n_marker ) break;
204 /* Preparo el escenario para la movida de registros */
205 fseek(f_fsc,-sizeof(EMUFS_FSC),SEEK_CUR);
206 n_destination = ftell(f_fsc);
207 n_source = n_destination+sizeof(EMUFS_FSC); /* Salteo el gap a eliminar! */
208 fseek(f_fsc,0,SEEK_END);
209 n_filesize = ftell(f_fsc);
210 n_reg_count = (n_filesize - n_source) / sizeof(EMUFS_FSC);
211 printf("Destination: %lu Source: %lu Cant Regs a Mover: %lu\n",n_destination,n_source,n_reg_count);
213 /* Comienzo a mover */
214 while (n_moved < n_reg_count) {
215 fseek(f_fsc,n_source,0);
216 fread(&gap_aux,sizeof(EMUFS_FSC),1,f_fsc);
217 fseek(f_fsc,-sizeof(EMUFS_FSC)*2,SEEK_CUR);
218 fwrite(&gap_aux,sizeof(EMUFS_FSC),1,f_fsc);
219 n_source += sizeof(EMUFS_FSC);
223 truncate(name_f_fsc, n_filesize - sizeof(EMUFS_FSC));
228 /* Objetivo: Actualiza un registro de espacio libre de acorde al FType */
229 int emufs_fsc_actualizar(EMUFS *emu, EMUFS_BLOCK_ID n_marker, EMUFS_FREE n_freespace)
233 char name_f_fsc[255];
235 strcpy(name_f_fsc,emu->nombre);
236 strcat(name_f_fsc, EMUFS_FSC_EXT);
238 /*busco el bloque o gap que modifique*/
239 if ( (f_fsc = fopen(name_f_fsc,"r+")) == NULL) return -1;
240 while ( !feof(f_fsc) ){
241 if ( fread(®,sizeof(EMUFS_FSC),1,f_fsc) != 1) continue;
242 if ( reg.n_marker == n_marker ){
243 reg.n_freespace = n_freespace;
244 fseek(f_fsc,-sizeof(EMUFS_FSC),SEEK_CUR);
245 fwrite(®,sizeof(EMUFS_FSC),1,f_fsc);
253 /* Actualiza un registro de gap, en el archivo de Gaps en Disco */
254 int emufs_fsc_actualizar_gap(EMUFS *emu, EMUFS_OFFSET n_marker, EMUFS_FREE n_freespace)
258 char name_f_fsc[255];
260 strcpy(name_f_fsc,emu->nombre);
261 strcat(name_f_fsc, EMUFS_FSC_EXT);
263 /*busco el bloque o gap que modifique*/
264 if ( (f_fsc = fopen(name_f_fsc,"r+")) == NULL) return -1;
265 while ( !feof(f_fsc) ){
266 if ( fread(&gap_aux,sizeof(EMUFS_FSC),1,f_fsc) != 1) continue;
267 if ( gap_aux.n_marker == n_marker ){
268 gap_aux.n_marker = n_marker + gap_aux.n_freespace - n_freespace;
269 gap_aux.n_freespace = n_freespace;
270 fseek(f_fsc,-sizeof(EMUFS_FSC),SEEK_CUR);
271 fwrite(&gap_aux,sizeof(EMUFS_FSC),1,f_fsc);
279 /* Me devuelve el ID del bloque u Offset del Gap donde quepa un registro, y guarda en n_freespace el espacio libre actualizado */
280 EMUFS_BLOCK_ID emufs_fsc_buscar_lugar(EMUFS *emu, EMUFS_FREE n_regsize, EMUFS_FREE *n_freespace)
284 char name_f_fsc[255];
287 strcpy(name_f_fsc,emu->nombre);
288 strcat(name_f_fsc, EMUFS_FSC_EXT);
290 if ( (f_fsc = fopen(name_f_fsc,"r"))==NULL ) return EMUFS_NOT_FOUND;
292 /* Inicializamos la estructura para devolver algun valor en concreto */
293 /* en caso de que no se halle un espacio libre apropiado */
295 if (fread(®,sizeof(EMUFS_FSC),1,f_fsc) != 1) continue;
296 if (reg.n_freespace >= n_regsize) {
302 /* Si salio por error o por fin de archivo y no encontro space... */
304 reg.n_marker = EMUFS_NOT_FOUND;
305 *n_freespace = emu->tam_bloque;
307 else *n_freespace = reg.n_freespace;
313 /* Devuelve el espacio libre de un Bloque o Gap dado */
314 EMUFS_FREE emufs_fsc_get_fs(EMUFS *emu, EMUFS_BLOCK_ID n_marker)
318 char name_f_fsc[255];
320 strcpy(name_f_fsc,emu->nombre);
321 strcat(name_f_fsc, EMUFS_FSC_EXT);
323 /* Busco el Bloque o Gap pedido y obtengo su espacio libre */
324 if ( (f_fsc = fopen(name_f_fsc,"r"))==NULL ) return -1;
325 while ( !feof(f_fsc) ){
326 if ( fread(®,sizeof(EMUFS_FSC),1,f_fsc) != 1 ) continue;
327 if ( reg.n_marker == n_marker )
332 return reg.n_freespace;
335 EMUFS_FREE emufs_fsc_get_total_fs(EMUFS *emu)
339 char name_f_fsc[255];
342 strcpy(name_f_fsc,emu->nombre);
343 strcat(name_f_fsc, EMUFS_FSC_EXT);
345 if ( (f_fsc = fopen(name_f_fsc,"r"))==NULL ) return -1;
347 while ( !feof(f_fsc) ){
348 if ( fread(®, sizeof(EMUFS_FSC), 1, f_fsc) != 1) continue;
349 total += reg.n_freespace;