mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 06:47:35 +00:00
Kernel: Added unmount ability to VFS
It is now possible to unmount file systems from the VFS via `umount`. It works via looking up the `fsid` of the filesystem from the `Inode`'s metatdata so I'm not sure how fragile it is. It seems to work for now though as something to get us going.
This commit is contained in:
parent
f7251c74a9
commit
bc22456f89
13 changed files with 98 additions and 3 deletions
|
@ -1395,3 +1395,16 @@ unsigned Ext2FS::free_inode_count() const
|
|||
LOCKER(m_lock);
|
||||
return super_block().s_free_inodes_count;
|
||||
}
|
||||
|
||||
KResult Ext2FS::prepare_to_unmount() const
|
||||
{
|
||||
LOCKER(m_lock); // Acquire lock for this FS
|
||||
for (auto it = m_inode_cache.begin(); it != m_inode_cache.end(); ++it) {
|
||||
if (it->value.ptr()->ref_count() > 1)
|
||||
return KResult(-EBUSY);
|
||||
}
|
||||
|
||||
dbg() << "here!";
|
||||
m_inode_cache.clear();
|
||||
return KSuccess;
|
||||
}
|
||||
|
|
|
@ -69,6 +69,8 @@ public:
|
|||
virtual unsigned total_inode_count() const override;
|
||||
virtual unsigned free_inode_count() const override;
|
||||
|
||||
virtual KResult prepare_to_unmount() const override;
|
||||
|
||||
private:
|
||||
typedef unsigned BlockIndex;
|
||||
typedef unsigned GroupIndex;
|
||||
|
|
|
@ -8,8 +8,8 @@
|
|||
#include <AK/Function.h>
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/OwnPtr.h>
|
||||
#include <AK/RefPtr.h>
|
||||
#include <AK/RefCounted.h>
|
||||
#include <AK/RefPtr.h>
|
||||
#include <AK/WeakPtr.h>
|
||||
#include <AK/kstdio.h>
|
||||
#include <Kernel/Devices/DiskDevice.h>
|
||||
|
@ -45,6 +45,8 @@ public:
|
|||
virtual unsigned total_inode_count() const { return 0; }
|
||||
virtual unsigned free_inode_count() const { return 0; }
|
||||
|
||||
virtual KResult prepare_to_unmount() const { return KSuccess; }
|
||||
|
||||
struct DirectoryEntry {
|
||||
DirectoryEntry(const char* name, InodeIdentifier, u8 file_type);
|
||||
DirectoryEntry(const char* name, int name_length, InodeIdentifier, u8 file_type);
|
||||
|
|
|
@ -49,6 +49,7 @@ KResult VFS::mount(NonnullRefPtr<FS>&& file_system, Custody& mount_point)
|
|||
|
||||
KResult VFS::mount(NonnullRefPtr<FS>&& file_system, StringView path)
|
||||
{
|
||||
LOCKER(m_lock);
|
||||
auto result = resolve_path(path, root_custody());
|
||||
if (result.is_error()) {
|
||||
dbg() << "VFS: mount can't resolve mount point '" << path << "'";
|
||||
|
@ -57,6 +58,28 @@ KResult VFS::mount(NonnullRefPtr<FS>&& file_system, StringView path)
|
|||
return mount(move(file_system), result.value());
|
||||
}
|
||||
|
||||
KResult VFS::unmount(NonnullRefPtr<FS>&& file_system)
|
||||
{
|
||||
LOCKER(m_lock);
|
||||
dbg() << "VFS: unmount called with fsid " << file_system.ptr()->fsid();
|
||||
|
||||
for (auto i = 0; i < m_mounts.size(); i++) {
|
||||
auto mount = m_mounts.at(i);
|
||||
if (mount.guest_fs().fsid() == file_system.ptr()->fsid()) {
|
||||
if (mount.guest_fs().prepare_to_unmount() != KSuccess) {
|
||||
dbg() << "VFS: Failed to unmount! Device busy";
|
||||
return KResult(-EBUSY);
|
||||
}
|
||||
dbg() << "VFS: found fs " << file_system.ptr()->fsid() << " at mount " << i << "! Unmounting...";
|
||||
m_mounts.remove(i);
|
||||
return KSuccess;
|
||||
}
|
||||
}
|
||||
|
||||
dbg() << "VFS: unmount unable to find fsid in m_mounts!";
|
||||
return KResult(-ENODEV);
|
||||
}
|
||||
|
||||
bool VFS::mount_root(NonnullRefPtr<FS>&& file_system)
|
||||
{
|
||||
if (m_root_inode) {
|
||||
|
|
|
@ -59,6 +59,7 @@ public:
|
|||
bool mount_root(NonnullRefPtr<FS>&&);
|
||||
KResult mount(NonnullRefPtr<FS>&&, StringView path);
|
||||
KResult mount(NonnullRefPtr<FS>&&, Custody& mount_point);
|
||||
KResult unmount(NonnullRefPtr<FS>&&);
|
||||
|
||||
KResultOr<NonnullRefPtr<FileDescription>> open(StringView path, int options, mode_t mode, Custody& base);
|
||||
KResultOr<NonnullRefPtr<FileDescription>> create(StringView path, int options, mode_t mode, Custody& parent_custody);
|
||||
|
@ -105,6 +106,8 @@ private:
|
|||
Mount* find_mount_for_host(InodeIdentifier);
|
||||
Mount* find_mount_for_guest(InodeIdentifier);
|
||||
|
||||
Lock m_lock { "VFSLock" };
|
||||
|
||||
RefPtr<Inode> m_root_inode;
|
||||
NonnullOwnPtrVector<Mount> m_mounts;
|
||||
HashMap<u32, Device*> m_devices;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue