From 5ca3cec48ec3cf8ca1d811385e58383f5fbe9351 Mon Sep 17 00:00:00 2001 From: Enrico Fraccaroli Date: Sat, 25 Dec 2021 10:03:31 +0100 Subject: [PATCH] Wait for RTC to initialize global time. Complete mkdir and creat for EXT2 filesystem. --- mentos/inc/fs/ext2.h | 2 + mentos/src/drivers/rtc.c | 15 +- mentos/src/fs/ext2.c | 397 +++++++++++++++++++++++++++++++-------- mentos/src/kernel.c | 10 +- 4 files changed, 335 insertions(+), 89 deletions(-) diff --git a/mentos/inc/fs/ext2.h b/mentos/inc/fs/ext2.h index 0968c85..9d1ffbd 100644 --- a/mentos/inc/fs/ext2.h +++ b/mentos/inc/fs/ext2.h @@ -15,3 +15,5 @@ int ext2_initialize(); /// @brief De-initializes the EXT2 drivers. /// @return 0 on success, 1 on error. int ext2_finalize(); + +void ext2_test(); diff --git a/mentos/src/drivers/rtc.c b/mentos/src/drivers/rtc.c index 65bfce8..6521063 100644 --- a/mentos/src/drivers/rtc.c +++ b/mentos/src/drivers/rtc.c @@ -91,12 +91,11 @@ static inline void rtc_read_datetime() } } -static inline void rtc_handler_isr(pt_regs *f) +static inline void rtc_update_datetime() { static unsigned int first_update = 1; // Wait until rtc is not updating. - while (is_updating_rtc()) - ; + while (is_updating_rtc()) {} // Read the values. rtc_read_datetime(); if (first_update) { @@ -104,8 +103,7 @@ static inline void rtc_handler_isr(pt_regs *f) // Save the previous global time. previous_global_time = global_time; // Wait until rtc is not updating. - while (is_updating_rtc()) - ; + while (is_updating_rtc()) {} // Read the values. rtc_read_datetime(); } while (!rtc_are_different(&previous_global_time, &global_time)); @@ -113,6 +111,11 @@ static inline void rtc_handler_isr(pt_regs *f) } } +static inline void rtc_handler_isr(pt_regs *f) +{ + rtc_update_datetime(); +} + void gettime(tm_t *time) { // Copy the update time. @@ -137,6 +140,8 @@ int rtc_initialize() irq_install_handler(IRQ_REAL_TIME_CLOCK, rtc_handler_isr, "Real Time Clock (RTC)"); // Enable the IRQ. pic8259_irq_enable(IRQ_REAL_TIME_CLOCK); + // Wait until rtc is ready. + rtc_update_datetime(); return 0; } diff --git a/mentos/src/fs/ext2.c b/mentos/src/fs/ext2.c index 0102d53..4da8608 100644 --- a/mentos/src/fs/ext2.c +++ b/mentos/src/fs/ext2.c @@ -526,32 +526,40 @@ static void ext2_dump_group_descriptor(ext2_group_descriptor_t *gd) /// @param inode the object to dump. static void ext2_dump_inode(ext2_inode_t *inode) { - pr_debug("mode : %u\n", inode->mode); - pr_debug("uid : %u\n", inode->uid); - pr_debug("size : %u\n", inode->size); - pr_debug("atime : %u\n", inode->atime); - pr_debug("ctime : %u\n", inode->ctime); - pr_debug("mtime : %u\n", inode->mtime); - pr_debug("dtime : %u\n", inode->dtime); - pr_debug("gid : %u\n", inode->gid); - pr_debug("links_count : %u\n", inode->links_count); - pr_debug("blocks_count : %u\n", inode->blocks_count); - pr_debug("flags : %u\n", inode->flags); - pr_debug("osd1 : %u\n", inode->osd1); - pr_debug("data : {\n"); - for (int i = 0; i < EXT2_INDIRECT_BLOCKS; ++i) - pr_debug(" data.blocks.D[%2d] : %u\n", i, inode->data.blocks.dir_blocks[i]); - pr_debug(" data.blocks.IND_B : %u\n", inode->data.blocks.indir_block); - pr_debug(" data.blocks.DBL_B : %u\n", inode->data.blocks.doubly_indir_block); - pr_debug(" data.blocks.TRB_B : %u\n", inode->data.blocks.trebly_indir_block); - pr_debug(" data.symblink : %s\n", inode->data.symlink); - pr_debug("data : }\n"); - pr_debug("generation : %u\n", inode->generation); - pr_debug("file_acl : %u\n", inode->file_acl); - pr_debug("dir_acl : %u\n", inode->dir_acl); - pr_debug("osd2[0] : %u\n", inode->osd2[0]); - pr_debug("osd2[1] : %u\n", inode->osd2[1]); - pr_debug("osd2[2] : %u\n", inode->osd2[2]); + char mask[32]; + tm_t *timeinfo; + strmode(inode->mode, mask); + pr_debug(" Size : %6u N. Blocks : %4u\n", inode->size, inode->blocks_count); + pr_debug(" Access : (%4d/%s) Uid: (%d, %s) Gid: (%d, %s)\n", inode->mode, mask, inode->uid, "None", inode->gid, "None"); + timeinfo = localtime(&inode->atime); + pr_debug(" Access : %4d-%02d-%02d %2d:%2d:%2d (%d)\n", + timeinfo->tm_year, timeinfo->tm_mon, timeinfo->tm_mday, + timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, inode->atime); + timeinfo = localtime(&inode->mtime); + pr_debug(" Modify : %4d-%02d-%02d %2d:%2d:%2d (%d)\n", + timeinfo->tm_year, timeinfo->tm_mon, timeinfo->tm_mday, + timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, inode->mtime); + timeinfo = localtime(&inode->ctime); + pr_debug(" Change : %4d-%02d-%02d %2d:%2d:%2d (%d)\n", + timeinfo->tm_year, timeinfo->tm_mon, timeinfo->tm_mday, + timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, inode->ctime); + timeinfo = localtime(&inode->dtime); + pr_debug(" Delete : %4d-%02d-%02d %2d:%2d:%2d (%d)\n", + timeinfo->tm_year, timeinfo->tm_mon, timeinfo->tm_mday, + timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, inode->dtime); + pr_debug(" Links : %2u Flags : %d\n", inode->links_count, inode->flags); + pr_debug(" Blocks : [ "); + for (int i = 0; i < EXT2_INDIRECT_BLOCKS; ++i) { + if (inode->data.blocks.dir_blocks[i]) + pr_debug("%u ", inode->data.blocks.dir_blocks[i]); + } + pr_debug("]\n"); + pr_debug("IBlocks : %u\n", inode->data.blocks.indir_block); + pr_debug("DBlocks : %u\n", inode->data.blocks.doubly_indir_block); + pr_debug("TBlocks : %u\n", inode->data.blocks.trebly_indir_block); + pr_debug("Symlink : %s\n", inode->data.symlink); + pr_debug("Generation : %u file_acl : %u dir_acl : %u\n", + inode->generation, inode->file_acl, inode->dir_acl); } /// @brief Dumps on debugging output the BGDT. @@ -1304,7 +1312,7 @@ static int ext2_allocate_inode_block(ext2_filesystem_t *fs, ext2_inode_t *inode, uint32_t blocks_count = (block_index + 1) * fs->blocks_per_block_count; if (inode->blocks_count < blocks_count) { inode->blocks_count = blocks_count; - pr_debug("Setting the block count for inode to %d = (%d blocks)", + pr_debug("Setting the block count for inode to %d = (%d blocks)\n", blocks_count, blocks_count / fs->blocks_per_block_count); } // Update the inode. @@ -1344,8 +1352,8 @@ static ssize_t ext2_read_inode_block(ext2_filesystem_t *fs, ext2_inode_t *inode, static ssize_t ext2_write_inode_block(ext2_filesystem_t *fs, ext2_inode_t *inode, uint32_t inode_index, uint32_t block_index, uint8_t *buffer) { while (block_index >= (inode->blocks_count / fs->blocks_per_block_count)) { - pr_err("Tried to read an invalid block `%d`, but inode only has %d!", - block_index, (inode->blocks_count / fs->blocks_per_block_count)); + pr_warning("Tried to read an invalid block `%d`, but inode only has %d!\n", + block_index, (inode->blocks_count / fs->blocks_per_block_count)); ext2_allocate_inode_block(fs, inode, inode_index, (inode->blocks_count / fs->blocks_per_block_count)); ext2_write_inode(fs, inode, inode_index); } @@ -1606,12 +1614,19 @@ void ext2_direntry_iterator_next(ext2_direntry_iterator_t *iterator) static inline uint32_t ext2_get_rec_len_from_name(const char *name) { - unsigned int rec_len = sizeof(ext2_dirent_t) + strlen(name); + unsigned int rec_len = sizeof(ext2_dirent_t) + strlen(name) - EXT2_NAME_LEN; rec_len += (rec_len % 4) ? (4 - (rec_len % 4)) : 0; return rec_len; } -static int ext2_allocate_direntry(ext2_filesystem_t *fs, vfs_file_t *parent, const char *name, uint32_t inode_index) +static inline uint32_t ext2_get_rec_len_from_direntry(const ext2_dirent_t *direntry) +{ + unsigned int rec_len = sizeof(ext2_dirent_t) + direntry->name_len - EXT2_NAME_LEN; + rec_len += (rec_len % 4) ? (4 - (rec_len % 4)) : 0; + return rec_len; +} + +static int ext2_allocate_direntry(ext2_filesystem_t *fs, vfs_file_t *parent, const char *name, uint32_t inode_index, uint8_t file_type) { // Get the inode associated with the file. ext2_inode_t parent_inode; @@ -1645,52 +1660,58 @@ static int ext2_allocate_direntry(ext2_filesystem_t *fs, vfs_file_t *parent, con // Iterate the directory entries. ext2_direntry_iterator_t it = ext2_direntry_iterator_begin(fs, cache, &parent_inode); for (; ext2_direntry_iterator_valid(&it); ext2_direntry_iterator_next(&it)) { - // Save the previous direntry. - previous = it.direntry; + // Compute the real rec_len of the entry. + uint32_t real_rec_len = ext2_get_rec_len_from_direntry(it.direntry); + // If the previous direntry has a wrong rec_len (wrong because it identifies the last). + if ((it.direntry->rec_len != real_rec_len) && (it.total_offset + it.direntry->rec_len == parent_inode.size)) { + // Set the previous pointer. + previous = it.direntry; + // Fix the rec_len of the entry. + it.direntry->rec_len = real_rec_len; + // Move the block offset correctly. + it.block_offset += real_rec_len; + // Move the total offset correctly. + it.total_offset += real_rec_len; + // Clean the pointer to the direntry inside the iterator. + it.direntry = NULL; + // Stop here. + break; + } // If we hit a direntry with an empty inode, that is a free direntry. if (it.direntry->inode == 0) break; } if (it.direntry) { pr_debug("We need to replace the direntry: %p\n", it.direntry); - } else { - if ((it.block_offset + rec_len) >= fs->block_size) { - pr_debug("We need a new direntry, and a new block.\n"); - it.block_index += 1; - if (ext2_allocate_inode_block(fs, &parent_inode, parent->ino, it.block_index) == -1) { - pr_err("Failed to allocate a new block for an inode.\n"); - // Free the cache. - kmem_cache_free(cache); - return -1; - } - it.block_offset = 0; - parent_inode.size += fs->block_size; - if (ext2_write_inode(fs, &parent_inode, parent->ino) == -1) { - pr_err("Failed to update the inode of the father directory.\n"); - // Free the cache. - kmem_cache_free(cache); - return -1; - } - } else { - pr_debug("We need a new direntry, from the same block.\n"); - if (previous == NULL) { - pr_err("Previous direntry is NULL!\n"); - } else { - unsigned int sreclen = previous->name_len + sizeof(ext2_dirent_t); - sreclen += (sreclen % 4) ? (4 - (sreclen % 4)) : 0; - previous->rec_len = sreclen; - } + } else if ((it.block_offset + rec_len) >= fs->block_size) { + pr_debug("We need a new direntry, and a new block (%d + %d >= %d).\n", it.block_offset, rec_len, fs->block_size); + it.block_index += 1; + if (ext2_allocate_inode_block(fs, &parent_inode, parent->ino, it.block_index) == -1) { + pr_err("Failed to allocate a new block for an inode.\n"); + // Free the cache. + kmem_cache_free(cache); + return -1; } + it.block_offset = 0; + parent_inode.size += fs->block_size; + if (ext2_write_inode(fs, &parent_inode, parent->ino) == -1) { + pr_err("Failed to update the inode of the father directory.\n"); + // Free the cache. + kmem_cache_free(cache); + return -1; + } + } else if (previous) { + pr_debug("We need a new direntry, from the same block (after \"%s\").\n", previous->name); } - pr_debug(" total_offset = 0x%x\n", it.total_offset); - pr_debug(" block_offset = 0x%x\n", it.block_offset); + pr_debug(" total_offset = %d\n", it.total_offset); + pr_debug(" block_offset = %d\n", it.block_offset); ext2_dirent_t *new_direntry = (ext2_dirent_t *)((uintptr_t)cache + it.block_offset); new_direntry->inode = inode_index; new_direntry->rec_len = fs->block_size - it.block_offset; new_direntry->name_len = strlen(name); - new_direntry->file_type = ext2_file_type_regular_file; + new_direntry->file_type = file_type; memcpy(new_direntry->name, name, strlen(name)); if (ext2_write_inode_block(fs, &parent_inode, parent->ino, it.block_index, cache) == -1) { @@ -1728,16 +1749,21 @@ static int ext2_find_direntry(ext2_filesystem_t *fs, ino_t ino, const char *name return -1; } pr_debug("ext2_find_direntry(ino: %d, name: \"%s\")\n", ino, name); - // Allocate the cache. - uint8_t *cache = kmem_cache_alloc(fs->ext2_buffer_cache, GFP_KERNEL); - // Clean the cache. - memset(cache, 0, fs->block_size); // Get the inode associated with the file. ext2_inode_t inode; if (ext2_read_inode(fs, &inode, ino) == -1) { pr_err("Failed to read the inode (%d).\n", ino); - goto free_cache_return_error; + return -1; } + // Check that the parent is a directory. + if (!bitmask_check(inode.mode, EXT2_S_IFDIR)) { + pr_err("The parent inode is not a directory (ino: %d, mode: %d).\n", ino, inode.mode); + return -1; + } + // Allocate the cache. + uint8_t *cache = kmem_cache_alloc(fs->ext2_buffer_cache, GFP_KERNEL); + // Clean the cache. + memset(cache, 0, fs->block_size); ext2_direntry_iterator_t it = ext2_direntry_iterator_begin(fs, cache, &inode); for (; ext2_direntry_iterator_valid(&it); ext2_direntry_iterator_next(&it)) { // Chehck the name. @@ -1774,6 +1800,18 @@ free_cache_return_error: return -1; } +/// @brief Finds the entry with the given `name` inside the `directory`. +/// @param directory the directory in which we perform the search. +/// @param name the name of the entry we are looking for. +/// @param search the output variable where we save the info about the entry. +/// @return 0 on success, -1 on failure. +static int ext2_find_direntry_simple(ext2_filesystem_t *fs, ino_t ino, const char *name, ext2_dirent_t *direntry) +{ + // Prepare the structure for the search. + ext2_direntry_search_t search = { .direntry = direntry, .block_index = 0, .block_offset = 0, .parent_inode = 0 }; + return ext2_find_direntry(fs, ino, name, &search); +} + /// @brief Searches the entry specified in `path` starting from `directory`. /// @param directory the directory from which we start performing the search. /// @param path the path of the entry we are looking for, it cna be a relative path. @@ -1973,7 +2011,11 @@ static vfs_file_t *ext2_find_vfs_file_with_inode(ext2_filesystem_t *fs, ino_t in /// @param inode the inode we use to initialize the root of the filesystem. /// @param preferred_group the preferred group where the inode should be allocated. /// @return the inode index on success, -1 on failure. -static int ext2_create_inode(ext2_filesystem_t *fs, ext2_inode_t *inode, uint32_t preferred_group) +static int ext2_create_inode( + ext2_filesystem_t *fs, + ext2_inode_t *inode, + mode_t mode, + uint32_t preferred_group) { if (fs == NULL) { pr_err("Received a null EXT2 filesystem.\n"); @@ -2001,6 +2043,8 @@ static int ext2_create_inode(ext2_filesystem_t *fs, ext2_inode_t *inode, uint32_ pr_err("Failed to read the newly created inode.\n"); return -1; } + // Set the inode mode. + inode->mode = mode; // Set the user identifiers of the owners. inode->uid = task->uid; // Set the size of the file in bytes. @@ -2043,25 +2087,55 @@ static int ext2_create_inode(ext2_filesystem_t *fs, ext2_inode_t *inode, uint32_ return inode_index; } -static vfs_file_t *ext2_creat(vfs_file_t *parent, const char *name, mode_t mode) +static vfs_file_t *ext2_creat(vfs_file_t *parent, const char *name, mode_t permission) { + // flags = O_WRONLY | O_CREAT | O_TRUNC // Get the filesystem. ext2_filesystem_t *fs = (ext2_filesystem_t *)parent->device; if (fs == NULL) { pr_err("The parent does not belong to an EXT2 filesystem `%s`.\n", parent->name); return NULL; } + // Prepare the structure for the direntry. + ext2_dirent_t direntry; + // Prepare an inode, it will come in handy either way. + ext2_inode_t inode; + // Search if the entry already exists. + if (!ext2_find_direntry_simple(fs, parent->ino, name, &direntry)) { + if (ext2_read_inode(fs, &inode, direntry.inode) == -1) { + pr_err("Failed to read the inode of `%s`.\n", direntry.name); + return NULL; + } + vfs_file_t *file = ext2_find_vfs_file_with_inode(fs, direntry.inode); + if (file == NULL) { + // Allocate the memory for the file. + file = kmem_cache_alloc(vfs_file_cache, GFP_KERNEL); + if (file == NULL) { + pr_err("Failed to allocate memory for the EXT2 file.\n"); + return NULL; + } + if (ext2_init_vfs_file(fs, file, &inode, direntry.inode, direntry.name, direntry.name_len) == -1) { + pr_err("Failed to properly set the VFS file.\n"); + return NULL; + } + // Add the vfs_file to the list of associated files. + list_head_add_tail(&file->siblings, &fs->opened_files); + } + return file; + } + // Set the inode mode. + uint32_t mode = EXT2_S_IFREG; + mode |= 0xFFF & permission; // Get the group index of the parent. uint32_t group_index = ext2_get_group_index_from_inode(fs, parent->ino); // Create and initialize the new inode. - ext2_inode_t inode; - int inode_index = ext2_create_inode(fs, &inode, group_index); + int inode_index = ext2_create_inode(fs, &inode, mode, group_index); if (inode_index == -1) { pr_err("Failed to create a new inode inside `%s` (group index: %d).\n", parent->name, group_index); return NULL; } // Initialize the file. - if (ext2_allocate_direntry(fs, parent, name, inode_index) == -1) { + if (ext2_allocate_direntry(fs, parent, name, inode_index, ext2_file_type_regular_file) == -1) { pr_err("Failed to allocate a new direntry for the inode.\n"); return NULL; } @@ -2474,9 +2548,103 @@ static int ext2_getdents(vfs_file_t *file, dirent_t *dirp, off_t doff, size_t co return written; } -static int ext2_mkdir(const char *path, mode_t mode) +static int ext2_mkdir(const char *path, mode_t permission) { - return -1; + pr_debug("ext2_mkdir(%s, %d)\n", path, permission); + // Get the absolute path. + char absolute_path[PATH_MAX]; + // If the first character is not the '/' then get the absolute path. + if (!realpath(path, absolute_path)) { + pr_err("Cannot get the absolute path for path `%s`.\n", path); + return -ENOENT; + } + // Get the EXT2 filesystem. + ext2_filesystem_t *fs = get_ext2_filesystem(absolute_path); + if (fs == NULL) { + pr_err("Failed to get the EXT2 filesystem for absolute path `%s`.\n", absolute_path); + return -ENOENT; + } + // Prepare the structure for the direntry. + ext2_dirent_t direntry; + memset(&direntry, 0, sizeof(ext2_dirent_t)); + // Prepare an inode, it will come in handy either way. + ext2_inode_t inode; + // Search if the entry already exists. + if (!ext2_resolve_path_direntry(fs->root, absolute_path, &direntry)) { + // Get the associated inode. + if (ext2_read_inode(fs, &inode, direntry.inode) == -1) { + pr_err("Failed to read the inode of `%s`.\n", direntry.name); + return -ENOENT; + } + // Create a VFS file. + vfs_file_t *file = ext2_find_vfs_file_with_inode(fs, direntry.inode); + if (file == NULL) { + // Allocate the memory for the file. + file = kmem_cache_alloc(vfs_file_cache, GFP_KERNEL); + if (file == NULL) { + pr_err("Failed to allocate memory for the EXT2 file.\n"); + return -ENOMEM; + } + if (ext2_init_vfs_file(fs, file, &inode, direntry.inode, direntry.name, direntry.name_len) == -1) { + pr_err("Failed to properly set the VFS file.\n"); + return -ENOENT; + } + // Add the vfs_file to the list of associated files. + list_head_add_tail(&file->siblings, &fs->opened_files); + } + ext2_close(file); + return 0; + } + // Get the parent directory. + char *parent_path = dirname(path); + if (strcmp(parent_path, path) == 0) { + pr_err("Failed to properly get the parent directory (%s == %s).\n", parent_path, path); + return -ENOENT; + } + // Get the parent VFS node. + vfs_file_t *parent = ext2_open(parent_path, O_RDONLY, 0); + if (parent == NULL) { + pr_err("Failed to open parent directory (%s).\n", parent_path); + return -ENOENT; + } + // Set the inode mode. + uint32_t mode = EXT2_S_IFDIR; + mode |= 0xFFF & permission; + // Get the group index of the parent. + uint32_t group_index = ext2_get_group_index_from_inode(fs, parent->ino); + // Create and initialize the new inode. + int inode_index = ext2_create_inode(fs, &inode, mode, group_index); + if (inode_index == -1) { + pr_err("Failed to create a new inode inside `%s` (group index: %d).\n", parent->name, group_index); + // Close the parent directory. + ext2_close(parent); + return -ENOENT; + } + // Initialize the file. + if (ext2_allocate_direntry(fs, parent, basename(path), inode_index, ext2_file_type_directory) == -1) { + pr_err("Failed to allocate a new direntry for the inode.\n"); + // Close the parent directory. + ext2_close(parent); + return -ENOENT; + } + // Allocate the memory for the file. + vfs_file_t *new_file = kmem_cache_alloc(vfs_file_cache, GFP_KERNEL); + if (new_file == NULL) { + pr_err("Failed to allocate memory for the EXT2 file.\n"); + // Close the parent directory. + ext2_close(parent); + return -ENOMEM; + } + if (ext2_init_vfs_file(fs, new_file, &inode, inode_index, basename(path), strlen(basename(path))) == -1) { + pr_err("Failed to properly set the VFS file.\n"); + // Close the parent directory. + ext2_close(parent); + return -ENOENT; + } + // Close the parent directory. + ext2_close(parent); + ext2_close(new_file); + return 0; } static int ext2_rmdir(const char *path) @@ -2722,4 +2890,83 @@ int ext2_finalize(void) { vfs_unregister_filesystem(&ext2_file_system_type); return 0; +} + +#include "assert.h" + +void dump_dir(vfs_file_t *dir) +{ + ext2_filesystem_t *fs = (ext2_filesystem_t *)dir->device; + // Check the filesystem. + if (fs == NULL) { + pr_err("The directory does not belong to an EXT2 filesystem `%s`.\n", dir->name); + return; + } + // Check the magic number. + if (fs->superblock.magic != EXT2_SUPERBLOCK_MAGIC) { + pr_err("The directory does not belong to an EXT2 filesystem `%s`.\n", dir->name); + return; + } + // Get the inode associated with the directory. + ext2_inode_t inode; + if (ext2_read_inode(fs, &inode, dir->ino) == -1) { + pr_err("Failed to read the inode (%d).\n", dir->ino); + return; + } + // Allocate the cache. + uint8_t *cache = kmem_cache_alloc(fs->ext2_buffer_cache, GFP_KERNEL); + // Clean the cache. + memset(cache, 0, fs->block_size); + // Iterate the directory. + ext2_direntry_iterator_t it = ext2_direntry_iterator_begin(fs, cache, &inode); + for (; ext2_direntry_iterator_valid(&it); ext2_direntry_iterator_next(&it)) { + ext2_inode_t __inode; + if (ext2_read_inode(fs, &__inode, it.direntry->inode) == -1) { + pr_err("Failed to read the inode (%d).\n", it.direntry->inode); + } + pr_debug("name: %12s inode: %4d file_type: %2d rec_len: %d name_len: %d (realRL: %d, block: %d, total: %d)\n", + it.direntry->name, + it.direntry->inode, + it.direntry->file_type, + it.direntry->rec_len, + it.direntry->name_len, + ext2_get_rec_len_from_direntry(it.direntry), + it.block_offset, + it.total_offset); + ext2_dump_inode(&__inode); + pr_debug("\n"); + } + kmem_cache_free(cache); +} + +void ext2_test() +{ + vfs_file_t *home = ext2_open("/home", O_RDONLY, 0); + assert(home && "Failed to read home."); + + dump_dir(home); + + vfs_file_t *test1 = ext2_creat(home, "test1.txt", EXT2_S_IWUSR | EXT2_S_IRUSR | EXT2_S_IRGRP | EXT2_S_IROTH); + assert(test1 && "Failed to create test1.txt."); + vfs_file_t *test2 = ext2_creat(home, "test2.txt", EXT2_S_IWUSR | EXT2_S_IRUSR | EXT2_S_IRGRP | EXT2_S_IROTH); + assert(test2 && "Failed to create test2.txt."); + vfs_file_t *test3 = ext2_creat(home, "test3.txt", EXT2_S_IWUSR | EXT2_S_IRUSR | EXT2_S_IRGRP | EXT2_S_IROTH); + assert(test3 && "Failed to create test3.txt."); + + char buffer[256]; + memset(buffer, 0, 256); + for (int i = 0; i < 256; ++i) { + buffer[i] = '0' + (i % 9); + } + buffer[255] = 0; + + dump_dir(home); + + ext2_write(test1, buffer, 0, 256); + ext2_write(test2, buffer, 0, 256); + ext2_write(test3, buffer, 0, 256); + + dump_dir(home); + + ext2_mkdir("/home/pippo", EXT2_S_IRWXU | EXT2_S_IRGRP | EXT2_S_IXGRP | EXT2_S_IROTH | EXT2_S_IXOTH); } \ No newline at end of file diff --git a/mentos/src/kernel.c b/mentos/src/kernel.c index 403377b..10d568d 100644 --- a/mentos/src/kernel.c +++ b/mentos/src/kernel.c @@ -350,15 +350,7 @@ int kmain(boot_info_t *boot_informations) } print_ok(); - vfs_file_t *file1 = vfs_open("/home/test4.txt", O_CREAT | O_EXCL, 0); - char buffer[512]; - for (int i = 0; i < 512; ++i) { - buffer[i] = '0' + (i % 9); - } - vfs_write(file1, buffer, 0, 512); - vfs_close(file1); - - while (true) {} + //ext2_test(); // We have completed the booting procedure. pr_notice("Booting done, jumping into init process.\n");