예제 #1
0
  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);
  }
예제 #2
0
  // 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;
  }