You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@ozone.apache.org by GitBox <gi...@apache.org> on 2022/09/23 17:14:37 UTC

[GitHub] [ozone] xichen01 commented on a diff in pull request #3774: HDDS-7253. Fix exception when '/' in key name

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


##########
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:
   I want to avoid return in finally here, return in finally is not a good practice, but I didn't find a better way to deal with it. do you have any suggestions?



-- 
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: issues-unsubscribe@ozone.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscribe@ozone.apache.org
For additional commands, e-mail: issues-help@ozone.apache.org