[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[tyndur-devel] [PATCH libext2 6/8] libext2: Bootloader nicht zerstören



Die ersten 1024 Bytes auf dem Gerät müssen in Ruhe gelassen werden. Wenn
sie Teil des ersten Blocks sind, müssen sie bei jedem Superblock-Update
rausgeschrieben werden, weil der Cache nur auf Blockgranularität
arbeitet.

Signed-off-by: Kevin Wolf <kevin@xxxxxxxxxx>
---
 libext2/fs.c           | 21 +++++++++++++++++----
 libext2/include/ext2.h |  3 +++
 libext2/superblock.c   | 14 ++++++++++++--
 3 files changed, 32 insertions(+), 6 deletions(-)

diff --git a/libext2/fs.c b/libext2/fs.c
index 036257c..06f8565 100644
--- a/libext2/fs.c
+++ b/libext2/fs.c
@@ -66,11 +66,18 @@ static int fs_check_fast(ext2_fs_t* fs)
 int ext2_fs_mount(ext2_fs_t* fs)
 {
     fs->sb = malloc(sizeof(ext2_superblock_t));
+    fs->boot_sectors = malloc(1024);
+
+    if (!fs->sb || !fs->boot_sectors) {
+        goto fail;
+    }
 
     if (!ext2_sb_read(fs, fs->sb)) {
-        free(fs->sb);
-        fs->sb = NULL;
-        return 0;
+        goto fail;
+    }
+
+    if (!fs->dev_read(0, 1024, fs->boot_sectors, fs->dev_private)) {
+        goto fail;
     }
 
     fs->cache_handle = fs->cache_create(fs, ext2_sb_blocksize(fs->sb));
@@ -88,6 +95,12 @@ int ext2_fs_mount(ext2_fs_t* fs)
     }
 #endif
     return 1;
+
+fail:
+    free(fs->boot_sectors);
+    free(fs->sb);
+    fs->sb = NULL;
+    return 0;
 }
 
 int ext2_fs_unmount(ext2_fs_t* fs)
@@ -97,6 +110,7 @@ int ext2_fs_unmount(ext2_fs_t* fs)
         return 0;
     }
 
+    free(fs->boot_sectors);
     free(fs->sb);
     fs->cache_destroy(fs->cache_handle);
     fs->sb = fs->cache_handle = NULL;
@@ -107,4 +121,3 @@ void ext2_fs_sync(ext2_fs_t* fs)
 {
     fs->cache_sync(fs->cache_handle);
 }
-
diff --git a/libext2/include/ext2.h b/libext2/include/ext2.h
index 6f7563c..9529960 100644
--- a/libext2/include/ext2.h
+++ b/libext2/include/ext2.h
@@ -158,6 +158,9 @@ typedef struct ext2_fs {
 
     /// Letzte allozierte Blocknummer
     uint64_t block_prev_alloc;
+
+    /// Der Inhalt der ersten 1024 Bytes auf dem Gerät
+    void* boot_sectors;
 } ext2_fs_t;
 
 /**
diff --git a/libext2/superblock.c b/libext2/superblock.c
index c761066..6dc8737 100644
--- a/libext2/superblock.c
+++ b/libext2/superblock.c
@@ -130,8 +130,18 @@ int ext2_sb_update(ext2_fs_t* fs, ext2_superblock_t* sb)
             blocks_per_group) * block_size;
 
         block = fs->cache_block(fs->cache_handle, start / block_size, 1);
-        memcpy(block->data + (start % block_size), sb,
-            sizeof(ext2_superblock_t));
+        if (i == 0 && block_size > 1024) {
+            memcpy(block->data, fs->boot_sectors, 1024);
+            memcpy(block->data + 1024, sb, sizeof(ext2_superblock_t));
+            memset(block->data + 1024 + sizeof(ext2_superblock_t), 0,
+                   block_size - 1024 - sizeof(ext2_superblock_t));
+        } else if (i == 0) {
+            memcpy(block->data, sb, sizeof(ext2_superblock_t));
+        } else {
+            memcpy(block->data, sb, sizeof(ext2_superblock_t));
+            memset(block->data + sizeof(ext2_superblock_t), 0,
+                   block_size - sizeof(ext2_superblock_t));
+        }
         fs->cache_block_free(block, 1);
     }
 
-- 
1.8.1.4