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

标签 c system system-calls

为了完成一个项目,我必须使用文件“创建”一个动态 HDD(我称他为 FDD)。该文件首先包含一个寻址表,其中包含一个 inode 的 off_t 。 一个inode包含n个off_t,每个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;
}

最佳答案

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

谢谢你所做的一切。

关于C - 系统调用 - 读/写结构中的错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21564309/

相关文章:

c - 从字符串中提取不确定数量的整数

c - Berkeley DB SIGBUS 错误

perl - 如何在后台运行 Perl 系统命令?

c - 可能滥用 perf_event_open 系统调用

c - 在c中首先调度最短的作业

c++ - 用于集成测试的模拟库

Java - 为什么系统类和运行时类具有相同的方法?

mysql - 记录和统计用户登录的系统

c++ - 使用 process_vm_readv 从另一个进程修改整数值

Linux 使用堆栈上的字符串写入系统调用