libfs: separating closing a file descriptor from releasing a reference to the file itself

This commit is contained in:
2026-04-01 18:55:47 +01:00
parent 3a9539adbc
commit f6993553cd
2 changed files with 25 additions and 7 deletions
+22 -5
View File
@@ -145,13 +145,15 @@ static enum fs_status handle_event(struct fs_context *ctx, xpc_msg_t *msg)
{ {
switch (msg->msg_event) { switch (msg->msg_event) {
case KERN_MSG_EVENT_CONNECTION: case KERN_MSG_EVENT_CONNECTION:
kern_logf("received connection"); kern_tracef("received connection");
break; break;
case KERN_MSG_EVENT_DISCONNECTION: { case KERN_MSG_EVENT_DISCONNECTION: {
kern_tracef("received disconnect");
struct fs_file *f struct fs_file *f
= fs_context_get_file(ctx, msg->msg_sender.e_port); = fs_context_get_file(ctx, msg->msg_sender.e_port);
if (f) { if (f) {
fs_context_close_file(ctx, f); fs_context_close_file(ctx, f);
fs_context_unref_file(ctx, f);
} }
break; break;
} }
@@ -200,7 +202,14 @@ static enum fs_status handle_page_request_detach(
equeue_packet_page_request_t *packet, equeue_packet_page_request_t *packet,
struct file_mapping *mapping) struct file_mapping *mapping)
{ {
if (!mapping) {
kern_logf( 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", "received page request (detach) for file %s",
mapping->m_file->f_dent->d_name); 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); kern_handle_close(mapping->m_vmo);
fs_context_free(ctx, mapping); fs_context_free(ctx, mapping);
fs_context_close_file(ctx, f); fs_context_unref_file(ctx, f);
return FS_SUCCESS; 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); 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) { if (f->f_ref > 1) {
kern_logf( kern_tracef(
"reference to file '%s' has been closed", "reference to file '%s' has been closed",
f->f_dent->d_name); f->f_dent->d_name);
f->f_ref--; f->f_ref--;
return; return;
} }
kern_logf("file '%s' has been closed", f->f_dent->d_name); 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); 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) static size_t get_first_path_component(const char *in, char *out, size_t max)
+1
View File
@@ -42,6 +42,7 @@ extern struct fs_file *fs_context_open_file(
extern struct fs_file *fs_context_get_file( extern struct fs_file *fs_context_get_file(
struct fs_context *ctx, struct fs_context *ctx,
unsigned long id); 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 void fs_context_close_file(struct fs_context *ctx, struct fs_file *f);
extern enum fs_status fs_context_resolve_path( extern enum fs_status fs_context_resolve_path(