/// <summary>
        /// If some blocks at the end of the block list no longer belongs to
        /// any inode, collect them and update the block list.
        /// </summary>
        public virtual void CollectBlocksAndClear(BlockStoragePolicySuite bsps, INodeFile
                                                  file, INode.BlocksMapUpdateInfo info, IList <INode> removedINodes)
        {
            // check if everything is deleted.
            if (IsCurrentFileDeleted() && GetDiffs().AsList().IsEmpty())
            {
                file.DestroyAndCollectBlocks(bsps, info, removedINodes);
                return;
            }
            // find max file size.
            long     max;
            FileDiff diff = GetDiffs().GetLast();

            if (IsCurrentFileDeleted())
            {
                max = diff == null ? 0 : diff.GetFileSize();
            }
            else
            {
                max = file.ComputeFileSize();
            }
            // Collect blocks that should be deleted
            FileDiff last = diffs.GetLast();

            BlockInfoContiguous[] snapshotBlocks = last == null ? null : last.GetBlocks();
            if (snapshotBlocks == null)
            {
                file.CollectBlocksBeyondMax(max, info);
            }
            else
            {
                file.CollectBlocksBeyondSnapshot(snapshotBlocks, info);
            }
        }
Exemplo n.º 2
0
 public virtual void DestroyAndCollectSnapshotBlocks(INode.BlocksMapUpdateInfo collectedBlocks
                                                     )
 {
     foreach (FileDiff d in AsList())
     {
         d.DestroyAndCollectSnapshotBlocks(collectedBlocks);
     }
 }
Exemplo n.º 3
0
        /// <summary>Delete a snapshot for a snapshottable directory</summary>
        /// <param name="snapshotName">Name of the snapshot to be deleted</param>
        /// <param name="collectedBlocks">Used to collect information to update blocksMap</param>
        /// <exception cref="System.IO.IOException"/>
        public virtual void DeleteSnapshot(INodesInPath iip, string snapshotName, INode.BlocksMapUpdateInfo
                                           collectedBlocks, IList <INode> removedINodes)
        {
            INodeDirectory srcRoot = GetSnapshottableRoot(iip);

            srcRoot.RemoveSnapshot(fsdir.GetBlockStoragePolicySuite(), snapshotName, collectedBlocks
                                   , removedINodes);
            numSnapshots.GetAndDecrement();
        }
Exemplo n.º 4
0
            internal override QuotaCounts CombinePosteriorAndCollectBlocks(BlockStoragePolicySuite
                                                                           bsps, INodeDirectory currentDir, DirectoryWithSnapshotFeature.DirectoryDiff posterior
                                                                           , INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes)
            {
                QuotaCounts counts = new QuotaCounts.Builder().Build();

                diff.CombinePosterior(posterior.diff, new _Processor_218(bsps, counts, collectedBlocks
                                                                         , removedINodes));
                return(counts);
            }
Exemplo n.º 5
0
        internal override QuotaCounts CombinePosteriorAndCollectBlocks(BlockStoragePolicySuite
                                                                       bsps, INodeFile currentINode, Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.FileDiff
                                                                       posterior, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes
                                                                       )
        {
            FileWithSnapshotFeature sf = currentINode.GetFileWithSnapshotFeature();

            System.Diagnostics.Debug.Assert(sf != null, "FileWithSnapshotFeature is null");
            return(sf.UpdateQuotaAndCollectBlocks(bsps, currentINode, posterior, collectedBlocks
                                                  , removedINodes));
        }
Exemplo n.º 6
0
 public virtual void Clear(BlockStoragePolicySuite bsps, INodeDirectory currentINode
                           , INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes)
 {
     // destroy its diff list
     foreach (DirectoryWithSnapshotFeature.DirectoryDiff diff in diffs)
     {
         diff.DestroyDiffAndCollectBlocks(bsps, currentINode, collectedBlocks, removedINodes
                                          );
     }
     diffs.Clear();
 }
Exemplo n.º 7
0
 public virtual void DestroyAndCollectSnapshotBlocks(INode.BlocksMapUpdateInfo collectedBlocks
                                                     )
 {
     if (blocks == null || collectedBlocks == null)
     {
         return;
     }
     foreach (BlockInfoContiguous blk in blocks)
     {
         collectedBlocks.AddDeleteBlock(blk);
     }
     blocks = null;
 }
