Commit bf41e53e authored by Alexi Demers's avatar Alexi Demers Committed by Anas Nashif
Browse files

disk: disk_access: changed mutex for a spinlock



disk_access functions were called from an interupt context, thus
crashing on mutexes (no sleep is allowed in interrupt context).
The usage of a spinlock is permitted. The functions guarded by
the spinlock are executed very quickly anyway, so the spinlock
is applicable.

Signed-off-by: default avatarAlexi Demers <alexi.demers@axceta.com>
parent 32481b64
Loading
Loading
Loading
Loading
+16 −21
Original line number Diff line number Diff line
@@ -22,15 +22,15 @@ LOG_MODULE_REGISTER(disk);
static sys_dlist_t disk_access_list = SYS_DLIST_STATIC_INIT(&disk_access_list);

/* lock to protect storage layer registration */
static K_MUTEX_DEFINE(mutex);
static struct k_spinlock lock;

struct disk_info *disk_access_get_di(const char *name)
{
	struct disk_info *disk = NULL, *itr;
	size_t name_len = strlen(name);
	sys_dnode_t *node;
	k_spinlock_key_t spinlock_key = k_spin_lock(&lock);

	k_mutex_lock(&mutex, K_FOREVER);
	SYS_DLIST_FOR_EACH_NODE(&disk_access_list, node) {
		itr = CONTAINER_OF(node, struct disk_info, node);

@@ -49,7 +49,7 @@ struct disk_info *disk_access_get_di(const char *name)
			break;
		}
	}
	k_mutex_unlock(&mutex);
	k_spin_unlock(&lock, spinlock_key);

	return disk;
}
@@ -167,52 +167,47 @@ int disk_access_ioctl(const char *pdrv, uint8_t cmd, void *buf)

int disk_access_register(struct disk_info *disk)
{
	int rc = 0;
	k_spinlock_key_t spinlock_key;

	k_mutex_lock(&mutex, K_FOREVER);
	if ((disk == NULL) || (disk->name == NULL)) {
		LOG_ERR("invalid disk interface!!");
		rc = -EINVAL;
		goto reg_err;
		return -EINVAL;
	}

	if (disk_access_get_di(disk->name) != NULL) {
		LOG_ERR("disk interface already registered!!");
		rc = -EINVAL;
		goto reg_err;
		return -EINVAL;
	}

	/* Initialize reference count to zero */
	disk->refcnt = 0U;

	spinlock_key = k_spin_lock(&lock);
	/*  append to the disk list */
	sys_dlist_append(&disk_access_list, &disk->node);
	LOG_DBG("disk interface(%s) registered", disk->name);
reg_err:
	k_mutex_unlock(&mutex);
	return rc;
	k_spin_unlock(&lock, spinlock_key);
	return 0;
}

int disk_access_unregister(struct disk_info *disk)
{
	int rc = 0;
	k_spinlock_key_t spinlock_key;

	k_mutex_lock(&mutex, K_FOREVER);
	if ((disk == NULL) || (disk->name == NULL)) {
		LOG_ERR("invalid disk interface!!");
		rc = -EINVAL;
		goto unreg_err;
		return -EINVAL;
	}

	if (disk_access_get_di(disk->name) == NULL) {
		LOG_ERR("disk interface not registered!!");
		rc = -EINVAL;
		goto unreg_err;
		return -EINVAL;
	}

	spinlock_key = k_spin_lock(&lock);
	/* remove disk node from the list */
	sys_dlist_remove(&disk->node);
	k_spin_unlock(&lock, spinlock_key);
	LOG_DBG("disk interface(%s) unregistered", disk->name);
unreg_err:
	k_mutex_unlock(&mutex);
	return rc;
	return 0;
}