diff --git a/src/core/file_sys/vfs.cpp b/src/core/file_sys/vfs.cpp
index 7b584de7fd..e33327ef03 100644
--- a/src/core/file_sys/vfs.cpp
+++ b/src/core/file_sys/vfs.cpp
@@ -384,6 +384,28 @@ bool VfsDirectory::DeleteSubdirectoryRecursive(std::string_view name) {
     return success;
 }
 
+bool VfsDirectory::CleanSubdirectoryRecursive(std::string_view name) {
+    auto dir = GetSubdirectory(name);
+    if (dir == nullptr) {
+        return false;
+    }
+
+    bool success = true;
+    for (const auto& file : dir->GetFiles()) {
+        if (!dir->DeleteFile(file->GetName())) {
+            success = false;
+        }
+    }
+
+    for (const auto& sdir : dir->GetSubdirectories()) {
+        if (!dir->DeleteSubdirectoryRecursive(sdir->GetName())) {
+            success = false;
+        }
+    }
+
+    return success;
+}
+
 bool VfsDirectory::Copy(std::string_view src, std::string_view dest) {
     const auto f1 = GetFile(src);
     auto f2 = CreateFile(dest);
@@ -431,10 +453,34 @@ std::shared_ptr<VfsFile> ReadOnlyVfsDirectory::CreateFile(std::string_view name)
     return nullptr;
 }
 
+std::shared_ptr<VfsFile> ReadOnlyVfsDirectory::CreateFileAbsolute(std::string_view path) {
+    return nullptr;
+}
+
+std::shared_ptr<VfsFile> ReadOnlyVfsDirectory::CreateFileRelative(std::string_view path) {
+    return nullptr;
+}
+
+std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectory::CreateDirectoryAbsolute(std::string_view path) {
+    return nullptr;
+}
+
+std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectory::CreateDirectoryRelative(std::string_view path) {
+    return nullptr;
+}
+
 bool ReadOnlyVfsDirectory::DeleteSubdirectory(std::string_view name) {
     return false;
 }
 
+bool ReadOnlyVfsDirectory::DeleteSubdirectoryRecursive(std::string_view name) {
+    return false;
+}
+
+bool ReadOnlyVfsDirectory::CleanSubdirectoryRecursive(std::string_view name) {
+    return false;
+}
+
 bool ReadOnlyVfsDirectory::DeleteFile(std::string_view name) {
     return false;
 }
diff --git a/src/core/file_sys/vfs.h b/src/core/file_sys/vfs.h
index 002f99d4e5..e5641b2554 100644
--- a/src/core/file_sys/vfs.h
+++ b/src/core/file_sys/vfs.h
@@ -245,12 +245,18 @@ public:
     // any failure.
     virtual std::shared_ptr<VfsDirectory> CreateDirectoryAbsolute(std::string_view path);
 
-    // Deletes the subdirectory with name and returns true on success.
+    // Deletes the subdirectory with the given name and returns true on success.
     virtual bool DeleteSubdirectory(std::string_view name) = 0;
-    // Deletes all subdirectories and files of subdirectory with name recirsively and then deletes
-    // the subdirectory. Returns true on success.
+
+    // Deletes all subdirectories and files within the provided directory and then deletes
+    // the directory itself. Returns true on success.
     virtual bool DeleteSubdirectoryRecursive(std::string_view name);
-    // Returnes whether or not the file with name name was deleted successfully.
+
+    // Deletes all subdirectories and files within the provided directory.
+    // Unlike DeleteSubdirectoryRecursive, this does not delete the provided directory.
+    virtual bool CleanSubdirectoryRecursive(std::string_view name);
+
+    // Returns whether or not the file with name name was deleted successfully.
     virtual bool DeleteFile(std::string_view name) = 0;
 
     // Returns whether or not this directory was renamed to name.
@@ -276,7 +282,13 @@ public:
     bool IsReadable() const override;
     std::shared_ptr<VfsDirectory> CreateSubdirectory(std::string_view name) override;
     std::shared_ptr<VfsFile> CreateFile(std::string_view name) override;
