[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)) {