Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix race conditions in emlog #17

Closed
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions emlog.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

/*
* EMLOG: the EMbedded-device LOGger
*
Expand Down Expand Up @@ -90,7 +89,9 @@ static dev_t emlog_dev_type = 0;
static struct cdev *emlog_cdev = NULL;
static struct class *emlog_class = NULL;
static struct device *emlog_dev_reg;
static struct emlog_info *emlog_info_list = NULL;

static struct emlog_info *emlog_info_list = NULL; // protected by emlog_info_list_lock
static spinlock_t emlog_info_list_lock;

module_param(emlog_autofree, bool, 0644);
module_param(emlog_debug, bool, 0644);
Expand All @@ -109,9 +110,13 @@ static struct emlog_info *get_einfo(const struct inode *inode)
if (inode == NULL)
return NULL;

spin_lock(&emlog_info_list_lock); // Peeba
vishwamartur marked this conversation as resolved.
Show resolved Hide resolved
for (einfo = emlog_info_list; einfo != NULL; einfo = einfo->next)
if (einfo->i_ino == inode->i_ino && einfo->i_rdev == inode->i_rdev)
if (einfo->i_ino == inode->i_ino && einfo->i_rdev == inode->i_rdev) {
spin_unlock(&emlog_info_list_lock); // Peeba
return einfo;
}
spin_unlock(&emlog_info_list_lock); // Peeba

return NULL;
}
Expand Down Expand Up @@ -144,8 +149,10 @@ static int create_einfo(const struct inode *inode, int minor,
goto data_malloc_failed;

/* add it to our linked list */
spin_lock(&emlog_info_list_lock); // P714a
einfo->next = emlog_info_list;
emlog_info_list = einfo;
spin_unlock(&emlog_info_list_lock); // P714a

if (emlog_debug)
pr_debug("allocating resources associated with inode %ld.\n", einfo->i_ino);
Expand Down Expand Up @@ -184,6 +191,7 @@ static void free_einfo(struct emlog_info *einfo)
/* now delete the 'einfo' structure from the linked list. 'ptr' is
* the pointer that needs to be changed... which is either the list
* head or one of the 'next' pointers on the list. */
spin_lock(&emlog_info_list_lock); // P714a
ptr = &emlog_info_list;
while (*ptr != einfo) {
if (!*ptr) {
Expand All @@ -194,6 +202,7 @@ static void free_einfo(struct emlog_info *einfo)

}
*ptr = einfo->next;
spin_unlock(&emlog_info_list_lock); // P714a

}

Expand Down Expand Up @@ -516,6 +525,8 @@ static int __init emlog_init(void)
ret_val = -5; goto emlog_init_error;
}

spin_lock_init(&emlog_info_list_lock); // P714a

goto emlog_init_okay;
emlog_init_error:
if (emlog_dev_reg) device_destroy(emlog_class, emlog_dev_type);
Expand Down