/// <summary> /// Serialize a /// <see cref="INodeReference"/> /// node /// </summary> /// <exception cref="System.IO.IOException"/> private static void WriteINodeReference(INodeReference @ref, DataOutput @out, bool writeUnderConstruction, SnapshotFSImageFormat.ReferenceMap referenceMap) { WriteLocalName(@ref, @out); @out.WriteLong(@ref.GetId()); @out.WriteShort(0); // replication @out.WriteLong(0); // modification time @out.WriteLong(0); // access time @out.WriteLong(0); // preferred block size @out.WriteInt(-3); // # of blocks bool isWithName = @ref is INodeReference.WithName; @out.WriteBoolean(isWithName); if (!isWithName) { Preconditions.CheckState(@ref is INodeReference.DstReference); // dst snapshot id @out.WriteInt(((INodeReference.DstReference)@ref).GetDstSnapshotId()); } else { @out.WriteInt(((INodeReference.WithName)@ref).GetLastSnapshotId()); } INodeReference.WithCount withCount = (INodeReference.WithCount)@ref.GetReferredINode (); referenceMap.WriteINodeReferenceWithCount(withCount, @out, writeUnderConstruction ); }
/// <exception cref="System.IO.IOException"/> internal void LoadINodeDirectorySection(InputStream @in) { IList <INodeReference> refList = parent.GetLoaderContext().GetRefList(); while (true) { FsImageProto.INodeDirectorySection.DirEntry e = FsImageProto.INodeDirectorySection.DirEntry .ParseDelimitedFrom(@in); // note that in is a LimitedInputStream if (e == null) { break; } INodeDirectory p = dir.GetInode(e.GetParent()).AsDirectory(); foreach (long id in e.GetChildrenList()) { INode child = dir.GetInode(id); AddToParent(p, child); } foreach (int refId in e.GetRefChildrenList()) { INodeReference @ref = refList[refId]; AddToParent(p, @ref); } } }
/// <summary>This method is usually called by the undo section of rename.</summary> /// <remarks> /// This method is usually called by the undo section of rename. /// Before calling this function, in the rename operation, we replace the /// original src node (of the rename operation) with a reference node (WithName /// instance) in both the children list and a created list, delete the /// reference node from the children list, and add it to the corresponding /// deleted list. /// To undo the above operations, we have the following steps in particular: /// <pre> /// 1) remove the WithName node from the deleted list (if it exists) /// 2) replace the WithName node in the created list with srcChild /// 3) add srcChild back as a child of srcParent. Note that we already add /// the node into the created list of a snapshot diff in step 2, we do not need /// to add srcChild to the created list of the latest snapshot. /// </pre> /// We do not need to update quota usage because the old child is in the /// deleted list before. /// </remarks> /// <param name="oldChild">The reference node to be removed/replaced</param> /// <param name="newChild">The node to be added back</param> /// <exception cref="Org.Apache.Hadoop.Hdfs.Protocol.QuotaExceededException">should not throw this exception /// </exception> public virtual void UndoRename4ScrParent(INodeReference oldChild, INode newChild) { DirectoryWithSnapshotFeature sf = GetDirectoryWithSnapshotFeature(); Preconditions.CheckState(sf != null, "Directory does not have snapshot feature"); sf.GetDiffs().RemoveChild(Diff.ListType.Deleted, oldChild); sf.GetDiffs().ReplaceChild(Diff.ListType.Created, oldChild, newChild); AddChild(newChild, true, Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot .CurrentStateId); }
public override void DestroyAndCollectBlocks(BlockStoragePolicySuite bsps, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes) { int snapshot = GetSelfSnapshot(); if (RemoveReference(this) <= 0) { GetReferredINode().DestroyAndCollectBlocks(bsps, collectedBlocks, removedINodes); } else { int prior = GetPriorSnapshot(this); INode referred = GetReferredINode().AsReference().GetReferredINode(); if (snapshot != Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.NoSnapshotId) { if (prior != Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.NoSnapshotId && snapshot <= prior) { // the snapshot to be deleted has been deleted while traversing // the src tree of the previous rename operation. This usually // happens when rename's src and dst are under the same // snapshottable directory. E.g., the following operation sequence: // 1. create snapshot s1 on /test // 2. rename /test/foo/bar to /test/foo2/bar // 3. create snapshot s2 on /test // 4. rename foo2 again // 5. delete snapshot s2 return; } try { QuotaCounts counts = referred.CleanSubtree(bsps, snapshot, prior, collectedBlocks , removedINodes); INodeReference @ref = GetReferredINode().GetParentReference(); if (@ref != null) { @ref.AddSpaceConsumed(counts.Negation(), true); } } catch (QuotaExceededException e) { Log.Error("should not exceed quota while snapshot deletion", e); } } } }
public override QuotaCounts CleanSubtree(BlockStoragePolicySuite bsps, int snapshot , int prior, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes ) { // since WithName node resides in deleted list acting as a snapshot copy, // the parameter snapshot must be non-null Preconditions.CheckArgument(snapshot != Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot .CurrentStateId); // if prior is NO_SNAPSHOT_ID, we need to check snapshot belonging to the // previous WithName instance if (prior == Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.NoSnapshotId) { prior = GetPriorSnapshot(this); } if (prior != Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.NoSnapshotId && Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.IdIntegerComparator .Compare(snapshot, prior) <= 0) { return(new QuotaCounts.Builder().Build()); } QuotaCounts counts = GetReferredINode().CleanSubtree(bsps, snapshot, prior, collectedBlocks , removedINodes); INodeReference @ref = GetReferredINode().GetParentReference(); if (@ref != null) { try { @ref.AddSpaceConsumed(counts.Negation(), true); } catch (QuotaExceededException) { Org.Mortbay.Log.Log.Warn("Should not have QuotaExceededException"); } } if (snapshot < lastSnapshotId) { // for a WithName node, when we compute its quota usage, we only count // in all the nodes existing at the time of the corresponding rename op. // Thus if we are deleting a snapshot before/at the snapshot associated // with lastSnapshotId, we do not need to update the quota upwards. counts = new QuotaCounts.Builder().Build(); } return(counts); }
/// <summary>Increment and then return the reference count.</summary> public virtual void AddReference(INodeReference @ref) { if (@ref is INodeReference.WithName) { INodeReference.WithName refWithName = (INodeReference.WithName)@ref; int i = Sharpen.Collections.BinarySearch(withNameList, refWithName, WithnameComparator ); Preconditions.CheckState(i < 0); withNameList.Add(-i - 1, refWithName); } else { if (@ref is INodeReference.DstReference) { SetParentReference(@ref); } } }
/// <summary>Decrement and then return the reference count.</summary> private override int RemoveReference(INodeReference @ref) { if (@ref is INodeReference.WithName) { int i = Sharpen.Collections.BinarySearch(withNameList, (INodeReference.WithName)@ref , WithnameComparator); if (i >= 0) { withNameList.Remove(i); } } else { if (@ref == GetParentReference()) { SetParent(null); } } }
/// <summary> /// When /// <see cref="RecordModification(int)"/> /// is called on a referred node, /// this method tells which snapshot the modification should be /// associated with: the snapshot that belongs to the SRC tree of the rename /// operation, or the snapshot belonging to the DST tree. /// </summary> /// <param name="latestInDst">id of the latest snapshot in the DST tree above the reference node /// </param> /// <returns> /// True: the modification should be recorded in the snapshot that /// belongs to the SRC tree. False: the modification should be /// recorded in the snapshot that belongs to the DST tree. /// </returns> public bool ShouldRecordInSrcSnapshot(int latestInDst) { Preconditions.CheckState(!IsReference()); if (latestInDst == Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.CurrentStateId) { return(true); } INodeReference withCount = GetParentReference(); if (withCount != null) { int dstSnapshotId = withCount.GetParentReference().GetDstSnapshotId(); if (dstSnapshotId != Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.CurrentStateId && dstSnapshotId >= latestInDst) { return(true); } } return(false); }
public string GetParentString() { INodeReference parentRef = GetParentReference(); if (parentRef != null) { return("parentRef=" + parentRef.GetLocalName() + "->"); } else { INodeDirectory parentDir = GetParent(); if (parentDir != null) { return("parentDir=" + parentDir.GetLocalName() + "/"); } else { return("parent=null"); } } }
/// <exception cref="Org.Apache.Hadoop.Hdfs.Protocol.QuotaExceededException"/> internal virtual void RestoreDst(BlockStoragePolicySuite bsps) { Preconditions.CheckState(oldDstChild != null); INodeDirectory dstParent = dstParentIIP.GetLastINode().AsDirectory(); if (dstParent.IsWithSnapshot()) { dstParent.UndoRename4DstParent(bsps, oldDstChild, dstIIP.GetLatestSnapshotId()); } else { fsd.AddLastINodeNoQuotaCheck(dstParentIIP, oldDstChild); } if (oldDstChild != null && oldDstChild.IsReference()) { INodeReference removedDstRef = oldDstChild.AsReference(); INodeReference.WithCount wc = (INodeReference.WithCount)removedDstRef.GetReferredINode ().AsReference(); wc.AddReference(removedDstRef); } }
/// <summary>Set container.</summary> public void SetParentReference(INodeReference parent) { this.parent = parent; }
public WithCount(INodeReference parent, INode referred) : base(parent, referred) { Preconditions.CheckArgument(!referred.IsReference()); referred.SetParentReference(this); }