diff --git a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java index ca6a8fd5179..d392d1f0cb0 100644 --- a/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java +++ b/hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java @@ -1518,6 +1518,9 @@ private OzoneFileStatus getOzoneFileStatus(OmKeyArgs args, OmKeyInfo fileKeyInfo = null; OmKeyInfo dirKeyInfo = null; OmKeyInfo fakeDirKeyInfo = null; + boolean needFakeDir = false; + BucketLayout layout = null; + metadataManager.getLock().acquireReadLock(BUCKET_LOCK, volumeName, bucketName); try { @@ -1530,8 +1533,7 @@ private OzoneFileStatus getOzoneFileStatus(OmKeyArgs args, // Check if the key is a file. String fileKeyBytes = metadataManager.getOzoneKey( volumeName, bucketName, keyName); - BucketLayout layout = - getBucketLayout(metadataManager, volumeName, bucketName); + layout = getBucketLayout(metadataManager, volumeName, bucketName); fileKeyInfo = metadataManager.getKeyTable(layout).get(fileKeyBytes); String dirKey = OzoneFSUtils.addTrailingSlashIfNeeded(keyName); @@ -1541,8 +1543,7 @@ private OzoneFileStatus getOzoneFileStatus(OmKeyArgs args, volumeName, bucketName, dirKey); dirKeyInfo = metadataManager.getKeyTable(layout).get(dirKeyBytes); if (dirKeyInfo == null) { - fakeDirKeyInfo = - createFakeDirIfShould(volumeName, bucketName, keyName, layout); + needFakeDir = true; } } } finally { @@ -1576,6 +1577,13 @@ private OzoneFileStatus getOzoneFileStatus(OmKeyArgs args, return new OzoneFileStatus(dirKeyInfo, scmBlockSize, true); } + // Called outside the lock: may open a RocksDB iterator that is slow + // when there are many tombstones to skip over. + if (needFakeDir) { + fakeDirKeyInfo = + createFakeDirIfShould(volumeName, bucketName, keyName, layout); + } + if (fakeDirKeyInfo != null) { return new OzoneFileStatus(fakeDirKeyInfo, scmBlockSize, true); }