xichen01 commented on code in PR #3774:
URL: https://github.com/apache/ozone/pull/3774#discussion_r978932970


##########
hadoop-ozone/ozone-manager/src/main/java/org/apache/hadoop/ozone/om/KeyManagerImpl.java:
##########
@@ -1262,44 +1264,70 @@ private OzoneFileStatus getOzoneFileStatus(OmKeyArgs 
args,
       // Check if the key is a file.
       String fileKeyBytes = metadataManager.getOzoneKey(
               volumeName, bucketName, keyName);
-      fileKeyInfo = metadataManager
-          .getKeyTable(getBucketLayout(metadataManager, volumeName, 
bucketName))
-          .get(fileKeyBytes);
+      BucketLayout layout =
+          getBucketLayout(metadataManager, volumeName, bucketName);
+      fileKeyInfo = metadataManager.getKeyTable(layout).get(fileKeyBytes);
+      String dirKey = OzoneFSUtils.addTrailingSlashIfNeeded(keyName);
 
       // Check if the key is a directory.
       if (fileKeyInfo == null) {
-        String dirKey = OzoneFSUtils.addTrailingSlashIfNeeded(keyName);
         String dirKeyBytes = metadataManager.getOzoneKey(
                 volumeName, bucketName, dirKey);
-        OmKeyInfo dirKeyInfo = metadataManager.getKeyTable(
-                getBucketLayout(metadataManager, volumeName, bucketName))
-            .get(dirKeyBytes);
-        if (dirKeyInfo != null) {
-          return new OzoneFileStatus(dirKeyInfo, scmBlockSize, true);
+        dirKeyInfo = metadataManager.getKeyTable(layout).get(dirKeyBytes);
+
+        // Check if the key is a prefix.
+        // Some keys may contain '/' Ozone will treat '/' as directory 
separator
+        // such as : key name is 'a/b/c', 'a' and 'b' may not really exist,
+        // but Ozone treats 'a' and 'b' as a directory.
+        // we need create a fake directory 'a' or 'a/b'
+        if (dirKeyInfo == null) {
+          Table.KeyValue<String, OmKeyInfo> keyValue =
+              
metadataManager.getKeyTable(layout).iterator().seek(fileKeyBytes);
+          if (keyValue != null) {
+            Path fullPath = Paths.get(keyValue.getValue().getKeyName());
+            Path subPath = Paths.get(dirKey);
+            OmKeyInfo omKeyInfo = keyValue.getValue();
+            if (fullPath.startsWith(subPath)) {
+              // create fake directory
+              fakeDirKeyInfo = createDirectoryKey(
+                  omKeyInfo.getVolumeName(),
+                  omKeyInfo.getBucketName(),
+                  dirKey,
+                  omKeyInfo.getAcls());
+            }
+          }
         }
       }
     } finally {
       metadataManager.getLock().releaseReadLock(BUCKET_LOCK, volumeName,
               bucketName);
+    }
 
+    if (fileKeyInfo != null) {

Review Comment:
   how about like that:
   ```java
     private OzoneFileStatus getOzoneFileStatus(OmKeyArgs args,
         String clientAddress) throws IOException {
   
       Preconditions.checkNotNull(args, "Key args can not be null");
       final String volumeName = args.getVolumeName();
       final String bucketName = args.getBucketName();
       final String keyName = args.getKeyName();
   
       OmKeyInfo fileKeyInfo = null;
       OmKeyInfo dirKeyInfo = null;
       OmKeyInfo fakeDirKeyInfo = null;
       metadataManager.getLock().acquireReadLock(BUCKET_LOCK, volumeName,
           bucketName);
       String dirKey = OzoneFSUtils.addTrailingSlashIfNeeded(keyName);
       String fileKeyBytes = metadataManager.getOzoneKey(
           volumeName, bucketName, keyName);
       BucketLayout layout =
           getBucketLayout(metadataManager, volumeName, bucketName);
       try {
         // Check if this is the root of the filesystem.
         if (keyName.length() == 0) {
           OMFileRequest.validateBucket(metadataManager, volumeName, 
bucketName);
           return new OzoneFileStatus();
         }
   
         // Check if the key is a file.
         fileKeyInfo = metadataManager.getKeyTable(layout).get(fileKeyBytes);
         } catch (Exception e) {
           LOG.error("", e);
         }
         if (fileKeyInfo != null) {
           metadataManager.getLock().releaseReadLock(BUCKET_LOCK, volumeName,
               bucketName);
           // if the key is a file then do refresh pipeline info in OM by 
asking SCM
           if (args.getLatestVersionLocation()) {
             slimLocationVersion(fileKeyInfo);
           }
           // If operation is head, do not perform any additional steps
           // As head operation does not need any of those details.
           if (!args.isHeadOp()) {
             // refreshPipeline flag check has been removed as part of
             // https://issues.apache.org/jira/browse/HDDS-3658.
             // Please refer this jira for more details.
             refresh(fileKeyInfo);
             if (args.getSortDatanodes()) {
               sortDatanodes(clientAddress, fileKeyInfo);
             }
           }
           return new OzoneFileStatus(fileKeyInfo, scmBlockSize, false);
         } else {
           try {
             // Check if the key is a directory.
             String dirKeyBytes = metadataManager.getOzoneKey(
                 volumeName, bucketName, dirKey);
             dirKeyInfo = metadataManager.getKeyTable(layout).get(dirKeyBytes);
   
             // Check if the key is a prefix.
             // Some keys may contain '/' Ozone will treat '/' as directory 
separator
             // such as : key name is 'a/b/c', 'a' and 'b' may not really exist,
             // but Ozone treats 'a' and 'b' as a directory.
             // we need create a fake directory 'a' or 'a/b'
             if (dirKeyInfo == null) {
               Table.KeyValue<String, OmKeyInfo> keyValue =
                   
metadataManager.getKeyTable(layout).iterator().seek(fileKeyBytes);
               if (keyValue != null) {
                 Path fullPath = Paths.get(keyValue.getValue().getKeyName());
                 Path subPath = Paths.get(dirKey);
                 OmKeyInfo omKeyInfo = keyValue.getValue();
                 if (fullPath.startsWith(subPath)) {
                   // create fake directory
                   fakeDirKeyInfo = createDirectoryKey(
                       omKeyInfo.getVolumeName(),
                       omKeyInfo.getBucketName(),
                       dirKey,
                       omKeyInfo.getAcls());
                 }
               }
             }
           } finally {
             metadataManager.getLock().releaseReadLock(BUCKET_LOCK, volumeName,
                 bucketName);
         }
       }
   
       if (dirKeyInfo != null) {
         return new OzoneFileStatus(dirKeyInfo, scmBlockSize, true);
       }
   
       if (fakeDirKeyInfo != null) {
         return new OzoneFileStatus(fakeDirKeyInfo, scmBlockSize, true);
       }
   
       // Key is not found, throws exception
       if (LOG.isDebugEnabled()) {
         LOG.debug("Unable to get file status for the key: volume: {}, bucket:" 
+
                 " {}, key: {}, with error: No such file exists.",
             volumeName, bucketName, keyName);
       }
       throw new OMException("Unable to get file status: volume: " +
           volumeName + " bucket: " + bucketName + " key: " + keyName,
           FILE_NOT_FOUND);
    }
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to