C - 系统调用 - 读/写结构中的错误

时间:2014-02-04 21:53:45

标签: c system system-calls

为了完成一个项目,我将使用一个文件“创建”一个动态硬盘(我称之为FDD)。该文件首先包含一个寻址表,其中包含inode的off_t。 inode包含n off_t,每个代表文件中簇的开头。

工作正常!

然后,我添加一个选项来删除FDD中包含的文件。为了避免太大的孔,我将它们保存在一个寻址表(称为“无效表”)中,该表可以知道孔的位置以及它们的大小。

实际上这不起作用......事实上,当我删除一个文件时,我注意到它的空表,它很好地添加了漏洞,最后执行,我的表完全被破坏了(有价值像“47878465”......)。我的FDD也残酷地超过400GB(当它应该是大约3kB),不知道为什么......

这里是“无效表”.c和.h 失败来自函数“ajouterVide”,正是我写下英文评论的地方。

__ _ __ _ __ _ __ .H

`typedef struct{

    int taille[NTAB];
    off_t vide[NTAB];
    off_t next;
    off_t mypos;

}vide;`

__ _ __ _ __ _ __ .C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>

#include "virtualFS.h"
#include "inode.h"
#include "inode_t.h"
#include "table.h"
#include "table_t.h"
#include "tableVide.h"

vide* creerVide(){  
    int i;
    vide* v = (vide*)malloc(sizeof(vide));
    v->next = -1;
    v->mypos = sizeof(table);

    for(i=0; i<NTAB; i++){
        v->vide[i] = -1;
        v->taille[i] = 0;
    }

    return v;
}

void freeVide(vide** v){
    free(*v);
    *v = NULL;
}

off_t saveVide(int fd, vide* v){

    off_t curr = lseek(fd, 0, SEEK_CUR);

    if(curr == -1){
        perror("");
        exit(EXIT_FAILURE);
    }

    if(write(fd, v->taille, sizeof(int) * NTAB) == -1){
        perror("Ecriture n");
        exit(EXIT_FAILURE);
    }

    if(write(fd, v->vide, sizeof(off_t) * NTAB) == -1){
        perror("");
        exit(EXIT_FAILURE);
    }

    if(write(fd, &v->next, sizeof(off_t)) == -1){
        perror("");
        exit(EXIT_FAILURE);
    }

    if(write(fd, &v->mypos, sizeof(off_t)) == -1){
        perror("");
        exit(EXIT_FAILURE);
    }

    return curr;
}

vide* loadVide(int fd){

    vide* v = creerVide();

    if(read(fd, v->taille, sizeof(int) * NTAB) == -1){
        perror("Lecteure1 vide");
        exit(EXIT_FAILURE);
    }

    if(read(fd, v->vide, sizeof(off_t) * NTAB) == -1){
        perror("Lecture vide");
        exit(EXIT_FAILURE);
    }

    if(read(fd, &v->next, sizeof(off_t)) == -1){
        perror("Lecture vide");
        exit(EXIT_FAILURE);
    }

    if(read(fd, &v->mypos, sizeof(off_t)) == -1){
        perror("Lecture vide");
        exit(EXIT_FAILURE);
    }

    return v;
}

vide* rechercherTableVide(int fd, int* indice){

    int ind = 0;
    vide* v, * newv;

    lseek(fd, 0 , SEEK_SET);
    loadTable(fd);
    v = loadVide(fd);
    afficherVide(v);

    while(v->vide[ind] != -1){
        if(ind == NTAB){
            ind = 0;
            if(v->next != -1){
                lseek(fd, v->next, SEEK_SET);
                freeVide(&v);
                v = loadVide(fd);
            }else{
                newv = videEnfant(fd, v);
                freeVide(&v);
                v = newv;
            }
        }else
            ind++;
    }

    *indice = ind;
    return v;
}

void ajouterVide(int fd, inode* i, off_t pos){

    int j, ind = 0;
    vide* v = NULL;
    size_t taille;

    for(j=0; j<NBLOCK; j++){
        if(i->tab_ad[j] == -1)
            j = NBLOCK;
        else{
            v = rechercherTableVide(fd, &ind);
            v->vide[ind] = i->tab_ad[j];

            if(j == NBLOCK-1 || i->tab_ad[j + 1] == -1) /*On est au dernier bloc, potentiellement plus petit*/
                taille = i->taille % TBLOCK;
            else{
                int jj;
                taille = TBLOCK;

                for(jj=j; jj<NBLOCK-1; jj++){
                    if(contigue(i->tab_ad[jj], TBLOCK, i->tab_ad[jj+1]) == 1){
                        if(jj == NBLOCK-2 || i->tab_ad[jj+2] == -1)
                            taille += i->taille % TBLOCK;
                        else
                            taille += TBLOCK;
                        j++;    
                    }else
                        jj = NBLOCK;
                }           
            }
            v->taille[ind] = taille;
            lseek(fd, v->mypos, SEEK_SET);
            saveVide(fd, v);
            /*If i load / save / load / save many times, its always Ok here*/
            freeVide(&v);
        }
    }

    v = rechercherTableVide(fd, &ind);
    /*Here its completly fucked :( */
    v->vide[ind] = pos;     
    v->taille[ind] = tailleInode(i);
    lseek(fd, v->mypos, SEEK_SET);
    saveVide(fd, v);
    freeVide(&v);
}

int contigue(off_t d1, size_t taille, off_t d2){
    return d1 + (off_t)taille == d2 ? 1 : 0;
}

1 个答案:

答案 0 :(得分:0)

我找到了问题的解释。它是由数据结构对齐引起的,我已成功解决问题:)

感谢您的一切。