|
@@ -43,6 +43,7 @@ import org.apache.hadoop.conf.Configuration;
|
|
|
import org.apache.hadoop.fs.permission.FsPermission;
|
|
|
import org.apache.hadoop.io.IOUtils;
|
|
|
import org.apache.hadoop.io.nativeio.NativeIO;
|
|
|
+import org.apache.hadoop.io.nativeio.NativeIOException;
|
|
|
import org.apache.hadoop.util.Progressable;
|
|
|
import org.apache.hadoop.util.Shell;
|
|
|
import org.apache.hadoop.util.StringUtils;
|
|
@@ -208,8 +209,28 @@ public class RawLocalFileSystem extends FileSystem {
|
|
|
class LocalFSFileOutputStream extends OutputStream {
|
|
|
private FileOutputStream fos;
|
|
|
|
|
|
- private LocalFSFileOutputStream(Path f, boolean append) throws IOException {
|
|
|
- this.fos = new FileOutputStream(pathToFile(f), append);
|
|
|
+ private LocalFSFileOutputStream(Path f, boolean append,
|
|
|
+ FsPermission permission) throws IOException {
|
|
|
+ File file = pathToFile(f);
|
|
|
+ if (permission == null) {
|
|
|
+ this.fos = new FileOutputStream(file, append);
|
|
|
+ } else {
|
|
|
+ if (Shell.WINDOWS && NativeIO.isAvailable()) {
|
|
|
+ this.fos = NativeIO.Windows.createFileOutputStreamWithMode(file,
|
|
|
+ append, permission.toShort());
|
|
|
+ } else {
|
|
|
+ this.fos = new FileOutputStream(file, append);
|
|
|
+ boolean success = false;
|
|
|
+ try {
|
|
|
+ setPermission(f, permission);
|
|
|
+ success = true;
|
|
|
+ } finally {
|
|
|
+ if (!success) {
|
|
|
+ IOUtils.cleanup(LOG, this.fos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/*
|
|
@@ -248,19 +269,20 @@ public class RawLocalFileSystem extends FileSystem {
|
|
|
throw new IOException("Cannot append to a diretory (=" + f + " )");
|
|
|
}
|
|
|
return new FSDataOutputStream(new BufferedOutputStream(
|
|
|
- new LocalFSFileOutputStream(f, true), bufferSize), statistics);
|
|
|
+ createOutputStreamWithMode(f, true, null), bufferSize), statistics);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
public FSDataOutputStream create(Path f, boolean overwrite, int bufferSize,
|
|
|
short replication, long blockSize, Progressable progress)
|
|
|
throws IOException {
|
|
|
- return create(f, overwrite, true, bufferSize, replication, blockSize, progress);
|
|
|
+ return create(f, overwrite, true, bufferSize, replication, blockSize,
|
|
|
+ progress, null);
|
|
|
}
|
|
|
|
|
|
private FSDataOutputStream create(Path f, boolean overwrite,
|
|
|
boolean createParent, int bufferSize, short replication, long blockSize,
|
|
|
- Progressable progress) throws IOException {
|
|
|
+ Progressable progress, FsPermission permission) throws IOException {
|
|
|
if (exists(f) && !overwrite) {
|
|
|
throw new FileAlreadyExistsException("File already exists: " + f);
|
|
|
}
|
|
@@ -269,12 +291,18 @@ public class RawLocalFileSystem extends FileSystem {
|
|
|
throw new IOException("Mkdirs failed to create " + parent.toString());
|
|
|
}
|
|
|
return new FSDataOutputStream(new BufferedOutputStream(
|
|
|
- createOutputStream(f, false), bufferSize), statistics);
|
|
|
+ createOutputStreamWithMode(f, false, permission), bufferSize),
|
|
|
+ statistics);
|
|
|
}
|
|
|
|
|
|
protected OutputStream createOutputStream(Path f, boolean append)
|
|
|
throws IOException {
|
|
|
- return new LocalFSFileOutputStream(f, append);
|
|
|
+ return createOutputStreamWithMode(f, append, null);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected OutputStream createOutputStreamWithMode(Path f, boolean append,
|
|
|
+ FsPermission permission) throws IOException {
|
|
|
+ return new LocalFSFileOutputStream(f, append, permission);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -286,7 +314,8 @@ public class RawLocalFileSystem extends FileSystem {
|
|
|
throw new FileAlreadyExistsException("File already exists: " + f);
|
|
|
}
|
|
|
return new FSDataOutputStream(new BufferedOutputStream(
|
|
|
- new LocalFSFileOutputStream(f, false), bufferSize), statistics);
|
|
|
+ createOutputStreamWithMode(f, false, permission), bufferSize),
|
|
|
+ statistics);
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -294,18 +323,9 @@ public class RawLocalFileSystem extends FileSystem {
|
|
|
boolean overwrite, int bufferSize, short replication, long blockSize,
|
|
|
Progressable progress) throws IOException {
|
|
|
|
|
|
- FSDataOutputStream out = create(f,
|
|
|
- overwrite, bufferSize, replication, blockSize, progress);
|
|
|
- boolean success = false;
|
|
|
- try {
|
|
|
- setPermission(f, permission);
|
|
|
- success = true;
|
|
|
- return out;
|
|
|
- } finally {
|
|
|
- if (!success) {
|
|
|
- IOUtils.cleanup(LOG, out);
|
|
|
- }
|
|
|
- }
|
|
|
+ FSDataOutputStream out = create(f, overwrite, true, bufferSize, replication,
|
|
|
+ blockSize, progress, permission);
|
|
|
+ return out;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -313,18 +333,9 @@ public class RawLocalFileSystem extends FileSystem {
|
|
|
boolean overwrite,
|
|
|
int bufferSize, short replication, long blockSize,
|
|
|
Progressable progress) throws IOException {
|
|
|
- FSDataOutputStream out = create(f,
|
|
|
- overwrite, false, bufferSize, replication, blockSize, progress);
|
|
|
- boolean success = false;
|
|
|
- try {
|
|
|
- setPermission(f, permission);
|
|
|
- success = true;
|
|
|
- return out;
|
|
|
- } finally {
|
|
|
- if (!success) {
|
|
|
- IOUtils.cleanup(LOG, out);
|
|
|
- }
|
|
|
- }
|
|
|
+ FSDataOutputStream out = create(f, overwrite, false, bufferSize, replication,
|
|
|
+ blockSize, progress, permission);
|
|
|
+ return out;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
@@ -430,7 +441,34 @@ public class RawLocalFileSystem extends FileSystem {
|
|
|
}
|
|
|
|
|
|
protected boolean mkOneDir(File p2f) throws IOException {
|
|
|
- return p2f.mkdir();
|
|
|
+ return mkOneDirWithMode(new Path(p2f.getAbsolutePath()), p2f, null);
|
|
|
+ }
|
|
|
+
|
|
|
+ protected boolean mkOneDirWithMode(Path p, File p2f, FsPermission permission)
|
|
|
+ throws IOException {
|
|
|
+ if (permission == null) {
|
|
|
+ return p2f.mkdir();
|
|
|
+ } else {
|
|
|
+ if (Shell.WINDOWS && NativeIO.isAvailable()) {
|
|
|
+ try {
|
|
|
+ NativeIO.Windows.createDirectoryWithMode(p2f, permission.toShort());
|
|
|
+ return true;
|
|
|
+ } catch (IOException e) {
|
|
|
+ if (LOG.isDebugEnabled()) {
|
|
|
+ LOG.debug(String.format(
|
|
|
+ "NativeIO.createDirectoryWithMode error, path = %s, mode = %o",
|
|
|
+ p2f, permission.toShort()), e);
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ boolean b = p2f.mkdir();
|
|
|
+ if (b) {
|
|
|
+ setPermission(p, permission);
|
|
|
+ }
|
|
|
+ return b;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -439,6 +477,16 @@ public class RawLocalFileSystem extends FileSystem {
|
|
|
*/
|
|
|
@Override
|
|
|
public boolean mkdirs(Path f) throws IOException {
|
|
|
+ return mkdirsWithOptionalPermission(f, null);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean mkdirs(Path f, FsPermission permission) throws IOException {
|
|
|
+ return mkdirsWithOptionalPermission(f, permission);
|
|
|
+ }
|
|
|
+
|
|
|
+ private boolean mkdirsWithOptionalPermission(Path f, FsPermission permission)
|
|
|
+ throws IOException {
|
|
|
if(f == null) {
|
|
|
throw new IllegalArgumentException("mkdirs path arg is null");
|
|
|
}
|
|
@@ -457,25 +505,7 @@ public class RawLocalFileSystem extends FileSystem {
|
|
|
" and is not a directory: " + p2f.getCanonicalPath());
|
|
|
}
|
|
|
return (parent == null || parent2f.exists() || mkdirs(parent)) &&
|
|
|
- (mkOneDir(p2f) || p2f.isDirectory());
|
|
|
- }
|
|
|
-
|
|
|
- @Override
|
|
|
- public boolean mkdirs(Path f, FsPermission permission) throws IOException {
|
|
|
- boolean b = mkdirs(f);
|
|
|
- if(b) {
|
|
|
- setPermission(f, permission);
|
|
|
- }
|
|
|
- return b;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- @Override
|
|
|
- protected boolean primitiveMkdir(Path f, FsPermission absolutePermission)
|
|
|
- throws IOException {
|
|
|
- boolean b = mkdirs(f);
|
|
|
- setPermission(f, absolutePermission);
|
|
|
- return b;
|
|
|
+ (mkOneDirWithMode(f, p2f, permission) || p2f.isDirectory());
|
|
|
}
|
|
|
|
|
|
|