Riferimenti per il file write_fat.c

#include <stdio.h>
#include <stdlib.h>
#include <libgen.h>
#include <string.h>
#include "Include/fat.h"
#include "Include/util.h"

Vai al codice sorgente di questo file.

Funzioni

int fat_write (FILE *fs, struct fat_ctrl *f_ctrl, char *path, char *data, int data_len)

Descrizione dettagliata

Autore:
Tranchida Giulio, No Matricola 241732
Si dichiara che il contenuto di questo file e', in ogni sua parte, opera originale dell'autore.

This program is free software; you can redistribuite it and/or modify it under the terms of the GNU/General Pubblic License as published the Free software Foundation; either version 2 of the License, or (at your opinion) any later version.

Definizione nel file write_fat.c.


Documentazione delle funzioni

int fat_write ( FILE *  fs,
struct fat_ctrl f_ctrl,
char *  path,
char *  data,
int  data_len 
)

Questa funzione ha il compito di scrivere una sequenza di byte all'interno di un file memorizzato in un filesystem SFAT. Osserviamo che:

  • Il file su cui si vuole effettuare la scrittura deve essere gia' stato creato all'interno del filesystem SFAT.
  • I dati che debbono essere scritti sono visti da questa funzione come una sequenza di byte.
  • I dati vengono sempre scritti alla fine del file.

Questa funzione deve realizzare le seguenti operazioni:

  • Controllare che il file esista.
  • Determinare il blocco e l'offset all'interno del blocco in cui effettuare la scrittura dei nuovi dati.
  • Determinare se sia necessario allocare uno o piu' blocchi in cui memorizzare i nuovi dati.
  • Scrivere i nuovi dati eventualmente distribuendoli tra i vari blocchi allocati al passo precedente.
  • Aggiornare in modo consistente le varie sttruture dati come ad esempio la lunghezza del file e la File Allocation table.
Parametri:
fs il FILE pointer che consente di acceddre al file dove il filesystem e' memorizzato.
f_ctrl puntatore alla struttura che mantiene tutte le informazioni di controllo del filesystem.
path la stringa che contiene il path assoluto del file su cui effettuare la scrittura.
data il buffer contenete i nuovi dati da scrivere all'interno del file.
data_len il numero di bytes contenuti nel buffer data che debbono essere scritti nel file.
Restituisce:
  • EBDP (Error Bad Directory Path) se il path specificato non e' assoluto, ossia non inizia con il carattere '/'
  • ENTL (Error Name Too Long) uno degli elementi del pathname supera la lunghezza consentita (MAX_LEN_NAME).
  • ENSFD (Error Not Such File or Directory) se un elemento del pah non siste o non e' una directory.
  • 0 se l'operazione termina con successo.

Definizione alla linea 21 del file write_fat.c.

