|
@@ -32,7 +32,6 @@ import java.nio.channels.FileChannel;
|
|
|
import java.nio.file.Files;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Collection;
|
|
|
-import java.util.Collections;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.HashSet;
|
|
|
import java.util.Iterator;
|
|
@@ -41,9 +40,6 @@ import java.util.Map;
|
|
|
import java.util.Set;
|
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
|
import java.util.concurrent.Executor;
|
|
|
-import java.util.concurrent.locks.Condition;
|
|
|
-import java.util.concurrent.TimeUnit;
|
|
|
-import java.util.concurrent.locks.ReentrantReadWriteLock;
|
|
|
|
|
|
import javax.management.NotCompliantMBeanException;
|
|
|
import javax.management.ObjectName;
|
|
@@ -64,6 +60,10 @@ import org.apache.hadoop.fs.StorageType;
|
|
|
import org.apache.hadoop.hdfs.DFSConfigKeys;
|
|
|
import org.apache.hadoop.hdfs.DFSUtilClient;
|
|
|
import org.apache.hadoop.hdfs.ExtendedBlockId;
|
|
|
+import org.apache.hadoop.hdfs.server.common.AutoCloseDataSetLock;
|
|
|
+import org.apache.hadoop.hdfs.server.common.DataNodeLockManager;
|
|
|
+import org.apache.hadoop.hdfs.server.common.DataNodeLockManager.LockLevel;
|
|
|
+import org.apache.hadoop.hdfs.server.datanode.DataSetLockManager;
|
|
|
import org.apache.hadoop.hdfs.server.datanode.FileIoProvider;
|
|
|
import org.apache.hadoop.hdfs.server.datanode.FinalizedReplica;
|
|
|
import org.apache.hadoop.hdfs.server.datanode.LocalReplica;
|
|
@@ -119,7 +119,6 @@ import org.apache.hadoop.util.Daemon;
|
|
|
import org.apache.hadoop.util.DataChecksum;
|
|
|
import org.apache.hadoop.util.DiskChecker.DiskErrorException;
|
|
|
import org.apache.hadoop.util.DiskChecker.DiskOutOfSpaceException;
|
|
|
-import org.apache.hadoop.util.InstrumentedReadWriteLock;
|
|
|
import org.apache.hadoop.util.Lists;
|
|
|
import org.apache.hadoop.util.ReflectionUtils;
|
|
|
import org.apache.hadoop.util.Sets;
|
|
@@ -188,7 +187,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
|
|
|
@Override
|
|
|
public FsVolumeImpl getVolume(final ExtendedBlock b) {
|
|
|
- try (AutoCloseableLock lock = datasetReadLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.readLock(LockLevel.BLOCK_POOl,
|
|
|
+ b.getBlockPoolId())) {
|
|
|
final ReplicaInfo r =
|
|
|
volumeMap.get(b.getBlockPoolId(), b.getLocalBlock());
|
|
|
return r != null ? (FsVolumeImpl) r.getVolume() : null;
|
|
@@ -198,7 +198,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
@Override // FsDatasetSpi
|
|
|
public Block getStoredBlock(String bpid, long blkid)
|
|
|
throws IOException {
|
|
|
- try (AutoCloseableLock lock = datasetReadLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.readLock(LockLevel.BLOCK_POOl,
|
|
|
+ bpid)) {
|
|
|
ReplicaInfo r = volumeMap.get(bpid, blkid);
|
|
|
if (r == null) {
|
|
|
return null;
|
|
@@ -210,12 +211,16 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
@Override
|
|
|
public Set<? extends Replica> deepCopyReplica(String bpid)
|
|
|
throws IOException {
|
|
|
- Set<? extends Replica> replicas = null;
|
|
|
- try (AutoCloseableLock lock = datasetReadLock.acquire()) {
|
|
|
- replicas = new HashSet<>(volumeMap.replicas(bpid) == null ? Collections.
|
|
|
- EMPTY_SET : volumeMap.replicas(bpid));
|
|
|
+ try (AutoCloseDataSetLock l = lockManager.readLock(LockLevel.BLOCK_POOl, bpid)) {
|
|
|
+ Set<ReplicaInfo> replicas = new HashSet<>();
|
|
|
+ volumeMap.replicas(bpid, (iterator) -> {
|
|
|
+ while (iterator.hasNext()) {
|
|
|
+ ReplicaInfo b = iterator.next();
|
|
|
+ replicas.add(b);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return replicas;
|
|
|
}
|
|
|
- return Collections.unmodifiableSet(replicas);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -275,13 +280,7 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
private boolean blockPinningEnabled;
|
|
|
private final int maxDataLength;
|
|
|
|
|
|
- @VisibleForTesting
|
|
|
- final AutoCloseableLock datasetWriteLock;
|
|
|
- @VisibleForTesting
|
|
|
- final AutoCloseableLock datasetReadLock;
|
|
|
- @VisibleForTesting
|
|
|
- final InstrumentedReadWriteLock datasetRWLock;
|
|
|
- private final Condition datasetWriteLockCondition;
|
|
|
+ private final DataSetLockManager lockManager;
|
|
|
private static String blockPoolId = "";
|
|
|
|
|
|
// Make limited notify times from DirectoryScanner to NameNode.
|
|
@@ -300,33 +299,7 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
this.dataStorage = storage;
|
|
|
this.conf = conf;
|
|
|
this.smallBufferSize = DFSUtilClient.getSmallBufferSize(conf);
|
|
|
- this.datasetRWLock = new InstrumentedReadWriteLock(
|
|
|
- conf.getBoolean(DFSConfigKeys.DFS_DATANODE_LOCK_FAIR_KEY,
|
|
|
- DFSConfigKeys.DFS_DATANODE_LOCK_FAIR_DEFAULT),
|
|
|
- "FsDatasetRWLock", LOG, conf.getTimeDuration(
|
|
|
- DFSConfigKeys.DFS_LOCK_SUPPRESS_WARNING_INTERVAL_KEY,
|
|
|
- DFSConfigKeys.DFS_LOCK_SUPPRESS_WARNING_INTERVAL_DEFAULT,
|
|
|
- TimeUnit.MILLISECONDS),
|
|
|
- conf.getTimeDuration(
|
|
|
- DFSConfigKeys.DFS_DATANODE_LOCK_REPORTING_THRESHOLD_MS_KEY,
|
|
|
- DFSConfigKeys.DFS_DATANODE_LOCK_REPORTING_THRESHOLD_MS_DEFAULT,
|
|
|
- TimeUnit.MILLISECONDS));
|
|
|
- this.datasetWriteLock = new AutoCloseableLock(datasetRWLock.writeLock());
|
|
|
- boolean enableRL = conf.getBoolean(
|
|
|
- DFSConfigKeys.DFS_DATANODE_LOCK_READ_WRITE_ENABLED_KEY,
|
|
|
- DFSConfigKeys.DFS_DATANODE_LOCK_READ_WRITE_ENABLED_DEFAULT);
|
|
|
- // The read lock can be disabled by the above config key. If it is disabled
|
|
|
- // then we simply make the both the read and write lock variables hold
|
|
|
- // the write lock. All accesses to the lock are via these variables, so that
|
|
|
- // effectively disables the read lock.
|
|
|
- if (enableRL) {
|
|
|
- LOG.info("The datanode lock is a read write lock");
|
|
|
- this.datasetReadLock = new AutoCloseableLock(datasetRWLock.readLock());
|
|
|
- } else {
|
|
|
- LOG.info("The datanode lock is an exclusive write lock");
|
|
|
- this.datasetReadLock = this.datasetWriteLock;
|
|
|
- }
|
|
|
- this.datasetWriteLockCondition = datasetWriteLock.newCondition();
|
|
|
+ this.lockManager = datanode.getDataSetLockManager();
|
|
|
|
|
|
// The number of volumes required for operation is the total number
|
|
|
// of volumes minus the number of failed volumes we can tolerate.
|
|
@@ -365,7 +338,7 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
}
|
|
|
|
|
|
storageMap = new ConcurrentHashMap<String, DatanodeStorage>();
|
|
|
- volumeMap = new ReplicaMap(datasetReadLock, datasetWriteLock);
|
|
|
+ volumeMap = new ReplicaMap(lockManager);
|
|
|
ramDiskReplicaTracker = RamDiskReplicaTracker.getInstance(conf, this);
|
|
|
|
|
|
@SuppressWarnings("unchecked")
|
|
@@ -421,16 +394,6 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
lastDirScannerNotifyTime = System.currentTimeMillis();
|
|
|
}
|
|
|
|
|
|
- @Override
|
|
|
- public AutoCloseableLock acquireDatasetLock() {
|
|
|
- return datasetWriteLock.acquire();
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public AutoCloseableLock acquireDatasetReadLock() {
|
|
|
- return datasetReadLock.acquire();
|
|
|
- }
|
|
|
-
|
|
|
/**
|
|
|
* Gets initial volume failure information for all volumes that failed
|
|
|
* immediately at startup. The method works by determining the set difference
|
|
@@ -465,42 +428,40 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
* Activate a volume to serve requests.
|
|
|
* @throws IOException if the storage UUID already exists.
|
|
|
*/
|
|
|
- private void activateVolume(
|
|
|
+ private synchronized void activateVolume(
|
|
|
ReplicaMap replicaMap,
|
|
|
Storage.StorageDirectory sd, StorageType storageType,
|
|
|
FsVolumeReference ref) throws IOException {
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
- DatanodeStorage dnStorage = storageMap.get(sd.getStorageUuid());
|
|
|
- if (dnStorage != null) {
|
|
|
- final String errorMsg = String.format(
|
|
|
- "Found duplicated storage UUID: %s in %s.",
|
|
|
- sd.getStorageUuid(), sd.getVersionFile());
|
|
|
- LOG.error(errorMsg);
|
|
|
- throw new IOException(errorMsg);
|
|
|
- }
|
|
|
- // Check if there is same storage type on the mount.
|
|
|
- // Only useful when same disk tiering is turned on.
|
|
|
- FsVolumeImpl volumeImpl = (FsVolumeImpl) ref.getVolume();
|
|
|
- FsVolumeReference checkRef = volumes
|
|
|
- .getMountVolumeMap()
|
|
|
- .getVolumeRefByMountAndStorageType(
|
|
|
- volumeImpl.getMount(), volumeImpl.getStorageType());
|
|
|
- if (checkRef != null) {
|
|
|
- final String errorMsg = String.format(
|
|
|
- "Storage type %s already exists on same mount: %s.",
|
|
|
- volumeImpl.getStorageType(), volumeImpl.getMount());
|
|
|
- checkRef.close();
|
|
|
- LOG.error(errorMsg);
|
|
|
- throw new IOException(errorMsg);
|
|
|
- }
|
|
|
- volumeMap.mergeAll(replicaMap);
|
|
|
- storageMap.put(sd.getStorageUuid(),
|
|
|
- new DatanodeStorage(sd.getStorageUuid(),
|
|
|
- DatanodeStorage.State.NORMAL,
|
|
|
- storageType));
|
|
|
- asyncDiskService.addVolume(volumeImpl);
|
|
|
- volumes.addVolume(ref);
|
|
|
- }
|
|
|
+ DatanodeStorage dnStorage = storageMap.get(sd.getStorageUuid());
|
|
|
+ if (dnStorage != null) {
|
|
|
+ final String errorMsg = String.format(
|
|
|
+ "Found duplicated storage UUID: %s in %s.",
|
|
|
+ sd.getStorageUuid(), sd.getVersionFile());
|
|
|
+ LOG.error(errorMsg);
|
|
|
+ throw new IOException(errorMsg);
|
|
|
+ }
|
|
|
+ // Check if there is same storage type on the mount.
|
|
|
+ // Only useful when same disk tiering is turned on.
|
|
|
+ FsVolumeImpl volumeImpl = (FsVolumeImpl) ref.getVolume();
|
|
|
+ FsVolumeReference checkRef = volumes
|
|
|
+ .getMountVolumeMap()
|
|
|
+ .getVolumeRefByMountAndStorageType(
|
|
|
+ volumeImpl.getMount(), volumeImpl.getStorageType());
|
|
|
+ if (checkRef != null) {
|
|
|
+ final String errorMsg = String.format(
|
|
|
+ "Storage type %s already exists on same mount: %s.",
|
|
|
+ volumeImpl.getStorageType(), volumeImpl.getMount());
|
|
|
+ checkRef.close();
|
|
|
+ LOG.error(errorMsg);
|
|
|
+ throw new IOException(errorMsg);
|
|
|
+ }
|
|
|
+ volumeMap.mergeAll(replicaMap);
|
|
|
+ storageMap.put(sd.getStorageUuid(),
|
|
|
+ new DatanodeStorage(sd.getStorageUuid(),
|
|
|
+ DatanodeStorage.State.NORMAL,
|
|
|
+ storageType));
|
|
|
+ asyncDiskService.addVolume(volumeImpl);
|
|
|
+ volumes.addVolume(ref);
|
|
|
}
|
|
|
|
|
|
private void addVolume(Storage.StorageDirectory sd) throws IOException {
|
|
@@ -517,8 +478,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
.setConf(this.conf)
|
|
|
.build();
|
|
|
FsVolumeReference ref = fsVolume.obtainReference();
|
|
|
- ReplicaMap tempVolumeMap =
|
|
|
- new ReplicaMap(datasetReadLock, datasetWriteLock);
|
|
|
+ // no need to acquire lock.
|
|
|
+ ReplicaMap tempVolumeMap = new ReplicaMap();
|
|
|
fsVolume.getVolumeMap(tempVolumeMap, ramDiskReplicaTracker);
|
|
|
|
|
|
activateVolume(tempVolumeMap, sd, storageLocation.getStorageType(), ref);
|
|
@@ -557,13 +518,13 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
StorageType storageType = location.getStorageType();
|
|
|
final FsVolumeImpl fsVolume =
|
|
|
createFsVolume(sd.getStorageUuid(), sd, location);
|
|
|
- final ReplicaMap tempVolumeMap =
|
|
|
- new ReplicaMap(new ReentrantReadWriteLock());
|
|
|
+ // no need to add lock
|
|
|
+ final ReplicaMap tempVolumeMap = new ReplicaMap();
|
|
|
ArrayList<IOException> exceptions = Lists.newArrayList();
|
|
|
|
|
|
for (final NamespaceInfo nsInfo : nsInfos) {
|
|
|
String bpid = nsInfo.getBlockPoolID();
|
|
|
- try {
|
|
|
+ try (AutoCloseDataSetLock l = lockManager.writeLock(LockLevel.BLOCK_POOl, bpid)) {
|
|
|
fsVolume.addBlockPool(bpid, this.conf, this.timer);
|
|
|
fsVolume.getVolumeMap(bpid, tempVolumeMap, ramDiskReplicaTracker);
|
|
|
} catch (IOException e) {
|
|
@@ -603,7 +564,9 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
new ArrayList<>(storageLocsToRemove);
|
|
|
Map<String, List<ReplicaInfo>> blkToInvalidate = new HashMap<>();
|
|
|
List<String> storageToRemove = new ArrayList<>();
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
+ // This object lock is protect data structure related volumes like add and
|
|
|
+ // remove.This will obtain volumeMap lock again if access replicaInfo.
|
|
|
+ synchronized (this) {
|
|
|
for (int idx = 0; idx < dataStorage.getNumStorageDirs(); idx++) {
|
|
|
Storage.StorageDirectory sd = dataStorage.getStorageDir(idx);
|
|
|
final StorageLocation sdLocation = sd.getStorageLocation();
|
|
@@ -615,7 +578,7 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
// Disable the volume from the service.
|
|
|
asyncDiskService.removeVolume(sd.getStorageUuid());
|
|
|
volumes.removeVolume(sdLocation, clearFailure);
|
|
|
- volumes.waitVolumeRemoved(5000, datasetWriteLockCondition);
|
|
|
+ volumes.waitVolumeRemoved(5000, this);
|
|
|
|
|
|
// Removed all replica information for the blocks on the volume.
|
|
|
// Unlike updating the volumeMap in addVolume(), this operation does
|
|
@@ -623,18 +586,19 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
for (String bpid : volumeMap.getBlockPoolList()) {
|
|
|
List<ReplicaInfo> blocks = blkToInvalidate
|
|
|
.computeIfAbsent(bpid, (k) -> new ArrayList<>());
|
|
|
- for (Iterator<ReplicaInfo> it =
|
|
|
- volumeMap.replicas(bpid).iterator(); it.hasNext();) {
|
|
|
- ReplicaInfo block = it.next();
|
|
|
- final StorageLocation blockStorageLocation =
|
|
|
- block.getVolume().getStorageLocation();
|
|
|
- LOG.trace("checking for block " + block.getBlockId() +
|
|
|
- " with storageLocation " + blockStorageLocation);
|
|
|
- if (blockStorageLocation.equals(sdLocation)) {
|
|
|
- blocks.add(block);
|
|
|
- it.remove();
|
|
|
+ volumeMap.replicas(bpid, (iterator) -> {
|
|
|
+ while (iterator.hasNext()) {
|
|
|
+ ReplicaInfo block = iterator.next();
|
|
|
+ final StorageLocation blockStorageLocation =
|
|
|
+ block.getVolume().getStorageLocation();
|
|
|
+ LOG.trace("checking for block " + block.getBlockId() +
|
|
|
+ " with storageLocation " + blockStorageLocation);
|
|
|
+ if (blockStorageLocation.equals(sdLocation)) {
|
|
|
+ blocks.add(block);
|
|
|
+ iterator.remove();
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
+ });
|
|
|
}
|
|
|
storageToRemove.add(sd.getStorageUuid());
|
|
|
storageLocationsToRemove.remove(sdLocation);
|
|
@@ -662,8 +626,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
- for(String storageUuid : storageToRemove) {
|
|
|
+ synchronized (this) {
|
|
|
+ for (String storageUuid : storageToRemove) {
|
|
|
storageMap.remove(storageUuid);
|
|
|
}
|
|
|
}
|
|
@@ -853,7 +817,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
long seekOffset) throws IOException {
|
|
|
|
|
|
ReplicaInfo info;
|
|
|
- try (AutoCloseableLock lock = datasetReadLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.readLock(LockLevel.BLOCK_POOl,
|
|
|
+ b.getBlockPoolId())) {
|
|
|
info = volumeMap.get(b.getBlockPoolId(), b.getLocalBlock());
|
|
|
}
|
|
|
|
|
@@ -941,7 +906,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
@Override // FsDatasetSpi
|
|
|
public ReplicaInputStreams getTmpInputStreams(ExtendedBlock b,
|
|
|
long blkOffset, long metaOffset) throws IOException {
|
|
|
- try (AutoCloseableLock lock = datasetReadLock.acquire()) {
|
|
|
+ try (AutoCloseDataSetLock l = lockManager.readLock(LockLevel.BLOCK_POOl,
|
|
|
+ b.getBlockPoolId())) {
|
|
|
ReplicaInfo info = getReplicaInfo(b);
|
|
|
FsVolumeReference ref = info.getVolume().obtainReference();
|
|
|
try {
|
|
@@ -1117,7 +1083,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
targetStorageType, targetStorageId);
|
|
|
boolean useVolumeOnSameMount = false;
|
|
|
|
|
|
- try (AutoCloseableLock lock = datasetReadLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.readLock(LockLevel.BLOCK_POOl,
|
|
|
+ block.getBlockPoolId())) {
|
|
|
if (shouldConsiderSameMountVolume) {
|
|
|
volumeRef = volumes.getVolumeByMount(targetStorageType,
|
|
|
((FsVolumeImpl) replicaInfo.getVolume()).getMount(),
|
|
@@ -1311,7 +1278,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
|
|
|
FsVolumeReference volumeRef = null;
|
|
|
|
|
|
- try (AutoCloseableLock lock = datasetReadLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.readLock(LockLevel.BLOCK_POOl,
|
|
|
+ block.getBlockPoolId())) {
|
|
|
volumeRef = destination.obtainReference();
|
|
|
}
|
|
|
|
|
@@ -1325,6 +1293,11 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
return replicaInfo;
|
|
|
}
|
|
|
|
|
|
+ @Override
|
|
|
+ public DataNodeLockManager<AutoCloseDataSetLock> acquireDatasetLockManager() {
|
|
|
+ return lockManager;
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* Compute and store the checksum for a block file that does not already have
|
|
|
* its checksum computed.
|
|
@@ -1399,7 +1372,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
@Override // FsDatasetSpi
|
|
|
public ReplicaHandler append(ExtendedBlock b,
|
|
|
long newGS, long expectedBlockLen) throws IOException {
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.writeLock(LockLevel.BLOCK_POOl,
|
|
|
+ b.getBlockPoolId())) {
|
|
|
// If the block was successfully finalized because all packets
|
|
|
// were successfully processed at the Datanode but the ack for
|
|
|
// some of the packets were not received by the client. The client
|
|
@@ -1451,7 +1425,7 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
private ReplicaInPipeline append(String bpid,
|
|
|
ReplicaInfo replicaInfo, long newGS, long estimateBlockLen)
|
|
|
throws IOException {
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.writeLock(LockLevel.BLOCK_POOl, bpid)) {
|
|
|
// If the block is cached, start uncaching it.
|
|
|
if (replicaInfo.getState() != ReplicaState.FINALIZED) {
|
|
|
throw new IOException("Only a Finalized replica can be appended to; "
|
|
@@ -1547,7 +1521,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
|
|
|
while (true) {
|
|
|
try {
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.writeLock(LockLevel.BLOCK_POOl,
|
|
|
+ b.getBlockPoolId())) {
|
|
|
ReplicaInfo replicaInfo = recoverCheck(b, newGS, expectedBlockLen);
|
|
|
FsVolumeReference ref = replicaInfo.getVolume().obtainReference();
|
|
|
ReplicaInPipeline replica;
|
|
@@ -1579,7 +1554,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
LOG.info("Recover failed close " + b);
|
|
|
while (true) {
|
|
|
try {
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.writeLock(LockLevel.BLOCK_POOl,
|
|
|
+ b.getBlockPoolId())) {
|
|
|
// check replica's state
|
|
|
ReplicaInfo replicaInfo = recoverCheck(b, newGS, expectedBlockLen);
|
|
|
// bump the replica's GS
|
|
@@ -1602,7 +1578,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
StorageType storageType, String storageId, ExtendedBlock b,
|
|
|
boolean allowLazyPersist) throws IOException {
|
|
|
long startTimeMs = Time.monotonicNow();
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.writeLock(LockLevel.BLOCK_POOl,
|
|
|
+ b.getBlockPoolId())) {
|
|
|
ReplicaInfo replicaInfo = volumeMap.get(b.getBlockPoolId(),
|
|
|
b.getBlockId());
|
|
|
if (replicaInfo != null) {
|
|
@@ -1680,7 +1657,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
try {
|
|
|
while (true) {
|
|
|
try {
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.writeLock(LockLevel.BLOCK_POOl,
|
|
|
+ b.getBlockPoolId())) {
|
|
|
ReplicaInfo replicaInfo =
|
|
|
getReplicaInfo(b.getBlockPoolId(), b.getBlockId());
|
|
|
// check the replica's state
|
|
@@ -1711,7 +1689,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
private ReplicaHandler recoverRbwImpl(ReplicaInPipeline rbw,
|
|
|
ExtendedBlock b, long newGS, long minBytesRcvd, long maxBytesRcvd)
|
|
|
throws IOException {
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.writeLock(LockLevel.BLOCK_POOl,
|
|
|
+ b.getBlockPoolId())) {
|
|
|
// check generation stamp
|
|
|
long replicaGenerationStamp = rbw.getGenerationStamp();
|
|
|
if (replicaGenerationStamp < b.getGenerationStamp() ||
|
|
@@ -1772,7 +1751,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
public ReplicaInPipeline convertTemporaryToRbw(
|
|
|
final ExtendedBlock b) throws IOException {
|
|
|
long startTimeMs = Time.monotonicNow();
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.writeLock(LockLevel.BLOCK_POOl,
|
|
|
+ b.getBlockPoolId())) {
|
|
|
final long blockId = b.getBlockId();
|
|
|
final long expectedGs = b.getGenerationStamp();
|
|
|
final long visible = b.getNumBytes();
|
|
@@ -1851,7 +1831,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
ReplicaInfo lastFoundReplicaInfo = null;
|
|
|
boolean isInPipeline = false;
|
|
|
do {
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.writeLock(LockLevel.BLOCK_POOl,
|
|
|
+ b.getBlockPoolId())) {
|
|
|
ReplicaInfo currentReplicaInfo =
|
|
|
volumeMap.get(b.getBlockPoolId(), b.getBlockId());
|
|
|
if (currentReplicaInfo == lastFoundReplicaInfo) {
|
|
@@ -1906,7 +1887,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
false);
|
|
|
}
|
|
|
long startHoldLockTimeMs = Time.monotonicNow();
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.writeLock(LockLevel.BLOCK_POOl,
|
|
|
+ b.getBlockPoolId())) {
|
|
|
FsVolumeReference ref = volumes.getNextVolume(storageType, storageId, b
|
|
|
.getNumBytes());
|
|
|
FsVolumeImpl v = (FsVolumeImpl) ref.getVolume();
|
|
@@ -1967,7 +1949,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
ReplicaInfo replicaInfo = null;
|
|
|
ReplicaInfo finalizedReplicaInfo = null;
|
|
|
long startTimeMs = Time.monotonicNow();
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.writeLock(LockLevel.BLOCK_POOl,
|
|
|
+ b.getBlockPoolId())) {
|
|
|
if (Thread.interrupted()) {
|
|
|
// Don't allow data modifications from interrupted threads
|
|
|
throw new IOException("Cannot finalize block from Interrupted Thread");
|
|
@@ -2003,7 +1986,7 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
|
|
|
private ReplicaInfo finalizeReplica(String bpid, ReplicaInfo replicaInfo)
|
|
|
throws IOException {
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.writeLock(LockLevel.BLOCK_POOl, bpid)) {
|
|
|
// Compare generation stamp of old and new replica before finalizing
|
|
|
if (volumeMap.get(bpid, replicaInfo.getBlockId()).getGenerationStamp()
|
|
|
> replicaInfo.getGenerationStamp()) {
|
|
@@ -2049,7 +2032,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
@Override // FsDatasetSpi
|
|
|
public void unfinalizeBlock(ExtendedBlock b) throws IOException {
|
|
|
long startTimeMs = Time.monotonicNow();
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.writeLock(LockLevel.BLOCK_POOl,
|
|
|
+ b.getBlockPoolId())) {
|
|
|
ReplicaInfo replicaInfo = volumeMap.get(b.getBlockPoolId(),
|
|
|
b.getLocalBlock());
|
|
|
if (replicaInfo != null &&
|
|
@@ -2107,47 +2091,50 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
new HashMap<String, BlockListAsLongs.Builder>();
|
|
|
|
|
|
List<FsVolumeImpl> curVolumes = null;
|
|
|
- try (AutoCloseableLock lock = datasetReadLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.readLock(LockLevel.BLOCK_POOl, bpid)) {
|
|
|
curVolumes = volumes.getVolumes();
|
|
|
for (FsVolumeSpi v : curVolumes) {
|
|
|
builders.put(v.getStorageID(), BlockListAsLongs.builder(maxDataLength));
|
|
|
}
|
|
|
|
|
|
Set<String> missingVolumesReported = new HashSet<>();
|
|
|
- for (ReplicaInfo b : volumeMap.replicas(bpid)) {
|
|
|
- // skip PROVIDED replicas.
|
|
|
- if (b.getVolume().getStorageType() == StorageType.PROVIDED) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- String volStorageID = b.getVolume().getStorageID();
|
|
|
- switch(b.getState()) {
|
|
|
- case FINALIZED:
|
|
|
- case RBW:
|
|
|
- case RWR:
|
|
|
- break;
|
|
|
- case RUR:
|
|
|
- // use the original replica.
|
|
|
- b = b.getOriginalReplica();
|
|
|
- break;
|
|
|
- case TEMPORARY:
|
|
|
- continue;
|
|
|
- default:
|
|
|
- assert false : "Illegal ReplicaInfo state.";
|
|
|
- continue;
|
|
|
- }
|
|
|
- BlockListAsLongs.Builder storageBuilder = builders.get(volStorageID);
|
|
|
- // a storage in the process of failing will not be in the volumes list
|
|
|
- // but will be in the replica map.
|
|
|
- if (storageBuilder != null) {
|
|
|
- storageBuilder.add(b);
|
|
|
- } else {
|
|
|
- if (!missingVolumesReported.contains(volStorageID)) {
|
|
|
- LOG.warn("Storage volume: " + volStorageID + " missing for the"
|
|
|
- + " replica block: " + b + ". Probably being removed!");
|
|
|
- missingVolumesReported.add(volStorageID);
|
|
|
+ volumeMap.replicas(bpid, (iterator) -> {
|
|
|
+ while (iterator.hasNext()) {
|
|
|
+ ReplicaInfo b = iterator.next();
|
|
|
+ // skip PROVIDED replicas.
|
|
|
+ if (b.getVolume().getStorageType() == StorageType.PROVIDED) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ String volStorageID = b.getVolume().getStorageID();
|
|
|
+ switch(b.getState()) {
|
|
|
+ case FINALIZED:
|
|
|
+ case RBW:
|
|
|
+ case RWR:
|
|
|
+ break;
|
|
|
+ case RUR:
|
|
|
+ // use the original replica.
|
|
|
+ b = b.getOriginalReplica();
|
|
|
+ break;
|
|
|
+ case TEMPORARY:
|
|
|
+ continue;
|
|
|
+ default:
|
|
|
+ assert false : "Illegal ReplicaInfo state.";
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ BlockListAsLongs.Builder storageBuilder = builders.get(volStorageID);
|
|
|
+ // a storage in the process of failing will not be in the volumes list
|
|
|
+ // but will be in the replica map.
|
|
|
+ if (storageBuilder != null) {
|
|
|
+ storageBuilder.add(b);
|
|
|
+ } else {
|
|
|
+ if (!missingVolumesReported.contains(volStorageID)) {
|
|
|
+ LOG.warn("Storage volume: " + volStorageID + " missing for the"
|
|
|
+ + " replica block: " + b + ". Probably being removed!");
|
|
|
+ missingVolumesReported.add(volStorageID);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
for (FsVolumeImpl v : curVolumes) {
|
|
@@ -2162,7 +2149,7 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
* Gets a list of references to the finalized blocks for the given block pool.
|
|
|
* <p>
|
|
|
* Callers of this function should call
|
|
|
- * {@link FsDatasetSpi#acquireDatasetLock()} to avoid blocks' status being
|
|
|
+ * {@link FsDatasetSpi#acquireDatasetLockManager()} ()} to avoid blocks' status being
|
|
|
* changed during list iteration.
|
|
|
* </p>
|
|
|
* @return a list of references to the finalized blocks for the given block
|
|
@@ -2170,14 +2157,17 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
*/
|
|
|
@Override
|
|
|
public List<ReplicaInfo> getFinalizedBlocks(String bpid) {
|
|
|
- try (AutoCloseableLock lock = datasetReadLock.acquire()) {
|
|
|
- final List<ReplicaInfo> finalized = new ArrayList<ReplicaInfo>(
|
|
|
- volumeMap.size(bpid));
|
|
|
- for (ReplicaInfo b : volumeMap.replicas(bpid)) {
|
|
|
- if (b.getState() == ReplicaState.FINALIZED) {
|
|
|
- finalized.add(b);
|
|
|
+ try (AutoCloseDataSetLock l = lockManager.readLock(LockLevel.BLOCK_POOl, bpid)) {
|
|
|
+ ArrayList<ReplicaInfo> finalized =
|
|
|
+ new ArrayList<>(volumeMap.size(bpid));
|
|
|
+ volumeMap.replicas(bpid, (iterator) -> {
|
|
|
+ while (iterator.hasNext()) {
|
|
|
+ ReplicaInfo b = iterator.next();
|
|
|
+ if (b.getState() == ReplicaState.FINALIZED) {
|
|
|
+ finalized.add(new FinalizedReplica((FinalizedReplica)b));
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
+ });
|
|
|
return finalized;
|
|
|
}
|
|
|
}
|
|
@@ -2310,7 +2300,7 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
for (int i = 0; i < invalidBlks.length; i++) {
|
|
|
final ReplicaInfo removing;
|
|
|
final FsVolumeImpl v;
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.writeLock(LockLevel.BLOCK_POOl, bpid)) {
|
|
|
final ReplicaInfo info = volumeMap.get(bpid, invalidBlks[i]);
|
|
|
if (info == null) {
|
|
|
ReplicaInfo infoByBlockId =
|
|
@@ -2433,7 +2423,7 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
long length, genstamp;
|
|
|
Executor volumeExecutor;
|
|
|
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.writeLock(LockLevel.BLOCK_POOl, bpid)) {
|
|
|
ReplicaInfo info = volumeMap.get(bpid, blockId);
|
|
|
boolean success = false;
|
|
|
try {
|
|
@@ -2501,7 +2491,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
|
|
|
@Override // FsDatasetSpi
|
|
|
public boolean contains(final ExtendedBlock block) {
|
|
|
- try (AutoCloseableLock lock = datasetReadLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.readLock(LockLevel.BLOCK_POOl,
|
|
|
+ block.getBlockPoolId())) {
|
|
|
final long blockId = block.getLocalBlock().getBlockId();
|
|
|
final String bpid = block.getBlockPoolId();
|
|
|
final ReplicaInfo r = volumeMap.get(bpid, blockId);
|
|
@@ -2628,7 +2619,7 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
curDirScannerNotifyCount = 0;
|
|
|
lastDirScannerNotifyTime = startTimeMs;
|
|
|
}
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.writeLock(LockLevel.BLOCK_POOl, bpid)) {
|
|
|
memBlockInfo = volumeMap.get(bpid, blockId);
|
|
|
if (memBlockInfo != null &&
|
|
|
memBlockInfo.getState() != ReplicaState.FINALIZED) {
|
|
@@ -2851,7 +2842,7 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
|
|
|
@Override
|
|
|
public String getReplicaString(String bpid, long blockId) {
|
|
|
- try (AutoCloseableLock lock = datasetReadLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.readLock(LockLevel.BLOCK_POOl, bpid)) {
|
|
|
final Replica r = volumeMap.get(bpid, blockId);
|
|
|
return r == null ? "null" : r.toString();
|
|
|
}
|
|
@@ -2865,12 +2856,26 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
datanode.getDnConf().getXceiverStopTimeout());
|
|
|
}
|
|
|
|
|
|
+ ReplicaRecoveryInfo initReplicaRecovery(String bpid, ReplicaMap map,
|
|
|
+ Block block, long recoveryId, long xceiverStopTimeout) throws IOException {
|
|
|
+ while (true) {
|
|
|
+ try {
|
|
|
+ try (AutoCloseDataSetLock l = lockManager.writeLock(LockLevel.BLOCK_POOl, bpid)) {
|
|
|
+ return initReplicaRecoveryImpl(bpid, map, block, recoveryId);
|
|
|
+ }
|
|
|
+ } catch (MustStopExistingWriter e) {
|
|
|
+ e.getReplicaInPipeline().stopWriter(xceiverStopTimeout);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
/** static version of {@link #initReplicaRecovery(RecoveringBlock)}. */
|
|
|
static ReplicaRecoveryInfo initReplicaRecovery(String bpid, ReplicaMap map,
|
|
|
- Block block, long recoveryId, long xceiverStopTimeout) throws IOException {
|
|
|
+ Block block, long recoveryId, long xceiverStopTimeout, DataSetLockManager
|
|
|
+ lockManager) throws IOException {
|
|
|
while (true) {
|
|
|
try {
|
|
|
- try (AutoCloseableLock lock = map.getLock().acquire()) {
|
|
|
+ try (AutoCloseDataSetLock l = lockManager.writeLock(LockLevel.BLOCK_POOl, bpid)) {
|
|
|
return initReplicaRecoveryImpl(bpid, map, block, recoveryId);
|
|
|
}
|
|
|
} catch (MustStopExistingWriter e) {
|
|
@@ -2959,7 +2964,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
final long newBlockId,
|
|
|
final long newlength) throws IOException {
|
|
|
long startTimeMs = Time.monotonicNow();
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.writeLock(LockLevel.BLOCK_POOl,
|
|
|
+ oldBlock.getBlockPoolId())) {
|
|
|
//get replica
|
|
|
final String bpid = oldBlock.getBlockPoolId();
|
|
|
final ReplicaInfo replica = volumeMap.get(bpid, oldBlock.getBlockId());
|
|
@@ -3078,7 +3084,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
@Override // FsDatasetSpi
|
|
|
public long getReplicaVisibleLength(final ExtendedBlock block)
|
|
|
throws IOException {
|
|
|
- try (AutoCloseableLock lock = datasetReadLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.readLock(LockLevel.BLOCK_POOl,
|
|
|
+ block.getBlockPoolId())) {
|
|
|
final Replica replica = getReplicaInfo(block.getBlockPoolId(),
|
|
|
block.getBlockId());
|
|
|
if (replica.getGenerationStamp() < block.getGenerationStamp()) {
|
|
@@ -3095,7 +3102,7 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
throws IOException {
|
|
|
LOG.info("Adding block pool " + bpid);
|
|
|
AddBlockPoolException volumeExceptions = new AddBlockPoolException();
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.writeLock(LockLevel.BLOCK_POOl, bpid)) {
|
|
|
try {
|
|
|
volumes.addBlockPool(bpid, conf);
|
|
|
} catch (AddBlockPoolException e) {
|
|
@@ -3125,7 +3132,7 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
|
|
|
@Override
|
|
|
public void shutdownBlockPool(String bpid) {
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.writeLock(LockLevel.BLOCK_POOl, bpid)) {
|
|
|
LOG.info("Removing block pool " + bpid);
|
|
|
Map<DatanodeStorage, BlockListAsLongs> blocksPerVolume
|
|
|
= getBlockReports(bpid);
|
|
@@ -3199,7 +3206,7 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
@Override //FsDatasetSpi
|
|
|
public void deleteBlockPool(String bpid, boolean force)
|
|
|
throws IOException {
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.writeLock(LockLevel.BLOCK_POOl, bpid)) {
|
|
|
List<FsVolumeImpl> curVolumes = volumes.getVolumes();
|
|
|
if (!force) {
|
|
|
for (FsVolumeImpl volume : curVolumes) {
|
|
@@ -3228,7 +3235,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
@Override // FsDatasetSpi
|
|
|
public BlockLocalPathInfo getBlockLocalPathInfo(ExtendedBlock block)
|
|
|
throws IOException {
|
|
|
- try (AutoCloseableLock lock = datasetReadLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.readLock(LockLevel.BLOCK_POOl,
|
|
|
+ block.getBlockPoolId())) {
|
|
|
final Replica replica = volumeMap.get(block.getBlockPoolId(),
|
|
|
block.getBlockId());
|
|
|
if (replica == null) {
|
|
@@ -3282,7 +3290,7 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
@Override
|
|
|
public void onCompleteLazyPersist(String bpId, long blockId,
|
|
|
long creationTime, File[] savedFiles, FsVolumeImpl targetVolume) {
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.writeLock(LockLevel.BLOCK_POOl, bpId)) {
|
|
|
ramDiskReplicaTracker.recordEndLazyPersist(bpId, blockId, savedFiles);
|
|
|
|
|
|
targetVolume.incDfsUsedAndNumBlocks(bpId, savedFiles[0].length()
|
|
@@ -3416,7 +3424,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
try {
|
|
|
block = ramDiskReplicaTracker.dequeueNextReplicaToPersist();
|
|
|
if (block != null) {
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.writeLock(LockLevel.BLOCK_POOl,
|
|
|
+ block.getBlockPoolId())) {
|
|
|
replicaInfo = volumeMap.get(block.getBlockPoolId(), block.getBlockId());
|
|
|
|
|
|
// If replicaInfo is null, the block was either deleted before
|
|
@@ -3483,7 +3492,7 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
ReplicaInfo replicaInfo, newReplicaInfo;
|
|
|
final String bpid = replicaState.getBlockPoolId();
|
|
|
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
+ try (AutoCloseableLock lock = lockManager.writeLock(LockLevel.BLOCK_POOl, bpid)) {
|
|
|
replicaInfo = getReplicaInfo(replicaState.getBlockPoolId(),
|
|
|
replicaState.getBlockId());
|
|
|
Preconditions.checkState(replicaInfo.getVolume().isTransientStorage());
|
|
@@ -3661,18 +3670,21 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
|
}
|
|
|
|
|
|
void stopAllDataxceiverThreads(FsVolumeImpl volume) {
|
|
|
- try (AutoCloseableLock lock = datasetWriteLock.acquire()) {
|
|
|
- for (String bpid : volumeMap.getBlockPoolList()) {
|
|
|
- Collection<ReplicaInfo> replicas = volumeMap.replicas(bpid);
|
|
|
- for (ReplicaInfo replicaInfo : replicas) {
|
|
|
- if ((replicaInfo.getState() == ReplicaState.TEMPORARY
|
|
|
- || replicaInfo.getState() == ReplicaState.RBW)
|
|
|
- && replicaInfo.getVolume().equals(volume)) {
|
|
|
- ReplicaInPipeline replicaInPipeline =
|
|
|
- (ReplicaInPipeline) replicaInfo;
|
|
|
- replicaInPipeline.interruptThread();
|
|
|
+ for (String bpid : volumeMap.getBlockPoolList()) {
|
|
|
+ try (AutoCloseDataSetLock lock = lockManager
|
|
|
+ .writeLock(LockLevel.BLOCK_POOl, bpid)) {
|
|
|
+ volumeMap.replicas(bpid, (iterator) -> {
|
|
|
+ while (iterator.hasNext()) {
|
|
|
+ ReplicaInfo replicaInfo = iterator.next();
|
|
|
+ if ((replicaInfo.getState() == ReplicaState.TEMPORARY
|
|
|
+ || replicaInfo.getState() == ReplicaState.RBW)
|
|
|
+ && replicaInfo.getVolume().equals(volume)) {
|
|
|
+ ReplicaInPipeline replicaInPipeline =
|
|
|
+ (ReplicaInPipeline) replicaInfo;
|
|
|
+ replicaInPipeline.interruptThread();
|
|
|
+ }
|
|
|
}
|
|
|
- }
|
|
|
+ });
|
|
|
}
|
|
|
}
|
|
|
}
|