[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Lost] [PATCH] ! cdi/ext2:Beim Loeschen von Verzeichnissen . und .. Eintraege auch loeschen
---
src/modules/cdi/ext2/libext2/directory.c | 11 +++++++++++
src/modules/cdi/ext2/libext2/fs.c | 2 +-
src/modules/cdi/ext2/libext2/include/ext2.h | 3 +++
src/modules/cdi/ext2/libext2/inode.c | 21 ++++++++++++++++++++-
src/modules/cdi/ext2/res.c | 7 +++++++
5 files changed, 42 insertions(+), 2 deletions(-)
diff --git a/src/modules/cdi/ext2/libext2/directory.c b/src/modules/cdi/ext2/libext2/directory.c
index 1f578d1..2b0a5cf 100644
--- a/src/modules/cdi/ext2/libext2/directory.c
+++ b/src/modules/cdi/ext2/libext2/directory.c
@@ -236,6 +236,8 @@ int ext2_dir_unlink(ext2_inode_t* dir, const char* name)
char buf[dir->raw.size];
uint64_t pos = 0;
int ret = 0;
+ ext2_blockgroup_t bg;
+ uint32_t bgnum;
ext2_inode_readdata(dir, 0, dir->raw.size, buf);
while (pos < dir->raw.size) {
@@ -249,6 +251,15 @@ int ext2_dir_unlink(ext2_inode_t* dir, const char* name)
return 0;
}
if (--inode.raw.link_count == 0) {
+ if (EXT2_INODE_IS_DIR(&inode)) {
+ // Bei Verzeichnissen den Zaehler im Blockgrunppen
+ // deskriptor aktualisieren
+ bgnum = ext2_inode_to_internal(inode.fs, inode.number) /
+ inode.fs->sb->inodes_per_group;
+ ext2_bg_read(inode.fs, bgnum, &bg);
+ bg.used_directories--;
+ ext2_bg_update(inode.fs, bgnum, &bg);
+ }
ext2_inode_free(&inode);
}
if (!ext2_inode_update(&inode)) {
diff --git a/src/modules/cdi/ext2/libext2/fs.c b/src/modules/cdi/ext2/libext2/fs.c
index 6d0806e..036257c 100644
--- a/src/modules/cdi/ext2/libext2/fs.c
+++ b/src/modules/cdi/ext2/libext2/fs.c
@@ -74,7 +74,7 @@ int ext2_fs_mount(ext2_fs_t* fs)
}
fs->cache_handle = fs->cache_create(fs, ext2_sb_blocksize(fs->sb));
-
+ fs->block_prev_alloc = 0;
// Die Blocknummer in der der Superblock liegt, variiert je nach
// Blockgroesse, da der offset fix 1024 ist.
diff --git a/src/modules/cdi/ext2/libext2/include/ext2.h b/src/modules/cdi/ext2/libext2/include/ext2.h
index dea5231..6f7563c 100644
--- a/src/modules/cdi/ext2/libext2/include/ext2.h
+++ b/src/modules/cdi/ext2/libext2/include/ext2.h
@@ -155,6 +155,9 @@ typedef struct ext2_fs {
/// Darf vom Aufrufer benutzt werden
void* opaque;
+
+ /// Letzte allozierte Blocknummer
+ uint64_t block_prev_alloc;
} ext2_fs_t;
/**
diff --git a/src/modules/cdi/ext2/libext2/inode.c b/src/modules/cdi/ext2/libext2/inode.c
index f92a18b..19aa37b 100644
--- a/src/modules/cdi/ext2/libext2/inode.c
+++ b/src/modules/cdi/ext2/libext2/inode.c
@@ -350,6 +350,24 @@ static uint64_t block_alloc(ext2_fs_t* fs)
block = bbitmap_get_block(fs, &bg);
bitmap = block->data;
+ // Zuerst Blocks nach dem vorherigen alloziierten pruefen
+ if (fs->block_prev_alloc &&
+ (fs->block_prev_alloc /fs->sb->blocks_per_group == bgnum))
+ {
+ int first_j = fs->block_prev_alloc % 32;
+ int first_i = fs->block_prev_alloc / 32;
+ for (i = first_i;i < fs->sb->blocks_per_group / 32; i++) {
+ if (bitmap[i] != ~0) {
+ j = (i == first_i) ? first_j : 0;
+ for (; j < 32; j++) {
+ if ((bitmap[i] & (1 << j)) == 0) {
+ goto found;
+ }
+ }
+ }
+ }
+ }
+
// Freies Bit suchen
for (i = 0; i < fs->sb->blocks_per_group / 32; i++) {
if (bitmap[i] != ~0) {
@@ -386,6 +404,7 @@ found:
bg.free_blocks--;
ext2_bg_update(fs, bgnum, &bg);
+ fs->block_prev_alloc = block_num;
return block_num;
}
@@ -529,7 +548,7 @@ int ext2_inode_readblk(ext2_inode_t* inode, uint64_t block, void* buf,
// Ein paar Nullen fuer Sparse Files
if (block_offset == 0) {
// TODO: Mehrere Sparse-Blocks
- memset(buf, 0, block_size * count);
+ memset(buf, 0, block_size);
return 1;
}
diff --git a/src/modules/cdi/ext2/res.c b/src/modules/cdi/ext2/res.c
index 50d7cc4..3b46f4f 100644
--- a/src/modules/cdi/ext2/res.c
+++ b/src/modules/cdi/ext2/res.c
@@ -287,6 +287,13 @@ int ext2_fs_res_remove_class(struct cdi_fs_stream* stream,
// Bei Verzeichnissen muessen noch ein paar Interne Daten freigegeben werden
if (class == CDI_FS_CLASS_DIR) {
dir_clear(stream);
+
+ if (!ext2_dir_unlink(res->inode, ".") ||
+ !ext2_dir_unlink(res->inode, ".."))
+ {
+ stream->error = CDI_FS_ERROR_IO;
+ goto error_out;
+ }
}
if (!ext2_dir_unlink(parent_res->inode, res->res.name)) {