Esempio n. 1
0
        /// <summary>Delete a snapshot of a snapshottable directory</summary>
        /// <param name="snapshotRoot">The snapshottable directory</param>
        /// <param name="snapshotName">The name of the to-be-deleted snapshot</param>
        /// <exception cref="System.IO.IOException"/>
        internal static INode.BlocksMapUpdateInfo DeleteSnapshot(FSDirectory fsd, SnapshotManager
                                                                 snapshotManager, string snapshotRoot, string snapshotName, bool logRetryCache)
        {
            INodesInPath iip = fsd.GetINodesInPath4Write(snapshotRoot);

            if (fsd.IsPermissionEnabled())
            {
                FSPermissionChecker pc = fsd.GetPermissionChecker();
                fsd.CheckOwner(pc, iip);
            }
            INode.BlocksMapUpdateInfo collectedBlocks = new INode.BlocksMapUpdateInfo();
            ChunkedArrayList <INode>  removedINodes   = new ChunkedArrayList <INode>();

            fsd.WriteLock();
            try
            {
                snapshotManager.DeleteSnapshot(iip, snapshotName, collectedBlocks, removedINodes);
                fsd.RemoveFromInodeMap(removedINodes);
            }
            finally
            {
                fsd.WriteUnlock();
            }
            removedINodes.Clear();
            fsd.GetEditLog().LogDeleteSnapshot(snapshotRoot, snapshotName, logRetryCache);
            return(collectedBlocks);
        }
Esempio n. 2
0
 /// <exception cref="Org.Apache.Hadoop.Hdfs.Protocol.SnapshotException"/>
 public virtual Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot RemoveSnapshot
     (BlockStoragePolicySuite bsps, string snapshotName, INode.BlocksMapUpdateInfo collectedBlocks
     , IList <INode> removedINodes)
 {
     return(GetDirectorySnapshottableFeature().RemoveSnapshot(bsps, this, snapshotName
                                                              , collectedBlocks, removedINodes));
 }
Esempio n. 3
0
 public override QuotaCounts CleanSubtree(BlockStoragePolicySuite bsps, int snapshot
                                          , int prior, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes
                                          )
 {
     if (snapshot == Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.CurrentStateId &&
         prior == Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.NoSnapshotId)
     {
         QuotaCounts counts = new QuotaCounts.Builder().Build();
         this.ComputeQuotaUsage(bsps, counts, true);
         DestroyAndCollectBlocks(bsps, collectedBlocks, removedINodes);
         return(counts);
     }
     else
     {
         // 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 is not NO_SNAPSHOT_ID, and prior is not before the
         // to-be-deleted snapshot, we can quit here and leave the snapshot
         // deletion work to the src tree of rename
         if (snapshot != Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.CurrentStateId &&
             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());
         }
         return(GetReferredINode().CleanSubtree(bsps, snapshot, prior, collectedBlocks, removedINodes
                                                ));
     }
 }
Esempio n. 4
0
        public override QuotaCounts CleanSubtree(BlockStoragePolicySuite bsps, int snapshot
                                                 , int priorSnapshotId, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes
                                                 )
        {
            FileWithSnapshotFeature sf = GetFileWithSnapshotFeature();

            if (sf != null)
            {
                return(sf.CleanFile(bsps, this, snapshot, priorSnapshotId, collectedBlocks, removedINodes
                                    ));
            }
            QuotaCounts counts = new QuotaCounts.Builder().Build();

            if (snapshot == Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.CurrentStateId)
            {
                if (priorSnapshotId == Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.NoSnapshotId)
                {
                    // this only happens when deleting the current file and the file is not
                    // in any snapshot
                    ComputeQuotaUsage(bsps, counts, false);
                    DestroyAndCollectBlocks(bsps, collectedBlocks, removedINodes);
                }
                else
                {
                    // when deleting the current file and the file is in snapshot, we should
                    // clean the 0-sized block if the file is UC
                    FileUnderConstructionFeature uc = GetFileUnderConstructionFeature();
                    if (uc != null)
                    {
                        uc.CleanZeroSizeBlock(this, collectedBlocks);
                    }
                }
            }
            return(counts);
        }
