forked from Bananymous/banan-os
Kernel: TmpFS directory inodes now iterate over only valid entries
This commit is contained in:
parent
438f01a856
commit
3e33fc156b
|
@ -12,7 +12,7 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
|
|
||||||
template<typename F>
|
template<typename F>
|
||||||
concept for_each_entry_callback = requires(F func, const TmpDirectoryEntry& entry)
|
concept for_each_valid_entry_callback = requires(F func, TmpDirectoryEntry& entry)
|
||||||
{
|
{
|
||||||
requires BAN::is_same_v<decltype(func(entry)), BAN::Iteration>;
|
requires BAN::is_same_v<decltype(func(entry)), BAN::Iteration>;
|
||||||
};
|
};
|
||||||
|
@ -107,8 +107,8 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<void> link_inode(TmpInode&, BAN::StringView);
|
BAN::ErrorOr<void> link_inode(TmpInode&, BAN::StringView);
|
||||||
|
|
||||||
template<TmpFuncs::for_each_entry_callback F>
|
template<TmpFuncs::for_each_valid_entry_callback F>
|
||||||
void for_each_entry(F callback);
|
void for_each_valid_entry(F callback);
|
||||||
|
|
||||||
friend class TmpInode;
|
friend class TmpInode;
|
||||||
};
|
};
|
||||||
|
|
|
@ -260,9 +260,7 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
ino_t result = 0;
|
ino_t result = 0;
|
||||||
|
|
||||||
for_each_entry([&](const TmpDirectoryEntry& entry) {
|
for_each_valid_entry([&](TmpDirectoryEntry& entry) {
|
||||||
if (entry.type == DT_UNKNOWN)
|
|
||||||
return BAN::Iteration::Continue;
|
|
||||||
if (entry.name_sv() != name)
|
if (entry.name_sv() != name)
|
||||||
return BAN::Iteration::Continue;
|
return BAN::Iteration::Continue;
|
||||||
result = entry.ino;
|
result = entry.ino;
|
||||||
|
@ -339,7 +337,35 @@ namespace Kernel
|
||||||
|
|
||||||
BAN::ErrorOr<void> TmpDirectoryInode::unlink_impl(BAN::StringView)
|
BAN::ErrorOr<void> TmpDirectoryInode::unlink_impl(BAN::StringView)
|
||||||
{
|
{
|
||||||
return BAN::Error::from_errno(ENOTSUP);
|
ino_t entry_ino = 0;
|
||||||
|
|
||||||
|
for_each_valid_entry([&](TmpDirectoryEntry& entry) {
|
||||||
|
if (entry.name_sv() != name)
|
||||||
|
return BAN::Iteration::Continue;
|
||||||
|
|
||||||
|
// get ino of entry
|
||||||
|
entry_ino = entry.ino;
|
||||||
|
|
||||||
|
// invalidate the entry
|
||||||
|
entry.ino = 0;
|
||||||
|
entry.type = DT_UNKNOWN;
|
||||||
|
|
||||||
|
return BAN::Iteration::Break;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (entry_ino == 0)
|
||||||
|
return BAN::Error::from_errno(ENOENT);
|
||||||
|
|
||||||
|
// FIXME: this should be able to fail
|
||||||
|
auto inode = MUST(m_fs.open_inode(entry_ino));
|
||||||
|
|
||||||
|
ASSERT(inode->nlink() > 0);
|
||||||
|
inode->m_inode_info.nlink--;
|
||||||
|
|
||||||
|
if (inode->nlink() == 0 || (inode->mode().ifdir() && inode->nlink() <= 2))
|
||||||
|
m_fs.remove_from_cache(inode);
|
||||||
|
|
||||||
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::ErrorOr<void> TmpDirectoryInode::link_inode(TmpInode& inode, BAN::StringView name)
|
BAN::ErrorOr<void> TmpDirectoryInode::link_inode(TmpInode& inode, BAN::StringView name)
|
||||||
|
@ -391,8 +417,8 @@ namespace Kernel
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
template<TmpFuncs::for_each_entry_callback F>
|
template<TmpFuncs::for_each_valid_entry_callback F>
|
||||||
void TmpDirectoryInode::for_each_entry(F callback)
|
void TmpDirectoryInode::for_each_valid_entry(F callback)
|
||||||
{
|
{
|
||||||
bool done = false;
|
bool done = false;
|
||||||
for (size_t data_block_index = 0; !done && data_block_index * blksize() < (size_t)size(); data_block_index++)
|
for (size_t data_block_index = 0; !done && data_block_index * blksize() < (size_t)size(); data_block_index++)
|
||||||
|
@ -405,6 +431,8 @@ namespace Kernel
|
||||||
while (bytespan.size() > 0)
|
while (bytespan.size() > 0)
|
||||||
{
|
{
|
||||||
auto& entry = bytespan.as<TmpDirectoryEntry>();
|
auto& entry = bytespan.as<TmpDirectoryEntry>();
|
||||||
|
if (entry.type != DT_UNKNOWN)
|
||||||
|
{
|
||||||
switch (callback(entry))
|
switch (callback(entry))
|
||||||
{
|
{
|
||||||
case BAN::Iteration::Continue:
|
case BAN::Iteration::Continue:
|
||||||
|
@ -415,6 +443,7 @@ namespace Kernel
|
||||||
default:
|
default:
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
bytespan = bytespan.slice(entry.rec_len);
|
bytespan = bytespan.slice(entry.rec_len);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue