4141import java .util .concurrent .Executor ;
4242import java .util .concurrent .locks .Condition ;
4343import java .util .concurrent .TimeUnit ;
44- import java .util .concurrent .locks .ReentrantReadWriteLock ;
4544
4645import javax .management .NotCompliantMBeanException ;
4746import javax .management .ObjectName ;
@@ -179,7 +178,7 @@ public StorageReport[] getStorageReports(String bpid)
179178
180179 @ Override
181180 public FsVolumeImpl getVolume (final ExtendedBlock b ) {
182- try (AutoCloseableLock lock = datasetWriteLock .acquire ()) {
181+ try (AutoCloseableLock lock = datasetReadLock .acquire ()) {
183182 final ReplicaInfo r =
184183 volumeMap .get (b .getBlockPoolId (), b .getLocalBlock ());
185184 return r != null ? (FsVolumeImpl ) r .getVolume () : null ;
@@ -189,7 +188,7 @@ public FsVolumeImpl getVolume(final ExtendedBlock b) {
189188 @ Override // FsDatasetSpi
190189 public Block getStoredBlock (String bpid , long blkid )
191190 throws IOException {
192- try (AutoCloseableLock lock = datasetWriteLock .acquire ()) {
191+ try (AutoCloseableLock lock = datasetReadLock .acquire ()) {
193192 ReplicaInfo r = volumeMap .get (bpid , blkid );
194193 if (r == null ) {
195194 return null ;
@@ -206,7 +205,7 @@ public Block getStoredBlock(String bpid, long blkid)
206205 public Set <? extends Replica > deepCopyReplica (String bpid )
207206 throws IOException {
208207 Set <? extends Replica > replicas = null ;
209- try (AutoCloseableLock lock = datasetWriteLock .acquire ()) {
208+ try (AutoCloseableLock lock = datasetReadLock .acquire ()) {
210209 replicas =
211210 new HashSet <>(volumeMap .replicas (bpid ) == null ? Collections .EMPTY_SET
212211 : volumeMap .replicas (bpid ));
@@ -302,7 +301,20 @@ public LengthInputStream getMetaDataInputStream(ExtendedBlock b)
302301 DFSConfigKeys .DFS_DATANODE_LOCK_REPORTING_THRESHOLD_MS_DEFAULT ,
303302 TimeUnit .MILLISECONDS ));
304303 this .datasetWriteLock = new AutoCloseableLock (datasetRWLock .writeLock ());
305- this .datasetReadLock = new AutoCloseableLock (datasetRWLock .readLock ());
304+ boolean enableRL = conf .getBoolean (
305+ DFSConfigKeys .DFS_DATANODE_LOCK_READ_WRITE_ENABLED_KEY ,
306+ DFSConfigKeys .DFS_DATANODE_LOCK_READ_WRITE_ENABLED_DEFAULT );
307+ // The read lock can be disabled by the above config key. If it is disabled
308+ // then we simply make the both the read and write lock variables hold
309+ // the write lock. All accesses to the lock are via these variables, so that
310+ // effectively disables the read lock.
311+ if (enableRL ) {
312+ LOG .info ("The datanode lock is a read write lock" );
313+ this .datasetReadLock = new AutoCloseableLock (datasetRWLock .readLock ());
314+ } else {
315+ LOG .info ("The datanode lock is an exclusive write lock" );
316+ this .datasetReadLock = this .datasetWriteLock ;
317+ }
306318 this .datasetWriteLockCondition = datasetWriteLock .newCondition ();
307319
308320 // The number of volumes required for operation is the total number
@@ -342,7 +354,7 @@ public LengthInputStream getMetaDataInputStream(ExtendedBlock b)
342354 }
343355
344356 storageMap = new ConcurrentHashMap <String , DatanodeStorage >();
345- volumeMap = new ReplicaMap (datasetRWLock );
357+ volumeMap = new ReplicaMap (datasetReadLock , datasetWriteLock );
346358 ramDiskReplicaTracker = RamDiskReplicaTracker .getInstance (conf , this );
347359
348360 @ SuppressWarnings ("unchecked" )
@@ -475,7 +487,8 @@ private void addVolume(Storage.StorageDirectory sd) throws IOException {
475487 .setConf (this .conf )
476488 .build ();
477489 FsVolumeReference ref = fsVolume .obtainReference ();
478- ReplicaMap tempVolumeMap = new ReplicaMap (datasetRWLock );
490+ ReplicaMap tempVolumeMap =
491+ new ReplicaMap (datasetReadLock , datasetWriteLock );
479492 fsVolume .getVolumeMap (tempVolumeMap , ramDiskReplicaTracker );
480493
481494 activateVolume (tempVolumeMap , sd , storageLocation .getStorageType (), ref );
@@ -515,7 +528,7 @@ public void addVolume(final StorageLocation location,
515528 final FsVolumeImpl fsVolume =
516529 createFsVolume (sd .getStorageUuid (), sd , location );
517530 final ReplicaMap tempVolumeMap =
518- new ReplicaMap (new ReentrantReadWriteLock () );
531+ new ReplicaMap (datasetReadLock , datasetWriteLock );
519532 ArrayList <IOException > exceptions = Lists .newArrayList ();
520533
521534 for (final NamespaceInfo nsInfo : nsInfos ) {
@@ -810,7 +823,7 @@ public InputStream getBlockInputStream(ExtendedBlock b,
810823 long seekOffset ) throws IOException {
811824
812825 ReplicaInfo info ;
813- try (AutoCloseableLock lock = datasetWriteLock .acquire ()) {
826+ try (AutoCloseableLock lock = datasetReadLock .acquire ()) {
814827 info = volumeMap .get (b .getBlockPoolId (), b .getLocalBlock ());
815828 }
816829
@@ -898,7 +911,7 @@ ReplicaInfo getReplicaInfo(String bpid, long blkid)
898911 @ Override // FsDatasetSpi
899912 public ReplicaInputStreams getTmpInputStreams (ExtendedBlock b ,
900913 long blkOffset , long metaOffset ) throws IOException {
901- try (AutoCloseableLock lock = datasetWriteLock .acquire ()) {
914+ try (AutoCloseableLock lock = datasetReadLock .acquire ()) {
902915 ReplicaInfo info = getReplicaInfo (b );
903916 FsVolumeReference ref = info .getVolume ().obtainReference ();
904917 try {
@@ -1023,7 +1036,7 @@ public ReplicaInfo moveBlockAcrossStorage(ExtendedBlock block,
10231036 }
10241037
10251038 FsVolumeReference volumeRef = null ;
1026- try (AutoCloseableLock lock = datasetWriteLock .acquire ()) {
1039+ try (AutoCloseableLock lock = datasetReadLock .acquire ()) {
10271040 volumeRef = volumes .getNextVolume (targetStorageType , targetStorageId ,
10281041 block .getNumBytes ());
10291042 }
@@ -1137,7 +1150,7 @@ public ReplicaInfo moveBlockAcrossVolumes(ExtendedBlock block, FsVolumeSpi
11371150
11381151 FsVolumeReference volumeRef = null ;
11391152
1140- try (AutoCloseableLock lock = datasetWriteLock .acquire ()) {
1153+ try (AutoCloseableLock lock = datasetReadLock .acquire ()) {
11411154 volumeRef = destination .obtainReference ();
11421155 }
11431156
@@ -1891,7 +1904,7 @@ public Map<DatanodeStorage, BlockListAsLongs> getBlockReports(String bpid) {
18911904 new HashMap <String , BlockListAsLongs .Builder >();
18921905
18931906 List <FsVolumeImpl > curVolumes = null ;
1894- try (AutoCloseableLock lock = datasetWriteLock .acquire ()) {
1907+ try (AutoCloseableLock lock = datasetReadLock .acquire ()) {
18951908 curVolumes = volumes .getVolumes ();
18961909 for (FsVolumeSpi v : curVolumes ) {
18971910 builders .put (v .getStorageID (), BlockListAsLongs .builder (maxDataLength ));
@@ -1954,7 +1967,7 @@ public Map<DatanodeStorage, BlockListAsLongs> getBlockReports(String bpid) {
19541967 */
19551968 @ Override
19561969 public List <ReplicaInfo > getFinalizedBlocks (String bpid ) {
1957- try (AutoCloseableLock lock = datasetWriteLock .acquire ()) {
1970+ try (AutoCloseableLock lock = datasetReadLock .acquire ()) {
19581971 final List <ReplicaInfo > finalized = new ArrayList <ReplicaInfo >(
19591972 volumeMap .size (bpid ));
19601973 for (ReplicaInfo b : volumeMap .replicas (bpid )) {
@@ -2047,9 +2060,7 @@ private boolean isValid(final ExtendedBlock b, final ReplicaState state) {
20472060 ReplicaInfo validateBlockFile (String bpid , long blockId ) {
20482061 //Should we check for metadata file too?
20492062 final ReplicaInfo r ;
2050- try (AutoCloseableLock lock = datasetWriteLock .acquire ()) {
2051- r = volumeMap .get (bpid , blockId );
2052- }
2063+ r = volumeMap .get (bpid , blockId );
20532064 if (r != null ) {
20542065 if (r .blockDataExists ()) {
20552066 return r ;
@@ -2292,7 +2303,7 @@ public boolean isCached(String bpid, long blockId) {
22922303
22932304 @ Override // FsDatasetSpi
22942305 public boolean contains (final ExtendedBlock block ) {
2295- try (AutoCloseableLock lock = datasetWriteLock .acquire ()) {
2306+ try (AutoCloseableLock lock = datasetReadLock .acquire ()) {
22962307 final long blockId = block .getLocalBlock ().getBlockId ();
22972308 final String bpid = block .getBlockPoolId ();
22982309 final ReplicaInfo r = volumeMap .get (bpid , blockId );
@@ -2613,7 +2624,7 @@ public ReplicaInfo getReplica(String bpid, long blockId) {
26132624
26142625 @ Override
26152626 public String getReplicaString (String bpid , long blockId ) {
2616- try (AutoCloseableLock lock = datasetWriteLock .acquire ()) {
2627+ try (AutoCloseableLock lock = datasetReadLock .acquire ()) {
26172628 final Replica r = volumeMap .get (bpid , blockId );
26182629 return r == null ? "null" : r .toString ();
26192630 }
@@ -2833,7 +2844,7 @@ private ReplicaInfo updateReplicaUnderRecovery(
28332844 @ Override // FsDatasetSpi
28342845 public long getReplicaVisibleLength (final ExtendedBlock block )
28352846 throws IOException {
2836- try (AutoCloseableLock lock = datasetWriteLock .acquire ()) {
2847+ try (AutoCloseableLock lock = datasetReadLock .acquire ()) {
28372848 final Replica replica = getReplicaInfo (block .getBlockPoolId (),
28382849 block .getBlockId ());
28392850 if (replica .getGenerationStamp () < block .getGenerationStamp ()) {
@@ -2983,18 +2994,20 @@ public void deleteBlockPool(String bpid, boolean force)
29832994 @ Override // FsDatasetSpi
29842995 public BlockLocalPathInfo getBlockLocalPathInfo (ExtendedBlock block )
29852996 throws IOException {
2986- try (AutoCloseableLock lock = datasetWriteLock .acquire ()) {
2997+ try (AutoCloseableLock lock = datasetReadLock .acquire ()) {
29872998 final Replica replica = volumeMap .get (block .getBlockPoolId (),
29882999 block .getBlockId ());
29893000 if (replica == null ) {
29903001 throw new ReplicaNotFoundException (block );
29913002 }
2992- if (replica .getGenerationStamp () < block .getGenerationStamp ()) {
2993- throw new IOException (
2994- "Replica generation stamp < block generation stamp, block="
2995- + block + ", replica=" + replica );
2996- } else if (replica .getGenerationStamp () > block .getGenerationStamp ()) {
2997- block .setGenerationStamp (replica .getGenerationStamp ());
3003+ synchronized (replica ) {
3004+ if (replica .getGenerationStamp () < block .getGenerationStamp ()) {
3005+ throw new IOException (
3006+ "Replica generation stamp < block generation stamp, block="
3007+ + block + ", replica=" + replica );
3008+ } else if (replica .getGenerationStamp () > block .getGenerationStamp ()) {
3009+ block .setGenerationStamp (replica .getGenerationStamp ());
3010+ }
29983011 }
29993012 }
30003013
0 commit comments