Esempio n. 5
0
        /// <summary>Exclude blocks collected for deletion that belong to a snapshot.</summary>
        internal virtual void ExcludeSnapshotBlocks(int snapshotId, INode.BlocksMapUpdateInfo
                                                    collectedBlocks)
        {
            if (collectedBlocks == null || collectedBlocks.GetToDeleteList().IsEmpty())
            {
                return;
            }
            FileWithSnapshotFeature sf = GetFileWithSnapshotFeature();

            if (sf == null)
            {
                return;
            }
            BlockInfoContiguous[] snapshotBlocks = GetDiffs().FindEarlierSnapshotBlocks(snapshotId
                                                                                        );
            if (snapshotBlocks == null)
            {
                return;
            }
            IList <Block> toDelete = collectedBlocks.GetToDeleteList();

            foreach (Block blk in snapshotBlocks)
            {
                if (toDelete.Contains(blk))
                {
                    collectedBlocks.RemoveDeleteBlock(blk);
                }
            }
        }
Esempio n. 6
0
        public override void DestroyAndCollectBlocks(BlockStoragePolicySuite bsps, INode.BlocksMapUpdateInfo
                                                     collectedBlocks, IList <INode> removedINodes)
        {
            if (blocks != null && collectedBlocks != null)
            {
                foreach (BlockInfoContiguous blk in blocks)
                {
                    collectedBlocks.AddDeleteBlock(blk);
                    blk.SetBlockCollection(null);
                }
            }
            SetBlocks(null);
            if (GetAclFeature() != null)
            {
                AclStorage.RemoveAclFeature(GetAclFeature());
            }
            Clear();
            removedINodes.AddItem(this);
            FileWithSnapshotFeature sf = GetFileWithSnapshotFeature();

            if (sf != null)
            {
                sf.GetDiffs().DestroyAndCollectSnapshotBlocks(collectedBlocks);
                sf.ClearDiffs();
            }
        }
Esempio n. 7
0
        /// <summary>Remove full blocks at the end file up to newLength</summary>
        /// <returns>sum of sizes of the remained blocks</returns>
        public virtual long CollectBlocksBeyondMax(long max, INode.BlocksMapUpdateInfo collectedBlocks
                                                   )
        {
            BlockInfoContiguous[] oldBlocks = GetBlocks();
            if (oldBlocks == null)
            {
                return(0);
            }
            // find the minimum n such that the size of the first n blocks > max
            int  n    = 0;
            long size = 0;

            for (; n < oldBlocks.Length && max > size; n++)
            {
                size += oldBlocks[n].GetNumBytes();
            }
            if (n >= oldBlocks.Length)
            {
                return(size);
            }
            // starting from block n, the data is beyond max.
            // resize the array.
            TruncateBlocksTo(n);
            // collect the blocks beyond max
            if (collectedBlocks != null)
            {
                for (; n < oldBlocks.Length; n++)
                {
                    collectedBlocks.AddDeleteBlock(oldBlocks[n]);
                }
            }
            return(size);
        }
Esempio n. 8
0
        public override QuotaCounts CleanSubtree(BlockStoragePolicySuite bsps, int snapshotId
                                                 , int priorSnapshotId, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes
                                                 )
        {
            DirectoryWithSnapshotFeature sf = GetDirectoryWithSnapshotFeature();

            // there is snapshot data
            if (sf != null)
            {
                return(sf.CleanDirectory(bsps, this, snapshotId, priorSnapshotId, collectedBlocks
                                         , removedINodes));
            }
            // there is no snapshot data
            if (priorSnapshotId == Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.NoSnapshotId &&
                snapshotId == Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.CurrentStateId)
            {
                // destroy the whole subtree and collect blocks that should be deleted
                QuotaCounts counts = new QuotaCounts.Builder().Build();
                this.ComputeQuotaUsage(bsps, counts, true);
                DestroyAndCollectBlocks(bsps, collectedBlocks, removedINodes);
                return(counts);
            }
            else
            {
                // process recursively down the subtree
                QuotaCounts counts = CleanSubtreeRecursively(bsps, snapshotId, priorSnapshotId, collectedBlocks
                                                             , removedINodes, null);
                if (IsQuotaSet())
                {
                    GetDirectoryWithQuotaFeature().AddSpaceConsumed2Cache(counts.Negation());
                }
                return(counts);
            }
        }
