1
Fork 0
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:
Jesse Buhagiar 2019-08-11 23:56:39 +10:00 committed by Andreas Kling
parent f7251c74a9
commit bc22456f89
13 changed files with 98 additions and 3 deletions

View file

@ -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;
}

View file

@ -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;

View file

@ -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);

View file

@ -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) {

View file

@ -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;