Skip to content

Commit 4c179ad

Browse files
author
bradley childs
committed
Merge pull request #9 from mattf/address-mkdirs-race
Address a potential race in File.mkdirs() with a double exists() check
2 parents 8ac7a8b + f96f098 commit 4c179ad

File tree

1 file changed

+22
-4
lines changed

1 file changed

+22
-4
lines changed

src/main/java/org/apache/hadoop/fs/glusterfs/GlusterFileSystem.java

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -312,10 +312,28 @@ public FSDataOutputStream create(Path path, FsPermission permission,
312312

313313
parent = path.getParent();
314314
fParent = new File((makeAbsolute(parent)).toUri().getPath());
315-
if ((parent != null) && (fParent != null) && (!fParent.exists()))
316-
if (!fParent.mkdirs())
317-
throw new IOException("cannot create parent directory: "
318-
+ fParent.getPath());
315+
if ((parent != null) && (fParent != null) && (!fParent.exists())) {
316+
if (!fParent.mkdirs()) {
317+
//
318+
// File.mkdirs() is not multi-process safe. It is possible for
319+
// a peer who is running mkdirs() to cause us to fail. In such
320+
// a case, a rudimentary test is to try our exists() test for a
321+
// second time. The isDirectory() protects us from exists()
322+
// passing when a file is put in place of the directory we were
323+
// trying to create. We can be fooled by a directory, or set of
324+
// directories in the path, being owned by another user or with
325+
// incompatible permissions.
326+
//
327+
// This could be slightly improved to retry the mkdirs(), which
328+
// would cover races deep within the fParent's path. Each
329+
// iteration will address one race.
330+
//
331+
if (!fParent.exists() || !fParent.isDirectory()) {
332+
throw new IOException("cannot create parent directory: "
333+
+ fParent.getPath());
334+
}
335+
}
336+
}
319337

320338
glusterFileStream = new FSDataOutputStream(new GlusterFUSEOutputStream(
321339
f.getPath(), false));

0 commit comments

Comments
 (0)