+    std::shared_ptr<VfsFile> CreateFileAbsolute(std::string_view path) override;
+    std::shared_ptr<VfsFile> CreateFileRelative(std::string_view path) override;
+    std::shared_ptr<VfsDirectory> CreateDirectoryAbsolute(std::string_view path) override;
+    std::shared_ptr<VfsDirectory> CreateDirectoryRelative(std::string_view path) override;
     bool DeleteSubdirectory(std::string_view name) override;
+    bool DeleteSubdirectoryRecursive(std::string_view name) override;
+    bool CleanSubdirectoryRecursive(std::string_view name) override;
     bool DeleteFile(std::string_view name) override;
     bool Rename(std::string_view name) override;
 };
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp
index 2aa77f68dd..3bdff40361 100644
--- a/src/core/hle/service/filesystem/filesystem.cpp
+++ b/src/core/hle/service/filesystem/filesystem.cpp
@@ -113,6 +113,18 @@ ResultCode VfsDirectoryServiceWrapper::DeleteDirectoryRecursively(const std::str
     return RESULT_SUCCESS;
 }
 
+ResultCode VfsDirectoryServiceWrapper::CleanDirectoryRecursively(const std::string& path) const {
+    const std::string sanitized_path(FileUtil::SanitizePath(path));
+    auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(sanitized_path));
+
+    if (!dir->CleanSubdirectoryRecursive(FileUtil::GetFilename(sanitized_path))) {
+        // TODO(DarkLordZach): Find a better error code for this
+        return ResultCode(-1);
+    }
+
+    return RESULT_SUCCESS;
+}
+
 ResultCode VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path_,
                                                   const std::string& dest_path_) const {
     std::string src_path(FileUtil::SanitizePath(src_path_));
diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h
index 0a6cb66352..278cf90ab3 100644
--- a/src/core/hle/service/filesystem/filesystem.h
+++ b/src/core/hle/service/filesystem/filesystem.h
@@ -113,6 +113,18 @@ public:
      */
     ResultCode DeleteDirectoryRecursively(const std::string& path) const;
 
+    /**
+     * Cleans the specified directory. This is similar to DeleteDirectoryRecursively,
+     * in that it deletes all the contents of the specified directory, however, this
+     * function does *not* delete the directory itself. It only deletes everything
+     * within it.
+     *
+     * @param path Path relative to the archive.
+     *
+     * @return Result of the operation.
+     */
+    ResultCode CleanDirectoryRecursively(const std::string& path) const;
+
     /**
      * Rename a File specified by its path
      * @param src_path Source path relative to the archive
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp
index 99d9ebc398..694ec40ec1 100644
--- a/src/core/hle/service/filesystem/fsp_srv.cpp
+++ b/src/core/hle/service/filesystem/fsp_srv.cpp
@@ -291,7 +291,7 @@ public:
             {10, &IFileSystem::Commit, "Commit"},
             {11, nullptr, "GetFreeSpaceSize"},
             {12, nullptr, "GetTotalSpaceSize"},
-            {13, nullptr, "CleanDirectoryRecursively"},
+            {13, &IFileSystem::CleanDirectoryRecursively, "CleanDirectoryRecursively"},
             {14, nullptr, "GetFileTimeStampRaw"},
             {15, nullptr, "QueryEntry"},
         };
@@ -361,6 +361,16 @@ public:
         rb.Push(backend.DeleteDirectoryRecursively(name));
     }
 
+    void CleanDirectoryRecursively(Kernel::HLERequestContext& ctx) {
+        const auto file_buffer = ctx.ReadBuffer();
+        const std::string name = Common::StringFromBuffer(file_buffer);
+
+        LOG_DEBUG(Service_FS, "called. Directory: {}", name);
+
+        IPC::ResponseBuilder rb{ctx, 2};
+        rb.Push(backend.CleanDirectoryRecursively(name));
+    }
+
     void RenameFile(Kernel::HLERequestContext& ctx) {
         IPC::RequestParser rp{ctx};