00021                                                                                       {
00022         struct dir_entry file;
00023         int ret_val=0, index=0, new_index=0;
00024         int dati_len=0, start_index=0, da_scrivere=0;
00025         unsigned int len, my_start;
00026         long fs_entry, fs_pos=0;
00027         char * dati;
00028         
00029         if (!(fs) || !(f_ctrl) || !(path)) return EBDP;
00030         if (!strcmp("/", path)) return EDAEX;
00031         if (data_len==0 || data==NULL) return 0;
00032         
00033         /* a) Posizionamento nel filesystem, controllo del percoso ecc. */
00034         if ((ret_val = parsing(fs, f_ctrl, path, WRFILE))!=0) return ret_val;
00035         
00036         fs_pos = fs_entry = ftell(fs);
00037         /* Leggo l'entry del file */
00038         if (!(fread(&file, sizeof(struct dir_entry), 1, fs))) return ERBD;
00039         
00040         len = file.len; index = file.index;
00041         /* Caso pessimo, il file contiene gia' informazioni,
00042          * scorro la FAT fino ad raggiungere l'ultimo blocco del file */        
00043         while (len > f_ctrl->b_sector.block_size){
00044                 if (f_ctrl->fat_ptr[index]==BLOCK_FREE || f_ctrl->fat_ptr[index]==LAST_BLOCK)
00045                         return ERFCD;
00046                 index = f_ctrl->fat_ptr[index];                 
00047                 len -= f_ctrl->b_sector.block_size;
00048                 fs_pos = f_ctrl->blk_base + (index * f_ctrl->b_sector.block_size);
00049         }
00050         if ((len<f_ctrl->b_sector.block_size) && (len!=0)){
00051                 fs_pos = f_ctrl->blk_base + (index * f_ctrl->b_sector.block_size);
00052                 fs_pos += len;
00053         }
00054         if (len == f_ctrl->b_sector.block_size) len = 0; 
00055         if (len == 0){
00056                 /* Qui devo allocare un nuovo blocco e posizionarmi all'inizio di questo */
00057                 for (new_index=0; new_index<f_ctrl->b_sector.num_block; new_index++){
00058                         if (f_ctrl->fat_ptr[new_index] == BLOCK_FREE){
00059                                 if (file.index == BLOCK_FREE) file.index = new_index;
00060                                 else f_ctrl->fat_ptr[index] = new_index;
00061                                 f_ctrl->fat_ptr[new_index] = LAST_BLOCK;
00062                                 index = new_index;
00063                                 break;
00064                         }
00065                 }
00066                 /* Controllo che la fat non sia piena */
00067                 if (new_index>=f_ctrl->b_sector.num_block){
00068                         fseek(fs, sizeof(struct boot_sector), SEEK_SET);
00069                         if (!(fread(f_ctrl->fat_ptr, (f_ctrl->b_sector.num_block * sizeof(unsigned int)), 1, fs)))
00070                                 return EWFCD;
00071                         return ENMSD;
00072                 }
00073                 fs_pos = f_ctrl->blk_base + (index * f_ctrl->b_sector.block_size);
00074         }
00075         fseek(fs, fs_pos, SEEK_SET);
00076         start_index = index;
00077         
00078         /* Conteggio i nuovi blocchi da allocare nella fat */
00079         dati_len = len + data_len;
00080         while (dati_len > f_ctrl->b_sector.block_size){
00081                 dati_len -= f_ctrl->b_sector.block_size;
00082                 for (new_index=0; new_index<f_ctrl->b_sector.num_block; new_index++){
00083                         if (f_ctrl->fat_ptr[new_index] == BLOCK_FREE){
00084                                 if (file.index == BLOCK_FREE) file.index = new_index;
00085                                 else f_ctrl->fat_ptr[index] = new_index;
00086                                 f_ctrl->fat_ptr[new_index] = LAST_BLOCK;
00087                                 index = new_index;
00088                                 break;
00089                         }
00090                 }
00091                 /* Controllo che la fat non sia piena */
00092                 if (new_index>=f_ctrl->b_sector.num_block){
00093                         fseek(fs, sizeof(struct boot_sector), SEEK_SET);
00094                         if (!(fread(f_ctrl->fat_ptr, (f_ctrl->b_sector.num_block * sizeof(unsigned int)), 1, fs)))
00095                                 return EWFCD;
00096                         return ENMSD;
00097                 }       
00098 
00099         }
00100 
00101         my_start=len;
00102         len=data_len;
00103         index = start_index;
00104         dati = data;
00105         while(len){
00106                 if ((my_start+len) > f_ctrl->b_sector.block_size){
00107                         da_scrivere = f_ctrl->b_sector.block_size - my_start;
00108                         len -= da_scrivere;
00109                         my_start = 0;
00110                 }
00111                 else if ((my_start+len) <= f_ctrl->b_sector.block_size)
00112                         da_scrivere = len;
00113 
00114                 if (!(fwrite(dati, da_scrivere, 1, fs))) return ERBD;
00115                 dati+=da_scrivere;
00116                 if (da_scrivere == len) break;
00117                 /* Altrimenti spostati nel blocco successivo della FAT */
00118                 if (f_ctrl->fat_ptr[index]==BLOCK_FREE) return ERFCD;
00119                 fs_pos = f_ctrl->blk_base + (f_ctrl->fat_ptr[index] * f_ctrl->b_sector.block_size);
00120                 fseek(fs, fs_pos, SEEK_SET);
00121                 index = f_ctrl->fat_ptr[index];
00122         }
00123         
00124         /* Aggiorno i dati della entry del file */
00125         fseek(fs, fs_entry, SEEK_SET);
00126         file.len += data_len;
00127         if (!(fwrite(&file, sizeof(struct dir_entry), 1, fs))) return ERBD;
00128         
00129         /* Aggiorno i dati della FAT */
00130         fseek(fs, sizeof(struct boot_sector), SEEK_SET);
00131         if (!(fwrite(f_ctrl->fat_ptr, (f_ctrl->b_sector.num_block * sizeof(unsigned int)), 1, fs)))
00132                 return EWFCD;
00133         
00134         return 0;
00135 }

Generato il Fri Jan 28 22:16:32 2011 per SFAT: Simplified File Allocation Table Project da  doxygen 1.6.3