void write_inode(unsigned int inumber, const struct inode_s* inode) { unsigned char buffer[SECTOR_SIZE]; PRINT_ASSERT_ERROR_MSG(inumber != BLOC_NULL, "Null inode (write_inode)"); memcpy(buffer, inode, sizeof(struct inode_s)); write_bloc(current_vol, inumber, buffer); }
/*initialize a new bloc with all 0 inside*/ unsigned new_bloc_zero(){ int res; unsigned char buf[SECTORSIZE] = {0}; res=new_bloc(); write_bloc(CURRENT_VOLUME, res, buf); return res; }
/* * @brief Gestion du .blk lors de l'ajout d'un couple key/val * * Si un index de bloc existe déjà : * -> écriture de offset_key dans ce bloc (avec gestion de bloc plein) * Sinon : * -> création d'un nouveau bloc et écriture de l'index de ce bloc dans le .h * -> écriture de offset_key dans ce bloc (avec gestion de bloc plein) * * @param kv descripteur d'accès à la base * @param key clé * @param offset_key index du couple dans le .kv */ int kv_put_blk(KV *kv, const kv_datum *key, len_t *offset_key) { len_t val_h, offset_h; int offset_int = hash(key->ptr, kv); if(offset_int == -1) { return -1; } else { offset_h = offset_int; } int n = read_h(kv, offset_h, &val_h); if(n == -1) { return -1; } if(!n || val_h == 0) // clé pas hachée { len_t offset_new_bloc; if(new_bloc(kv, &offset_new_bloc) == -1) { return -1; } if(write_h(kv, offset_h, offset_new_bloc) == -1) { return -1; } if(write_bloc(kv, offset_new_bloc, offset_key) == -1) { return -1; } } else // clé déjà hachée { if(write_bloc(kv, val_h, offset_key) == -1) { return -1; } } return 42; }
unsigned initialize_bloc(unsigned address){ int new_bloc[NBPB]; int i; read_bloc(current_volume, address, (unsigned char*)new_bloc); for (i = 0; i < NBPB; i++){ new_bloc[i] = 0; } write_bloc(current_volume, address, (unsigned char*)new_bloc); return address; }
/* * @brief Détermine le bon bloc * * @param kv descripteur d'accès à la base * @param offset_bloc index dans le .blk * @param offset_data index dans le .kv (à écrire) */ int write_bloc(KV *kv, len_t offset_bloc, len_t * offset_data) { len_t offset_lu_courant, offset_courant, offset_bloc_suivant, offset_sauvegarde = offset_bloc; int i; off_t off; while(offset_bloc) { read_entete_bloc(kv, offset_bloc, &offset_bloc_suivant); // ce qui déplace juste apres l'en-tête du bon bloc for(i = 0; i < 1023; i++) { off = lseek(kv->fd2, 0, SEEK_CUR); if(off == -1) { return -1; } offset_courant = off; read(kv->fd2, &offset_lu_courant, 4); if(offset_lu_courant == 0) { write_bloc_entry(kv, offset_courant, *offset_data); return 42; } } offset_bloc = offset_bloc_suivant; } // pas de bloc suivant et plus de place dans le bloc courant len_t offset_new_bloc; if(new_bloc(kv, &offset_new_bloc)) { return -1; } if(write_bloc_entry(kv, offset_sauvegarde, offset_new_bloc)) { return -1; }; // lien entre les 2 blocs inverser les 2 ? if(write_bloc(kv, offset_new_bloc, offset_data)) { return -1; }; return 42; }
void free_bloc(unsigned int bloc) { if(bloc==0){ printf("Impossible de libérer le bloc : bloc inexistant\n"); return; } struct freeBloc_s freeB; unsigned char buffer[HDA_SECTORSIZE]; freeB.freebloc_nb_free = 1; freeB.freebloc_next = current_super.super_first_free_bloc; current_super.super_first_free_bloc = bloc; current_super.super_nb_free++; memset(buffer, 0, HDA_SECTORSIZE); memcpy(buffer, &freeB, sizeof(struct freeBloc_s)); write_bloc(current_vol, bloc, buffer); save_super(); }
/* note that flush don't need to worry about the bloc allocation; a previous write operation has already done it. */ void flush_ifile(file_desc_t *fd) { unsigned int fbloc; /* bloc index in the file */ unsigned int vbloc; /* bloc index in the volume */ if (fd-> fds_dirty) { /* compute the number of the bloc on the volume associated to the buffer */ fbloc = bloc_of_pos(fd->fds_pos); vbloc = vbloc_of_fbloc(fd-> fds_inumber, fbloc, TRUE); /* write back the buffer */ write_bloc(current_volume, vbloc, fd->fds_buf); /* done */ fd-> fds_dirty = FALSE ; } }
/* return the pos in the file ; RETURN_FAILURE in case of error */ int writec_ifile(file_desc_t *fd, char c) { unsigned int ibloc; /* write the char in the buffer */ fd->fds_buf[ibloc_of_pos(fd->fds_pos)] = c; /* first write in the bloc ? ensure the data bloc allocation */ if (! fd->fds_dirty) { ibloc = vbloc_of_fbloc(fd->fds_inumber, bloc_of_pos(fd->fds_pos), TRUE); if (! ibloc) { return RETURN_FAILURE; } fd->fds_dirty = TRUE; } /* is the buffer full? */ if (ibloc_of_pos(fd->fds_pos) == BLOC_SIZE-1) { /* write the buffer */ ibloc = vbloc_of_fbloc(fd->fds_inumber, bloc_of_pos(fd->fds_pos), FALSE); write_bloc(current_vol, ibloc, fd->fds_buf); /* read the new buffer */ ibloc = vbloc_of_fbloc(fd->fds_inumber, bloc_of_pos(fd->fds_pos+1), FALSE); if (! ibloc) memset(fd->fds_buf, 0, BLOC_SIZE); else read_bloc(current_vol, ibloc, fd->fds_buf); fd->fds_dirty = FALSE; } /* update the file cursor and size */ if (fd->fds_size < fd->fds_pos) fd->fds_size = fd->fds_pos; fd->fds_pos++; /* the position of the written char */ return fd->fds_pos - 1; }
void init_super(unsigned int vol) { printf("Initialisation du superbloc du volume ...\n"); struct volume_s volume; struct freeBloc_s fb; unsigned char buffer[HDA_SECTORSIZE]; //load_mbr(); volume = mbr.disque[vol]; current_super.super_magic = SUPER_MAGIC; current_super.super_first_free_bloc = 1; current_super.super_nb_free = volume.size - 1; //strncpy(current_super.super_name, nom, 32); fb.freebloc_nb_free=volume.size - 1; fb.freebloc_next=0; save_super(); memset(buffer, 0, HDA_SECTORSIZE); memcpy(buffer, &fb, sizeof(struct freeBloc_s)); write_bloc(vol, 1, buffer); current_vol=vol; printf("Initialisation du superbloc du volume terminé\n"); }
unsigned int new_bloc(){ struct freeBloc_s *fb; unsigned char buffer[HDA_SECTORSIZE]; unsigned res; if(current_super.super_nb_free==0) return 0; assert(current_super.super_first_free_bloc); read_bloc(current_vol, current_super.super_first_free_bloc, buffer); fb = (struct freeBloc_s*) buffer; res = current_super.super_first_free_bloc; if(fb->freebloc_nb_free > 1){ current_super.super_nb_free --; fb->freebloc_nb_free--; write_bloc(current_vol, current_super.super_first_free_bloc, buffer); } else { current_super.super_first_free_bloc = fb->freebloc_next; } //current_super.super_first_free_bloc--; save_super(); return res; }
// Recopié depuis le cahier, les noms sont pas forcément les bons unsigned int vbloc_of_fbloc(unsigned int inumber, unsigned int fbloc,bool_t do_allocate){ struct inode_s inode; unsigned int bloc_index = fbloc; read_inode(inumber, &inode); //direct if (bloc_index < NDIRECT){ if (inode.direct[bloc_index] == 0){ if(do_allocate){ inode.direct[bloc_index] = initialize_bloc(new_bloc()); write_inode(inumber,&inode); }else{return BLOC_NULL;} } return inode.direct[bloc_index]; } bloc_index -= NDIRECT; //indirect simple if (bloc_index < NBPB){ // if the indirect entry in the inode is not allocated yet if (inode.direct == 0){ if(do_allocate){ inode.indirect = initialize_bloc(new_bloc());; write_inode(inumber,&inode); }else{return BLOC_NULL;} } int indirect[NBPB]; read_bloc(current_volume, inode.indirect, (unsigned char *)indirect); if (indirect[bloc_index] == 0){ if(do_allocate){ indirect[bloc_index] = initialize_bloc(new_bloc());; write_bloc(current_volume, inode.indirect, (unsigned char*)indirect); }else{return BLOC_NULL;} } return indirect[bloc_index]; } bloc_index -= NBPB; //indirect double if(bloc_index < NBPB*NBPB){ if (inode.two_indirect == 0){ if(do_allocate){ inode.two_indirect = initialize_bloc(new_bloc());; write_inode(inumber,&inode); }else{return BLOC_NULL;} } int db_indirect_index = bloc_index / NBPB; int indirect_index = bloc_index % NBPB; int db_indirect[NBPB]; read_bloc(current_volume, inode.two_indirect, (unsigned char*)db_indirect); if (db_indirect[db_indirect_index] == 0){ if(do_allocate){ db_indirect[db_indirect_index] = initialize_bloc(new_bloc()); write_bloc(current_volume, inode.two_indirect, (unsigned char*)db_indirect); }else{return BLOC_NULL;} } int indirect[NBPB]; read_bloc(current_volume, db_indirect[db_indirect_index], (unsigned char*)indirect); if (indirect[indirect_index] == 0){ if(do_allocate){ //printf("allocate indirect[%d]\n",indirect_index); indirect[indirect_index] = initialize_bloc(new_bloc());; write_bloc(current_volume, db_indirect[db_indirect_index], (unsigned char*)indirect); }else{return BLOC_NULL;} } return indirect[indirect_index]; } //fprintf(stderr,"fbloc is too big.\n\tfbloc provided: %d\n\tfbloc max size: %d",fbloc, NDIRECT+NBPB+NBPB*NBPB); return -1; }
void write_inode (unsigned int inumber, const struct inode_s *inode) { assert(BLOC_SIZE == sizeof(struct inode_s)); write_bloc(current_volume, inumber, (unsigned char *)inode); }
void save_super(){ unsigned char buffer[HDA_SECTORSIZE]; memset(buffer, 0, HDA_SECTORSIZE); memcpy(buffer, ¤t_super, sizeof(struct superBloc_s)); write_bloc(current_vol, 0, buffer); }
unsigned int vbloc_of_fbloc(unsigned int inumber, unsigned int fbloc, bool_t do_allocate) { struct inode_s inode; unsigned int buffer_indirect[SECTOR_SIZE]; unsigned int buffer_indirect2[SECTOR_SIZE]; PRINT_ASSERT_ERROR_MSG(inumber != BLOC_NULL, "Null inode (vbloc_of_fbloc)"); read_inode(inumber, &inode); if(fbloc < NB_DIRECT_BLOC) { /* Direct */ if(inode.inode_direct_bloc[fbloc] == BLOC_NULL) { if(do_allocate) { inode.inode_direct_bloc[fbloc] = new_bloc(); write_inode(inumber, &inode); } else { return BLOC_NULL; } } return inode.inode_direct_bloc[fbloc]; } else if(fbloc < NB_INDIRECT_BLOC + NB_DIRECT_BLOC) { /* Indirect 1 */ fbloc -= NB_DIRECT_BLOC; unsigned int vbloc; /* Level 0 */ if(inode.inode_indirect_1 == BLOC_NULL) { if(do_allocate) { inode.inode_indirect_1 = new_bloc(); if(inode.inode_indirect_1 == BLOC_NULL) { return BLOC_NULL; } /* set 0 to new bloc */ memset(buffer_indirect, 0, SECTOR_SIZE); write_bloc(current_vol, inode.inode_indirect_1, (unsigned char*)buffer_indirect); write_inode(inumber, &inode); } else { return BLOC_NULL; } } /* Level 1 */ read_bloc(current_vol, inode.inode_indirect_1, (unsigned char*)buffer_indirect); vbloc = buffer_indirect[fbloc]; if(vbloc == BLOC_NULL) { if(do_allocate) { buffer_indirect[fbloc] = new_bloc(); if(buffer_indirect[fbloc] == BLOC_NULL) { return BLOC_NULL; } write_bloc(current_vol, inode.inode_indirect_1, (unsigned char*)buffer_indirect); vbloc = buffer_indirect[fbloc]; } else { return BLOC_NULL; } } return vbloc; } else if (fbloc < NB_INDIRECT_BLOC + NB_DIRECT_BLOC + NB_INDIRECT_BLOC*NB_INDIRECT_BLOC) { /* Indirect 2 */ unsigned int vbloc_1, vbloc_2; fbloc -= NB_DIRECT_BLOC+NB_INDIRECT_BLOC; /* Level 0 */ if(inode.inode_indirect_2 == BLOC_NULL) { if(do_allocate) { inode.inode_indirect_2 = new_bloc(); if(inode.inode_indirect_2 == BLOC_NULL) { return BLOC_NULL; } /* set 0 to new bloc */ memset(buffer_indirect, 0, SECTOR_SIZE); write_bloc(current_vol, inode.inode_indirect_2, (unsigned char*)buffer_indirect); write_inode(inumber, &inode); } else { return BLOC_NULL; } } /* Level 1 */ read_bloc(current_vol, inode.inode_indirect_2, (unsigned char*)buffer_indirect); vbloc_1 = buffer_indirect[fbloc/NB_INDIRECT_BLOC]; if(vbloc_1 == BLOC_NULL) { if(do_allocate) { buffer_indirect[fbloc/NB_INDIRECT_BLOC] = new_bloc(); if(buffer_indirect[fbloc/NB_INDIRECT_BLOC] == BLOC_NULL) { return BLOC_NULL; }; /* set 0 to new bloc */ memset(buffer_indirect2, 0, SECTOR_SIZE); write_bloc(current_vol, buffer_indirect[fbloc/NB_INDIRECT_BLOC], (unsigned char*)buffer_indirect2); write_bloc(current_vol, inode.inode_indirect_2, (unsigned char*)buffer_indirect); vbloc_1 = buffer_indirect[fbloc/NB_INDIRECT_BLOC]; } else { return BLOC_NULL; } } /* Level 2 */ read_bloc(current_vol, vbloc_1, (unsigned char*)buffer_indirect); vbloc_2 = buffer_indirect[fbloc%NB_INDIRECT_BLOC]; if(vbloc_2 == BLOC_NULL) { if(do_allocate) { buffer_indirect[fbloc%NB_INDIRECT_BLOC] = new_bloc(); if(buffer_indirect[fbloc%NB_INDIRECT_BLOC] == BLOC_NULL) { return BLOC_NULL; } write_bloc(current_vol, vbloc_1, (unsigned char*)buffer_indirect); vbloc_2 = buffer_indirect[fbloc%NB_INDIRECT_BLOC]; } else { return BLOC_NULL; } } return vbloc_2; } else return BLOC_NULL; }