/** * Invalidate lsid inside ring buffer. */ bool invalidate_lsid(struct walb_dev *wdev, u64 lsid) { struct sector_data *zero_sector; struct walb_super_sector *super; u64 off; bool ret; ASSERT(lsid != INVALID_LSID); zero_sector = sector_alloc( wdev->physical_bs, GFP_KERNEL | __GFP_ZERO); if (!zero_sector) { LOGe("sector allocation failed.\n"); return false; } spin_lock(&wdev->lsuper0_lock); super = get_super_sector(wdev->lsuper0); off = get_offset_of_lsid_2(super, lsid); spin_unlock(&wdev->lsuper0_lock); ret = sector_io(WRITE, wdev->ldev, off, zero_sector); if (!ret) { LOGe("sector write failed.\n"); iocore_set_readonly(wdev); } sector_free(zero_sector); return ret; }
/** * Free memories for a logpack. */ void free_logpack(struct logpack *pack) { if (pack) { sector_free(pack->sectd); sector_array_free(pack->sectd_ary); free(pack); } }
/** * Check logpack of the given lsid exists. * * @lsid lsid to check. * * @return Non-zero if valid, or 0. */ int walb_check_lsid_valid(struct walb_dev *wdev, u64 lsid) { struct sector_data *sect; struct walb_logpack_header *logh; u64 off; ASSERT(wdev); sect = sector_alloc(wdev->physical_bs, GFP_NOIO); if (!sect) { LOGe("walb_check_lsid_valid: alloc sector failed.\n"); goto error0; } ASSERT(is_same_size_sector(sect, wdev->lsuper0)); logh = get_logpack_header(sect); spin_lock(&wdev->lsuper0_lock); off = get_offset_of_lsid_2(get_super_sector(wdev->lsuper0), lsid); spin_unlock(&wdev->lsuper0_lock); if (!sector_io(READ, wdev->ldev, off, sect)) { LOGe("walb_check_lsid_valid: read sector failed.\n"); goto error1; } /* Check valid logpack header. */ if (!is_valid_logpack_header_with_checksum( logh, wdev->physical_bs, wdev->log_checksum_salt)) { goto error1; } /* Check lsid. */ if (logh->logpack_lsid != lsid) { goto error1; } sector_free(sect); return 1; error1: sector_free(sect); error0: return 0; }
/** * Cleans up a world_t for exit */ static void world_free(world_t* world) { for (int x = 0; x < NUM_SECTORS_X; x++) { for (int y = 0; y < NUM_SECTORS_Y; y++) { for (int z = 0; z < 4; z++) { if (world->sectors[x][y][z] != (world_sector_t*)NULL) { sector_free(world->sectors[x][y][z]); world->sectors[x][y][z] = (world_sector_t*)NULL; } } } } }
/** * Performs garbage collection on the world, cleaning and deallocating any * un-used sectors. */ void world_gc(world_t* world) { for (int x = 0; x < NUM_SECTORS_X; x++) { for (int y = 0; y < NUM_SECTORS_Y; y++) { for (int z = 0; z < 4; z++) { world_sector_t* sector = world->sectors[x][y][z]; if (sector != (world_sector_t*)NULL) { if (list_empty(§or->players)) { sector_free(sector); world->sectors[x][y][z] = (world_sector_t*)NULL; } } } } } }
/** * Write invalid logpack header. * This just fill zero. * * @fd file descriptor of data device (opened). * @super_sect super sector. * @lsid lsid to invalidate. * * RETURN: * true in success, or false. */ bool write_invalid_logpack_header( int fd, const struct sector_data *super_sect, u64 lsid) { struct sector_data *sect; bool ret; const struct walb_super_sector *super = get_super_sector_const(super_sect); u64 off = get_offset_of_lsid_2(super, lsid); sect = sector_alloc_zero(super->physical_bs); if (!sect) { LOGe("Allocate sector failed.\n"); return false; } ret = sector_write(fd, off, sect); if (!ret) { LOGe("Write sector %"PRIu64" for lsid %"PRIu64" failed.\n", off, lsid); } sector_free(sect); return ret; }
/** * Write an end logpack header block. */ bool write_end_logpack_header(int fd, unsigned int pbs, u32 salt) { bool ret = false; struct walb_logpack_header *h; struct sector_data *sect = sector_alloc(pbs); if (!sect) { LOGe("sector_alloc failed.\n"); return false; } h = get_logpack_header(sect); memset(h, 0, pbs); h->sector_type = SECTOR_TYPE_LOGPACK; h->n_records = 0; h->logpack_lsid = (u64)(-1); h->checksum = 0; h->checksum = checksum((const u8 *)h, pbs, salt); ret = write_data(fd, (const u8 *)h, pbs); if (!ret) LOGe("write_data failed.\n"); sector_free(sect); return ret; }