use of com.ibm.disni.nvmef.NvmeCommand in project incubator-crail by apache.
the class NvmfStorageEndpoint method poll.
void poll() throws IOException {
long[] ca = completed.get();
int numberCompletions = endpoint.processCompletions(ca);
for (int i = 0; i < numberCompletions; i++) {
int idx = (int) ca[i];
NvmeCommand command = commands[idx];
IOCompletion completion = command.getCompletion();
completion.done();
futures[idx].signal(completion.getStatusCodeType(), completion.getStatusCode());
freeCommands.add(command);
}
}
use of com.ibm.disni.nvmef.NvmeCommand in project incubator-crail by apache.
the class NvmfStorageEndpoint method Op.
public StorageFuture Op(Operation op, CrailBuffer buffer, BlockInfo remoteMr, long remoteOffset) throws IOException, InterruptedException {
int length = buffer.remaining();
if (length > CrailConstants.BLOCK_SIZE) {
throw new IOException("write size too large " + length);
}
if (length <= 0) {
throw new IOException("write size too small, len " + length);
}
if (buffer.position() < 0) {
throw new IOException("local offset too small " + buffer.position());
}
if (remoteOffset < 0) {
throw new IOException("remote offset too small " + remoteOffset);
}
if (remoteMr.getAddr() + remoteOffset + length > endpoint.getNamespaceSize()) {
long tmpAddr = remoteMr.getAddr() + remoteOffset + length;
throw new IOException("remote fileOffset + remoteOffset + len = " + tmpAddr + " - size = " + endpoint.getNamespaceSize());
}
// LOG.info("op = " + op.name() +
// ", position = " + buffer.position() +
// ", localOffset = " + buffer.position() +
// ", remoteOffset = " + remoteOffset +
// ", remoteAddr = " + remoteMr.getAddr() +
// ", length = " + length);
NvmeCommand command = freeCommands.poll();
while (command == null) {
poll();
command = freeCommands.poll();
}
boolean aligned = NvmfStorageUtils.namespaceSectorOffset(sectorSize, remoteOffset) == 0 && NvmfStorageUtils.namespaceSectorOffset(sectorSize, length) == 0;
long lba = NvmfStorageUtils.linearBlockAddress(remoteMr, remoteOffset, sectorSize);
StorageFuture future = null;
if (aligned) {
// LOG.info("aligned");
command.setBuffer(buffer.getByteBuffer()).setLinearBlockAddress(lba);
switch(op) {
case READ:
command.read();
break;
case WRITE:
command.write();
break;
}
future = futures[(int) command.getId()] = new NvmfStorageFuture(this, length);
command.execute();
} else {
// LOG.info("unaligned");
long alignedLength = NvmfStorageUtils.alignLength(sectorSize, remoteOffset, length);
CrailBuffer stagingBuffer = cache.allocateBuffer();
stagingBuffer.limit((int) alignedLength);
try {
switch(op) {
case READ:
{
NvmfStorageFuture f = futures[(int) command.getId()] = new NvmfStorageFuture(this, (int) alignedLength);
command.setBuffer(stagingBuffer.getByteBuffer()).setLinearBlockAddress(lba).read().execute();
future = new NvmfStorageUnalignedReadFuture(f, this, buffer, remoteMr, remoteOffset, stagingBuffer);
break;
}
case WRITE:
{
if (NvmfStorageUtils.namespaceSectorOffset(sectorSize, remoteOffset) == 0) {
// Do not read if the offset is aligned to sector size
int sizeToWrite = length;
stagingBuffer.put(buffer.getByteBuffer());
stagingBuffer.position(0);
command.setBuffer(stagingBuffer.getByteBuffer()).setLinearBlockAddress(lba).write().execute();
future = futures[(int) command.getId()] = new NvmfStorageUnalignedWriteFuture(this, sizeToWrite, stagingBuffer);
} else {
// RMW but append only file system allows only reading last sector
// and dir entries are sector aligned
stagingBuffer.limit(sectorSize);
NvmfStorageFuture f = futures[(int) command.getId()] = new NvmfStorageFuture(this, sectorSize);
command.setBuffer(stagingBuffer.getByteBuffer()).setLinearBlockAddress(lba).read().execute();
future = new NvmfStorageUnalignedRMWFuture(f, this, buffer, remoteMr, remoteOffset, stagingBuffer);
}
break;
}
}
} catch (NoSuchFieldException e) {
throw new IOException(e);
} catch (IllegalAccessException e) {
throw new IOException(e);
}
}
return future;
}
Aggregations