public void commitBlockSynchronization(Block lastblock,
                                  long newgenerationstamp, long newlength,
                                  boolean closeFile, boolean deleteblock, DatanodeID[] newtargets
  ) throws IOException {
    LOG.info("commitBlockSynchronization(lastblock=" + lastblock
      + ", newgenerationstamp=" + newgenerationstamp
      + ", newlength=" + newlength
      + ", newtargets=" + Arrays.asList(newtargets)
      + ", closeFile=" + closeFile
      + ", deleteBlock=" + deleteblock
      + ")");
    String src = null;
    writeLock();
    try {
      if (isInSafeMode()) {
        throw new SafeModeException("Cannot commitBlockSynchronization "
          + lastblock, safeMode);
      }      
      Block blockWithWildcardGenstamp = new Block(lastblock.getBlockId());
      final BlockInfo oldblockinfo = blocksMap.getStoredBlock(blockWithWildcardGenstamp);
      if (oldblockinfo == null) {
        throw new IOException("Block (=" + lastblock + ") not found");
      }
      if (!deleteblock
          && lastblock.getGenerationStamp() != oldblockinfo
              .getGenerationStamp()
          && oldblockinfo.getGenerationStamp() >= newgenerationstamp) {
        throw new IOException("Try to update block " + oldblockinfo
            + " to generation stamp " + newgenerationstamp);
      }
      INodeFile iFile = oldblockinfo.getINode();
      if (!iFile.isUnderConstruction()) {
        throw new IOException("Unexpected block (=" + lastblock
          + ") since the file (=" + iFile.getLocalName()
          + ") is not under construction");
      }
      INodeFileUnderConstruction pendingFile = (INodeFileUnderConstruction) iFile;
      // Fail the request if the block being synchronized is not the last block
      // of the file.
      pendingFile.checkLastBlockId(lastblock.getBlockId());

      // Remove old block from blocks map. This always have to be done
      // because the generation stamp of this block is changing.
      blocksMap.removeBlock(oldblockinfo);

      if (deleteblock) {
        pendingFile.removeBlock(lastblock);
      } else {
        // update last block, construct newblockinfo and add it to the blocks map
        lastblock.set(lastblock.getBlockId(), newlength, newgenerationstamp);
        final BlockInfo newblockinfo = 
            blocksMap.addINode(lastblock, pendingFile, 
                               pendingFile.getReplication());

        // find the DatanodeDescriptor objects
        // There should be no locations in the blocksMap till now because the
        // file is underConstruction
        DatanodeDescriptor[] descriptors = null;
        List<DatanodeDescriptor> descriptorsList =
          new ArrayList<DatanodeDescriptor>(newtargets.length);
        for(int i = 0; i < newtargets.length; i++) {
          // We don't use getDatanode here since that method can
          // throw. If we were to throw an exception during this commit
          // process, we'd fall out of sync since DNs have already finalized
          // the block with the new GS.
          DatanodeDescriptor node =
            datanodeMap.get(newtargets[i].getStorageID());
          if (node != null) {
            if (closeFile) {
              // If we aren't closing the file, we shouldn't add it to the
              // block list for the node, since the block is still under
              // construction there. (in getAdditionalBlock, for example
              // we don't add to the block map for the targets)
              node.addBlock(newblockinfo);
            }
            descriptorsList.add(node);
          } else {
          LOG.error("commitBlockSynchronization included a target DN " +
            newtargets[i] + " which is not known to NN. Ignoring.");
          }
        }
        if (!descriptorsList.isEmpty()) {
          descriptors = descriptorsList.toArray(new DatanodeDescriptor[0]);
        }
        // add locations into the INodeUnderConstruction
        pendingFile.setLastBlock(newblockinfo, descriptors);
      }

      // Get the file's full name; make sure that the file is valid
      src = pendingFile.getFullPathName();
      
      // If this commit does not want to close the file, persist
      // blocks only if append is supported and return
      if (!closeFile) {
        // persist the blocks if we support appends, 
        // or the block was deleted from the file and we need to persist it
        if (supportAppends || persistBlocks) {
          dir.persistBlocks(src, pendingFile);
        }
      } else {
        // remove lease, close file
        // this will persist the blocks
        finalizeINodeFileUnderConstruction(src, pendingFile);
      }
    } finally {// end of synchronized section
      writeUnlock();
    }

    if (closeFile || supportAppends) {
      getEditLog().logSync();
    }
    LOG.info("commitBlockSynchronization(newblock=" + lastblock
      + ", file=" + src + ") successful");
  }
