FSDirectory implements Closeable { void verifyParentDir(INodesInPath iip) throws FileNotFoundException, ParentNotDirectoryException { if (iip.length() > 2) { final INode parentNode = iip.getINode(-2); if (parentNode == null) { throw new FileNotFoundException("Parent directory doesn't exist: " + iip.getParentPath()); } else if (!parentNode.isDirectory()) { throw new ParentNotDirectoryException("Parent path is not a directory: " + iip.getParentPath()); } } } FSDirectory(FSNamesystem ns, Configuration conf); void setINodeAttributeProvider(
      @Nullable INodeAttributeProvider provider); @Deprecated // dirLock is obsolete, use namesystem.fsLock instead int getReadHoldCount(); @Deprecated // dirLock is obsolete, use namesystem.fsLock instead int getWriteHoldCount(); int getListLimit(); boolean isImageLoaded(); SortedSet<String> getProtectedDirectories(); boolean isProtectedSubDirectoriesEnable(); INodeDirectory getRoot(); BlockStoragePolicySuite getBlockStoragePolicySuite(); @VisibleForTesting boolean isPosixAclInheritanceEnabled(); @VisibleForTesting void setPosixAclInheritanceEnabled(
      boolean posixAclInheritanceEnabled); @Override void close(); @VisibleForTesting INodesInPath resolvePath(FSPermissionChecker pc, String src,
      DirOp dirOp); INodesInPath unprotectedResolvePath(String src); boolean isNonEmptyDirectory(INodesInPath inodesInPath); void updateCount(INodesInPath iip, INode.QuotaDelta quotaDelta,
      boolean check); void updateSpaceForCompleteBlock(BlockInfo completeBlk,
      INodesInPath inodes); EnumCounters<StorageType> getStorageTypeDeltas(byte storagePolicyID,
      long dsDelta, short oldRep, short newRep); @VisibleForTesting INodesInPath addLastINode(INodesInPath existing, INode inode,
      FsPermission modes, boolean checkQuota); @VisibleForTesting long removeLastINode(final INodesInPath iip); @VisibleForTesting long getYieldCount(); INodeMap getINodeMap(); final void addToInodeMap(INode inode); final void addRootDirToEncryptionZone(XAttrFeature xaf); final void removeFromInodeMap(List<? extends INode> inodes); INode getInode(long id); static byte[][] getPathComponents(INode inode); static boolean isReservedName(INode inode); static boolean isReservedName(String src); static boolean isExactReservedName(String src); static boolean isExactReservedName(byte[][] components); INodesInPath getINodesInPath(String src, DirOp dirOp); INodesInPath getINodesInPath(byte[][] components, DirOp dirOp); @VisibleForTesting // should be removed after a lot of tests are updated INode getINode(String src); @VisibleForTesting // should be removed after a lot of tests are updated INode getINode4Write(String src); INode getINode(String src, DirOp dirOp); long getLastInodeId(); final static String DOT_RESERVED_STRING; final static String DOT_RESERVED_PATH_PREFIX; final static byte[] DOT_RESERVED; final static String DOT_INODES_STRING; final static byte[] DOT_INODES; final static HdfsFileStatus DOT_RESERVED_STATUS; final static HdfsFileStatus DOT_SNAPSHOT_DIR_STATUS; @VisibleForTesting
  final EncryptionZoneManager ezManager; }
@Test public void testVerifyParentDir() throws Exception { hdfs.mkdirs(new Path("/dir1/dir2")); hdfs.createNewFile(new Path("/dir1/file")); hdfs.createNewFile(new Path("/dir1/dir2/file")); INodesInPath iip = fsdir.resolvePath(null, "/", DirOp.READ); fsdir.verifyParentDir(iip); iip = fsdir.resolvePath(null, "/dir1", DirOp.READ); fsdir.verifyParentDir(iip); iip = fsdir.resolvePath(null, "/dir1/file", DirOp.READ); fsdir.verifyParentDir(iip); iip = fsdir.resolvePath(null, "/dir-nonexist/file", DirOp.READ); try { fsdir.verifyParentDir(iip); fail("expected FNF"); } catch (FileNotFoundException fnf) { } iip = fsdir.resolvePath(null, "/dir1/dir2", DirOp.READ); fsdir.verifyParentDir(iip); iip = fsdir.resolvePath(null, "/dir1/dir2/file", DirOp.READ); fsdir.verifyParentDir(iip); iip = fsdir.resolvePath(null, "/dir1/dir-nonexist/file", DirOp.READ); try { fsdir.verifyParentDir(iip); fail("expected FNF"); } catch (FileNotFoundException fnf) { } try { iip = fsdir.resolvePath(null, "/dir1/file/fail", DirOp.READ); fail("expected ACE"); } catch (AccessControlException ace) { assertTrue(ace.getMessage().contains("is not a directory")); } try { iip = fsdir.resolvePath(null, "/dir1/file/fail", DirOp.WRITE); fail("expected ACE"); } catch (AccessControlException ace) { assertTrue(ace.getMessage().contains("is not a directory")); } try { iip = fsdir.resolvePath(null, "/dir1/file/fail", DirOp.CREATE); fail("expected PNDE"); } catch (ParentNotDirectoryException pnde) { assertTrue(pnde.getMessage().contains("is not a directory")); } }