예제 #1
0
        /// <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
                                                      );
        }
예제 #2
0
            /// <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);
                    }
                }
            }
예제 #3
0
        /// <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);
        }
예제 #4
0
            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);
                        }
                    }
                }
            }
예제 #5
0
            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);
            }
예제 #6
0
 /// <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);
         }
     }
 }
예제 #7
0
 /// <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);
         }
     }
 }
예제 #8
0
        /// <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);
        }
예제 #9
0
        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");
                }
            }
        }
예제 #10
0
            /// <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);
                }
            }
예제 #11
0
 /// <summary>Set container.</summary>
 public void SetParentReference(INodeReference parent)
 {
     this.parent = parent;
 }
예제 #12
0
 public WithCount(INodeReference parent, INode referred)
     : base(parent, referred)
 {
     Preconditions.CheckArgument(!referred.IsReference());
     referred.SetParentReference(this);
 }