From 96aafa14fc2cfa2cf5bb2d366263c6b2f4985709 Mon Sep 17 00:00:00 2001 From: Andres Cera Date: Tue, 20 Oct 2026 19:47:16 -0500 Subject: [PATCH] Treat an existing /data mount as the fakelib directory layer Since 091dffb, track_sandbox_layer() refuses an existing mount whose source differs from the requested one. ShellCore always mounts /user/data at the sandbox's /data, so the /data layer failed with EBUSY and fakelib setup aborted, killing the game. If that path is already a mount point, treat it as the layer instead of stacking a second nullfs over it. --- src/sm_fakelib.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/sm_fakelib.c b/src/sm_fakelib.c index f7cf258..c702908 100644 --- a/src/sm_fakelib.c +++ b/src/sm_fakelib.c @@ -114,6 +114,11 @@ bool sm_fakelib_game_feature_enabled(void) { return runtime_config().backport_fakelib_enabled; } +static bool path_is_mount_point(const char *path) { + struct statfs fs; + return statfs(path, &fs) == 0 && strcmp(fs.f_mntonname, path) == 0; +} + static bool mount_sandbox_layer(const char *title_id, const char *source_path, const char *mount_path, @@ -327,6 +332,14 @@ static bool mount_sandbox_directory(const char *title_id, } } + // ShellCore mounts /user/data at the sandbox's /data. Treat that mount as + // the layer: a second nullfs over it is what fails with EBUSY or EDEADLK. + if (strcmp(source_path, "/data") == 0 && path_is_mount_point(mount_path)) { + log_debug(" [FAKELIB] directory already mounted for %s: %s", title_id, + mount_path); + return true; + } + size_t previous_count = g_fakelib_mount.layer_count; bool mounted = track_sandbox_layer(title_id, source_path, mount_path, "directory", false, flags);