diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-06-09 12:46:23 +0200 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-06-09 12:46:23 +0200 |
commit | 6873e7d01628eb2e8a850b0caebfeb6c1fd373db (patch) | |
tree | 81ca697bcfb0d35d071ebae99aaaf9dfef7fba61 /Kernel | |
parent | 3bc699a336190981afec80d9da47f6b4ab8e5b3a (diff) | |
download | serenity-6873e7d01628eb2e8a850b0caebfeb6c1fd373db.zip |
Ext2FS: Move directory writing logic into Ext2FSInode.
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/FileSystem/Ext2FileSystem.cpp | 109 | ||||
-rw-r--r-- | Kernel/FileSystem/Ext2FileSystem.h | 3 |
2 files changed, 56 insertions, 56 deletions
diff --git a/Kernel/FileSystem/Ext2FileSystem.cpp b/Kernel/FileSystem/Ext2FileSystem.cpp index 753863dcd5..c1c07963a9 100644 --- a/Kernel/FileSystem/Ext2FileSystem.cpp +++ b/Kernel/FileSystem/Ext2FileSystem.cpp @@ -704,6 +704,57 @@ bool Ext2FSInode::traverse_as_directory(Function<bool(const FS::DirectoryEntry&) return true; } +bool Ext2FSInode::write_directory(const Vector<FS::DirectoryEntry>& entries) +{ + LOCKER(m_lock); + dbgprintf("Ext2FS: New directory inode %u contents to write:\n", index()); + + int directory_size = 0; + for (auto& entry : entries) { + //kprintf(" - %08u %s\n", entry.inode.index(), entry.name); + directory_size += EXT2_DIR_REC_LEN(entry.name_length); + } + + auto block_size = fs().block_size(); + + int blocks_needed = ceil_div(directory_size, block_size); + int occupied_size = blocks_needed * block_size; + + dbgprintf("Ext2FS: directory size: %u (occupied: %u)\n", directory_size, occupied_size); + + auto directory_data = ByteBuffer::create_uninitialized(occupied_size); + + BufferStream stream(directory_data); + for (int i = 0; i < entries.size(); ++i) { + auto& entry = entries[i]; + + int record_length = EXT2_DIR_REC_LEN(entry.name_length); + if (i == entries.size() - 1) + record_length += occupied_size - directory_size; + + dbgprintf("* inode: %u", entry.inode.index()); + dbgprintf(", name_len: %u", word(entry.name_length)); + dbgprintf(", rec_len: %u", word(record_length)); + dbgprintf(", file_type: %u", byte(entry.file_type)); + dbgprintf(", name: %s\n", entry.name); + + stream << dword(entry.inode.index()); + stream << word(record_length); + stream << byte(entry.name_length); + stream << byte(entry.file_type); + stream << entry.name; + + int padding = record_length - entry.name_length - 8; + for (int j = 0; j < padding; ++j) + stream << byte(0); + } + + stream.fill_to_end(0); + + ssize_t nwritten = write_bytes(0, directory_data.size(), directory_data.pointer(), nullptr); + return nwritten == directory_data.size(); +} + KResult Ext2FSInode::add_child(InodeIdentifier child_id, const StringView& name, mode_t mode) { LOCKER(m_lock); @@ -733,7 +784,7 @@ KResult Ext2FSInode::add_child(InodeIdentifier child_id, const StringView& name, child_inode->increment_link_count(); entries.append({ name.characters(), name.length(), child_id, to_ext2_file_type(mode) }); - bool success = fs().write_directory_inode(index(), move(entries)); + bool success = write_directory(entries); if (success) m_lookup_cache.set(name, child_id.index()); return KSuccess; @@ -766,9 +817,9 @@ KResult Ext2FSInode::remove_child(const StringView& name) return true; }); - bool success = fs().write_directory_inode(index(), move(entries)); + bool success = write_directory(entries); if (!success) { - // FIXME: Plumb error from write_directory_inode(). + // FIXME: Plumb error from write_directory(). return KResult(-EIO); } @@ -779,56 +830,6 @@ KResult Ext2FSInode::remove_child(const StringView& name) return KSuccess; } -bool Ext2FS::write_directory_inode(InodeIndex directory_inode_index, Vector<DirectoryEntry>&& entries) -{ - LOCKER(m_lock); - dbgprintf("Ext2FS: New directory inode %u contents to write:\n", directory_inode_index); - - int directory_size = 0; - for (auto& entry : entries) { - //kprintf(" - %08u %s\n", entry.inode.index(), entry.name); - directory_size += EXT2_DIR_REC_LEN(entry.name_length); - } - - int blocks_needed = ceil_div(directory_size, block_size()); - int occupied_size = blocks_needed * block_size(); - - dbgprintf("Ext2FS: directory size: %u (occupied: %u)\n", directory_size, occupied_size); - - auto directory_data = ByteBuffer::create_uninitialized(occupied_size); - - BufferStream stream(directory_data); - for (int i = 0; i < entries.size(); ++i) { - auto& entry = entries[i]; - - int record_length = EXT2_DIR_REC_LEN(entry.name_length); - if (i == entries.size() - 1) - record_length += occupied_size - directory_size; - - dbgprintf("* inode: %u", entry.inode.index()); - dbgprintf(", name_len: %u", word(entry.name_length)); - dbgprintf(", rec_len: %u", word(record_length)); - dbgprintf(", file_type: %u", byte(entry.file_type)); - dbgprintf(", name: %s\n", entry.name); - - stream << dword(entry.inode.index()); - stream << word(record_length); - stream << byte(entry.name_length); - stream << byte(entry.file_type); - stream << entry.name; - - int padding = record_length - entry.name_length - 8; - for (int j = 0; j < padding; ++j) - stream << byte(0); - } - - stream.fill_to_end(0); - - auto directory_inode = get_inode({ fsid(), directory_inode_index }); - ssize_t nwritten = directory_inode->write_bytes(0, directory_data.size(), directory_data.pointer(), nullptr); - return nwritten == directory_data.size(); -} - unsigned Ext2FS::inodes_per_block() const { return EXT2_INODES_PER_BLOCK(&super_block()); @@ -1106,7 +1107,7 @@ RetainPtr<Inode> Ext2FS::create_directory(InodeIdentifier parent_id, const Strin entries.append({ ".", inode->identifier(), EXT2_FT_DIR }); entries.append({ "..", parent_id, EXT2_FT_DIR }); - bool success = write_directory_inode(inode->identifier().index(), move(entries)); + bool success = static_cast<Ext2FSInode&>(*inode).write_directory(entries); ASSERT(success); auto parent_inode = get_inode(parent_id); diff --git a/Kernel/FileSystem/Ext2FileSystem.h b/Kernel/FileSystem/Ext2FileSystem.h index ac7fff9946..ead3e9ec62 100644 --- a/Kernel/FileSystem/Ext2FileSystem.h +++ b/Kernel/FileSystem/Ext2FileSystem.h @@ -43,6 +43,7 @@ private: virtual KResult chown(uid_t, gid_t) override; virtual KResult truncate(off_t) override; + bool write_directory(const Vector<FS::DirectoryEntry>&); void populate_lookup_cache() const; bool resize(qword); @@ -103,8 +104,6 @@ private: Vector<BlockIndex> block_list_for_inode(const ext2_inode&, bool include_block_list_blocks = false) const; bool write_block_list_for_inode(InodeIndex, ext2_inode&, const Vector<BlockIndex>&); - bool add_inode_to_directory(InodeIndex parent, InodeIndex child, const String& name, byte file_type, int& error); - bool write_directory_inode(InodeIndex, Vector<DirectoryEntry>&&); bool get_inode_allocation_state(InodeIndex) const; bool set_inode_allocation_state(InodeIndex, bool); bool set_block_allocation_state(BlockIndex, bool); |