Exemplo n.º 8
0
        /// <summary>Delete a snapshot.</summary>
        /// <remarks>
        /// Delete a snapshot. The synchronization of the diff list will be done
        /// outside. If the diff to remove is not the first one in the diff list, we
        /// need to combine the diff with its previous one.
        /// </remarks>
        /// <param name="snapshot">The id of the snapshot to be deleted</param>
        /// <param name="prior">The id of the snapshot taken before the to-be-deleted snapshot
        ///     </param>
        /// <param name="collectedBlocks">Used to collect information for blocksMap update</param>
        /// <returns>delta in namespace.</returns>
        public QuotaCounts DeleteSnapshotDiff(BlockStoragePolicySuite bsps, int snapshot,
                                              int prior, N currentINode, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode
                                                                                                                           > removedINodes)
        {
            int         snapshotIndex = Sharpen.Collections.BinarySearch(diffs, snapshot);
            QuotaCounts counts        = new QuotaCounts.Builder().Build();
            D           removed       = null;

            if (snapshotIndex == 0)
            {
                if (prior != Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.NoSnapshotId)
                {
                    // there is still snapshot before
                    // set the snapshot to latestBefore
                    diffs[snapshotIndex].SetSnapshotId(prior);
                }
                else
                {
                    // there is no snapshot before
                    removed = diffs.Remove(0);
                    counts.Add(removed.DestroyDiffAndCollectBlocks(bsps, currentINode, collectedBlocks
                                                                   , removedINodes));
                }
            }
            else
            {
                if (snapshotIndex > 0)
                {
                    AbstractINodeDiff <N, A, D> previous = diffs[snapshotIndex - 1];
                    if (previous.GetSnapshotId() != prior)
                    {
                        diffs[snapshotIndex].SetSnapshotId(prior);
                    }
                    else
                    {
                        // combine the to-be-removed diff with its previous diff
                        removed = diffs.Remove(snapshotIndex);
                        if (previous.snapshotINode == null)
                        {
                            previous.snapshotINode = removed.snapshotINode;
                        }
                        counts.Add(previous.CombinePosteriorAndCollectBlocks(bsps, currentINode, removed,
                                                                             collectedBlocks, removedINodes));
                        previous.SetPosterior(removed.GetPosterior());
                        removed.SetPosterior(null);
                    }
                }
            }
            return(counts);
        }
Exemplo n.º 9
0
            /// <summary>clear the deleted list</summary>
            private QuotaCounts DestroyDeletedList(BlockStoragePolicySuite bsps, INode.BlocksMapUpdateInfo
                                                   collectedBlocks, IList <INode> removedINodes)
            {
                QuotaCounts   counts      = new QuotaCounts.Builder().Build();
                IList <INode> deletedList = GetList(Diff.ListType.Deleted);

                foreach (INode d in deletedList)
                {
                    d.ComputeQuotaUsage(bsps, counts, false);
                    d.DestroyAndCollectBlocks(bsps, collectedBlocks, removedINodes);
                }
                deletedList.Clear();
                return(counts);
            }
Exemplo n.º 10
0
            /// <summary>clear the created list</summary>
            private QuotaCounts DestroyCreatedList(BlockStoragePolicySuite bsps, INodeDirectory
                                                   currentINode, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes
                                                   )
            {
                QuotaCounts   counts      = new QuotaCounts.Builder().Build();
                IList <INode> createdList = GetList(Diff.ListType.Created);

                foreach (INode c in createdList)
                {
                    c.ComputeQuotaUsage(bsps, counts, true);
                    c.DestroyAndCollectBlocks(bsps, collectedBlocks, removedINodes);
                    // c should be contained in the children list, remove it
                    currentINode.RemoveChild(c);
                }
                createdList.Clear();
                return(counts);
            }
