HelenOS sources
This source file includes following definitions.
- mem_is_zero
- calc_num_check_blocks
- label_bd_is_empty
- label_bd_empty
- label_part_empty
#include <errno.h>
#include <io/log.h>
#include <label/empty.h>
#include <loc.h>
#include <stdlib.h>
enum {
min_empty_bytes = 16384,
min_empty_blocks = 17
};
static bool mem_is_zero(void *buf, size_t size)
{
uint8_t *bp;
size_t i;
bp = (uint8_t *)buf;
for (i = 0; i < size; i++) {
if (bp[i] != 0)
return false;
}
return true;
}
static void calc_num_check_blocks(aoff64_t nblocks, size_t block_size,
aoff64_t *ncb)
{
aoff64_t n;
n = (min_empty_bytes + block_size - 1) / block_size;
if (n < min_empty_blocks)
n = min_empty_blocks;
if (n > (nblocks + 1) / 2)
n = (nblocks + 1) / 2;
*ncb = n;
}
errno_t label_bd_is_empty(label_bd_t *bd, bool *rempty)
{
errno_t rc;
void *buf = NULL;
aoff64_t nblocks;
aoff64_t n;
aoff64_t i;
size_t block_size;
bool empty;
rc = bd->ops->get_bsize(bd->arg, &block_size);
if (rc != EOK) {
log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting "
"block size.");
rc = EIO;
goto error;
}
rc = bd->ops->get_nblocks(bd->arg, &nblocks);
if (rc != EOK) {
log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting "
"number of blocks.");
rc = EIO;
goto error;
}
calc_num_check_blocks(nblocks, block_size, &n);
buf = calloc(block_size, 1);
if (buf == NULL) {
log_msg(LOG_DEFAULT, LVL_ERROR, "Error allocating buffer.");
rc = ENOMEM;
goto error;
}
empty = true;
for (i = 0; i < n; i++) {
rc = bd->ops->read(bd->arg, i, 1, buf);
if (rc != EOK) {
log_msg(LOG_DEFAULT, LVL_ERROR, "Error "
"reading blocks.");
rc = EIO;
goto error;
}
if (!mem_is_zero(buf, block_size)) {
empty = false;
goto done;
}
}
for (i = 0; i < n; i++) {
rc = bd->ops->read(bd->arg, nblocks - n + i, 1, buf);
if (rc != EOK) {
log_msg(LOG_DEFAULT, LVL_ERROR, "Error "
"reading blocks.");
rc = EIO;
goto error;
}
if (!mem_is_zero(buf, block_size)) {
empty = false;
goto done;
}
}
done:
free(buf);
*rempty = empty;
return EOK;
error:
if (buf != NULL)
free(buf);
return rc;
}
errno_t label_bd_empty(label_bd_t *bd)
{
errno_t rc;
void *buf = NULL;
aoff64_t nblocks;
aoff64_t n;
aoff64_t i;
size_t block_size;
rc = bd->ops->get_bsize(bd->arg, &block_size);
if (rc != EOK) {
log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting "
"block size.");
rc = EIO;
goto error;
}
rc = bd->ops->get_nblocks(bd->arg, &nblocks);
if (rc != EOK) {
log_msg(LOG_DEFAULT, LVL_ERROR, "Error getting "
"number of blocks.");
rc = EIO;
goto error;
}
calc_num_check_blocks(nblocks, block_size, &n);
buf = calloc(block_size, 1);
if (buf == NULL) {
log_msg(LOG_DEFAULT, LVL_ERROR, "Error allocating buffer.");
rc = ENOMEM;
goto error;
}
for (i = 0; i < n; i++) {
rc = bd->ops->write(bd->arg, i, 1, buf);
if (rc != EOK) {
log_msg(LOG_DEFAULT, LVL_ERROR, "Error "
"reading blocks.");
rc = EIO;
goto error;
}
}
for (i = 0; i < n; i++) {
rc = bd->ops->write(bd->arg, nblocks - n + i, 1, buf);
if (rc != EOK) {
log_msg(LOG_DEFAULT, LVL_ERROR, "Error "
"reading blocks.");
rc = EIO;
goto error;
}
}
free(buf);
return EOK;
error:
if (buf != NULL)
free(buf);
return rc;
}
errno_t label_part_empty(label_part_t *part)
{
errno_t rc;
void *buf = NULL;
aoff64_t block0;
aoff64_t nblocks;
aoff64_t n;
aoff64_t i;
size_t block_size;
label_bd_t *bd;
bd = &part->label->bd;
block_size = part->label->block_size;
block0 = part->block0;
nblocks = part->nblocks;
calc_num_check_blocks(nblocks, block_size, &n);
buf = calloc(block_size, 1);
if (buf == NULL) {
log_msg(LOG_DEFAULT, LVL_ERROR, "Error allocating buffer.");
rc = ENOMEM;
goto error;
}
for (i = 0; i < n; i++) {
rc = bd->ops->write(bd->arg, block0 + i, 1, buf);
if (rc != EOK) {
log_msg(LOG_DEFAULT, LVL_ERROR, "Error "
"reading blocks.");
rc = EIO;
goto error;
}
}
for (i = 0; i < n; i++) {
rc = bd->ops->write(bd->arg, block0 + nblocks - n + i, 1, buf);
if (rc != EOK) {
log_msg(LOG_DEFAULT, LVL_ERROR, "Error "
"reading blocks.");
rc = EIO;
goto error;
}
}
free(buf);
return EOK;
error:
if (buf != NULL)
free(buf);
return rc;
}
HelenOS homepage, sources at GitHub