#include #include #include #include #include #include #include "inode.h" struct inode_desc_t new_inode(unsigned int volume, enum file_type_e t) { struct inode_desc_t inode; memset(&inode, 0, sizeof(struct inode_desc_t)); inode.volume = volume; inode.magic_key = INODE_MAGIC; inode.type = t; return inode; } uint32_t block_of_pos(struct inode_desc_t inode, unsigned int offset) { int pos = offset / block_size(); if ( pos < INODE_DIRECT ) return inode.ind_direct[pos]; /* blocs indirects */ pos -= INODE_DIRECT; /* Nous n'avons aucun bloc alloué */ if ( inode.ind_indirect == 0 ) return 0; if ( pos < INODE_FIELDS ) { uint32_t data[INODE_FIELDS]; read_data_from_block(inode.volume, inode.ind_indirect, data, sizeof(data)); return data[pos]; } /* Double indirects */ pos -= INODE_FIELDS; if ( inode.ind_d_indirect == 0 ) return 0; if ( pos < (INODE_FIELDS*INODE_FIELDS) ) { int ind1 = pos / INODE_FIELDS; uint32_t data[INODE_FIELDS]; /* Lecture de la table des doubles indirects */ read_data_from_block(inode.volume, inode.ind_d_indirect, data, sizeof(data)); /* Bloc non alloué */ if ( data[ind1] == 0 ) return 0; int ind2 = pos % INODE_FIELDS; /* Lecture de la table de dernier niveau */ read_data_from_block(inode.volume, data[ind1], data, sizeof(data)); return data[ind2]; } assert(!"Dépassement de la capacité possible d'un fichier, panic!"); return 0; } uint32_t block_of_pos_alloc(struct inode_desc_t *inode, unsigned int offset, unsigned int filesize) { int pos = offset / block_size(); /* Blocs directs */ if ( pos < INODE_DIRECT ) { if ( inode->ind_direct[pos] == 0 ) { //printf("Creating direct block\n"); inode->ind_direct[pos] = new_block(inode->volume); inode->size = filesize; assert(inode->ind_direct[pos] && "Pas de place sur le disque"); } return inode->ind_direct[pos]; } /* Indirect simple */ pos -= INODE_DIRECT; if ( pos < INODE_FIELDS ) { uint32_t data[INODE_FIELDS]; /* On n'a jamais eu de blocs indirects */ if ( inode->ind_indirect == 0 ) { //printf("Creating indirect table\n"); inode->ind_indirect = new_block(inode->volume); /* Lire la liste des blocs que l'on vient de créer */ read_data_from_block(inode->volume, inode->ind_indirect, data, sizeof(data)); /* Initialiser */ memset(data, 0, sizeof(data)); } else { /* Lire la liste des blocs */ read_data_from_block(inode->volume, inode->ind_indirect, data, sizeof(data)); } /* Non alloué ! */ if ( data[pos] == 0 ) { //printf("Creating indirect bloc entry\n"); data[pos] = new_block(inode->volume); inode->size = filesize; assert(data[pos] && "Pas de place sur le disque"); /* Ecrire la liste des blocs modifiée */ write_data_to_block(inode->volume, inode->ind_indirect, data, sizeof(data)); } return data[pos]; } /* Doubles indirects */ pos -= INODE_FIELDS; if ( pos < (INODE_FIELDS*INODE_FIELDS) ) { uint32_t level1[INODE_FIELDS]; uint32_t level2[INODE_FIELDS]; /* Si on n'a pas la table des doubles indirects */ if ( inode->ind_d_indirect == 0 ) { //printf("Creating double indirect table\n"); inode->ind_d_indirect = new_block(inode->volume); /* Lire la liste des blocs que l'on vient de créer */ read_data_from_block(inode->volume, inode->ind_d_indirect, level1, sizeof(level1)); /* Initialiser */ memset(level1, 0, sizeof(level1)); } else { /* Lire la liste des blocs */ read_data_from_block(inode->volume, inode->ind_d_indirect, level1, sizeof(level1)); } int ind1 = pos / INODE_FIELDS; /* Bloc de niveau1 non alloué */ if ( level1[ind1] == 0 ) { //printf("Creating double indirect 'indirect table'\n"); level1[ind1] = new_block(inode->volume); assert(level1[ind1] && "Pas de place sur le disque"); /* Ecrire la liste des blocs modifiée */ write_data_to_block(inode->volume, inode->ind_d_indirect, level1, sizeof(level1)); /* Lire la liste des blocs que l'on vient de créer */ read_data_from_block(inode->volume, level1[ind1], level2, sizeof(level2)); memset(level2, 0, sizeof(level2)); } else { /* Lire la liste des blocs de niveau 2 */ read_data_from_block(inode->volume, level1[ind1], level2, sizeof(level2)); } int ind2 = pos % INODE_FIELDS; /* Bloc non alloué */ if ( level2[ind2] == 0 ) { //printf("Creating double indirect bloc entry\n"); level2[ind2] = new_block(inode->volume); //inode->size += block_size(); inode->size = filesize; assert(level2[ind2] && "Pas de place sur le disque"); /* Ecrire la liste des blocs modifiée */ write_data_to_block(inode->volume, level1[ind1], level2, sizeof(level2)); } return level2[ind2]; } assert(!"Dépassement de la capacité possible d'un fichier, panic!"); return 0; } void free_inode_blocks(struct inode_desc_t inode) { int rspace = inode.size; /* Libère les blocs directs */ void free_inode_block_direct(uint32_t *blocks, unsigned int count) { int i; for(i=0;i 0 ) free_inode_block_indirect(inode.ind_indirect); if ( rspace > 0 ) free_inode_block_double_indirect(); }