Exemplo n.º 11
0
        /// <summary>
        /// Remove the snapshot with the given name from
        /// <see cref="snapshotsByNames"/>
        /// ,
        /// and delete all the corresponding DirectoryDiff.
        /// </summary>
        /// <param name="snapshotRoot">The directory where we take snapshots</param>
        /// <param name="snapshotName">The name of the snapshot to be removed</param>
        /// <param name="collectedBlocks">Used to collect information to update blocksMap</param>
        /// <returns>
        /// The removed snapshot. Null if no snapshot with the given name
        /// exists.
        /// </returns>
        /// <exception cref="Org.Apache.Hadoop.Hdfs.Protocol.SnapshotException"/>
        public virtual Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot RemoveSnapshot
            (BlockStoragePolicySuite bsps, INodeDirectory snapshotRoot, string snapshotName,
            INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes)
        {
            int i = SearchSnapshot(DFSUtil.String2Bytes(snapshotName));

            if (i < 0)
            {
                throw new SnapshotException("Cannot delete snapshot " + snapshotName + " from path "
                                            + snapshotRoot.GetFullPathName() + ": the snapshot does not exist.");
            }
            else
            {
                Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot snapshot = snapshotsByNames
                                                                                    [i];
                int prior = Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.FindLatestSnapshot
                                (snapshotRoot, snapshot.GetId());
                try
                {
                    QuotaCounts counts = snapshotRoot.CleanSubtree(bsps, snapshot.GetId(), prior, collectedBlocks
                                                                   , removedINodes);
                    INodeDirectory parent = snapshotRoot.GetParent();
                    if (parent != null)
                    {
                        // there will not be any WithName node corresponding to the deleted
                        // snapshot, thus only update the quota usage in the current tree
                        parent.AddSpaceConsumed(counts.Negation(), true);
                    }
                }
                catch (QuotaExceededException e)
                {
                    INode.Log.Error("BUG: removeSnapshot increases namespace usage.", e);
                }
                // remove from snapshotsByNames after successfully cleaning the subtree
                snapshotsByNames.Remove(i);
                return(snapshot);
            }
        }
Exemplo n.º 12
0
 public virtual QuotaCounts CleanFile(BlockStoragePolicySuite bsps, INodeFile file
                                      , int snapshotId, int priorSnapshotId, INode.BlocksMapUpdateInfo collectedBlocks
                                      , IList <INode> removedINodes)
 {
     if (snapshotId == Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.CurrentStateId)
     {
         // delete the current file while the file has snapshot feature
         if (!IsCurrentFileDeleted())
         {
             file.RecordModification(priorSnapshotId);
             DeleteCurrentFile();
         }
         CollectBlocksAndClear(bsps, file, collectedBlocks, removedINodes);
         return(new QuotaCounts.Builder().Build());
     }
     else
     {
         // delete the snapshot
         priorSnapshotId = GetDiffs().UpdatePrior(snapshotId, priorSnapshotId);
         return(diffs.DeleteSnapshotDiff(bsps, snapshotId, priorSnapshotId, file, collectedBlocks
                                         , removedINodes));
     }
 }
Exemplo n.º 13
0
 internal override QuotaCounts DestroyDiffAndCollectBlocks(BlockStoragePolicySuite
                                                           bsps, INodeFile currentINode, INode.BlocksMapUpdateInfo collectedBlocks, IList <
                                                               INode> removedINodes)
 {
     return(currentINode.GetFileWithSnapshotFeature().UpdateQuotaAndCollectBlocks(bsps
                                                                                  , currentINode, this, collectedBlocks, removedINodes));
 }