public void commitBlockSynchronization ( Block lastblock , long newgenerationstamp , long newlength , boolean closeFile , boolean deleteblock , DatanodeID [ ] newtargets ) throws IOException { LOG . info ( "commitBlockSynchronization(lastblock=" + lastblock + ", newgenerationstamp=" + newgenerationstamp + ", newlength=" + newlength + ", newtargets=" + Arrays . asList ( newtargets ) + ", closeFile=" + closeFile + ", deleteBlock=" + deleteblock + ")" ) ; String src = null ; writeLock ( ) ; try { if ( isInSafeMode ( ) ) { throw new SafeModeException ( "Cannot commitBlockSynchronization " + lastblock , safeMode ) ; } Block blockWithWildcardGenstamp = new Block ( lastblock . getBlockId ( ) ) ; final BlockInfo oldblockinfo = blocksMap . getStoredBlock ( blockWithWildcardGenstamp ) ; if ( oldblockinfo == null ) { throw new IOException ( "Block (=" + lastblock + ") not found" ) ; } if ( ! deleteblock && lastblock . getGenerationStamp ( ) != oldblockinfo . getGenerationStamp ( ) && oldblockinfo . getGenerationStamp ( ) >= newgenerationstamp ) { throw new IOException ( "Try to update block " + oldblockinfo + " to generation stamp " + newgenerationstamp ) ; } INodeFile iFile = oldblockinfo . getINode ( ) ; if ( ! iFile . isUnderConstruction ( ) ) { throw new IOException ( "Unexpected block (=" + lastblock + ") since the file (=" + iFile . getLocalName ( ) + ") is not under construction" ) ; } INodeFileUnderConstruction pendingFile = ( INodeFileUnderConstruction ) iFile ; pendingFile . checkLastBlockId ( lastblock . getBlockId ( ) ) ; blocksMap . removeBlock ( oldblockinfo ) ; if ( deleteblock ) { pendingFile . removeBlock ( lastblock ) ; } else { lastblock . set ( lastblock . getBlockId ( ) , newlength , newgenerationstamp ) ; final BlockInfo newblockinfo = blocksMap . addINode ( lastblock , pendingFile , pendingFile . getReplication ( ) ) ; DatanodeDescriptor [ ] descriptors = null ; List < DatanodeDescriptor > descriptorsList = new ArrayList < DatanodeDescriptor > ( newtargets . length ) ; for ( int i = 0 ; i < newtargets . length ; i ++ ) { DatanodeDescriptor node = datanodeMap . get ( newtargets [ i ] . getStorageID ( ) ) ; if ( node != null ) { if ( closeFile ) { node . addBlock ( newblockinfo ) ; } descriptorsList . add ( node ) ; } else { LOG . error ( "commitBlockSynchronization included a target DN " + newtargets [ i ] + " which is not known to NN. Ignoring." ) ; } } if ( ! descriptorsList . isEmpty ( ) ) { descriptors = descriptorsList . toArray ( new DatanodeDescriptor [ 0 ] ) ; } pendingFile . setLastBlock ( newblockinfo , descriptors ) ; } src = pendingFile . getFullPathName ( ) ; if ( ! closeFile ) { if ( supportAppends || persistBlocks ) { dir . persistBlocks ( src , pendingFile ) ; } } else { finalizeINodeFileUnderConstruction ( src , pendingFile ) ; } } finally { writeUnlock ( ) ; } if ( closeFile || supportAppends ) { getEditLog ( ) . logSync ( ) ; } LOG . info ( "commitBlockSynchronization(newblock=" + lastblock + ", file=" + src + ") successful" ) ; }
public only for testing