Esempio n. 9
0
        /// <summary>Delete the target directory and collect the blocks under it</summary>
        /// <param name="iip">the INodesInPath instance containing all the INodes for the path
        ///     </param>
        /// <param name="collectedBlocks">Blocks under the deleted directory</param>
        /// <param name="removedINodes">INodes that should be removed from inodeMap</param>
        /// <returns>the number of files that have been removed</returns>
        /// <exception cref="System.IO.IOException"/>
        internal static long Delete(FSDirectory fsd, INodesInPath iip, INode.BlocksMapUpdateInfo
                                    collectedBlocks, IList <INode> removedINodes, long mtime)
        {
            if (NameNode.stateChangeLog.IsDebugEnabled())
            {
                NameNode.stateChangeLog.Debug("DIR* FSDirectory.delete: " + iip.GetPath());
            }
            long filesRemoved;

            fsd.WriteLock();
            try
            {
                if (!DeleteAllowed(iip, iip.GetPath()))
                {
                    filesRemoved = -1;
                }
                else
                {
                    IList <INodeDirectory> snapshottableDirs = new AList <INodeDirectory>();
                    FSDirSnapshotOp.CheckSnapshot(iip.GetLastINode(), snapshottableDirs);
                    filesRemoved = UnprotectedDelete(fsd, iip, collectedBlocks, removedINodes, mtime);
                    fsd.GetFSNamesystem().RemoveSnapshottableDirs(snapshottableDirs);
                }
            }
            finally
            {
                fsd.WriteUnlock();
            }
            return(filesRemoved);
        }
Esempio n. 10
0
        /// <summary>
        /// Delete a path from the name space
        /// Update the count at each ancestor directory with quota
        /// <br />
        /// Note: This is to be used by
        /// <see cref="FSEditLog"/>
        /// only.
        /// <br />
        /// </summary>
        /// <param name="src">a string representation of a path to an inode</param>
        /// <param name="mtime">the time the inode is removed</param>
        /// <exception cref="System.IO.IOException"/>
        internal static void DeleteForEditLog(FSDirectory fsd, string src, long mtime)
        {
            System.Diagnostics.Debug.Assert(fsd.HasWriteLock());
            FSNamesystem fsn = fsd.GetFSNamesystem();

            INode.BlocksMapUpdateInfo collectedBlocks = new INode.BlocksMapUpdateInfo();
            IList <INode>             removedINodes   = new ChunkedArrayList <INode>();
            INodesInPath iip = fsd.GetINodesInPath4Write(FSDirectory.NormalizePath(src), false
                                                         );

            if (!DeleteAllowed(iip, src))
            {
                return;
            }
            IList <INodeDirectory> snapshottableDirs = new AList <INodeDirectory>();

            FSDirSnapshotOp.CheckSnapshot(iip.GetLastINode(), snapshottableDirs);
            long filesRemoved = UnprotectedDelete(fsd, iip, collectedBlocks, removedINodes, mtime
                                                  );

            fsn.RemoveSnapshottableDirs(snapshottableDirs);
            if (filesRemoved >= 0)
            {
                fsn.RemoveLeasesAndINodes(src, removedINodes, false);
                fsn.RemoveBlocksAndUpdateSafemodeTotal(collectedBlocks);
            }
        }
Esempio n. 11
0
        /// <summary>The new rename which has the POSIX semantic.</summary>
        /// <exception cref="System.IO.IOException"/>
        internal static KeyValuePair <INode.BlocksMapUpdateInfo, HdfsFileStatus> RenameToInt
            (FSDirectory fsd, string srcArg, string dstArg, bool logRetryCache, params Options.Rename
            [] options)
        {
            string src = srcArg;
            string dst = dstArg;

            if (NameNode.stateChangeLog.IsDebugEnabled())
            {
                NameNode.stateChangeLog.Debug("DIR* NameSystem.renameTo: with options -" + " " +
                                              src + " to " + dst);
            }
            if (!DFSUtil.IsValidName(dst))
            {
                throw new InvalidPathException("Invalid name: " + dst);
            }
            FSPermissionChecker pc = fsd.GetPermissionChecker();

            byte[][] srcComponents = FSDirectory.GetPathComponentsForReservedPath(src);
            byte[][] dstComponents = FSDirectory.GetPathComponentsForReservedPath(dst);
            INode.BlocksMapUpdateInfo collectedBlocks = new INode.BlocksMapUpdateInfo();
            src = fsd.ResolvePath(pc, src, srcComponents);
            dst = fsd.ResolvePath(pc, dst, dstComponents);
            RenameTo(fsd, pc, src, dst, collectedBlocks, logRetryCache, options);
            INodesInPath   dstIIP        = fsd.GetINodesInPath(dst, false);
            HdfsFileStatus resultingStat = fsd.GetAuditFileInfo(dstIIP);

            return(new AbstractMap.SimpleImmutableEntry <INode.BlocksMapUpdateInfo, HdfsFileStatus
                                                         >(collectedBlocks, resultingStat));
        }