Exemplo n.º 14
0
        /// <summary>
        /// Copy blocks from the removed snapshot into the previous snapshot
        /// up to the file length of the latter.
        /// </summary>
        /// <remarks>
        /// Copy blocks from the removed snapshot into the previous snapshot
        /// up to the file length of the latter.
        /// Collect unused blocks of the removed snapshot.
        /// </remarks>
        internal virtual void CombineAndCollectSnapshotBlocks(BlockStoragePolicySuite bsps
                                                              , INodeFile file, FileDiff removed, INode.BlocksMapUpdateInfo collectedBlocks, IList
                                                              <INode> removedINodes)
        {
            BlockInfoContiguous[] removedBlocks = removed.GetBlocks();
            if (removedBlocks == null)
            {
                FileWithSnapshotFeature sf = file.GetFileWithSnapshotFeature();
                System.Diagnostics.Debug.Assert(sf != null, "FileWithSnapshotFeature is null");
                if (sf.IsCurrentFileDeleted())
                {
                    sf.CollectBlocksAndClear(bsps, file, collectedBlocks, removedINodes);
                }
                return;
            }
            int      p           = GetPrior(removed.GetSnapshotId(), true);
            FileDiff earlierDiff = p == Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot
                                   .NoSnapshotId ? null : GetDiffById(p);

            // Copy blocks to the previous snapshot if not set already
            if (earlierDiff != null)
            {
                earlierDiff.SetBlocks(removedBlocks);
            }
            BlockInfoContiguous[] earlierBlocks = (earlierDiff == null ? new BlockInfoContiguous
                                                   [] {  } : earlierDiff.GetBlocks());
            // Find later snapshot (or file itself) with blocks
            BlockInfoContiguous[] laterBlocks = FindLaterSnapshotBlocks(removed.GetSnapshotId
                                                                            ());
            laterBlocks = (laterBlocks == null) ? file.GetBlocks() : laterBlocks;
            // Skip blocks, which belong to either the earlier or the later lists
            int i = 0;

            for (; i < removedBlocks.Length; i++)
            {
                if (i < earlierBlocks.Length && removedBlocks[i] == earlierBlocks[i])
                {
                    continue;
                }
                if (i < laterBlocks.Length && removedBlocks[i] == laterBlocks[i])
                {
                    continue;
                }
                break;
            }
            // Check if last block is part of truncate recovery
            BlockInfoContiguous lastBlock = file.GetLastBlock();
            Block dontRemoveBlock         = null;

            if (lastBlock != null && lastBlock.GetBlockUCState().Equals(HdfsServerConstants.BlockUCState
                                                                        .UnderRecovery))
            {
                dontRemoveBlock = ((BlockInfoContiguousUnderConstruction)lastBlock).GetTruncateBlock
                                      ();
            }
            // Collect the remaining blocks of the file, ignoring truncate block
            for (; i < removedBlocks.Length; i++)
            {
                if (dontRemoveBlock == null || !removedBlocks[i].Equals(dontRemoveBlock))
                {
                    collectedBlocks.AddDeleteBlock(removedBlocks[i]);
                }
            }
        }
Exemplo n.º 15
0
        public virtual QuotaCounts UpdateQuotaAndCollectBlocks(BlockStoragePolicySuite bsps
                                                               , INodeFile file, FileDiff removed, INode.BlocksMapUpdateInfo collectedBlocks, IList
                                                               <INode> removedINodes)
        {
            long oldStoragespace                  = file.StoragespaceConsumed();
            byte storagePolicyID                  = file.GetStoragePolicyID();
            BlockStoragePolicy         bsp        = null;
            EnumCounters <StorageType> typeSpaces = new EnumCounters <StorageType>(typeof(StorageType
                                                                                          ));

            if (storagePolicyID != BlockStoragePolicySuite.IdUnspecified)
            {
                bsp = bsps.GetPolicy(file.GetStoragePolicyID());
            }
            if (removed.snapshotINode != null)
            {
                short replication = removed.snapshotINode.GetFileReplication();
                short currentRepl = file.GetBlockReplication();
                if (currentRepl == 0)
                {
                    long oldFileSizeNoRep = file.ComputeFileSize(true, true);
                    oldStoragespace = oldFileSizeNoRep * replication;
                    if (bsp != null)
                    {
                        IList <StorageType> oldTypeChosen = bsp.ChooseStorageTypes(replication);
                        foreach (StorageType t in oldTypeChosen)
                        {
                            if (t.SupportTypeQuota())
                            {
                                typeSpaces.Add(t, -oldFileSizeNoRep);
                            }
                        }
                    }
                }
                else
                {
                    if (replication > currentRepl)
                    {
                        long oldFileSizeNoRep = file.StoragespaceConsumedNoReplication();
                        oldStoragespace = oldFileSizeNoRep * replication;
                        if (bsp != null)
                        {
                            IList <StorageType> oldTypeChosen = bsp.ChooseStorageTypes(replication);
                            foreach (StorageType t in oldTypeChosen)
                            {
                                if (t.SupportTypeQuota())
                                {
                                    typeSpaces.Add(t, -oldFileSizeNoRep);
                                }
                            }
                            IList <StorageType> newTypeChosen = bsp.ChooseStorageTypes(currentRepl);
                            foreach (StorageType t_1 in newTypeChosen)
                            {
                                if (t_1.SupportTypeQuota())
                                {
                                    typeSpaces.Add(t_1, oldFileSizeNoRep);
                                }
                            }
                        }
                    }
                }
                AclFeature aclFeature = removed.GetSnapshotINode().GetAclFeature();
                if (aclFeature != null)
                {
                    AclStorage.RemoveAclFeature(aclFeature);
                }
            }
            GetDiffs().CombineAndCollectSnapshotBlocks(bsps, file, removed, collectedBlocks,
                                                       removedINodes);
            long ssDelta = oldStoragespace - file.StoragespaceConsumed();

            return(new QuotaCounts.Builder().StorageSpace(ssDelta).TypeSpaces(typeSpaces).Build
                       ());
        }
