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