Esempio n. 12
0
        /// <summary>Call cleanSubtree(..) recursively down the subtree.</summary>
        public virtual QuotaCounts CleanSubtreeRecursively(BlockStoragePolicySuite bsps,
                                                           int snapshot, int prior, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode>
                                                           removedINodes, IDictionary <INode, INode> excludedNodes)
        {
            QuotaCounts counts = new QuotaCounts.Builder().Build();
            // in case of deletion snapshot, since this call happens after we modify
            // the diff list, the snapshot to be deleted has been combined or renamed
            // to its latest previous snapshot. (besides, we also need to consider nodes
            // created after prior but before snapshot. this will be done in
            // DirectoryWithSnapshotFeature)
            int s = snapshot != Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.CurrentStateId &&
                    prior != Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.NoSnapshotId
                                 ? prior : snapshot;

            foreach (INode child in GetChildrenList(s))
            {
                if (snapshot != Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.CurrentStateId &&
                    excludedNodes != null && excludedNodes.Contains(child))
                {
                    continue;
                }
                else
                {
                    QuotaCounts childCounts = child.CleanSubtree(bsps, snapshot, prior, collectedBlocks
                                                                 , removedINodes);
                    counts.Add(childCounts);
                }
            }
            return(counts);
        }
Esempio n. 13
0
        /// <summary>Remove a file/directory from the namespace.</summary>
        /// <remarks>
        /// Remove a file/directory from the namespace.
        /// <p>
        /// For large directories, deletion is incremental. The blocks under
        /// the directory are collected and deleted a small number at a time holding
        /// the
        /// <see cref="FSNamesystem"/>
        /// lock.
        /// <p>
        /// For small directory or file the deletion is done in one shot.
        /// </remarks>
        /// <exception cref="System.IO.IOException"/>
        internal static INode.BlocksMapUpdateInfo DeleteInternal(FSNamesystem fsn, string
                                                                 src, INodesInPath iip, bool logRetryCache)
        {
            System.Diagnostics.Debug.Assert(fsn.HasWriteLock());
            if (NameNode.stateChangeLog.IsDebugEnabled())
            {
                NameNode.stateChangeLog.Debug("DIR* NameSystem.delete: " + src);
            }
            FSDirectory fsd = fsn.GetFSDirectory();

            INode.BlocksMapUpdateInfo collectedBlocks = new INode.BlocksMapUpdateInfo();
            IList <INode>             removedINodes   = new ChunkedArrayList <INode>();
            long mtime = Time.Now();
            // Unlink the target directory from directory tree
            long filesRemoved = Delete(fsd, iip, collectedBlocks, removedINodes, mtime);

            if (filesRemoved < 0)
            {
                return(null);
            }
            fsd.GetEditLog().LogDelete(src, mtime, logRetryCache);
            IncrDeletedFileCount(filesRemoved);
            fsn.RemoveLeasesAndINodes(src, removedINodes, true);
            if (NameNode.stateChangeLog.IsDebugEnabled())
            {
                NameNode.stateChangeLog.Debug("DIR* Namesystem.delete: " + src + " is removed");
            }
            return(collectedBlocks);
        }
Esempio n. 14
0
 public override QuotaCounts CleanSubtree(BlockStoragePolicySuite bsps, int snapshot
                                          , int prior, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes
                                          )
 {
     // used by WithCount
     return(referred.CleanSubtree(bsps, snapshot, prior, collectedBlocks, removedINodes
                                  ));
 }