Exemplo n.º 16
0
 public _Processor_218(BlockStoragePolicySuite bsps, QuotaCounts counts, INode.BlocksMapUpdateInfo
                       collectedBlocks, IList <INode> removedINodes)
 {
     this.bsps            = bsps;
     this.counts          = counts;
     this.collectedBlocks = collectedBlocks;
     this.removedINodes   = removedINodes;
 }
Exemplo n.º 17
0
 /// <summary>Delete and clear self.</summary>
 /// <param name="bsps">The block storage policy suite used to retrieve storage policy
 ///     </param>
 /// <param name="currentINode">The inode where the deletion happens.</param>
 /// <param name="collectedBlocks">Used to collect blocks for deletion.</param>
 /// <param name="removedINodes">INodes removed</param>
 /// <returns>quota usage delta</returns>
 internal abstract QuotaCounts DestroyDiffAndCollectBlocks(BlockStoragePolicySuite
                                                           bsps, N currentINode, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes
                                                           );
Exemplo n.º 18
0
 /// <summary>Combine the posterior diff and collect blocks for deletion.</summary>
 internal abstract QuotaCounts CombinePosteriorAndCollectBlocks(BlockStoragePolicySuite
                                                                bsps, N currentINode, D posterior, INode.BlocksMapUpdateInfo collectedBlocks, IList
                                                                <INode> removedINodes);
Exemplo n.º 19
0
        public virtual QuotaCounts CleanDirectory(BlockStoragePolicySuite bsps, INodeDirectory
                                                  currentINode, int snapshot, int prior, INode.BlocksMapUpdateInfo collectedBlocks
                                                  , IList <INode> removedINodes)
        {
            QuotaCounts counts = new QuotaCounts.Builder().Build();
            IDictionary <INode, INode> priorCreated = null;
            IDictionary <INode, INode> priorDeleted = null;

            if (snapshot == Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.CurrentStateId)
            {
                // delete the current directory
                currentINode.RecordModification(prior);
                // delete everything in created list
                DirectoryWithSnapshotFeature.DirectoryDiff lastDiff = diffs.GetLast();
                if (lastDiff != null)
                {
                    counts.Add(lastDiff.diff.DestroyCreatedList(bsps, currentINode, collectedBlocks,
                                                                removedINodes));
                }
                counts.Add(currentINode.CleanSubtreeRecursively(bsps, snapshot, prior, collectedBlocks
                                                                , removedINodes, priorDeleted));
            }
            else
            {
                // update prior
                prior = GetDiffs().UpdatePrior(snapshot, prior);
                // if there is a snapshot diff associated with prior, we need to record
                // its original created and deleted list before deleting post
                if (prior != Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.NoSnapshotId)
                {
                    DirectoryWithSnapshotFeature.DirectoryDiff priorDiff = this.GetDiffs().GetDiffById
                                                                               (prior);
                    if (priorDiff != null && priorDiff.GetSnapshotId() == prior)
                    {
                        IList <INode> cList = priorDiff.diff.GetList(Diff.ListType.Created);
                        IList <INode> dList = priorDiff.diff.GetList(Diff.ListType.Deleted);
                        priorCreated = CloneDiffList(cList);
                        priorDeleted = CloneDiffList(dList);
                    }
                }
                counts.Add(GetDiffs().DeleteSnapshotDiff(bsps, snapshot, prior, currentINode, collectedBlocks
                                                         , removedINodes));
                counts.Add(currentINode.CleanSubtreeRecursively(bsps, snapshot, prior, collectedBlocks
                                                                , removedINodes, priorDeleted));
                // check priorDiff again since it may be created during the diff deletion
                if (prior != Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.NoSnapshotId)
                {
                    DirectoryWithSnapshotFeature.DirectoryDiff priorDiff = this.GetDiffs().GetDiffById
                                                                               (prior);
                    if (priorDiff != null && priorDiff.GetSnapshotId() == prior)
                    {
                        // For files/directories created between "prior" and "snapshot",
                        // we need to clear snapshot copies for "snapshot". Note that we must
                        // use null as prior in the cleanSubtree call. Files/directories that
                        // were created before "prior" will be covered by the later
                        // cleanSubtreeRecursively call.
                        if (priorCreated != null)
                        {
                            // we only check the node originally in prior's created list
                            foreach (INode cNode in priorDiff.GetChildrenDiff().GetList(Diff.ListType.Created
                                                                                        ))
                            {
                                if (priorCreated.Contains(cNode))
                                {
                                    counts.Add(cNode.CleanSubtree(bsps, snapshot, Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot
                                                                  .NoSnapshotId, collectedBlocks, removedINodes));
                                }
                            }
                        }
                        // When a directory is moved from the deleted list of the posterior
                        // diff to the deleted list of this diff, we need to destroy its
                        // descendants that were 1) created after taking this diff and 2)
                        // deleted after taking posterior diff.
                        // For files moved from posterior's deleted list, we also need to
                        // delete its snapshot copy associated with the posterior snapshot.
                        foreach (INode dNode in priorDiff.GetChildrenDiff().GetList(Diff.ListType.Deleted
                                                                                    ))
                        {
                            if (priorDeleted == null || !priorDeleted.Contains(dNode))
                            {
                                counts.Add(CleanDeletedINode(bsps, dNode, snapshot, prior, collectedBlocks, removedINodes
                                                             ));
                            }
                        }
                    }
                }
            }
            if (currentINode.IsQuotaSet())
            {
                currentINode.GetDirectoryWithQuotaFeature().AddSpaceConsumed2Cache(counts.Negation
                                                                                       ());
            }
            return(counts);
        }
