Dateisystem-Implementierung in C: MFS-Funktionen

Informatik10,09 KB

Übersicht über die Dateisystem-Funktionen (MFS)

Die folgenden Abschnitte enthalten Bereinigungen und syntaktische Korrekturen der C-Codefunktionen zur Verwaltung von Inodes, Pfaden und Verzeichnissen.

Funktion: mfs_write

int mfs_write(int fd, void *buf, size_t count) {
int start, not_done, num_block;
char block[fs->sb.block_size];
char *next;
if (fd < 0 || fd >= row_num) return -1;
if (fs->Datei[fd].num == -1) {
printf("Trying to ungeöffneten fd schreiben\n");
return -1;
}
if (fs->file_count[fd].ino.e.size * fs->sb.block_size - fs->file[fd].pos)
count = fs->Datei[fd].ino.e.size * fs->sb.block_size - fs->Datei[fd].pos;
start = fs->Datei[fd].pos % fs->sb.block_size;
num_block = (fs->Datei[fd].pos / fs->sb.block_size) + fs->Datei[fd].ino.e.start;
not_done = count;
next = buf;
while (not_done) {
int len;
if (fs->sb.block_size - start < not_done)
len = fs->sb.block_size - start;
else
len = not_done;
if (len != fs->sb.block_size) {
data_read(fs, block, num_block);
memcpy(block + start, next, len);
data_write(fs, block, num_block);
} else {
data_write(fs, next, num_block);
}
num_block++;
not_done -= len;
next += len;
start = 0;
}
fs->Datei[fd].pos += count;
if (fs->Datei[fd].pos > fs->Datei[fd].ino.size) {
fs->Datei[fd].ino.size = fs->Datei[fd].pos;
inode_write(fs, &fs->Datei[fd].ino, fs->Datei[fd].num);
}
return count;
}

Funktion: get_inodo_previo

static int get_inodo_previo(struct file_system *fs, char *path) {
// Gibt den Inode aus früherem vollständigen Pfad zurück
int i = 0, j = 0, inode = -1, inodo_anterior = -1;
int con_dir = -1;
int path_len = strlen(path);
char *rest = malloc(sizeof(char) * path_len);
char *name = malloc(sizeof(char) * path_len);
struct disk_inode ino;
while (path[i] != '\0' && path[i] != '/') { // Get the first [dir1] / [dir2/archivo.1txt] Kette Trennung
name[i] = path[i];
i++;
}
if (path[i] == '/') con_dir = 0; // if / then im Verzeichnispfad muss gehen
name[i] = '\0'; // Wir fuegen \0 an die Zeichenfolge an, sodass sie immer gueltig endet
i++;
while (i < strlen(path)) {
rest[j] = path[i];
i++; j++;
rest[j] = '\0';
if (path[i] == '\0') break;
}
inode = namei(fs, &(fs->root), name); // Ermittle den Initial-root-inode
if (con_dir == -1) return 0;
inodo_anterior = inode; // Bei der Erörterung des Rests, zum ersten Mal bisheriger Inode
if (inode == -1) return -1; // Das erste Element des Weges existiert nicht
else if (inode != -1) {
i = 0; j = 0; con_dir = -1;
inode_read(fs, &ino, inode); // Lesen des Inodes, den wir zuletzt hatten
while (rest[i] != '\0' && rest[i] != '/') {
name[i] = rest[i];
i++;
}
if (rest[i] == '/') con_dir = 0;
name[i] = '\0';
i++;
while (i < strlen(rest)) {
rest[j] = rest[i];
i++; j++;
if (rest[i] == '\0') break;
}
rest[j] = '\0'; // Vollständige Kette des Rests halten
inodo_anterior = inode; // Inode vor dem nächsten Schritt merken
inode = namei(fs, &ino, name); // Get the new inode
if (con_dir == 0) return inode; // Wenn Verzeichnisse vorhanden sind, fortsetzen
else return inodo_anterior;
}
return inode;
}

Funktion: get_inodo