Esempio n. 15
0
 public override void DestroyAndCollectBlocks(BlockStoragePolicySuite bsps, INode.BlocksMapUpdateInfo
                                              collectedBlocks, IList <INode> removedINodes)
 {
     // used by WithCount
     if (RemoveReference(this) <= 0)
     {
         referred.DestroyAndCollectBlocks(bsps, collectedBlocks, removedINodes);
     }
 }
Esempio n. 16
0
 public override QuotaCounts CleanSubtree(BlockStoragePolicySuite bsps, int snapshotId
                                          , int priorSnapshotId, INode.BlocksMapUpdateInfo collectedBlocks, IList <INode> removedINodes
                                          )
 {
     if (snapshotId == Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.CurrentStateId &&
         priorSnapshotId == Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.
         NoSnapshotId)
     {
         DestroyAndCollectBlocks(bsps, collectedBlocks, removedINodes);
     }
     return(new QuotaCounts.Builder().NameSpace(1).Build());
 }
Esempio n. 17
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);
        }
Esempio n. 18
0
        /// <summary>Rename src to dst.</summary>
        /// <remarks>
        /// Rename src to dst.
        /// <br />
        /// Note: This is to be used by
        /// <see cref="FSEditLogLoader"/>
        /// only.
        /// <br />
        /// </remarks>
        /// <param name="fsd">FSDirectory</param>
        /// <param name="src">source path</param>
        /// <param name="dst">destination path</param>
        /// <param name="timestamp">modification time</param>
        /// <param name="options">Rename options</param>
        /// <exception cref="System.IO.IOException"/>
        internal static bool RenameForEditLog(FSDirectory fsd, string src, string dst, long
                                              timestamp, params Options.Rename[] options)
        {
            INode.BlocksMapUpdateInfo collectedBlocks = new INode.BlocksMapUpdateInfo();
            INodesInPath srcIIP = fsd.GetINodesInPath4Write(src, false);
            INodesInPath dstIIP = fsd.GetINodesInPath4Write(dst, false);
            bool         ret    = UnprotectedRenameTo(fsd, src, dst, srcIIP, dstIIP, timestamp, collectedBlocks
                                                      , options);

            if (!collectedBlocks.GetToDeleteList().IsEmpty())
            {
                fsd.GetFSNamesystem().RemoveBlocksAndUpdateSafemodeTotal(collectedBlocks);
            }
            return(ret);
        }
		/// <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);
				}
			}
		}
Esempio n. 20
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);
            }
Esempio n. 21
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);
            }
Esempio n. 22
0
        public override void DestroyAndCollectBlocks(BlockStoragePolicySuite bsps, INode.BlocksMapUpdateInfo
                                                     collectedBlocks, IList <INode> removedINodes)
        {
            DirectoryWithSnapshotFeature sf = GetDirectoryWithSnapshotFeature();

            if (sf != null)
            {
                sf.Clear(bsps, this, collectedBlocks, removedINodes);
            }
            foreach (INode child in GetChildrenList(Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot
                                                    .CurrentStateId))
            {
                child.DestroyAndCollectBlocks(bsps, collectedBlocks, removedINodes);
            }
            if (GetAclFeature() != null)
            {
                AclStorage.RemoveAclFeature(GetAclFeature());
            }
            Clear();
            removedINodes.AddItem(this);
        }
Esempio n. 23
0
        public virtual void CollectBlocksBeyondSnapshot(BlockInfoContiguous[] snapshotBlocks
                                                        , INode.BlocksMapUpdateInfo collectedBlocks)
        {
            BlockInfoContiguous[] oldBlocks = GetBlocks();
            if (snapshotBlocks == null || oldBlocks == null)
            {
                return;
            }
            // Skip blocks in common between the file and the snapshot
            int n = 0;

            while (n < oldBlocks.Length && n < snapshotBlocks.Length && oldBlocks[n] == snapshotBlocks
                   [n])
            {
                n++;
            }
            TruncateBlocksTo(n);
            // Collect the remaining blocks of the file
            while (n < oldBlocks.Length)
            {
                collectedBlocks.AddDeleteBlock(oldBlocks[n++]);
            }
        }