Exemplo n.º 20
0
            internal override QuotaCounts DestroyDiffAndCollectBlocks(BlockStoragePolicySuite
                                                                      bsps, INodeDirectory currentINode, INode.BlocksMapUpdateInfo collectedBlocks, IList
                                                                      <INode> removedINodes)
            {
                // this diff has been deleted
                QuotaCounts counts = new QuotaCounts.Builder().Build();

                counts.Add(diff.DestroyDeletedList(bsps, collectedBlocks, removedINodes));
                INodeDirectoryAttributes snapshotINode = GetSnapshotINode();

                if (snapshotINode != null && snapshotINode.GetAclFeature() != null)
                {
                    AclStorage.RemoveAclFeature(snapshotINode.GetAclFeature());
                }
                return(counts);
            }
Exemplo n.º 21
0
        /// <summary>
        /// Clean an inode while we move it from the deleted list of post to the
        /// deleted list of prior.
        /// </summary>
        /// <param name="bsps">The block storage policy suite.</param>
        /// <param name="inode">The inode to clean.</param>
        /// <param name="post">The post snapshot.</param>
        /// <param name="prior">The id of the prior snapshot.</param>
        /// <param name="collectedBlocks">Used to collect blocks for later deletion.</param>
        /// <returns>Quota usage update.</returns>
        private static QuotaCounts CleanDeletedINode(BlockStoragePolicySuite bsps, INode
                                                     inode, int post, int prior, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode
                                                                                                                                   > removedINodes)
        {
            QuotaCounts   counts = new QuotaCounts.Builder().Build();
            Deque <INode> queue  = new ArrayDeque <INode>();

            queue.AddLast(inode);
            while (!queue.IsEmpty())
            {
                INode topNode = queue.PollFirst();
                if (topNode is INodeReference.WithName)
                {
                    INodeReference.WithName wn = (INodeReference.WithName)topNode;
                    if (wn.GetLastSnapshotId() >= post)
                    {
                        wn.CleanSubtree(bsps, post, prior, collectedBlocks, removedINodes);
                    }
                }
                else
                {
                    // For DstReference node, since the node is not in the created list of
                    // prior, we should treat it as regular file/dir
                    if (topNode.IsFile() && topNode.AsFile().IsWithSnapshot())
                    {
                        INodeFile file = topNode.AsFile();
                        counts.Add(file.GetDiffs().DeleteSnapshotDiff(bsps, post, prior, file, collectedBlocks
                                                                      , removedINodes));
                    }
                    else
                    {
                        if (topNode.IsDirectory())
                        {
                            INodeDirectory dir = topNode.AsDirectory();
                            DirectoryWithSnapshotFeature.ChildrenDiff priorChildrenDiff = null;
                            DirectoryWithSnapshotFeature sf = dir.GetDirectoryWithSnapshotFeature();
                            if (sf != null)
                            {
                                // delete files/dirs created after prior. Note that these
                                // files/dirs, along with inode, were deleted right after post.
                                DirectoryWithSnapshotFeature.DirectoryDiff priorDiff = sf.GetDiffs().GetDiffById(
                                    prior);
                                if (priorDiff != null && priorDiff.GetSnapshotId() == prior)
                                {
                                    priorChildrenDiff = priorDiff.GetChildrenDiff();
                                    counts.Add(priorChildrenDiff.DestroyCreatedList(bsps, dir, collectedBlocks, removedINodes
                                                                                    ));
                                }
                            }
                            foreach (INode child in dir.GetChildrenList(prior))
                            {
                                if (priorChildrenDiff != null && priorChildrenDiff.Search(Diff.ListType.Deleted,
                                                                                          child.GetLocalNameBytes()) != null)
                                {
                                    continue;
                                }
                                queue.AddLast(child);
                            }
                        }
                    }
                }
            }
            return(counts);
        }