static int get_inodo(struct file_system *fs, char *path) {
// Gibt den Inode aus dem vollständigen Pfad zurück
int i = 0, j = 0, n = 0, inode = -1;
int inodo_anterior = -1, con_dir = -1;
int path_len = strlen(path);
char *rest = malloc(sizeof(char) * path_len);
char *name = malloc(sizeof(char) * path_len);
char *dir_anterior = malloc(sizeof(char) * path_len);
struct disk_inode ino;
while (path[i] != '\0' && path[i] != '/') { // Pfad analysieren
name[i] = path[i]; // Erstes Element kopieren
i++;
}
if (path[i] == '/') con_dir = 0; // Folgt ein Schrägstrich, ist es ein Verzeichnis
name[i] = '\0'; // Nullterminierung setzen
i++;
while (i < strlen(path)) { // Restlichen Pfad kopieren
rest[j] = path[i];
i++; j++;
rest[j] = '\0';
if (path[i] == '\0') break;
}
if (strcmp(name, "..") == 0) return 0; // Übergeordnetes Verzeichnis (Wurzel)
inode = namei(fs, &(fs->root), name); // Inode des ersten Elements ermitteln
if (con_dir == -1) return inode; // Wenn kein Verzeichnis, Inode zurückgeben
inodo_anterior = inode; // Vorherigen Inode für folgende Schritte sichern

if (inode == -1) return -1;
else if (inode != -1) {
i = 0; j = 0; con_dir = -1;
inode_read(fs, &ino, inode); // Lese Daten des Inodes ino
while (rest[i] != '\0' && rest[i] != '/') {
name[i] = rest[i];
i++;
}
if (rest[i] == '/') con_dir = 0;
name[i] = '\0';
i++;
while (i < strlen(rest)) {
rest[j] = rest[i];
i++; j++;
if (rest[i] == '\0') break;
}
rest[j] = '\0';
inodo_anterior = inode;
inode = namei(fs, &ino, name);
if (name[0] == '.' && name[1] == '.') {
int s;
for (s = 0; s < strlen(path); s++) {
if ((path[s] == '/') && (path[s + 1] == '.') && (path[s + 2] == '.')) {
return get_inodo_previo(fs, dir_anterior);
}
dir_anterior[s] = path[s];
}
}
if (name[0] == '.' && name[1] == '\0') return inodo_anterior;
if (con_dir == 0) return inode;
else return inode;
}
return inode;
}

Funktion: is_dir

static int is_dir(struct file_system *fs, struct disk_inode *d, char *directory) {
// Prüfen, ob ein Eintrag im aktuellen Inode ein Verzeichnis ist
char block[fs->sb.block_size];
struct entry *dir = (struct entry *) block;
int r = 0, i, j;
if (directory[0] == '.' && directory[1] == '\0') return 1; // '.' ist immer ein Verzeichnis
for (i = 0; i < d->e.size; i++) {
data_read(fs, block, d->e.start + i);
for (j = 0; j < fs->sb.block_size / sizeof(struct entry); j++) {
if (dir[j].inode != -1 && strncmp(directory, dir[j].name, ENTRY_SIZE) == 0) {
if (dir[j].is_dir == 0) r = 1;
}
}
}
return r;
}

Funktion: mfs_opendir

struct mfs_dir *mfs_opendir(const char *name) {
// Verzeichnis über Pfadnamen öffnen
int num_inodo;
if (fs == NULL) fs_init();
printf("\t\tExplorando Verzeichnis: '%s'\n", name);
if (name[0] == '.' && name[1] == '\0') { // Wurzelverzeichnis bearbeiten
if (fs->dir.num_inodo == -1) {
inode_read(fs, &fs->dir.inodo, fs->sb.root_inode);
fs->dir.num_inodo = fs->sb.root_inode;
fs->dir.pos = 0;
fs->dir.pos_block = 0;
strcpy(fs->dir.path, name);
} else return NULL;
} else { // Alle übrigen Fälle
if (fs->dir.num_inodo == -1) {
num_inodo = get_inodo(fs, (char *)name);
if (num_inodo == -1) return NULL;
inode_read(fs, &fs->dir.inodo, num_inodo);
fs->dir.num_inodo = num_inodo;
fs->dir.pos = 0;
fs->dir.pos_block = 0;
strcpy(fs->dir.path, name);
} else return NULL;
}
return &fs->dir; // Gibt die initialisierte Verzeichnisstruktur zurück
}

Funktion: mfs_readdir

struct dirent *mfs_readdir(MFS_DIR *dir) {
// Nächsten Verzeichniseintrag lesen
char block[fs->sb.block_size];
struct dirent *entry = NULL;
struct entry *ent = (struct entry *) block;
struct disk_inode ino_previo;
int num_inodo_root, inodo_root_previo, root_is_dir = 1, i = 0;
printf("ent[dir->pos].name: %s\n", ent[dir->pos].name);
printf("ent[dir->pos].inode: %d\n", ent[dir->pos].inode);
printf("dir->inodo.e.start: %d\n", dir->inodo.e.start);
printf("dir->pos: %d\n", dir->pos);
data_read(fs, block, dir->inodo.e.start + i);
if (dir->pos != -1) { // Gültige Position in der Datei
if (ent[dir->pos].inode != -1) { // Gültiger Inode vorhanden
printf("dir->num_inodo: %d\n", dir->num_inodo);
printf("get_inodo_previo: %d\n", get_inodo_previo(fs, dir->path));
entry = malloc(sizeof(struct dirent));
strcpy(entry->d_name, ent[dir->pos].name); // Eintragsname zuweisen
num_inodo_root = dir->num_inodo;
}
}
return entry;
}

Herunterladen

PDF Word HTML