Skip to content

Commit e7dd027

Browse files
HADOOP-17029. Return correct permission and owner for listing on internal directories in ViewFs. Contributed by Abhishek Das.
1 parent 76fa022 commit e7dd027

File tree

3 files changed

+146
-40
lines changed

3 files changed

+146
-40
lines changed

hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ViewFileSystem.java

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,13 +1200,26 @@ public FileStatus[] listStatus(Path f) throws AccessControlException,
12001200
INode<FileSystem> inode = iEntry.getValue();
12011201
if (inode.isLink()) {
12021202
INodeLink<FileSystem> link = (INodeLink<FileSystem>) inode;
1203-
1204-
result[i++] = new FileStatus(0, false, 0, 0,
1205-
creationTime, creationTime, PERMISSION_555,
1206-
ugi.getShortUserName(), ugi.getPrimaryGroupName(),
1207-
link.getTargetLink(),
1208-
new Path(inode.fullPath).makeQualified(
1209-
myUri, null));
1203+
try {
1204+
String linkedPath = link.getTargetFileSystem().getUri().getPath();
1205+
FileStatus status =
1206+
((ChRootedFileSystem)link.getTargetFileSystem())
1207+
.getMyFs().getFileStatus(new Path(linkedPath));
1208+
result[i++] = new FileStatus(status.getLen(), false,
1209+
status.getReplication(), status.getBlockSize(),
1210+
status.getModificationTime(), status.getAccessTime(),
1211+
status.getPermission(), status.getOwner(), status.getGroup(),
1212+
link.getTargetLink(),
1213+
new Path(inode.fullPath).makeQualified(
1214+
myUri, null));
1215+
} catch (FileNotFoundException ex) {
1216+
result[i++] = new FileStatus(0, false, 0, 0,
1217+
creationTime, creationTime, PERMISSION_555,
1218+
ugi.getShortUserName(), ugi.getPrimaryGroupName(),
1219+
link.getTargetLink(),
1220+
new Path(inode.fullPath).makeQualified(
1221+
myUri, null));
1222+
}
12101223
} else {
12111224
result[i++] = new FileStatus(0, true, 0, 0,
12121225
creationTime, creationTime, PERMISSION_555,

hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/fs/viewfs/ViewFs.java

Lines changed: 34 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -917,11 +917,25 @@ public FileStatus getFileLinkStatus(final Path f)
917917
if (inode.isLink()) {
918918
INodeLink<AbstractFileSystem> inodelink =
919919
(INodeLink<AbstractFileSystem>) inode;
920-
result = new FileStatus(0, false, 0, 0, creationTime, creationTime,
920+
try {
921+
String linkedPath = inodelink.getTargetFileSystem()
922+
.getUri().getPath();
923+
FileStatus status = ((ChRootedFs)inodelink.getTargetFileSystem())
924+
.getMyFs().getFileStatus(new Path(linkedPath));
925+
result = new FileStatus(status.getLen(), false,
926+
status.getReplication(), status.getBlockSize(),
927+
status.getModificationTime(), status.getAccessTime(),
928+
status.getPermission(), status.getOwner(), status.getGroup(),
929+
inodelink.getTargetLink(),
930+
new Path(inode.fullPath).makeQualified(
931+
myUri, null));
932+
} catch (FileNotFoundException ex) {
933+
result = new FileStatus(0, false, 0, 0, creationTime, creationTime,
921934
PERMISSION_555, ugi.getShortUserName(), ugi.getPrimaryGroupName(),
922935
inodelink.getTargetLink(),
923936
new Path(inode.fullPath).makeQualified(
924937
myUri, null));
938+
}
925939
} else {
926940
result = new FileStatus(0, true, 0, 0, creationTime, creationTime,
927941
PERMISSION_555, ugi.getShortUserName(), ugi.getPrimaryGroupName(),
@@ -976,12 +990,25 @@ public FileStatus[] listStatus(final Path f) throws AccessControlException,
976990
INodeLink<AbstractFileSystem> link =
977991
(INodeLink<AbstractFileSystem>) inode;
978992

979-
result[i++] = new FileStatus(0, false, 0, 0,
980-
creationTime, creationTime,
981-
PERMISSION_555, ugi.getShortUserName(), ugi.getPrimaryGroupName(),
982-
link.getTargetLink(),
983-
new Path(inode.fullPath).makeQualified(
984-
myUri, null));
993+
try {
994+
String linkedPath = link.getTargetFileSystem().getUri().getPath();
995+
FileStatus status = ((ChRootedFs)link.getTargetFileSystem())
996+
.getMyFs().getFileStatus(new Path(linkedPath));
997+
result[i++] = new FileStatus(status.getLen(), false,
998+
status.getReplication(), status.getBlockSize(),
999+
status.getModificationTime(), status.getAccessTime(),
1000+
status.getPermission(), status.getOwner(), status.getGroup(),
1001+
link.getTargetLink(),
1002+
new Path(inode.fullPath).makeQualified(
1003+
myUri, null));
1004+
} catch (FileNotFoundException ex) {
1005+
result[i++] = new FileStatus(0, false, 0, 0,
1006+
creationTime, creationTime, PERMISSION_555,
1007+
ugi.getShortUserName(), ugi.getPrimaryGroupName(),
1008+
link.getTargetLink(),
1009+
new Path(inode.fullPath).makeQualified(
1010+
myUri, null));
1011+
}
9851012
} else {
9861013
result[i++] = new FileStatus(0, true, 0, 0,
9871014
creationTime, creationTime,

hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/fs/viewfs/TestViewfsFileStatus.java

Lines changed: 92 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,13 @@
2929
import org.apache.hadoop.fs.FsConstants;
3030
import org.apache.hadoop.fs.Path;
3131
import org.apache.hadoop.fs.contract.ContractTestUtils;
32+
import org.apache.hadoop.fs.permission.FsPermission;
3233
import org.apache.hadoop.io.DataInputBuffer;
3334
import org.apache.hadoop.io.DataOutputBuffer;
3435
import org.apache.hadoop.test.GenericTestUtils;
36+
import org.junit.After;
3537
import org.junit.AfterClass;
38+
import org.junit.Before;
3639
import org.junit.Test;
3740
import org.mockito.Mockito;
3841

@@ -48,6 +51,17 @@ public class TestViewfsFileStatus {
4851
private static final File TEST_DIR = GenericTestUtils.getTestDir(
4952
TestViewfsFileStatus.class.getSimpleName());
5053

54+
@Before
55+
public void setUp() {
56+
FileUtil.fullyDelete(TEST_DIR);
57+
assertTrue(TEST_DIR.mkdirs());
58+
}
59+
60+
@After
61+
public void tearDown() throws IOException {
62+
FileUtil.fullyDelete(TEST_DIR);
63+
}
64+
5165
@Test
5266
public void testFileStatusSerialziation()
5367
throws IOException, URISyntaxException {
@@ -56,38 +70,90 @@ public void testFileStatusSerialziation()
5670
File infile = new File(TEST_DIR, testfilename);
5771
final byte[] content = "dingos".getBytes();
5872

59-
FileOutputStream fos = null;
60-
try {
61-
fos = new FileOutputStream(infile);
73+
try (FileOutputStream fos = new FileOutputStream(infile)) {
6274
fos.write(content);
63-
} finally {
64-
if (fos != null) {
65-
fos.close();
66-
}
6775
}
6876
assertEquals((long)content.length, infile.length());
6977

7078
Configuration conf = new Configuration();
7179
ConfigUtil.addLink(conf, "/foo/bar/baz", TEST_DIR.toURI());
72-
FileSystem vfs = FileSystem.get(FsConstants.VIEWFS_URI, conf);
73-
assertEquals(ViewFileSystem.class, vfs.getClass());
74-
Path path = new Path("/foo/bar/baz", testfilename);
75-
FileStatus stat = vfs.getFileStatus(path);
76-
assertEquals(content.length, stat.getLen());
77-
ContractTestUtils.assertNotErasureCoded(vfs, path);
78-
assertTrue(path + " should have erasure coding unset in " +
79-
"FileStatus#toString(): " + stat,
80-
stat.toString().contains("isErasureCoded=false"));
81-
82-
// check serialization/deserialization
83-
DataOutputBuffer dob = new DataOutputBuffer();
84-
stat.write(dob);
85-
DataInputBuffer dib = new DataInputBuffer();
86-
dib.reset(dob.getData(), 0, dob.getLength());
87-
FileStatus deSer = new FileStatus();
88-
deSer.readFields(dib);
89-
assertEquals(content.length, deSer.getLen());
90-
assertFalse(deSer.isErasureCoded());
80+
try (FileSystem vfs = FileSystem.get(FsConstants.VIEWFS_URI, conf)) {
81+
assertEquals(ViewFileSystem.class, vfs.getClass());
82+
Path path = new Path("/foo/bar/baz", testfilename);
83+
FileStatus stat = vfs.getFileStatus(path);
84+
assertEquals(content.length, stat.getLen());
85+
ContractTestUtils.assertNotErasureCoded(vfs, path);
86+
assertTrue(path + " should have erasure coding unset in " +
87+
"FileStatus#toString(): " + stat,
88+
stat.toString().contains("isErasureCoded=false"));
89+
90+
// check serialization/deserialization
91+
DataOutputBuffer dob = new DataOutputBuffer();
92+
stat.write(dob);
93+
DataInputBuffer dib = new DataInputBuffer();
94+
dib.reset(dob.getData(), 0, dob.getLength());
95+
FileStatus deSer = new FileStatus();
96+
deSer.readFields(dib);
97+
assertEquals(content.length, deSer.getLen());
98+
assertFalse(deSer.isErasureCoded());
99+
}
100+
}
101+
102+
/**
103+
* Tests the ACL returned from getFileStatus for directories and files.
104+
* @throws IOException
105+
*/
106+
@Test
107+
public void testListStatusACL() throws IOException {
108+
String testfilename = "testFileACL";
109+
String childDirectoryName = "testDirectoryACL";
110+
TEST_DIR.mkdirs();
111+
File infile = new File(TEST_DIR, testfilename);
112+
final byte[] content = "dingos".getBytes();
113+
114+
try (FileOutputStream fos = new FileOutputStream(infile)) {
115+
fos.write(content);
116+
}
117+
assertEquals(content.length, infile.length());
118+
File childDir = new File(TEST_DIR, childDirectoryName);
119+
childDir.mkdirs();
120+
121+
Configuration conf = new Configuration();
122+
ConfigUtil.addLink(conf, "/file", infile.toURI());
123+
ConfigUtil.addLink(conf, "/dir", childDir.toURI());
124+
125+
try (FileSystem vfs = FileSystem.get(FsConstants.VIEWFS_URI, conf)) {
126+
assertEquals(ViewFileSystem.class, vfs.getClass());
127+
FileStatus[] statuses = vfs.listStatus(new Path("/"));
128+
129+
FileSystem localFs = FileSystem.getLocal(conf);
130+
FileStatus fileStat = localFs.getFileStatus(new Path(infile.getPath()));
131+
FileStatus dirStat = localFs.getFileStatus(new Path(childDir.getPath()));
132+
133+
for (FileStatus status : statuses) {
134+
if (status.getPath().getName().equals("file")) {
135+
assertEquals(fileStat.getPermission(), status.getPermission());
136+
} else {
137+
assertEquals(dirStat.getPermission(), status.getPermission());
138+
}
139+
}
140+
141+
localFs.setPermission(new Path(infile.getPath()),
142+
FsPermission.valueOf("-rwxr--r--"));
143+
localFs.setPermission(new Path(childDir.getPath()),
144+
FsPermission.valueOf("-r--rwxr--"));
145+
146+
statuses = vfs.listStatus(new Path("/"));
147+
for (FileStatus status : statuses) {
148+
if (status.getPath().getName().equals("file")) {
149+
assertEquals(FsPermission.valueOf("-rwxr--r--"),
150+
status.getPermission());
151+
} else {
152+
assertEquals(FsPermission.valueOf("-r--rwxr--"),
153+
status.getPermission());
154+
}
155+
}
156+
}
91157
}
92158

93159
// Tests that ViewFileSystem.getFileChecksum calls res.targetFileSystem

0 commit comments

Comments
 (0)