void handleCommit( DFSClient dfsClient, FileHandle fileHandle, long commitOffset, Channel channel, int xid, Nfs3FileAttributes preOpAttr) { int status; OpenFileCtx openFileCtx = fileContextCache.get(fileHandle); if (openFileCtx == null) { LOG.info( "No opened stream for fileId:" + fileHandle.getFileId() + " commitOffset=" + commitOffset + ". Return success in this case."); status = Nfs3Status.NFS3_OK; } else { COMMIT_STATUS ret = openFileCtx.checkCommit(dfsClient, commitOffset, channel, xid, preOpAttr, false); switch (ret) { case COMMIT_FINISHED: case COMMIT_INACTIVE_CTX: status = Nfs3Status.NFS3_OK; break; case COMMIT_INACTIVE_WITH_PENDING_WRITE: case COMMIT_ERROR: status = Nfs3Status.NFS3ERR_IO; break; case COMMIT_WAIT: // Do nothing. Commit is async now. return; case COMMIT_SPECIAL_WAIT: status = Nfs3Status.NFS3ERR_JUKEBOX; break; case COMMIT_SPECIAL_SUCCESS: status = Nfs3Status.NFS3_OK; break; default: LOG.error("Should not get commit return code:" + ret.name()); throw new RuntimeException("Should not get commit return code:" + ret.name()); } } // Send out the response Nfs3FileAttributes postOpAttr = null; try { postOpAttr = getFileAttr(dfsClient, new FileHandle(preOpAttr.getFileId()), iug); } catch (IOException e1) { LOG.info("Can't get postOpAttr for fileId: " + preOpAttr.getFileId(), e1); } WccData fileWcc = new WccData(Nfs3Utils.getWccAttr(preOpAttr), postOpAttr); COMMIT3Response response = new COMMIT3Response(status, fileWcc, Nfs3Constant.WRITE_COMMIT_VERF); Nfs3Utils.writeChannelCommit( channel, response.serialize(new XDR(), xid, new VerifierNone()), xid); }
// Do a possible commit before read request in case there is buffered data // inside DFSClient which has been flushed but not synced. int commitBeforeRead(DFSClient dfsClient, FileHandle fileHandle, long commitOffset) { int status; OpenFileCtx openFileCtx = fileContextCache.get(fileHandle); if (openFileCtx == null) { if (LOG.isDebugEnabled()) { LOG.debug( "No opened stream for fileId:" + fileHandle.getFileId() + " commitOffset=" + commitOffset + ". Return success in this case."); } status = Nfs3Status.NFS3_OK; } else { COMMIT_STATUS ret = openFileCtx.checkCommit(dfsClient, commitOffset, null, 0, null, true); switch (ret) { case COMMIT_FINISHED: case COMMIT_INACTIVE_CTX: status = Nfs3Status.NFS3_OK; break; case COMMIT_INACTIVE_WITH_PENDING_WRITE: case COMMIT_ERROR: status = Nfs3Status.NFS3ERR_IO; break; case COMMIT_WAIT: case COMMIT_SPECIAL_WAIT: /** * This should happen rarely in some possible cases, such as read request arrives before * DFSClient is able to quickly flush data to DN, or Prerequisite writes is not available. * Won't wait since we don't want to block read. */ status = Nfs3Status.NFS3ERR_JUKEBOX; break; case COMMIT_SPECIAL_SUCCESS: // Read beyond eof could result in partial read status = Nfs3Status.NFS3_OK; break; default: LOG.error("Should not get commit return code:" + ret.name()); throw new RuntimeException("Should not get commit return code:" + ret.name()); } } return status; }