/// <summary> /// When deleting a file in the current fs directory, and the file is contained /// in a snapshot, we should delete the last block if it's under construction /// and its size is 0. /// </summary> internal virtual void CleanZeroSizeBlock(INodeFile f, INode.BlocksMapUpdateInfo collectedBlocks ) { BlockInfoContiguous[] blocks = f.GetBlocks(); if (blocks != null && blocks.Length > 0 && blocks[blocks.Length - 1] is BlockInfoContiguousUnderConstruction) { BlockInfoContiguousUnderConstruction lastUC = (BlockInfoContiguousUnderConstruction )blocks[blocks.Length - 1]; if (lastUC.GetNumBytes() == 0) { // this is a 0-sized block. do not need check its UC state here collectedBlocks.AddDeleteBlock(lastUC); f.RemoveLastBlock(lastUC); } } }
/// <exception cref="System.IO.IOException"/> public virtual BlockInfoContiguousUnderConstruction SetLastBlock(BlockInfoContiguous lastBlock, DatanodeStorageInfo[] locations) { // BlockCollection, the file should be under construction Preconditions.CheckState(IsUnderConstruction(), "file is no longer under construction" ); if (NumBlocks() == 0) { throw new IOException("Failed to set last block: File is empty."); } BlockInfoContiguousUnderConstruction ucBlock = lastBlock.ConvertToBlockUnderConstruction (HdfsServerConstants.BlockUCState.UnderConstruction, locations); SetBlock(NumBlocks() - 1, ucBlock); return(ucBlock); }
// Helper function that reads in an INodeUnderConstruction // from the input stream // /// <exception cref="System.IO.IOException"/> internal static INodeFile ReadINodeUnderConstruction(DataInput @in, FSNamesystem fsNamesys, int imgVersion) { byte[] name = ReadBytes(@in); long inodeId = NameNodeLayoutVersion.Supports(LayoutVersion.Feature.AddInodeId, imgVersion ) ? @in.ReadLong() : fsNamesys.dir.AllocateNewInodeId(); short blockReplication = @in.ReadShort(); long modificationTime = @in.ReadLong(); long preferredBlockSize = @in.ReadLong(); int numBlocks = @in.ReadInt(); BlockInfoContiguous[] blocks = new BlockInfoContiguous[numBlocks]; Block blk = new Block(); int i = 0; for (; i < numBlocks - 1; i++) { blk.ReadFields(@in); blocks[i] = new BlockInfoContiguous(blk, blockReplication); } // last block is UNDER_CONSTRUCTION if (numBlocks > 0) { blk.ReadFields(@in); blocks[i] = new BlockInfoContiguousUnderConstruction(blk, blockReplication, HdfsServerConstants.BlockUCState .UnderConstruction, null); } PermissionStatus perm = PermissionStatus.Read(@in); string clientName = ReadString(@in); string clientMachine = ReadString(@in); // We previously stored locations for the last block, now we // just record that there are none int numLocs = @in.ReadInt(); System.Diagnostics.Debug.Assert(numLocs == 0, "Unexpected block locations"); // Images in the pre-protobuf format will not have the lazyPersist flag, // so it is safe to pass false always. INodeFile file = new INodeFile(inodeId, name, perm, modificationTime, modificationTime , blocks, blockReplication, preferredBlockSize, unchecked ((byte)0)); file.ToUnderConstruction(clientName, clientMachine); return(file); }
/// <exception cref="System.IO.IOException"/> private FSNamesystem MakeNameSystemSpy(Block block, INodeFile file) { Configuration conf = new Configuration(); FSImage image = new FSImage(conf); DatanodeStorageInfo[] targets = new DatanodeStorageInfo[] { }; FSNamesystem namesystem = new FSNamesystem(conf, image); namesystem.SetImageLoaded(true); // set file's parent as root and put the file to inodeMap, so // FSNamesystem's isFileDeleted() method will return false on this file if (file.GetParent() == null) { INodeDirectory mparent = Org.Mockito.Mockito.Mock <INodeDirectory>(); INodeDirectory parent = new INodeDirectory(mparent.GetId(), new byte[0], mparent. GetPermissionStatus(), mparent.GetAccessTime()); parent.SetLocalName(new byte[0]); parent.AddChild(file); file.SetParent(parent); } namesystem.dir.GetINodeMap().Put(file); FSNamesystem namesystemSpy = Org.Mockito.Mockito.Spy(namesystem); BlockInfoContiguousUnderConstruction blockInfo = new BlockInfoContiguousUnderConstruction (block, (short)1, HdfsServerConstants.BlockUCState.UnderConstruction, targets); blockInfo.SetBlockCollection(file); blockInfo.SetGenerationStamp(genStamp); blockInfo.InitializeBlockRecovery(genStamp); Org.Mockito.Mockito.DoReturn(true).When(file).RemoveLastBlock(Matchers.Any <Block> ()); Org.Mockito.Mockito.DoReturn(true).When(file).IsUnderConstruction(); Org.Mockito.Mockito.DoReturn(new BlockInfoContiguous[1]).When(file).GetBlocks(); Org.Mockito.Mockito.DoReturn(blockInfo).When(namesystemSpy).GetStoredBlock(Matchers.Any <Block>()); Org.Mockito.Mockito.DoReturn(blockInfo).When(file).GetLastBlock(); Org.Mockito.Mockito.DoReturn(string.Empty).When(namesystemSpy).CloseFileCommitBlocks (Matchers.Any <INodeFile>(), Matchers.Any <BlockInfoContiguous>()); Org.Mockito.Mockito.DoReturn(Org.Mockito.Mockito.Mock <FSEditLog>()).When(namesystemSpy ).GetEditLog(); return(namesystemSpy); }