Exemplo n.º 22
0
 /// <summary>Destroy a subtree under a DstReference node.</summary>
 /// <exception cref="Org.Apache.Hadoop.Hdfs.Protocol.QuotaExceededException"/>
 public static void DestroyDstSubtree(BlockStoragePolicySuite bsps, INode inode, int
                                      snapshot, int prior, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes
                                      )
 {
     Preconditions.CheckArgument(prior != Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot
                                 .NoSnapshotId);
     if (inode.IsReference())
     {
         if (inode is INodeReference.WithName && snapshot != Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot
             .CurrentStateId)
         {
             // this inode has been renamed before the deletion of the DstReference
             // subtree
             inode.CleanSubtree(bsps, snapshot, prior, collectedBlocks, removedINodes);
         }
         else
         {
             // for DstReference node, continue this process to its subtree
             DestroyDstSubtree(bsps, inode.AsReference().GetReferredINode(), snapshot, prior,
                               collectedBlocks, removedINodes);
         }
     }
     else
     {
         if (inode.IsFile())
         {
             inode.CleanSubtree(bsps, snapshot, prior, collectedBlocks, removedINodes);
         }
         else
         {
             if (inode.IsDirectory())
             {
                 IDictionary <INode, INode>   excludedNodes = null;
                 INodeDirectory               dir           = inode.AsDirectory();
                 DirectoryWithSnapshotFeature sf            = dir.GetDirectoryWithSnapshotFeature();
                 if (sf != null)
                 {
                     DirectoryWithSnapshotFeature.DirectoryDiffList diffList  = sf.GetDiffs();
                     DirectoryWithSnapshotFeature.DirectoryDiff     priorDiff = diffList.GetDiffById(prior
                                                                                                     );
                     if (priorDiff != null && priorDiff.GetSnapshotId() == prior)
                     {
                         IList <INode> dList = priorDiff.diff.GetList(Diff.ListType.Deleted);
                         excludedNodes = CloneDiffList(dList);
                     }
                     if (snapshot != Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.CurrentStateId)
                     {
                         diffList.DeleteSnapshotDiff(bsps, snapshot, prior, dir, collectedBlocks, removedINodes
                                                     );
                     }
                     priorDiff = diffList.GetDiffById(prior);
                     if (priorDiff != null && priorDiff.GetSnapshotId() == prior)
                     {
                         priorDiff.diff.DestroyCreatedList(bsps, dir, collectedBlocks, removedINodes);
                     }
                 }
                 foreach (INode child in inode.AsDirectory().GetChildrenList(prior))
                 {
                     if (excludedNodes != null && excludedNodes.Contains(child))
                     {
                         continue;
                     }
                     DestroyDstSubtree(bsps, child, snapshot, prior, collectedBlocks, removedINodes);
                 }
             }
         }
     }
 }