Beispiel #1
0
 /// <summary>
 /// <inheritDoc/>
 /// <br/>
 /// To destroy a DstReference node, we first remove its link with the
 /// referred node. If the reference number of the referred node is &lt;= 0, we
 /// destroy the subtree of the referred node. Otherwise, we clean the
 /// referred node's subtree and delete everything created after the last
 /// rename operation, i.e., everything outside of the scope of the prior
 /// WithName nodes.
 /// </summary>
 public override void DestroyAndCollectBlocks(BlockStoragePolicySuite bsps, INode.BlocksMapUpdateInfo
                                              collectedBlocks, IList <INode> removedINodes)
 {
     if (RemoveReference(this) <= 0)
     {
         GetReferredINode().DestroyAndCollectBlocks(bsps, collectedBlocks, removedINodes);
     }
     else
     {
         // we will clean everything, including files, directories, and
         // snapshots, that were created after this prior snapshot
         int prior = GetPriorSnapshot(this);
         // prior must be non-null, otherwise we do not have any previous
         // WithName nodes, and the reference number will be 0.
         Preconditions.CheckState(prior != Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot
                                  .NoSnapshotId);
         // identify the snapshot created after prior
         int   snapshot = GetSelfSnapshot(prior);
         INode referred = GetReferredINode().AsReference().GetReferredINode();
         if (referred.IsFile())
         {
             // if referred is a file, it must be a file with snapshot since we did
             // recordModification before the rename
             INodeFile file = referred.AsFile();
             Preconditions.CheckState(file.IsWithSnapshot());
             // make sure we mark the file as deleted
             file.GetFileWithSnapshotFeature().DeleteCurrentFile();
             // when calling cleanSubtree of the referred node, since we
             // compute quota usage updates before calling this destroy
             // function, we use true for countDiffChange
             referred.CleanSubtree(bsps, snapshot, prior, collectedBlocks, removedINodes);
         }
         else
         {
             if (referred.IsDirectory())
             {
                 // similarly, if referred is a directory, it must be an
                 // INodeDirectory with snapshot
                 INodeDirectory dir = referred.AsDirectory();
                 Preconditions.CheckState(dir.IsWithSnapshot());
                 try
                 {
                     DirectoryWithSnapshotFeature.DestroyDstSubtree(bsps, dir, snapshot, prior, collectedBlocks
                                                                    , removedINodes);
                 }
                 catch (QuotaExceededException e)
                 {
                     Log.Error("should not exceed quota while snapshot deletion", e);
                 }
             }
         }
     }
 }
Beispiel #2
0
        /// <summary>
        /// Delete a path from the name space
        /// Update the count at each ancestor directory with quota
        /// </summary>
        /// <param name="iip">the inodes resolved from the path</param>
        /// <param name="collectedBlocks">blocks collected from the deleted path</param>
        /// <param name="removedINodes">inodes that should be removed from inodeMap</param>
        /// <param name="mtime">the time the inode is removed</param>
        /// <returns>the number of inodes deleted; 0 if no inodes are deleted.</returns>
        private static long UnprotectedDelete(FSDirectory fsd, INodesInPath iip, INode.BlocksMapUpdateInfo
                                              collectedBlocks, IList <INode> removedINodes, long mtime)
        {
            System.Diagnostics.Debug.Assert(fsd.HasWriteLock());
            // check if target node exists
            INode targetNode = iip.GetLastINode();

            if (targetNode == null)
            {
                return(-1);
            }
            // record modification
            int latestSnapshot = iip.GetLatestSnapshotId();

            targetNode.RecordModification(latestSnapshot);
            // Remove the node from the namespace
            long removed = fsd.RemoveLastINode(iip);

            if (removed == -1)
            {
                return(-1);
            }
            // set the parent's modification time
            INodeDirectory parent = targetNode.GetParent();

            parent.UpdateModificationTime(mtime, latestSnapshot);
            fsd.UpdateCountForDelete(targetNode, iip);
            if (removed == 0)
            {
                return(0);
            }
            // collect block and update quota
            if (!targetNode.IsInLatestSnapshot(latestSnapshot))
            {
                targetNode.DestroyAndCollectBlocks(fsd.GetBlockStoragePolicySuite(), collectedBlocks
                                                   , removedINodes);
            }
            else
            {
                QuotaCounts counts = targetNode.CleanSubtree(fsd.GetBlockStoragePolicySuite(), Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot
                                                             .CurrentStateId, latestSnapshot, collectedBlocks, removedINodes);
                removed = counts.GetNameSpace();
                fsd.UpdateCountNoQuotaCheck(iip, iip.Length() - 1, counts.Negation());
            }
            if (NameNode.stateChangeLog.IsDebugEnabled())
            {
                NameNode.stateChangeLog.Debug("DIR* FSDirectory.unprotectedDelete: " + iip.GetPath
                                                  () + " is removed");
            }
            return(removed);
        }
Beispiel #3
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);
                        }
                    }
                }
            }
Beispiel #4
0
            /// <exception cref="Org.Apache.Hadoop.Hdfs.Protocol.QuotaExceededException"/>
            internal virtual bool CleanDst(BlockStoragePolicySuite bsps, INode.BlocksMapUpdateInfo
                                           collectedBlocks)
            {
                Preconditions.CheckState(oldDstChild != null);
                IList <INode> removedINodes = new ChunkedArrayList <INode>();
                bool          filesDeleted;

                if (!oldDstChild.IsInLatestSnapshot(dstIIP.GetLatestSnapshotId()))
                {
                    oldDstChild.DestroyAndCollectBlocks(bsps, collectedBlocks, removedINodes);
                    filesDeleted = true;
                }
                else
                {
                    filesDeleted = oldDstChild.CleanSubtree(bsps, Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot
                                                            .CurrentStateId, dstIIP.GetLatestSnapshotId(), collectedBlocks, removedINodes).GetNameSpace
                                       () >= 0;
                }
                fsd.GetFSNamesystem().RemoveLeasesAndINodes(src, removedINodes, false);
                return(filesDeleted);
            }