From f6993553cd2e9699a810f3d700ab4e2d108562ea Mon Sep 17 00:00:00 2001 From: Max Wash Date: Wed, 1 Apr 2026 18:55:47 +0100 Subject: [PATCH] libfs: separating closing a file descriptor from releasing a reference to the file itself --- lib/libfs/context.c | 31 ++++++++++++++++++++++++------- lib/libfs/include/fs/context.h | 1 + 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/lib/libfs/context.c b/lib/libfs/context.c index 65df1b5..db9823c 100644 --- a/lib/libfs/context.c +++ b/lib/libfs/context.c @@ -145,13 +145,15 @@ static enum fs_status handle_event(struct fs_context *ctx, xpc_msg_t *msg) { switch (msg->msg_event) { case KERN_MSG_EVENT_CONNECTION: - kern_logf("received connection"); + kern_tracef("received connection"); break; case KERN_MSG_EVENT_DISCONNECTION: { + kern_tracef("received disconnect"); struct fs_file *f = fs_context_get_file(ctx, msg->msg_sender.e_port); if (f) { fs_context_close_file(ctx, f); + fs_context_unref_file(ctx, f); } break; } @@ -200,7 +202,14 @@ static enum fs_status handle_page_request_detach( equeue_packet_page_request_t *packet, struct file_mapping *mapping) { - kern_logf( + if (!mapping) { + kern_logf( + "received DETACH request from VMO with no associated " + "mapping"); + return FS_ERR_INTERNAL_FAILURE; + } + + kern_tracef( "received page request (detach) for file %s", mapping->m_file->f_dent->d_name); @@ -216,7 +225,7 @@ static enum fs_status handle_page_request_detach( kern_handle_close(mapping->m_vmo); fs_context_free(ctx, mapping); - fs_context_close_file(ctx, f); + fs_context_unref_file(ctx, f); return FS_SUCCESS; } @@ -335,18 +344,26 @@ struct fs_file *fs_context_get_file(struct fs_context *ctx, unsigned long id) return get_file(&ctx->ctx_filelist, id); } -void fs_context_close_file(struct fs_context *ctx, struct fs_file *f) +void fs_context_unref_file(struct fs_context *ctx, struct fs_file *f) { if (f->f_ref > 1) { - kern_logf( + kern_tracef( "reference to file '%s' has been closed", f->f_dent->d_name); f->f_ref--; return; } - kern_logf("file '%s' has been closed", f->f_dent->d_name); - btree_delete(&ctx->ctx_filelist, &f->f_node); + kern_tracef("file '%s' has been closed", f->f_dent->d_name); + fs_context_free(ctx, f); +} + +void fs_context_close_file(struct fs_context *ctx, struct fs_file *f) +{ + if (f->f_id) { + btree_delete(&ctx->ctx_filelist, &f->f_node); + f->f_id = 0; + } } static size_t get_first_path_component(const char *in, char *out, size_t max) diff --git a/lib/libfs/include/fs/context.h b/lib/libfs/include/fs/context.h index d9e760a..246987e 100644 --- a/lib/libfs/include/fs/context.h +++ b/lib/libfs/include/fs/context.h @@ -42,6 +42,7 @@ extern struct fs_file *fs_context_open_file( extern struct fs_file *fs_context_get_file( struct fs_context *ctx, unsigned long id); +extern void fs_context_unref_file(struct fs_context *ctx, struct fs_file *f); extern void fs_context_close_file(struct fs_context *ctx, struct fs_file *f); extern enum fs_status fs_context_resolve_path(