/** * Remove the snapshot with the given name from {@link #snapshotsByNames}, and delete all the * corresponding DirectoryDiff. * * @param snapshotName The name of the snapshot to be removed * @param collectedBlocks Used to collect information to update blocksMap * @return The removed snapshot. Null if no snapshot with the given name exists. */ Snapshot removeSnapshot( String snapshotName, BlocksMapUpdateInfo collectedBlocks, final List<INode> removedINodes) throws SnapshotException { final int i = searchSnapshot(DFSUtil.string2Bytes(snapshotName)); if (i < 0) { throw new SnapshotException( "Cannot delete snapshot " + snapshotName + " from path " + this.getFullPathName() + ": the snapshot does not exist."); } else { final Snapshot snapshot = snapshotsByNames.get(i); Snapshot prior = Snapshot.findLatestSnapshot(this, snapshot); try { Quota.Counts counts = cleanSubtree(snapshot, prior, collectedBlocks, removedINodes, true); INodeDirectory parent = 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.get(Quota.NAMESPACE), -counts.get(Quota.DISKSPACE), true); } } catch (QuotaExceededException e) { LOG.error("BUG: removeSnapshot increases namespace usage.", e); } // remove from snapshotsByNames after successfully cleaning the subtree snapshotsByNames.remove(i); return snapshot; } }