Esempio n. 24
0
        /// <seealso>
        ///
        /// <see cref="UnprotectedRenameTo(FSDirectory, string, string, INodesInPath, INodesInPath, long, BlocksMapUpdateInfo, Org.Apache.Hadoop.FS.Options.Rename[])
        ///     "/>
        /// </seealso>
        /// <exception cref="System.IO.IOException"/>
        internal static void RenameTo(FSDirectory fsd, FSPermissionChecker pc, string src
                                      , string dst, INode.BlocksMapUpdateInfo collectedBlocks, bool logRetryCache, params
                                      Options.Rename[] options)
        {
            INodesInPath srcIIP = fsd.GetINodesInPath4Write(src, false);
            INodesInPath dstIIP = fsd.GetINodesInPath4Write(dst, false);

            if (fsd.IsPermissionEnabled())
            {
                // Rename does not operate on link targets
                // Do not resolveLink when checking permissions of src and dst
                // Check write access to parent of src
                fsd.CheckPermission(pc, srcIIP, false, null, FsAction.Write, null, null, false);
                // Check write access to ancestor of dst
                fsd.CheckPermission(pc, dstIIP, false, FsAction.Write, null, null, null, false);
            }
            if (NameNode.stateChangeLog.IsDebugEnabled())
            {
                NameNode.stateChangeLog.Debug("DIR* FSDirectory.renameTo: " + src + " to " + dst);
            }
            long mtime = Time.Now();

            fsd.WriteLock();
            try
            {
                if (UnprotectedRenameTo(fsd, src, dst, srcIIP, dstIIP, mtime, collectedBlocks, options
                                        ))
                {
                    FSDirDeleteOp.IncrDeletedFileCount(1);
                }
            }
            finally
            {
                fsd.WriteUnlock();
            }
            fsd.GetEditLog().LogRename(src, dst, mtime, logRetryCache, options);
        }
Esempio n. 25
0
 /// <summary>
 /// Destroy self and clear everything! If the INode is a file, this method
 /// collects its blocks for further block deletion.
 /// </summary>
 /// <remarks>
 /// Destroy self and clear everything! If the INode is a file, this method
 /// collects its blocks for further block deletion. If the INode is a
 /// directory, the method goes down the subtree and collects blocks from the
 /// descents, and clears its parent/children references as well. The method
 /// also clears the diff list if the INode contains snapshot diff list.
 /// </remarks>
 /// <param name="bsps">
 /// block storage policy suite to calculate intended storage type usage
 /// This is needed because INodeReference#destroyAndCollectBlocks() needs
 /// to call INode#cleanSubtree(), which calls INode#computeQuotaUsage().
 /// </param>
 /// <param name="collectedBlocks">
 /// blocks collected from the descents for further block
 /// deletion/update will be added to this map.
 /// </param>
 /// <param name="removedINodes">
 /// INodes collected from the descents for further cleaning up of
 /// inodeMap
 /// </param>
 public abstract void DestroyAndCollectBlocks(BlockStoragePolicySuite bsps, INode.BlocksMapUpdateInfo
                                              collectedBlocks, IList <Org.Apache.Hadoop.Hdfs.Server.Namenode.INode> removedINodes
                                              );
