2#include "pedigree/kernel/LockGuard.h"
3#include "pedigree/kernel/machine/Disk.h"
4#include "pedigree/kernel/syscallError.h"
5#include "pedigree/kernel/utilities/Vector.h"
6#include "pedigree/kernel/utilities/utility.h"
8#include "Ext2Filesystem.h"
11uint32_t Ext2Filesystem::findFreeInode(uint32_t uid, uint32_t gid) {
12#if THREADS || defined(STANDALONE_MUTEXES)
15 const uint32_t perGroup = LITTLE_TO_HOST32(
m_pSuperblock->s_inodes_per_group);
16 const uint32_t total = LITTLE_TO_HOST32(
m_pSuperblock->s_inodes_count);
19 if (!LITTLE_TO_HOST16(descriptor->bg_free_inodes_count)) {
22 if (!ensureFreeInodeBitmapLoaded(group)) {
26 for (uint32_t index = 0; index < perGroup; ++index) {
27 const uint64_t number =
static_cast<uint64_t
>(group) * perGroup + index + 1;
28 if (number > 0xffffffffULL || (total && number > total)) {
32 auto*
byte =
reinterpret_cast<uint8_t*
>(bitmap[field] + (index / 8) %
m_BlockSize);
33 const uint8_t bit = 1U << (index % 8);
37 Inode* inode = getInode(
static_cast<uint32_t
>(number));
41 const uint32_t generation = LITTLE_TO_HOST32(inode->i_generation);
42 if (generation == 0xffffffffU) {
50 if (!quotaSucceeded(m_Quota.create(
static_cast<uint32_t
>(number), uid, gid)))
53 Ext2Owner::setUid(*inode, uid);
54 Ext2Owner::setGid(*inode, gid);
55 inode->i_generation = HOST_TO_LITTLE32(generation + 1);
56 writeInode(
static_cast<uint32_t
>(number));
58 descriptor->bg_free_inodes_count =
59 HOST_TO_LITTLE16(LITTLE_TO_HOST16(descriptor->bg_free_inodes_count) - 1);
61 HOST_TO_LITTLE32(LITTLE_TO_HOST32(
m_pSuperblock->s_free_inodes_count) - 1);
63 writeBlock(LITTLE_TO_HOST32(descriptor->bg_inode_bitmap) + field);
64 const uint32_t descriptors = LITTLE_TO_HOST32(
m_pSuperblock->s_first_data_block) + 1;
66 return static_cast<uint32_t
>(number);
69 SYSCALL_ERROR(NoSpaceLeftOnDevice);
virtual void write(uint64_t location)
size_t m_nGroupDescriptors
GroupDesc ** m_pGroupDescriptors
void writeBlock(uint32_t block)
Vector< size_t > * m_pInodeBitmaps
Superblock * m_pSuperblock
A vector / dynamic array.