From f1cd39c112dd09ab22d42259ff1d8fc06bc58813 Mon Sep 17 00:00:00 2001 From: Yang Yu Date: Fri, 3 Nov 2023 23:37:53 +0800 Subject: [PATCH] fix: fix the getFileLinkStatus. --- .../org/apache/hadoop/fs/CosNFileSystem.java | 68 ++++++++++++------- .../org/apache/hadoop/fs/FileMetadata.java | 6 +- 2 files changed, 48 insertions(+), 26 deletions(-) diff --git a/src/main/java/org/apache/hadoop/fs/CosNFileSystem.java b/src/main/java/org/apache/hadoop/fs/CosNFileSystem.java index 508c2409..9214d6a1 100644 --- a/src/main/java/org/apache/hadoop/fs/CosNFileSystem.java +++ b/src/main/java/org/apache/hadoop/fs/CosNFileSystem.java @@ -586,15 +586,6 @@ public FileStatus innerGetFileStatus(Path f, boolean checkFile) throws IOExcepti } } - CosNResultInfo getSymlinkResultInfo = new CosNResultInfo(); - if (this.supportsSymlinks()) { - CosNSymlinkMetadata cosNSymlinkMetadata = - this.nativeStore.retrieveSymlinkMetadata(key, getSymlinkResultInfo); - if (null != cosNSymlinkMetadata) { - return newSymlink(cosNSymlinkMetadata, absolutePath); - } - } - if (isPosixBucket) { throw new FileNotFoundException("No such file or directory in posix bucket'" + absolutePath + "'"); } @@ -620,9 +611,8 @@ public FileStatus innerGetFileStatus(Path f, boolean checkFile) throws IOExcepti } if (listObjectsResultInfo.isKeySameToPrefix()) { - LOG.info("List the cos key [{}] same to prefix, getSymlink-id:[{}] head-id:[{}], " + - "list-id:[{}], list-type:[{}], thread-id:[{}], thread-name:[{}]", key, - getSymlinkResultInfo.getRequestID(), getObjectMetadataResultInfo.getRequestID(), + LOG.info("List the cos key [{}] same to prefix, head-id:[{}], " + + "list-id:[{}], list-type:[{}], thread-id:[{}], thread-name:[{}]", key, getObjectMetadataResultInfo.getRequestID(), listObjectsResultInfo.getRequestID(), listObjectsResultInfo.isKeySameToPrefix(), Thread.currentThread().getId(), Thread.currentThread().getName()); } @@ -680,6 +670,9 @@ public FileStatus[] listStatus(Path f) throws IOException { CosNSymlinkMetadata cosNSymlinkMetadata = this.nativeStore.retrieveSymlinkMetadata( fileMetadata.getKey()); if (null != cosNSymlinkMetadata) { + // 这里 CGI 的 GetSymlink 接口返回的 contentLength 是0,但是 List 接口又返回的是正确的值, + // 因此这里还是取 List 接口返回的软连接大小 + cosNSymlinkMetadata.setLength(fileMetadata.getLength()); status.add(newSymlink(cosNSymlinkMetadata, subPath)); continue; } @@ -1335,6 +1328,17 @@ public void createSymlink(Path target, Path link, boolean createParent) this.nativeStore.createSymlink(linkKey, targetKey); } + /** + * Return a file status object that represents the path. If the path refers to a symlink then the FileStatus of the symlink is returned. + * The behavior is equivalent to #getFileStatus() if the underlying file system does not support symbolic links. + * + * @param f The file or symlink path to be obtained. + * @return the filestatus for symbolic links or files themselves. + * @throws AccessControlException + * @throws FileNotFoundException + * @throws UnsupportedFileSystemException + * @throws IOException + */ @Override public FileStatus getFileLinkStatus(final Path f) throws AccessControlException, FileNotFoundException, @@ -1343,21 +1347,27 @@ public FileStatus getFileLinkStatus(final Path f) return super.getFileLinkStatus(f); } - Path absolutePath = makeAbsolute(f); - String symlinkKey = pathToKey(absolutePath); - CosNSymlinkMetadata cosNSymlinkMetadata = nativeStore.retrieveSymlinkMetadata(symlinkKey); - FileStatus fileStatus; - if (null != cosNSymlinkMetadata) { - fileStatus = newSymlink(cosNSymlinkMetadata, absolutePath); - } else { - throw new FileNotFoundException("Symbolic does not exist: " + f); - } - + // 这里会得到这个文件的元数据,如果不存在,则软连接也不存在,就直接返回了 + FileStatus fileStatus = this.getFileStatus(f); if (fileStatus.isSymlink()) { - Path targetQual = FSLinkResolver.qualifySymlinkTarget(uri, - fileStatus.getPath(), fileStatus.getSymlink()); - fileStatus.setSymlink(targetQual); + // 如果是软连接则需要取出软连接本身的元数据出来 + Path absolutePath = makeAbsolute(f); + String symlinkKey = pathToKey(absolutePath); + CosNSymlinkMetadata cosNSymlinkMetadata = this.nativeStore.retrieveSymlinkMetadata(symlinkKey); + if (null != cosNSymlinkMetadata) { + fileStatus = newSymlink(cosNSymlinkMetadata, absolutePath); + } else { + throw new FileNotFoundException("Symbolic does not exist: " + f); + } + + // 这里设置为规范化的 target 路径 + if (fileStatus.isSymlink()) { + Path targetQual = FSLinkResolver.qualifySymlinkTarget(uri, + fileStatus.getPath(), fileStatus.getSymlink()); + fileStatus.setSymlink(targetQual); + } } + return fileStatus; } @@ -1368,6 +1378,14 @@ public boolean supportsSymlinks() { CosNConfigKeys.DEFAULT_COSN_SUPPORT_SYMLINK_ENABLED); } + /** + * Returns the target of the given symbolic link as it was specified when the link was created. + * Links in the path leading up to the final path component are resolved transparently. + * + * @param f + * @return + * @throws IOException + */ @Override public Path getLinkTarget(final Path f) throws IOException { if (!this.supportsSymlinks()) { diff --git a/src/main/java/org/apache/hadoop/fs/FileMetadata.java b/src/main/java/org/apache/hadoop/fs/FileMetadata.java index 3f03f0b3..d82d739a 100644 --- a/src/main/java/org/apache/hadoop/fs/FileMetadata.java +++ b/src/main/java/org/apache/hadoop/fs/FileMetadata.java @@ -14,7 +14,7 @@ @InterfaceStability.Unstable public class FileMetadata { private final String key; - private final long length; + private long length; private final long lastModified; private final boolean isFile; private final String ETag; @@ -69,6 +69,10 @@ public long getLength() { return length; } + public void setLength(long length) { + this.length = length; + } + public long getLastModified() { return lastModified; }