use of org.apache.crail.storage.StorageFuture 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;
}
use of org.apache.crail.storage.StorageFuture in project incubator-crail by apache.
the class CoreStream method prepareAndTrigger.
private StorageFuture prepareAndTrigger(CoreSubOperation opDesc, CrailBuffer dataBuf, BlockInfo block) throws Exception {
try {
StorageEndpoint endpoint = endpointCache.getDataEndpoint(block.getDnInfo());
dataBuf.clear();
dataBuf.position(opDesc.getBufferPosition());
dataBuf.limit(dataBuf.position() + opDesc.getLen());
StorageFuture subFuture = trigger(endpoint, opDesc, dataBuf, block);
incStats(endpoint.isLocal());
return subFuture;
} catch (IOException e) {
LOG.info("ERROR: failed data operation");
e.printStackTrace();
throw e;
}
}
use of org.apache.crail.storage.StorageFuture in project incubator-crail by apache.
the class CoreStream method dataOperation.
final CoreDataOperation dataOperation(CrailBuffer dataBuf) throws Exception {
blockMap.clear();
pendingBlocks.clear();
CoreDataOperation multiOperation = new CoreDataOperation(this, dataBuf);
// compute off, len for the fragments, start transfer or start RPC if block info is missing
while (multiOperation.remaining() > 0) {
long blockRemaining = blockRemaining();
int opLen = CrailUtils.minFileBuf(blockRemaining, multiOperation.remaining());
CoreSubOperation subOperation = new CoreSubOperation(fileInfo.getFd(), position, multiOperation.getCurrentBufferPosition(), opLen);
// LOG.info("OpDesc: " + opDesc.toString());
ioStats.incTotalOps((long) opLen);
if (blockCache.containsKey(subOperation.key())) {
BlockInfo block = blockCache.get(subOperation.key());
StorageFuture subFuture = this.prepareAndTrigger(subOperation, dataBuf, block);
multiOperation.add(subFuture);
this.ioStats.incCachedOps();
} else if (nextBlockCache.containsKey(subOperation.key())) {
RpcFuture<RpcGetBlock> rpcFuture = nextBlockCache.get(subOperation.key());
blockMap.put(rpcFuture.getTicket(), subOperation);
pendingBlocks.add(rpcFuture);
} else {
this.syncedCapacity = fileInfo.getCapacity();
RpcFuture<RpcGetBlock> rpcFuture = namenodeClientRpc.getBlock(fileInfo.getFd(), fileInfo.getToken(), position, syncedCapacity);
blockMap.put(rpcFuture.getTicket(), subOperation);
pendingBlocks.add(rpcFuture);
}
position += opLen;
multiOperation.incProcessedLen(opLen);
}
// wait for RPC results and start reads for those blocks as well
for (RpcFuture<RpcGetBlock> rpcFuture = pendingBlocks.poll(); rpcFuture != null; rpcFuture = pendingBlocks.poll()) {
if (!rpcFuture.isDone()) {
this.ioStats.incBlockingOps();
if (rpcFuture.isPrefetched()) {
this.ioStats.incPrefetchedBlockingOps();
}
} else {
this.ioStats.incNonblockingOps();
if (rpcFuture.isPrefetched()) {
this.ioStats.incPrefetchedNonblockingOps();
}
}
RpcGetBlock getBlockRes = rpcFuture.get(CrailConstants.RPC_TIMEOUT, TimeUnit.MILLISECONDS);
if (!rpcFuture.isDone()) {
throw new IOException("rpc timeout ");
}
if (getBlockRes.getError() != RpcErrors.ERR_OK) {
LOG.info("inputStream: " + RpcErrors.messages[getBlockRes.getError()]);
throw new IOException(RpcErrors.messages[getBlockRes.getError()]);
}
BlockInfo block = getBlockRes.getBlockInfo();
CoreSubOperation subOperation = blockMap.get(rpcFuture.getTicket());
StorageFuture subFuture = prepareAndTrigger(subOperation, dataBuf, block);
multiOperation.add(subFuture);
blockCache.put(subOperation.key(), block);
}
if (!multiOperation.isProcessed()) {
throw new IOException("Internal error, processed data != operation length");
}
dataBuf.limit(multiOperation.getBufferLimit());
dataBuf.position(multiOperation.getCurrentBufferPosition());
return multiOperation;
}
Aggregations