Esempio n. 26
0
 /// <summary>
 /// Clean the subtree under this inode and collect the blocks from the descents
 /// for further block deletion/update.
 /// </summary>
 /// <remarks>
 /// Clean the subtree under this inode and collect the blocks from the descents
 /// for further block deletion/update. The current inode can either resides in
 /// the current tree or be stored as a snapshot copy.
 /// <pre>
 /// In general, we have the following rules.
 /// 1. When deleting a file/directory in the current tree, we have different
 /// actions according to the type of the node to delete.
 /// 1.1 The current inode (this) is an
 /// <see cref="INodeFile"/>
 /// .
 /// 1.1.1 If
 /// <c>prior</c>
 /// is null, there is no snapshot taken on ancestors
 /// before. Thus we simply destroy (i.e., to delete completely, no need to save
 /// snapshot copy) the current INode and collect its blocks for further
 /// cleansing.
 /// 1.1.2 Else do nothing since the current INode will be stored as a snapshot
 /// copy.
 /// 1.2 The current inode is an
 /// <see cref="INodeDirectory"/>
 /// .
 /// 1.2.1 If
 /// <c>prior</c>
 /// is null, there is no snapshot taken on ancestors
 /// before. Similarly, we destroy the whole subtree and collect blocks.
 /// 1.2.2 Else do nothing with the current INode. Recursively clean its
 /// children.
 /// 1.3 The current inode is a file with snapshot.
 /// Call recordModification(..) to capture the current states.
 /// Mark the INode as deleted.
 /// 1.4 The current inode is an
 /// <see cref="INodeDirectory"/>
 /// with snapshot feature.
 /// Call recordModification(..) to capture the current states.
 /// Destroy files/directories created after the latest snapshot
 /// (i.e., the inodes stored in the created list of the latest snapshot).
 /// Recursively clean remaining children.
 /// 2. When deleting a snapshot.
 /// 2.1 To clean
 /// <see cref="INodeFile"/>
 /// : do nothing.
 /// 2.2 To clean
 /// <see cref="INodeDirectory"/>
 /// : recursively clean its children.
 /// 2.3 To clean INodeFile with snapshot: delete the corresponding snapshot in
 /// its diff list.
 /// 2.4 To clean
 /// <see cref="INodeDirectory"/>
 /// with snapshot: delete the corresponding
 /// snapshot in its diff list. Recursively clean its children.
 /// </pre>
 /// </remarks>
 /// <param name="bsps">block storage policy suite to calculate intended storage type usage
 ///     </param>
 /// <param name="snapshotId">
 /// The id of the snapshot to delete.
 /// <see cref="Org.Apache.Hadoop.Hdfs.Server.Namenode.Snapshot.Snapshot.CurrentStateId
 ///     "/>
 /// means to delete the current
 /// file/directory.
 /// </param>
 /// <param name="priorSnapshotId">
 /// The id of the latest snapshot before the to-be-deleted snapshot.
 /// When deleting a current inode, this parameter captures the latest
 /// snapshot.
 /// </param>
 /// <param name="collectedBlocks">
 /// blocks collected from the descents for further block
 /// deletion/update will be added to the given map.
 /// </param>
 /// <param name="removedINodes">
 /// INodes collected from the descents for further cleaning up of
 /// inodeMap
 /// </param>
 /// <returns>quota usage delta when deleting a snapshot</returns>
 public abstract QuotaCounts CleanSubtree(BlockStoragePolicySuite bsps, int snapshotId
                                          , int priorSnapshotId, INode.BlocksMapUpdateInfo collectedBlocks, IList <Org.Apache.Hadoop.Hdfs.Server.Namenode.INode
                                                                                                                   > removedINodes);
