libfs: separating closing a file descriptor from releasing a reference to the file itself
This commit is contained in:
+24
-7
@@ -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)
|
||||
|
||||
@@ -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(
|
||||
|
||||
Reference in New Issue
Block a user