|
@@ -903,6 +903,17 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
return dstfile;
|
|
return dstfile;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ private void fsyncDirectory(FsVolumeSpi volume, File... dirs)
|
|
|
|
+ throws IOException {
|
|
|
|
+ for (File dir : dirs) {
|
|
|
|
+ try {
|
|
|
|
+ IOUtils.fsync(dir);
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ throw new IOException("Failed to sync " + dir, e);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Copy the block and meta files for the given block to the given destination.
|
|
* Copy the block and meta files for the given block to the given destination.
|
|
* @return the new meta and block files.
|
|
* @return the new meta and block files.
|
|
@@ -997,7 +1008,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
targetVolume, blockFiles[0].getParentFile(), 0);
|
|
targetVolume, blockFiles[0].getParentFile(), 0);
|
|
newReplicaInfo.setNumBytes(blockFiles[1].length());
|
|
newReplicaInfo.setNumBytes(blockFiles[1].length());
|
|
// Finalize the copied files
|
|
// Finalize the copied files
|
|
- newReplicaInfo = finalizeReplica(block.getBlockPoolId(), newReplicaInfo);
|
|
|
|
|
|
+ newReplicaInfo = finalizeReplica(block.getBlockPoolId(), newReplicaInfo,
|
|
|
|
+ false);
|
|
try(AutoCloseableLock lock = datasetLock.acquire()) {
|
|
try(AutoCloseableLock lock = datasetLock.acquire()) {
|
|
// Increment numBlocks here as this block moved without knowing to BPS
|
|
// Increment numBlocks here as this block moved without knowing to BPS
|
|
FsVolumeImpl volume = (FsVolumeImpl) newReplicaInfo.getVolume();
|
|
FsVolumeImpl volume = (FsVolumeImpl) newReplicaInfo.getVolume();
|
|
@@ -1358,7 +1370,7 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
bumpReplicaGS(replicaInfo, newGS);
|
|
bumpReplicaGS(replicaInfo, newGS);
|
|
// finalize the replica if RBW
|
|
// finalize the replica if RBW
|
|
if (replicaInfo.getState() == ReplicaState.RBW) {
|
|
if (replicaInfo.getState() == ReplicaState.RBW) {
|
|
- finalizeReplica(b.getBlockPoolId(), replicaInfo);
|
|
|
|
|
|
+ finalizeReplica(b.getBlockPoolId(), replicaInfo, false);
|
|
}
|
|
}
|
|
return replicaInfo;
|
|
return replicaInfo;
|
|
}
|
|
}
|
|
@@ -1707,7 +1719,8 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
* Complete the block write!
|
|
* Complete the block write!
|
|
*/
|
|
*/
|
|
@Override // FsDatasetSpi
|
|
@Override // FsDatasetSpi
|
|
- public void finalizeBlock(ExtendedBlock b) throws IOException {
|
|
|
|
|
|
+ public void finalizeBlock(ExtendedBlock b, boolean fsyncDir)
|
|
|
|
+ throws IOException {
|
|
try(AutoCloseableLock lock = datasetLock.acquire()) {
|
|
try(AutoCloseableLock lock = datasetLock.acquire()) {
|
|
if (Thread.interrupted()) {
|
|
if (Thread.interrupted()) {
|
|
// Don't allow data modifications from interrupted threads
|
|
// Don't allow data modifications from interrupted threads
|
|
@@ -1719,12 +1732,12 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
// been opened for append but never modified
|
|
// been opened for append but never modified
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- finalizeReplica(b.getBlockPoolId(), replicaInfo);
|
|
|
|
|
|
+ finalizeReplica(b.getBlockPoolId(), replicaInfo, fsyncDir);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
private FinalizedReplica finalizeReplica(String bpid,
|
|
private FinalizedReplica finalizeReplica(String bpid,
|
|
- ReplicaInfo replicaInfo) throws IOException {
|
|
|
|
|
|
+ ReplicaInfo replicaInfo, boolean fsyncDir) throws IOException {
|
|
try(AutoCloseableLock lock = datasetLock.acquire()) {
|
|
try(AutoCloseableLock lock = datasetLock.acquire()) {
|
|
FinalizedReplica newReplicaInfo = null;
|
|
FinalizedReplica newReplicaInfo = null;
|
|
if (replicaInfo.getState() == ReplicaState.RUR &&
|
|
if (replicaInfo.getState() == ReplicaState.RUR &&
|
|
@@ -1744,7 +1757,15 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
bpid, replicaInfo, f, replicaInfo.getBytesReserved());
|
|
bpid, replicaInfo, f, replicaInfo.getBytesReserved());
|
|
newReplicaInfo =
|
|
newReplicaInfo =
|
|
new FinalizedReplica(replicaInfo, v, dest.getParentFile());
|
|
new FinalizedReplica(replicaInfo, v, dest.getParentFile());
|
|
-
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Sync the directory after rename from tmp/rbw to Finalized if
|
|
|
|
+ * configured. Though rename should be atomic operation, sync on both
|
|
|
|
+ * dest and src directories are done because IOUtils.fsync() calls
|
|
|
|
+ * directory's channel sync, not the journal itself.
|
|
|
|
+ */
|
|
|
|
+ if (fsyncDir) {
|
|
|
|
+ fsyncDirectory(v, dest.getParentFile(), f.getParentFile());
|
|
|
|
+ }
|
|
if (v.isTransientStorage()) {
|
|
if (v.isTransientStorage()) {
|
|
releaseLockedMemory(
|
|
releaseLockedMemory(
|
|
replicaInfo.getOriginalBytesReserved()
|
|
replicaInfo.getOriginalBytesReserved()
|
|
@@ -2718,12 +2739,12 @@ class FsDatasetImpl implements FsDatasetSpi<FsVolumeImpl> {
|
|
// but it is immediately converted to finalized state within the same
|
|
// but it is immediately converted to finalized state within the same
|
|
// lock, so no need to update it.
|
|
// lock, so no need to update it.
|
|
volumeMap.add(bpid, newReplicaInfo);
|
|
volumeMap.add(bpid, newReplicaInfo);
|
|
- finalizeReplica(bpid, newReplicaInfo);
|
|
|
|
|
|
+ finalizeReplica(bpid, newReplicaInfo, false);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// finalize the block
|
|
// finalize the block
|
|
- return finalizeReplica(bpid, rur);
|
|
|
|
|
|
+ return finalizeReplica(bpid, rur, false);
|
|
}
|
|
}
|
|
|
|
|
|
private File[] copyReplicaWithNewBlockIdAndGS(
|
|
private File[] copyReplicaWithNewBlockIdAndGS(
|