BlockManager getBlockManager() { return getFSNamesystem().getBlockManager(); }
KeyProviderCryptoExtension getProvider() { return getFSNamesystem().getProvider(); }
@Override protected void checkPauseForTesting() throws InterruptedException { assert !dir.hasReadLock(); assert !dir.getFSNamesystem().hasReadLock(); while (shouldPauseForTesting) { LOG.info("Sleeping in the re-encrypt handler for unit test."); synchronized (reencryptionHandler) { if (shouldPauseForTesting) { reencryptionHandler.wait(30000); } } LOG.info("Continuing re-encrypt handler after pausing."); } }
protected void readLock() { dir.getFSNamesystem().readLock(); dir.readLock(); }
protected void readUnlock() { dir.readUnlock(); dir.getFSNamesystem().readUnlock("FSTreeTraverser"); }
private synchronized void checkPauseForTesting() throws InterruptedException { assert !dir.hasWriteLock(); assert !dir.getFSNamesystem().hasWriteLock(); if (pauseAfterNthCheckpoint != 0) { ZoneSubmissionTracker tracker = handler.unprotectedGetTracker(pauseZoneId); if (tracker != null) { if (tracker.numFutureDone == pauseAfterNthCheckpoint) { shouldPauseForTesting = true; pauseAfterNthCheckpoint = 0; } } } while (shouldPauseForTesting) { LOG.info("Sleeping in the re-encryption updater for unit test."); wait(); LOG.info("Continuing re-encryption updater after pausing."); } }
/** * Persist the block list for the inode. */ static void persistBlocks( FSDirectory fsd, String path, INodeFile file, boolean logRetryCache) { assert fsd.getFSNamesystem().hasWriteLock(); Preconditions.checkArgument(file.isUnderConstruction()); fsd.getEditLog().logUpdateBlocks(path, file, logRetryCache); if(NameNode.stateChangeLog.isDebugEnabled()) { NameNode.stateChangeLog.debug("persistBlocks: " + path + " with " + file.getBlocks().length + " blocks is persisted to" + " the file system"); } }
/** * Check whether zone is ready for re-encryption. Throws IOE if it's not. 1. * If EZ is deleted. 2. if the re-encryption is canceled. 3. If NN is not * active or is in safe mode. * * @throws IOException * if zone does not exist / is cancelled, or if NN is not ready * for write. */ @Override protected void checkINodeReady(long zoneId) throws IOException { final ZoneReencryptionStatus zs = getReencryptionStatus().getZoneStatus( zoneId); if (zs == null) { throw new IOException("Zone " + zoneId + " status cannot be found."); } if (zs.isCanceled()) { throw new IOException("Re-encryption is canceled for zone " + zoneId); } dir.getFSNamesystem().checkNameNodeSafeMode( "NN is in safe mode, cannot re-encrypt."); // re-encryption should be cancelled when NN goes to standby. Just // double checking for sanity. dir.getFSNamesystem().checkOperation(NameNode.OperationCategory.WRITE); }
private static void verifyQuota(FSDirectory fsd, INodesInPath targetIIP, QuotaCounts deltas) throws QuotaExceededException { if (!fsd.getFSNamesystem().isImageLoaded() || fsd.shouldSkipQuotaChecks()) { // Do not check quota if editlog is still being processed return; } FSDirectory.verifyQuota(targetIIP, targetIIP.length() - 1, deltas, null); }
/** * Check if the given path (or one of its descendants) is snapshottable and * already has snapshots. * * @param fsd the FSDirectory * @param iip inodes of the path * @param snapshottableDirs The list of directories that are snapshottable * but do not have snapshots yet */ static void checkSnapshot(FSDirectory fsd, INodesInPath iip, List<INodeDirectory> snapshottableDirs) throws SnapshotException { // avoid the performance penalty of recursing the tree if snapshots // are not in use SnapshotManager sm = fsd.getFSNamesystem().getSnapshotManager(); if (sm.getNumSnapshottableDirs() > 0) { checkSnapshot(iip.getLastINode(), snapshottableDirs); } } }
@VisibleForTesting public ZoneReencryptionStatus getZoneStatus(final String zone) throws IOException { final FSPermissionChecker pc = dir.getPermissionChecker(); final INode inode; dir.getFSNamesystem().readLock(); dir.readLock(); try { final INodesInPath iip = dir.resolvePath(pc, zone, DirOp.READ); inode = iip.getLastINode(); if (inode == null) { return null; } return getReencryptionStatus().getZoneStatus(inode.getId()); } finally { dir.readUnlock(); dir.getFSNamesystem().readUnlock(); } }
List<XAttr> completeReencryption(final INode zoneNode) throws IOException { assert dir.hasWriteLock(); assert dir.getFSNamesystem().hasWriteLock(); final Long zoneId = zoneNode.getId(); ZoneReencryptionStatus zs = getReencryptionStatus().getZoneStatus(zoneId); assert zs != null; LOG.info("Re-encryption completed on zone {}. Re-encrypted {} files," + " failures encountered: {}.", zoneNode.getFullPathName(), zs.getFilesReencrypted(), zs.getNumReencryptionFailures()); synchronized (this) { submissions.remove(zoneId); } return FSDirEncryptionZoneOp .updateReencryptionFinish(dir, INodesInPath.fromINode(zoneNode), zs); }
/** * Save the batch's edeks to file xattrs. */ static void saveFileXAttrsForBatch(FSDirectory fsd, List<FileEdekInfo> batch) { assert fsd.getFSNamesystem().hasWriteLock(); assert !fsd.hasWriteLock(); if (batch != null && !batch.isEmpty()) { for (FileEdekInfo entry : batch) { final INode inode = fsd.getInode(entry.getInodeId()); // no dir lock, so inode could be removed. no-op if so. if (inode == null) { NameNode.LOG.info("Cannot find inode {}, skip saving xattr for" + " re-encryption", entry.getInodeId()); continue; } fsd.getEditLog().logSetXAttrs(inode.getFullPathName(), inode.getXAttrFeature().getXAttrs(), false); } } }
/** * Reset the entire namespace tree. */ void reset() { writeLock(); try { rootDir = createRoot(getFSNamesystem()); inodeMap.clear(); addToInodeMap(rootDir); nameCache.reset(); inodeId.setCurrentValue(INodeId.LAST_RESERVED_ID); } finally { writeUnlock(); } }
/** * Update the quota usage after deletion. The quota update is only necessary * when image/edits have been loaded and the file/dir to be deleted is not * contained in snapshots. */ void updateCountForDelete(final INode inode, final INodesInPath iip) { if (getFSNamesystem().isImageLoaded() && !inode.isInLatestSnapshot(iip.getLatestSnapshotId())) { QuotaCounts counts = inode.computeQuotaUsage(getBlockStoragePolicySuite()); unprotectedUpdateCount(iip, iip.length() - 1, counts.negation()); } }
static void abandonBlock( FSDirectory fsd, FSPermissionChecker pc, ExtendedBlock b, long fileId, String src, String holder) throws IOException { final INodesInPath iip = fsd.resolvePath(pc, src, fileId); src = iip.getPath(); FSNamesystem fsn = fsd.getFSNamesystem(); final INodeFile file = fsn.checkLease(iip, holder, fileId); Preconditions.checkState(file.isUnderConstruction()); if (file.getBlockType() == BlockType.STRIPED) { return; // do not abandon block for striped file } Block localBlock = ExtendedBlock.getLocalBlock(b); fsd.writeLock(); try { // Remove the block from the pending creates list if (!unprotectedRemoveBlock(fsd, src, iip, file, localBlock)) { return; } } finally { fsd.writeUnlock(); } persistBlocks(fsd, src, file, false); }
private static ContentSummary getContentSummaryInt(FSDirectory fsd, FSPermissionChecker pc, INodesInPath iip) throws IOException { fsd.readLock(); try { INode targetNode = iip.getLastINode(); if (targetNode == null) { throw new FileNotFoundException("File does not exist: " + iip.getPath()); } else { // Make it relinquish locks everytime contentCountLimit entries are // processed. 0 means disabled. I.e. blocking for the entire duration. ContentSummaryComputationContext cscc = new ContentSummaryComputationContext(fsd, fsd.getFSNamesystem(), fsd.getContentCountLimit(), fsd.getContentSleepMicroSec(), pc); ContentSummary cs = targetNode.computeAndConvertContentSummary( iip.getPathSnapshotId(), cscc); fsd.addYieldCount(cscc.getYieldCount()); return cs; } } finally { fsd.readUnlock(); } }
static boolean unprotectedSetTimes( FSDirectory fsd, INodesInPath iip, long mtime, long atime, boolean force) throws QuotaExceededException { assert fsd.hasWriteLock(); boolean status = false; INode inode = iip.getLastINode(); int latest = iip.getLatestSnapshotId(); if (mtime != -1) { inode = inode.setModificationTime(mtime, latest); status = true; } // if the last access time update was within the last precision interval, // then no need to store access time if (atime != -1 && (status || force || atime > inode.getAccessTime() + fsd.getAccessTimePrecision())) { inode.setAccessTime(atime, latest, fsd.getFSNamesystem().getSnapshotManager(). getSkipCaptureAccessTimeOnlyChange()); status = true; } return status; } }
boolean cleanDst( BlockStoragePolicySuite bsps, BlocksMapUpdateInfo collectedBlocks) { Preconditions.checkState(oldDstChild != null); List<INode> removedINodes = new ChunkedArrayList<>(); List<Long> removedUCFiles = new ChunkedArrayList<>(); INode.ReclaimContext context = new INode.ReclaimContext( bsps, collectedBlocks, removedINodes, removedUCFiles); final boolean filesDeleted; if (!oldDstChild.isInLatestSnapshot(dstIIP.getLatestSnapshotId())) { oldDstChild.destroyAndCollectBlocks(context); filesDeleted = true; } else { oldDstChild.cleanSubtree(context, Snapshot.CURRENT_STATE_ID, dstIIP.getLatestSnapshotId()); filesDeleted = context.quotaDelta().getNsDelta() >= 0; } fsd.updateReplicationFactor(context.collectedBlocks() .toUpdateReplicationInfo()); fsd.getFSNamesystem().removeLeasesAndINodes( removedUCFiles, removedINodes, false); return filesDeleted; }
/** * Verify quota for rename operation where srcInodes[srcInodes.length-1] moves * dstInodes[dstInodes.length-1] */ private static void verifyQuotaForRename(FSDirectory fsd, INodesInPath src, INodesInPath dst) throws QuotaExceededException { if (!fsd.getFSNamesystem().isImageLoaded() || fsd.shouldSkipQuotaChecks()) { // Do not check quota if edits log is still being processed return; } int i = 0; while(src.getINode(i) == dst.getINode(i)) { i++; } // src[i - 1] is the last common ancestor. BlockStoragePolicySuite bsps = fsd.getBlockStoragePolicySuite(); final QuotaCounts delta = src.getLastINode().computeQuotaUsage(bsps); // Reduce the required quota by dst that is being removed final INode dstINode = dst.getLastINode(); if (dstINode != null) { delta.subtract(dstINode.computeQuotaUsage(bsps)); } FSDirectory.verifyQuota(dst, dst.length() - 1, delta, src.getINode(i - 1)); }