Esempio n. 27
0
        /// <summary>Rename src to dst.</summary>
        /// <remarks>
        /// Rename src to dst.
        /// See
        /// <see cref="Org.Apache.Hadoop.Hdfs.DistributedFileSystem.Rename(Org.Apache.Hadoop.FS.Path, Org.Apache.Hadoop.FS.Path, Org.Apache.Hadoop.FS.Options.Rename[])
        ///     "/>
        /// for details related to rename semantics and exceptions.
        /// </remarks>
        /// <param name="fsd">FSDirectory</param>
        /// <param name="src">source path</param>
        /// <param name="dst">destination path</param>
        /// <param name="timestamp">modification time</param>
        /// <param name="collectedBlocks">blocks to be removed</param>
        /// <param name="options">Rename options</param>
        /// <returns>whether a file/directory gets overwritten in the dst path</returns>
        /// <exception cref="System.IO.IOException"/>
        internal static bool UnprotectedRenameTo(FSDirectory fsd, string src, string dst,
                                                 INodesInPath srcIIP, INodesInPath dstIIP, long timestamp, INode.BlocksMapUpdateInfo
                                                 collectedBlocks, params Options.Rename[] options)
        {
            System.Diagnostics.Debug.Assert(fsd.HasWriteLock());
            bool overwrite = options != null && Arrays.AsList(options).Contains(Options.Rename
                                                                                .Overwrite);
            string error;
            INode  srcInode = srcIIP.GetLastINode();

            ValidateRenameSource(srcIIP);
            // validate the destination
            if (dst.Equals(src))
            {
                throw new FileAlreadyExistsException("The source " + src + " and destination " +
                                                     dst + " are the same");
            }
            ValidateDestination(src, dst, srcInode);
            if (dstIIP.Length() == 1)
            {
                error = "rename destination cannot be the root";
                NameNode.stateChangeLog.Warn("DIR* FSDirectory.unprotectedRenameTo: " + error);
                throw new IOException(error);
            }
            BlockStoragePolicySuite bsps = fsd.GetBlockStoragePolicySuite();

            fsd.ezManager.CheckMoveValidity(srcIIP, dstIIP, src);
            INode dstInode = dstIIP.GetLastINode();
            IList <INodeDirectory> snapshottableDirs = new AList <INodeDirectory>();

            if (dstInode != null)
            {
                // Destination exists
                ValidateOverwrite(src, dst, overwrite, srcInode, dstInode);
                FSDirSnapshotOp.CheckSnapshot(dstInode, snapshottableDirs);
            }
            INode dstParent = dstIIP.GetINode(-2);

            if (dstParent == null)
            {
                error = "rename destination parent " + dst + " not found.";
                NameNode.stateChangeLog.Warn("DIR* FSDirectory.unprotectedRenameTo: " + error);
                throw new FileNotFoundException(error);
            }
            if (!dstParent.IsDirectory())
            {
                error = "rename destination parent " + dst + " is a file.";
                NameNode.stateChangeLog.Warn("DIR* FSDirectory.unprotectedRenameTo: " + error);
                throw new ParentNotDirectoryException(error);
            }
            // Ensure dst has quota to accommodate rename
            VerifyFsLimitsForRename(fsd, srcIIP, dstIIP);
            VerifyQuotaForRename(fsd, srcIIP, dstIIP);
            FSDirRenameOp.RenameOperation tx = new FSDirRenameOp.RenameOperation(fsd, src, dst
                                                                                 , srcIIP, dstIIP);
            bool undoRemoveSrc = true;

            tx.RemoveSrc();
            bool undoRemoveDst = false;
            long removedNum    = 0;

            try
            {
                if (dstInode != null)
                {
                    // dst exists, remove it
                    removedNum = tx.RemoveDst();
                    if (removedNum != -1)
                    {
                        undoRemoveDst = true;
                    }
                }
                // add src as dst to complete rename
                if (tx.AddSourceToDestination())
                {
                    undoRemoveSrc = false;
                    if (NameNode.stateChangeLog.IsDebugEnabled())
                    {
                        NameNode.stateChangeLog.Debug("DIR* FSDirectory.unprotectedRenameTo: " + src + " is renamed to "
                                                      + dst);
                    }
                    tx.UpdateMtimeAndLease(timestamp);
                    // Collect the blocks and remove the lease for previous dst
                    bool filesDeleted = false;
                    if (undoRemoveDst)
                    {
                        undoRemoveDst = false;
                        if (removedNum > 0)
                        {
                            filesDeleted = tx.CleanDst(bsps, collectedBlocks);
                        }
                    }
                    if (snapshottableDirs.Count > 0)
                    {
                        // There are snapshottable directories (without snapshots) to be
                        // deleted. Need to update the SnapshotManager.
                        fsd.GetFSNamesystem().RemoveSnapshottableDirs(snapshottableDirs);
                    }
                    tx.UpdateQuotasInSourceTree(bsps);
                    return(filesDeleted);
                }
            }
            finally
            {
                if (undoRemoveSrc)
                {
                    tx.RestoreSource();
                }
                if (undoRemoveDst)
                {
                    // Rename failed - restore dst
                    tx.RestoreDst(bsps);
                }
            }
            NameNode.stateChangeLog.Warn("DIR* FSDirectory.unprotectedRenameTo: " + "failed to rename "
                                         + src + " to " + dst);
            throw new IOException("rename from " + src + " to " + dst + " failed.");
        }
Esempio n. 28
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);
                        }
                    }
                }
            }
Esempio n. 29
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);
                 }
             }
         }
     }
 }
Esempio n. 30
0
 public override void DestroyAndCollectBlocks(BlockStoragePolicySuite bsps, INode.BlocksMapUpdateInfo
                                              collectedBlocks, IList <INode> removedINodes)
 {
     removedINodes.AddItem(this);
 }