]> git.llucax.com Git - z.facultad/75.06/emufs.git/blob - emufs/fsc.c
Stats Tipo2 Listas, con implementancion IDX nueva.
[z.facultad/75.06/emufs.git] / emufs / fsc.c
1 /* vim: set noexpandtab tabstop=4 shiftwidth=4:
2  *----------------------------------------------------------------------------
3  *                                  emufs
4  *----------------------------------------------------------------------------
5  * This file is part of emufs.
6  *
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
10  * version.
11  *
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
15  * details.
16  *
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  *----------------------------------------------------------------------------
25  *
26  * $Id$
27  *
28  */
29
30 /** \file
31  *
32  * Archivo para administrar el espacio libre disponible.
33  * 
34  * Implementación del archivo para administrar el espacio libre disponible.
35  *
36  */
37
38 #include "fsc.h"
39 #include <string.h>
40 #include <unistd.h>
41
42 /* Crea un archivo de Gaps o Espacio Libre en Bloque */
43 int emufs_fsc_crear(EMUFS* efs)
44 {
45         return emufs_crear_archivo_auxiliar(efs->nombre, EMUFS_FSC_EXT);
46 }
47
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)
50 {
51         FILE *f_fsc;
52         EMUFS_FSC reg;
53         char name_f_fsc[255];
54         
55         strcpy(name_f_fsc,emu->nombre);
56         strcat(name_f_fsc, EMUFS_FSC_EXT);
57         
58         /* Cargo el registro */
59         reg.marker = marker;
60         reg.freespace = freespace;
61
62         /* Lo guardo en el archivo al final "a+"*/
63         if ( (f_fsc = fopen(name_f_fsc,"a+"))==NULL ) return -1;
64         fwrite(&reg,sizeof(EMUFS_FSC),1,f_fsc);
65         fclose(f_fsc);
66         return 0;
67 }
68
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)
71 {
72         FILE *f_fsc;
73         EMUFS_FSC gap_aux,gap_before,gap_after,gap_new;
74         char name_f_fsc[255];
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;
77                 
78         strcpy(name_f_fsc,emu->nombre);
79         strcat(name_f_fsc, EMUFS_FSC_EXT);
80         
81         gap_before.marker = -1;
82         gap_after.marker = -1;
83         
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;
89                 
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;
95                 }
96                 
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;
102                 }               
103                 reg_count += 1;
104         }
105         
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);
113                 fclose(f_fsc);          
114         }
115         
116         /* Si encuentro un GAP Justo por delante pero no por detras */
117         if ((gap_before.marker != -1) && (gap_after.marker == -1))
118         {
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);
125           fclose(f_fsc);
126         }
127         
128         /* Si encuentro un GAP Justo por detras pero no por delante */
129         if ((gap_before.marker == -1) && (gap_after.marker != -1))
130         {  
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);
137           fclose(f_fsc);
138         }
139         
140         /* Finalmente, si encuentro Justo por delante y por detras..*/
141         if ((gap_before.marker != -1) && (gap_after.marker != -1))
142         { 
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;
147           }
148           else {
149                 fseek(f_fsc,sizeof(EMUFS_FSC)*pos_gap_after,0);
150                 destination = sizeof(EMUFS_FSC)*pos_gap_before;
151           }
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);
155                 
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);
161           
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);            
169                 ++cant_moved;
170           }
171           fclose(f_fsc);
172           truncate(name_f_fsc, file_size - sizeof(EMUFS_FSC));
173         }       
174         
175     return 0;
176 }
177
178 /* Elimina un registro GAP del archivo de espacios libres (gaps) */
179 int emufs_fsc_remove_gap(EMUFS *emu, EMUFS_OFFSET marker)
180 {
181         FILE *f_fsc;
182         EMUFS_FSC gap_aux;
183         char name_f_fsc[255];
184     unsigned long source,destination,file_size,reg_count = 0,cant_moved = 0;    
185                 
186         strcpy(name_f_fsc,emu->nombre);
187         strcat(name_f_fsc, EMUFS_FSC_EXT);
188         
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;
194         }
195         
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);
203                 
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);          
211           ++cant_moved;
212         }
213         fclose(f_fsc);
214         truncate(name_f_fsc, file_size - sizeof(EMUFS_FSC));
215         
216         return 0;
217 }
218
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)
221 {
222         FILE *f_fsc;
223         EMUFS_FSC reg;
224         char name_f_fsc[255];
225         
226         strcpy(name_f_fsc,emu->nombre);
227         strcat(name_f_fsc, EMUFS_FSC_EXT);
228
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(&reg,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(&reg,sizeof(EMUFS_FSC),1,f_fsc);
237                         break;
238                 }
239         }
240         fclose(f_fsc);
241         return 0;
242 }
243
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)
246 {
247         FILE *f_fsc;
248         EMUFS_FSC gap_aux;
249         char name_f_fsc[255];
250         
251         strcpy(name_f_fsc,emu->nombre);
252         strcat(name_f_fsc, EMUFS_FSC_EXT);
253
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);
263                         break;
264                 }
265         }
266         fclose(f_fsc);
267         return 0;
268 }
269
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)
272 {
273         FILE *f_fsc;
274         EMUFS_FSC reg;
275         char name_f_fsc[255];
276         char found = 0;
277         
278         strcpy(name_f_fsc,emu->nombre);
279         strcat(name_f_fsc, EMUFS_FSC_EXT);
280
281         if ( (f_fsc = fopen(name_f_fsc,"r"))==NULL ) return EMUFS_NOT_FOUND;
282
283         /* Inicializamos la estructura para devolver algun valor en concreto */
284         /* en caso de que no se halle un espacio libre apropiado */
285         while(!feof(f_fsc)){
286                 if (fread(&reg,sizeof(EMUFS_FSC),1,f_fsc) != 1) continue;
287                 if (reg.freespace >= reg_size) {
288                         found = 1;
289                         break;
290                 }
291         }
292         
293         /* Si salio por error o por fin de archivo y no encontro space... */
294         if (!found) {
295           reg.marker = EMUFS_NOT_FOUND;
296           *freespace = emu->tam_bloque; 
297         }
298         else *freespace = reg.freespace;
299         
300         fclose(f_fsc);
301         return reg.marker;
302 }
303
304 /* Devuelve el espacio libre de un Bloque o Gap dado */
305 EMUFS_FREE emufs_fsc_get_fs(EMUFS *emu, EMUFS_BLOCK_ID marker)
306 {
307         FILE *f_fsc;
308         EMUFS_FSC reg;
309         char name_f_fsc[255];
310         
311         strcpy(name_f_fsc,emu->nombre);
312         strcat(name_f_fsc, EMUFS_FSC_EXT);
313
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(&reg,sizeof(EMUFS_FSC),1,f_fsc) != 1 ) continue;
318                 if ( reg.marker == marker )
319                         break;
320         }
321                 
322         fclose(f_fsc);
323         return reg.freespace;
324 }
325
326 EMUFS_FREE emufs_fsc_get_total_fs(EMUFS *emu)
327 {
328         FILE *f_fsc;
329         EMUFS_FSC reg;
330         char name_f_fsc[255];
331         EMUFS_FREE total;
332         
333         strcpy(name_f_fsc,emu->nombre);
334         strcat(name_f_fsc, EMUFS_FSC_EXT);
335
336         if ( (f_fsc = fopen(name_f_fsc,"r"))==NULL ) return -1;
337         total = 0;
338         while ( !feof(f_fsc) ){
339                 if ( fread(&reg, sizeof(EMUFS_FSC), 1, f_fsc) != 1) continue;
340                 total += reg.freespace;
341         }
342         fclose(f_fsc);
343         return total;
344 }
345
346 int emufs_fsc_get_max_min_fs(EMUFS *emu, EMUFS_FREE *min, EMUFS_FREE *max)
347 {
348         FILE *f_fsc;
349         EMUFS_FSC reg;
350         char name_f_fsc[255];
351         
352         strcpy(name_f_fsc,emu->nombre);
353         strcat(name_f_fsc, EMUFS_FSC_EXT);
354
355         *min = ULONG_MAX;
356         *max = 0;
357         if ( (f_fsc = fopen(name_f_fsc,"r"))==NULL ) return -1;
358         
359         while ( !feof(f_fsc) ){
360                 fread(&reg, sizeof(EMUFS_FSC), 1, f_fsc);
361                 if (  reg.freespace < *min )
362                         *min = reg.freespace;
363                 if ( reg.freespace > *max )
364                         *max = reg.freespace;
365         }
366
367         fclose(f_fsc);
368         return 0;
369 }
370
371 EMUFS_FREE emufs_fsc_get_media_fs(EMUFS *emu)
372 {
373         FILE *f_fsc;
374         EMUFS_FSC reg;
375         char name_f_fsc[255];
376         EMUFS_FREE total_fs = 0;
377         EMUFS_REG_ID gap_count = 0;
378         
379         strcpy(name_f_fsc,emu->nombre);
380         strcat(name_f_fsc, EMUFS_FSC_EXT);
381
382         if ( (f_fsc = fopen(name_f_fsc,"r"))==NULL ) return -1;
383         
384         while ( !feof(f_fsc) ){
385                 fread(&reg, sizeof(EMUFS_FSC), 1, f_fsc);
386                 total_fs += reg.freespace;
387                 ++gap_count;
388         }
389
390         fclose(f_fsc);
391         return total_fs/gap_count;
392 }