Add file removal, rm
This commit is contained in:
+76
-12
@@ -42,21 +42,20 @@ typedef struct {
|
||||
uint32_t size;
|
||||
uint16_t dir_cluster;
|
||||
uint16_t dir_index;
|
||||
uint8_t valid;
|
||||
uint8_t removed;
|
||||
} fat16_inode_t;
|
||||
|
||||
static fat16_inode_t inodes[MAX_INODES];
|
||||
|
||||
static fat16_inode_t *inode_create(uint16_t first_cluster, uint32_t size, uint16_t dir_cluster, uint16_t dir_index) {
|
||||
for (uint64_t i = 0; i < MAX_INODES; i++) {
|
||||
if (!inodes[i].valid) {
|
||||
if (!inodes[i].refs) {
|
||||
inodes[i] = (fat16_inode_t){
|
||||
.refs = 1,
|
||||
.first_cluster = first_cluster,
|
||||
.size = size,
|
||||
.dir_cluster = dir_cluster,
|
||||
.dir_index = dir_index,
|
||||
.valid = 1,
|
||||
};
|
||||
return &inodes[i];
|
||||
}
|
||||
@@ -66,7 +65,7 @@ static fat16_inode_t *inode_create(uint16_t first_cluster, uint32_t size, uint16
|
||||
|
||||
static fat16_inode_t *inode_get(uint32_t dir_cluster, uint16_t dir_index) {
|
||||
for (uint64_t i = 0; i < MAX_INODES; i++) {
|
||||
if (inodes[i].valid && inodes[i].dir_cluster == dir_cluster && inodes[i].dir_index == dir_index) {
|
||||
if (inodes[i].refs && inodes[i].dir_cluster == dir_cluster && inodes[i].dir_index == dir_index) {
|
||||
return &inodes[i];
|
||||
}
|
||||
}
|
||||
@@ -84,14 +83,8 @@ static fat16_inode_t *inode_use(uint16_t first_cluster, uint32_t size, uint16_t
|
||||
}
|
||||
|
||||
static void inode_free(fat16_inode_t *inode) {
|
||||
inode->refs--;
|
||||
if (!inode->refs) {
|
||||
for (uint64_t i = 0; i < MAX_INODES; i++) {
|
||||
if (&inodes[i] == inode) {
|
||||
inodes[i].valid = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (inode->refs) {
|
||||
inode->refs--;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,6 +256,10 @@ fs_node_t *fat16_open_by(const fs_node_t *directory, const char *name, uint64_t
|
||||
return NUL;
|
||||
}
|
||||
|
||||
if (((fat16_node_t *)directory)->inode->removed) {
|
||||
return NUL;
|
||||
}
|
||||
|
||||
uint16_t dir_cluster = ((fat16_node_t *)directory)->inode->first_cluster;
|
||||
|
||||
char name_8_3[12];
|
||||
@@ -350,6 +347,10 @@ fs_node_t *fat16_open_at(const fs_node_t *directory, uint16_t index, uint64_t fl
|
||||
return NUL;
|
||||
}
|
||||
|
||||
if (((fat16_node_t *)directory)->inode->removed) {
|
||||
return NUL;
|
||||
}
|
||||
|
||||
uint16_t dir_cluster = ((fat16_node_t *)directory)->inode->first_cluster;
|
||||
|
||||
fat16_dir_entry_t *entries;
|
||||
@@ -403,6 +404,10 @@ uint64_t fat16_read(const fs_node_t *file, uint32_t offset, uint32_t bytes, void
|
||||
return (uint64_t)-1;
|
||||
}
|
||||
|
||||
if (fat_file->inode->removed) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (offset >= fat_file->inode->size) {
|
||||
return 0;
|
||||
}
|
||||
@@ -460,6 +465,10 @@ uint64_t fat16_write(fs_node_t *file, uint32_t offset, const void *from, uint32_
|
||||
return (uint64_t)-1;
|
||||
}
|
||||
|
||||
if (fat_file->inode->removed) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
ensure_fat();
|
||||
|
||||
if (!fat_file->inode->first_cluster) {
|
||||
@@ -540,6 +549,10 @@ uint64_t fat16_truncate(fs_node_t *file, uint32_t size) {
|
||||
return (uint64_t)-1;
|
||||
}
|
||||
|
||||
if (fat_file->inode->removed) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (file->size == size) {
|
||||
return size;
|
||||
} else if (file->size < size) {
|
||||
@@ -585,6 +598,57 @@ uint64_t fat16_truncate(fs_node_t *file, uint32_t size) {
|
||||
return (uint64_t)-1;
|
||||
}
|
||||
|
||||
uint64_t fat16_remove(fs_node_t *file) {
|
||||
fat16_node_t *fat_file = (fat16_node_t *)file;
|
||||
|
||||
if (fat_file->base.type != FAT16) {
|
||||
return (uint64_t)-1;
|
||||
}
|
||||
|
||||
if (fat_file->inode->removed) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (file->is_dir) {
|
||||
fat16_dir_entry_t *subentries;
|
||||
uint16_t subentries_count = read_directory(fat_file->inode->first_cluster, &subentries);
|
||||
uint16_t ei = 0, vi = 0;
|
||||
while (ei < subentries_count && subentries[ei].name[0]) {
|
||||
if ((uint8_t)subentries[ei].name[0] != 0xE5 && (uint8_t)subentries[ei].attributes != 0x0F) {
|
||||
vi++;
|
||||
}
|
||||
ei++;
|
||||
}
|
||||
memory_free(subentries);
|
||||
if (vi > 2) {
|
||||
return (uint64_t)-1;
|
||||
}
|
||||
}
|
||||
|
||||
fat_file->inode->removed = 1;
|
||||
|
||||
if (fat_file->inode->first_cluster) {
|
||||
ensure_fat();
|
||||
uint64_t next_cluster = fat_file->inode->first_cluster;
|
||||
do {
|
||||
uint32_t swap = fat[next_cluster];
|
||||
fat[next_cluster] = 0;
|
||||
next_cluster = swap;
|
||||
} while (next_cluster < 0xFFF8);
|
||||
flush_fat();
|
||||
}
|
||||
|
||||
fat16_dir_entry_t *entries;
|
||||
uint16_t entries_count = read_directory(fat_file->inode->dir_cluster, &entries);
|
||||
entries[fat_file->inode->dir_index].name[0] = 0xE5;
|
||||
entries[fat_file->inode->dir_index].first_cluster = 0;
|
||||
entries[fat_file->inode->dir_index].size = 0;
|
||||
write_directory(fat_file->inode->dir_cluster, entries, entries_count);
|
||||
memory_free(entries);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
stream_t stream;
|
||||
fs_node_t *node;
|
||||
|
||||
Reference in New Issue
Block a user