1717#include < map>
1818#include < vector>
1919#include < cstdio>
20+ #include < cassert>
2021
2122#include < unistd.h>
2223#include < endian.h>
@@ -40,9 +41,9 @@ LkvsDev::LkvsDev()
4041 aligned4kBuf = (char *)memalign (ALIGNMENT, ALIGNMENT);
4142 memset (aligned4kBuf, 0 , ALIGNMENT);
4243 numZones = 0 ;
43- lastZoneAlloc = 1 ;
4444 lastReadZone = 0 ;
4545 zDevBlockSize = 0 ;
46+ cZones = 0 ;
4647 zDev = NULL ;
4748 zDevZones = NULL ;
4849 zoneMeta = NULL ;
@@ -54,9 +55,9 @@ LkvsDev::~LkvsDev()
5455
5556 // Release all of the zone specific MD buffers
5657 if ( zoneMeta ) {
57- for ( i = 1 ; i < zDevNumZones; i++){
58+ for ( i = cZones ; i < zDevNumZones; i++){
5859
59- if ( zoneMeta[i-1 ].mdBuf ) free ( zoneMeta[i-1 ].mdBuf );
60+ if ( zoneMeta[i-cZones ].mdBuf ) free ( zoneMeta[i-cZones ].mdBuf );
6061 }
6162 free (zoneMeta);
6263 }
@@ -199,14 +200,14 @@ int LkvsDev::populateMeta(int zoneIndex)
199200 }
200201
201202 if ( metaCount == 0 ){
202- zoneMeta[zoneIndex - 1 ].lastMDump = putMeta->mddump ;
203+ zoneMeta[zoneIndex - cZones ].lastMDump = putMeta->mddump ;
203204 }
204205
205206 if ( !blkCount ){
206- char *mdBufLocation = zoneMeta[zoneIndex -1 ].mdBuf ;
207- mdBufLocation += zoneMeta[zoneIndex -1 ].mdEntries * MD_PB_SZ;
207+ char *mdBufLocation = zoneMeta[zoneIndex - cZones ].mdBuf ;
208+ mdBufLocation += zoneMeta[zoneIndex - cZones ].mdEntries * MD_PB_SZ;
208209 memcpy (mdBufLocation, putMeta, MD_PB_SZ);
209- zoneMeta[zoneIndex -1 ].mdEntries ++;
210+ zoneMeta[zoneIndex - cZones ].mdEntries ++;
210211 }
211212 metaCount++;
212213 mdPopOffset += MD_PB_SZ;
@@ -242,7 +243,7 @@ int LkvsDev::openDev(const char *dev, int flags)
242243 goto out;
243244 }
244245
245- ret = zbc_open (targetDev.c_str (), O_RDWR | O_EXCL , &zDev);
246+ ret = zbc_open (targetDev.c_str (), O_RDWR, &zDev);
246247 if ( ret != 0 ) {
247248 std::cerr << " ZBC open fails" << std::endl;
248249 ret = LKVS_FAILURE;
@@ -255,7 +256,22 @@ int LkvsDev::openDev(const char *dev, int flags)
255256 ret = LKVS_FAILURE;
256257 goto out;
257258 }
258-
259+
260+ cZones = 0 ;
261+ // Determine how many zones that are not sequential only
262+ for ( i = 0 ; i < zDevNumZones; i++)
263+ {
264+ // Make sure that the conventional zones are in a contiguous
265+ // LBA range. May vary, but this works for our prototype drive.
266+ if (cZones > 0 && zbc_zone_conventional (&zDevZones[i])){
267+ assert (zbc_zone_conventional (&zDevZones[i-1 ]));
268+ cZones++;
269+ }else if (zbc_zone_conventional (&zDevZones[i])){
270+ cZones++;
271+ }
272+ }
273+
274+ lastZoneAlloc = cZones;
259275 zDevInfo = (zbc_device_info_t *)malloc (sizeof (zbc_device_info_t ));
260276 if (!zDevInfo){
261277 std::cerr << " Lkvs Dev info allocation failed" << std::endl;
@@ -288,26 +304,26 @@ int LkvsDev::openDev(const char *dev, int flags)
288304 }
289305
290306 // Alocate memory for zone MetaData
291- zoneMeta = (LkvsZone*)malloc (sizeof (LkvsZone) * zDevNumZones - 1 );
307+ zoneMeta = (LkvsZone*)malloc (sizeof (LkvsZone) * zDevNumZones - cZones );
292308 if ( !zoneMeta ) {
293309 std::cerr << " ZoneMeta alloc fails" << std::endl;
294310 ret = LKVS_FAILURE;
295311 goto out;
296312 }
297- memset (zoneMeta, 0 , sizeof (LkvsZone) * zDevNumZones - 1 );
313+ memset (zoneMeta, 0 , sizeof (LkvsZone) * ( zDevNumZones - cZones) );
298314 // Iterate over sequential only zones and grab metadata from
299315 // zones that have data
300- for ( i = 1 ; i < zDevNumZones; i++)
316+ for ( i = cZones ; i < zDevNumZones; i++)
301317 {
302- zoneMeta[ i - 1 ].mdBuf = (char *)memalign (ALIGNMENT, ALIGNMENT);
303- if ( ! zoneMeta[i - 1 ].mdBuf ){
318+ zoneMeta[ i - cZones ].mdBuf = (char *)memalign (ALIGNMENT, ALIGNMENT);
319+ if ( ! zoneMeta[i - cZones ].mdBuf ){
304320 std::cerr << " MdBuf alloc fails" << std::endl;
305321 ret = LKVS_FAILURE;
306322 goto out;
307323 }
308- memset (zoneMeta[i-1 ].mdBuf , 0 , ALIGNMENT);
309- zoneMeta[i- 1 ].lastMDump = 0 ;
310- zoneMeta[i- 1 ].mdEntries = 0 ;
324+ memset (zoneMeta[i- cZones ].mdBuf , 0 , ALIGNMENT);
325+ zoneMeta[i - cZones ].lastMDump = 0 ;
326+ zoneMeta[i - cZones ].mdEntries = 0 ;
311327
312328 if (zDevZones[i].zbz_write_pointer > zDevZones[i].zbz_start )
313329 {
@@ -387,7 +403,8 @@ int LkvsDev::Put(const char *key, void *buf, size_t size)
387403 goto out;
388404 }
389405 }
390-
406+
407+ // std::cerr << "Writing Request to Zone: " << lastZoneAlloc << std::endl;
391408 curZone = &zDevZones[lastZoneAlloc];
392409 // Align write pointer to 4k boundary
393410 // wrPointerOffset = curZone->zbz_write_pointer % 8;
@@ -432,6 +449,7 @@ int LkvsDev::Put(const char *key, void *buf, size_t size)
432449 if ( curWritten != curWritesz / zDevBlockSize) break ;
433450 written += curWritten * zDevBlockSize;
434451 cBuf += curWritten * zDevBlockSize;
452+ curZone->zbz_write_pointer += curWritten;
435453 }
436454 xferEnd = getTime ();
437455
@@ -445,15 +463,15 @@ int LkvsDev::Put(const char *key, void *buf, size_t size)
445463 goto out;
446464 }
447465
448- mdBufLocation = zoneMeta[lastZoneAlloc -1 ].mdBuf ;
449- if ( zoneMeta[lastZoneAlloc -1 ].mdEntries < MD_ENTRIES_PER_BLOCK){
450- mdBufLocation += (MD_PB_SZ * zoneMeta[lastZoneAlloc -1 ].mdEntries );
451- zoneMeta[lastZoneAlloc -1 ].mdEntries ++;
466+ mdBufLocation = zoneMeta[lastZoneAlloc - cZones ].mdBuf ;
467+ if ( zoneMeta[lastZoneAlloc - cZones ].mdEntries < MD_ENTRIES_PER_BLOCK){
468+ mdBufLocation += (MD_PB_SZ * zoneMeta[lastZoneAlloc - cZones ].mdEntries );
469+ zoneMeta[lastZoneAlloc - cZones ].mdEntries ++;
452470 }else {
453471 // std::cerr << "MdEntries: " << curZone->mdEntries
454472 // << ". Going to reset" << std::endl;
455- memset (zoneMeta[lastZoneAlloc - 1 ].mdBuf , 0 , ALIGNMENT);
456- zoneMeta[lastZoneAlloc -1 ].mdEntries = 1 ;
473+ memset (zoneMeta[lastZoneAlloc - cZones ].mdBuf , 0 , ALIGNMENT);
474+ zoneMeta[lastZoneAlloc - cZones ].mdEntries = 1 ;
457475 }
458476
459477 putMeta = (MetaData *)mdBufLocation;
@@ -463,24 +481,25 @@ int LkvsDev::Put(const char *key, void *buf, size_t size)
463481 ((size + slack) / zDevBlockSize);
464482 keyContainer.metaKeySet (putMeta);
465483 // Check the logic of this across zones
466- putMeta->mddump = zoneMeta[lastZoneAlloc - 1 ].lastMDump ;
484+ putMeta->mddump = zoneMeta[lastZoneAlloc - cZones ].lastMDump ;
467485 putMeta->magic = LKVS_META_MAGIC;
468486
469487 // Write the MD
470488
471- written = zbc_write (zDev, curZone, zoneMeta[lastZoneAlloc - 1 ].mdBuf ,
489+ written = zbc_write (zDev, curZone, zoneMeta[lastZoneAlloc - cZones ].mdBuf ,
472490 ALIGNMENT / zDevBlockSize );
473491 if ( written != ALIGNMENT / zDevBlockSize){
474492 std::cerr << " MD Wanted to write: " << ALIGNMENT / zDevBlockSize
475493 << " bytes but wrote: "
476494 << written << " bytes." << std::endl;
477495 std::cerr << strerror (errno);
478- zoneMeta[lastZoneAlloc - 1 ].mdEntries --;
496+ zoneMeta[lastZoneAlloc - cZones ].mdEntries --;
479497 goto out;
480498 }
499+ curZone->zbz_write_pointer += written;
481500 // Update last offset
482- if ( zoneMeta[lastZoneAlloc - 1 ].mdEntries == MD_ENTRIES_PER_BLOCK ){
483- zoneMeta[lastZoneAlloc - 1 ].lastMDump =
501+ if ( zoneMeta[lastZoneAlloc - cZones ].mdEntries == MD_ENTRIES_PER_BLOCK ){
502+ zoneMeta[lastZoneAlloc - cZones ].lastMDump =
484503 curZone->zbz_write_pointer - ALIGNMENT / zDevBlockSize;
485504 }
486505 zbc_flush (zDev);
@@ -610,7 +629,7 @@ int LkvsDev::searchForZone(size_t size){
610629
611630 unsigned int curZonePos;
612631
613- for (curZonePos = 1 ; curZonePos < zDevNumZones; curZonePos++){
632+ for (curZonePos = cZones ; curZonePos < zDevNumZones; curZonePos++){
614633 if ( !reserve (curZonePos, size) ){
615634 lastZoneAlloc = curZonePos;
616635 return LKVS_SUCCESS;
0 commit comments