@@ -228,6 +228,13 @@ static LocatedBlock storeAllocatedBlock(FSNamesystem fsn, String src,
228228 // while chooseTarget() was executing.
229229 LocatedBlock [] onRetryBlock = new LocatedBlock [1 ];
230230 INodesInPath iip = fsn .dir .resolvePath (null , src , fileId );
231+
232+ INode [] missing = new INode []{iip .getLastINode ()};
233+ INodesInPath existing = iip .getParentINodesInPath ();
234+ FSDirectory fsd = fsn .getFSDirectory ();
235+ // switch the locks
236+ fsd .getINodeMap ().latchWriteLock (existing , missing );
237+
231238 FileState fileState = analyzeFileState (fsn , iip , fileId , clientName ,
232239 previous , onRetryBlock );
233240 final INodeFile pendingFile = fileState .inode ;
@@ -392,8 +399,8 @@ static HdfsFileStatus startFile(
392399 }
393400 fsn .checkFsObjectLimit ();
394401 INodeFile newNode = null ;
395- INodesInPath parent =
396- FSDirMkdirOp . createAncestorDirectories ( fsd , iip , permissions );
402+ INodesInPath parent = FSDirMkdirOp . createMissingDirs ( fsd ,
403+ iip . getParentINodesInPath () , permissions );
397404 if (parent != null ) {
398405 iip = addFile (fsd , parent , iip .getLastLocalName (), permissions ,
399406 replication , blockSize , holder , clientMachine , shouldReplicate ,
@@ -541,41 +548,22 @@ private static INodesInPath addFile(
541548 FSDirectory fsd , INodesInPath existing , byte [] localName ,
542549 PermissionStatus permissions , short replication , long preferredBlockSize ,
543550 String clientName , String clientMachine , boolean shouldReplicate ,
544- String ecPolicyName , String storagePolicy ) throws IOException {
551+ String ecPolicyName , String storagePolicy )
552+ throws IOException {
545553
546554 Preconditions .checkNotNull (existing );
547555 long modTime = now ();
548556 INodesInPath newiip ;
549557 fsd .writeLock ();
550558 try {
551- boolean isStriped = false ;
552- ErasureCodingPolicy ecPolicy = null ;
553- byte storagepolicyid = 0 ;
554- if (storagePolicy != null && !storagePolicy .isEmpty ()) {
555- BlockStoragePolicy policy =
556- fsd .getBlockManager ().getStoragePolicy (storagePolicy );
557- if (policy == null ) {
558- throw new HadoopIllegalArgumentException (
559- "Cannot find a block policy with the name " + storagePolicy );
560- }
561- storagepolicyid = policy .getId ();
562- }
563- if (!shouldReplicate ) {
564- ecPolicy = FSDirErasureCodingOp .getErasureCodingPolicy (
565- fsd .getFSNamesystem (), ecPolicyName , existing );
566- if (ecPolicy != null && (!ecPolicy .isReplicationPolicy ())) {
567- isStriped = true ;
568- }
569- }
570- final BlockType blockType = isStriped ?
571- BlockType .STRIPED : BlockType .CONTIGUOUS ;
572- final Short replicationFactor = (!isStriped ? replication : null );
573- final Byte ecPolicyID = (isStriped ? ecPolicy .getId () : null );
574- INodeFile newNode = newINodeFile (fsd .allocateNewInodeId (), permissions ,
575- modTime , modTime , replicationFactor , ecPolicyID , preferredBlockSize ,
576- storagepolicyid , blockType );
577- newNode .setLocalName (localName );
578- newNode .toUnderConstruction (clientName , clientMachine );
559+ INodeFile newNode = createINodeFile (fsd , existing , localName ,
560+ permissions , replication , preferredBlockSize , clientName ,
561+ clientMachine , shouldReplicate , ecPolicyName , storagePolicy , modTime );
562+
563+ INode [] missing = new INode [] {newNode };
564+ // switch the locks
565+ fsd .getINodeMap ().latchWriteLock (existing , missing );
566+
579567 newiip = fsd .addINode (existing , newNode , permissions .getPermission ());
580568 } finally {
581569 fsd .writeUnlock ();
@@ -593,6 +581,42 @@ private static INodesInPath addFile(
593581 return newiip ;
594582 }
595583
584+ private static INodeFile createINodeFile (FSDirectory fsd ,
585+ INodesInPath existing , byte [] localName , PermissionStatus permissions ,
586+ short replication , long preferredBlockSize , String clientName ,
587+ String clientMachine , boolean shouldReplicate , String ecPolicyName ,
588+ String storagePolicy , long modTime ) throws IOException {
589+ boolean isStriped = false ;
590+ ErasureCodingPolicy ecPolicy = null ;
591+ byte storagepolicyid = 0 ;
592+ if (storagePolicy != null && !storagePolicy .isEmpty ()) {
593+ BlockStoragePolicy policy =
594+ fsd .getBlockManager ().getStoragePolicy (storagePolicy );
595+ if (policy == null ) {
596+ throw new HadoopIllegalArgumentException (
597+ "Cannot find a block policy with the name " + storagePolicy );
598+ }
599+ storagepolicyid = policy .getId ();
600+ }
601+ if (!shouldReplicate ) {
602+ ecPolicy = FSDirErasureCodingOp .getErasureCodingPolicy (
603+ fsd .getFSNamesystem (), ecPolicyName , existing );
604+ if (ecPolicy != null && (!ecPolicy .isReplicationPolicy ())) {
605+ isStriped = true ;
606+ }
607+ }
608+ final BlockType blockType = isStriped ?
609+ BlockType .STRIPED : BlockType .CONTIGUOUS ;
610+ final Short replicationFactor = (!isStriped ? replication : null );
611+ final Byte ecPolicyID = (isStriped ? ecPolicy .getId () : null );
612+ INodeFile newNode = newINodeFile (fsd .allocateNewInodeId (), permissions ,
613+ modTime , modTime , replicationFactor , ecPolicyID , preferredBlockSize ,
614+ storagepolicyid , blockType );
615+ newNode .setLocalName (localName );
616+ newNode .toUnderConstruction (clientName , clientMachine );
617+ return newNode ;
618+ }
619+
596620 private static FileState analyzeFileState (
597621 FSNamesystem fsn , INodesInPath iip , long fileId , String clientName ,
598622 ExtendedBlock previous , LocatedBlock [] onRetryBlock )
@@ -687,6 +711,14 @@ static boolean completeFile(FSNamesystem fsn, FSPermissionChecker pc,
687711 }
688712 checkBlock (fsn , last );
689713 INodesInPath iip = fsn .dir .resolvePath (pc , src , fileId );
714+
715+ assert (iip .getLastINode () instanceof INodeFile );
716+ INode [] missing = new INode [] {iip .getLastINode ()};
717+ INodesInPath existing = iip .getParentINodesInPath ();
718+ // switch the locks
719+ FSDirectory fsd = fsn .getFSDirectory ();
720+ fsd .getINodeMap ().latchWriteLock (existing , missing );
721+
690722 return completeFileInternal (fsn , iip , holder ,
691723 ExtendedBlock .getLocalBlock (last ), fileId );
692724 }
0 commit comments