2121import  static  org .apache .hadoop .fs .viewfs .Constants .CONFIG_VIEWFS_ENABLE_INNER_CACHE ;
2222import  static  org .apache .hadoop .fs .viewfs .Constants .CONFIG_VIEWFS_ENABLE_INNER_CACHE_DEFAULT ;
2323
24+ import  com .google .common .base .Function ;
2425import  java .io .FileNotFoundException ;
2526import  java .io .IOException ;
2627import  java .net .URI ;
2728import  java .net .URISyntaxException ;
29+ import  java .security .PrivilegedExceptionAction ;
2830import  java .util .Arrays ;
2931import  java .util .Collections ;
3032import  java .util .EnumSet ;
@@ -237,24 +239,40 @@ public void initialize(final URI theUri, final Configuration conf)
237239    config  = conf ;
238240    enableInnerCache  = config .getBoolean (CONFIG_VIEWFS_ENABLE_INNER_CACHE ,
239241        CONFIG_VIEWFS_ENABLE_INNER_CACHE_DEFAULT );
240-     final   InnerCache   innerCache  = new  InnerCache ();
242+     cache  = new  InnerCache ();
241243    // Now build  client side view (i.e. client side mount table) from config. 
242244    final  String  authority  = theUri .getAuthority ();
243245    try  {
244246      myUri  = new  URI (FsConstants .VIEWFS_SCHEME , authority , "/" , null , null );
245247      fsState  = new  InodeTree <FileSystem >(conf , authority ) {
246248
247249        @ Override 
248-         protected 
249-         FileSystem  getTargetFileSystem (final  URI  uri )
250-           throws  URISyntaxException , IOException  {
251-             FileSystem  fs ;
252-             if  (enableInnerCache ) {
253-               fs  = innerCache .get (uri , config );
254-             } else  {
255-               fs  = FileSystem .get (uri , config );
250+         protected  Function <URI , FileSystem > initAndGetTargetFs () {
251+           return  new  Function <URI , FileSystem >() {
252+             @ Override 
253+             public  FileSystem  apply (final  URI  uri ) {
254+               FileSystem  fs ;
255+               try  {
256+                 fs  = ugi .doAs (new  PrivilegedExceptionAction <FileSystem >() {
257+                   @ Override 
258+                   public  FileSystem  run () throws  IOException  {
259+                     if  (enableInnerCache ) {
260+                       synchronized  (cache ) {
261+                         return  cache .get (uri , config );
262+                       }
263+                     } else  {
264+                       return  FileSystem .get (uri , config );
265+                     }
266+                   }
267+                 });
268+                 return  new  ChRootedFileSystem (fs , uri );
269+               } catch  (IOException  | InterruptedException  ex ) {
270+                 LOG .error ("Could not initialize the underlying FileSystem " 
271+                     + "object. Exception: "  + ex .toString ());
272+               }
273+               return  null ;
256274            }
257-              return   new   ChRootedFileSystem ( fs ,  uri ) ;
275+           } ;
258276        }
259277
260278        @ Override 
@@ -273,12 +291,6 @@ FileSystem getTargetFileSystem(URI[] mergeFsURIList)
273291        }
274292      };
275293
276-       if  (enableInnerCache ) {
277-         // All fs instances are created and cached on startup. The cache is 
278-         // readonly after the initialize() so the concurrent access of the cache 
279-         // is safe. 
280-         cache  = innerCache .unmodifiableCache ();
281-       }
282294      workingDir  = this .getHomeDirectory ();
283295      renameStrategy  = RenameStrategy .valueOf (
284296          conf .get (Constants .CONFIG_VIEWFS_RENAME_STRATEGY ,
@@ -311,7 +323,7 @@ public ViewFileSystem(final Configuration conf) throws IOException {
311323    this (FsConstants .VIEWFS_URI , conf );
312324  }
313325
314-   public  Path  getTrashCanLocation (final  Path  f ) throws  FileNotFoundException  {
326+   public  Path  getTrashCanLocation (final  Path  f ) throws  IOException  {
315327    final  InodeTree .ResolveResult <FileSystem > res  = 
316328      fsState .resolve (getUriPath (f ), true );
317329    return  res .isInternalDir () ? null  : res .targetFileSystem .getHomeDirectory ();
@@ -767,9 +779,34 @@ public void removeXAttr(Path path, String name) throws IOException {
767779  public  void  setVerifyChecksum (final  boolean  verifyChecksum ) { 
768780    List <InodeTree .MountPoint <FileSystem >> mountPoints  = 
769781        fsState .getMountPoints ();
782+     Map <String , FileSystem > fsMap  = initializeMountedFileSystems (mountPoints );
783+     for  (InodeTree .MountPoint <FileSystem > mount  : mountPoints ) {
784+       fsMap .get (mount .src ).setVerifyChecksum (verifyChecksum );
785+     }
786+   }
787+ 
788+   /** 
789+    * Initialize the target filesystem for all mount points. 
790+    * @param mountPoints The mount points 
791+    * @return Mapping of mount point and the initialized target filesystems 
792+    * @throws RuntimeException when the target file system cannot be initialized 
793+    */ 
794+   private  Map <String , FileSystem > initializeMountedFileSystems (
795+       List <InodeTree .MountPoint <FileSystem >> mountPoints ) {
796+     FileSystem  fs  = null ;
797+     Map <String , FileSystem > fsMap  = new  HashMap <>(mountPoints .size ());
770798    for  (InodeTree .MountPoint <FileSystem > mount  : mountPoints ) {
771-       mount .target .targetFileSystem .setVerifyChecksum (verifyChecksum );
799+       try  {
800+         fs  = mount .target .getTargetFileSystem ();
801+         fsMap .put (mount .src , fs );
802+       } catch  (IOException  ex ) {
803+         String  errMsg  = "Not able to initialize FileSystem for mount path "  +
804+             mount .src  + " with exception "  + ex ;
805+         LOG .error (errMsg );
806+         throw  new  RuntimeException (errMsg , ex );
807+       }
772808    }
809+     return  fsMap ;
773810  }
774811
775812  @ Override 
@@ -795,6 +832,9 @@ public long getDefaultBlockSize(Path f) {
795832      return  res .targetFileSystem .getDefaultBlockSize (res .remainingPath );
796833    } catch  (FileNotFoundException  e ) {
797834      throw  new  NotInMountpointException (f , "getDefaultBlockSize" ); 
835+     } catch  (IOException  e ) {
836+       throw  new  RuntimeException ("Not able to initialize fs in " 
837+           + " getDefaultBlockSize for path "  + f  + " with exception" , e );
798838    }
799839  }
800840
@@ -806,6 +846,9 @@ public short getDefaultReplication(Path f) {
806846      return  res .targetFileSystem .getDefaultReplication (res .remainingPath );
807847    } catch  (FileNotFoundException  e ) {
808848      throw  new  NotInMountpointException (f , "getDefaultReplication" ); 
849+     } catch  (IOException  e ) {
850+       throw  new  RuntimeException ("Not able to initialize fs in " 
851+           + " getDefaultReplication for path "  + f  + " with exception" , e );
809852    }
810853  }
811854
@@ -834,18 +877,20 @@ public QuotaUsage getQuotaUsage(Path f) throws IOException {
834877  public  void  setWriteChecksum (final  boolean  writeChecksum ) { 
835878    List <InodeTree .MountPoint <FileSystem >> mountPoints  = 
836879        fsState .getMountPoints ();
880+     Map <String , FileSystem > fsMap  = initializeMountedFileSystems (mountPoints );
837881    for  (InodeTree .MountPoint <FileSystem > mount  : mountPoints ) {
838-       mount .target . targetFileSystem .setWriteChecksum (writeChecksum );
882+       fsMap . get ( mount .src ) .setWriteChecksum (writeChecksum );
839883    }
840884  }
841885
842886  @ Override 
843887  public  FileSystem [] getChildFileSystems () {
844888    List <InodeTree .MountPoint <FileSystem >> mountPoints  =
845889        fsState .getMountPoints ();
890+     Map <String , FileSystem > fsMap  = initializeMountedFileSystems (mountPoints );
846891    Set <FileSystem > children  = new  HashSet <FileSystem >();
847892    for  (InodeTree .MountPoint <FileSystem > mountPoint  : mountPoints ) {
848-       FileSystem  targetFs  = mountPoint .target . targetFileSystem ;
893+       FileSystem  targetFs  = fsMap . get ( mountPoint .src ) ;
849894      children .addAll (Arrays .asList (targetFs .getChildFileSystems ()));
850895    }
851896    return  children .toArray (new  FileSystem []{});
0 commit comments