Browse Source

Merge branch 'stable-5.7'

* stable-5.7:
  ObjectDirectoryInserter: Open FileOutputStream in try-with-resource
  ObjectDirectoryInserter: Remove redundant 'throws' declarations
  ObjectDirectory: Further clean up insertUnpackedObject
  ObjectDirectory: Explicitly handle NoSuchFileException
  ObjectDirectory: Fail immediately when atomic move is not supported

Change-Id: I05186baa517388680fcc6825c940c4c772f26d32
Signed-off-by: David Pursehouse <david.pursehouse@gmail.com>
master
David Pursehouse 5 years ago
parent
commit
1b4b05d4a3
  1. 65
      org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java
  2. 40
      org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java

65
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectory.java

@ -19,8 +19,8 @@ import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.FileNotFoundException; import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.nio.file.AtomicMoveNotSupportedException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.NoSuchFileException;
import java.nio.file.StandardCopyOption; import java.nio.file.StandardCopyOption;
import java.text.MessageFormat; import java.text.MessageFormat;
import java.util.ArrayList; import java.util.ArrayList;
@ -685,47 +685,46 @@ public class ObjectDirectory extends FileObjectDatabase {
FileUtils.delete(tmp, FileUtils.RETRY); FileUtils.delete(tmp, FileUtils.RETRY);
return InsertLooseObjectResult.EXISTS_LOOSE; return InsertLooseObjectResult.EXISTS_LOOSE;
} }
try { try {
Files.move(FileUtils.toPath(tmp), FileUtils.toPath(dst), return tryMove(tmp, dst, id);
StandardCopyOption.ATOMIC_MOVE); } catch (NoSuchFileException e) {
dst.setReadOnly(); // It's possible the directory doesn't exist yet as the object
unpackedObjectCache.add(id); // directories are always lazily created. Note that we try the
return InsertLooseObjectResult.INSERTED; // rename/move first as the directory likely does exist.
} catch (AtomicMoveNotSupportedException e) { //
LOG.error(e.getMessage(), e); // Create the directory.
//
FileUtils.mkdir(dst.getParentFile(), true);
} catch (IOException e) { } catch (IOException e) {
// ignore // Any other IO error is considered a failure.
//
LOG.error(e.getMessage(), e);
FileUtils.delete(tmp, FileUtils.RETRY);
return InsertLooseObjectResult.FAILURE;
} }
// Maybe the directory doesn't exist yet as the object
// directories are always lazily created. Note that we
// try the rename first as the directory likely does exist.
//
FileUtils.mkdir(dst.getParentFile(), true);
try { try {
Files.move(FileUtils.toPath(tmp), FileUtils.toPath(dst), return tryMove(tmp, dst, id);
StandardCopyOption.ATOMIC_MOVE);
dst.setReadOnly();
unpackedObjectCache.add(id);
return InsertLooseObjectResult.INSERTED;
} catch (AtomicMoveNotSupportedException e) {
LOG.error(e.getMessage(), e);
} catch (IOException e) { } catch (IOException e) {
LOG.debug(e.getMessage(), e); // The object failed to be renamed into its proper location and
} // it doesn't exist in the repository either. We really don't
// know what went wrong, so fail.
if (!createDuplicate && has(id)) { //
LOG.error(e.getMessage(), e);
FileUtils.delete(tmp, FileUtils.RETRY); FileUtils.delete(tmp, FileUtils.RETRY);
return InsertLooseObjectResult.EXISTS_PACKED; return InsertLooseObjectResult.FAILURE;
} }
}
// The object failed to be renamed into its proper private InsertLooseObjectResult tryMove(File tmp, File dst,
// location and it doesn't exist in the repository ObjectId id)
// either. We really don't know what went wrong, so throws IOException {
// fail. Files.move(FileUtils.toPath(tmp), FileUtils.toPath(dst),
// StandardCopyOption.ATOMIC_MOVE);
FileUtils.delete(tmp, FileUtils.RETRY); dst.setReadOnly();
return InsertLooseObjectResult.FAILURE; unpackedObjectCache.add(id);
return InsertLooseObjectResult.INSERTED;
} }
boolean searchPacksAgain(PackList old) { boolean searchPacksAgain(PackList old) {

40
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/file/ObjectDirectoryInserter.java

@ -14,7 +14,6 @@ package org.eclipse.jgit.internal.storage.file;
import java.io.EOFException; import java.io.EOFException;
import java.io.File; import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.FilterOutputStream; import java.io.FilterOutputStream;
import java.io.IOException; import java.io.IOException;
@ -116,7 +115,7 @@ class ObjectDirectoryInserter extends ObjectInserter {
private ObjectId insertOneObject( private ObjectId insertOneObject(
File tmp, ObjectId id, boolean createDuplicate) File tmp, ObjectId id, boolean createDuplicate)
throws IOException, ObjectWritingException { throws IOException {
switch (db.insertUnpackedObject(tmp, id, createDuplicate)) { switch (db.insertUnpackedObject(tmp, id, createDuplicate)) {
case INSERTED: case INSERTED:
case EXISTS_PACKED: case EXISTS_PACKED:
@ -163,18 +162,16 @@ class ObjectDirectoryInserter extends ObjectInserter {
} }
} }
@SuppressWarnings("resource" /* java 7 */)
private File toTemp(final SHA1 md, final int type, long len, private File toTemp(final SHA1 md, final int type, long len,
final InputStream is) throws IOException, FileNotFoundException, final InputStream is) throws IOException {
Error {
boolean delete = true; boolean delete = true;
File tmp = newTempFile(); File tmp = newTempFile();
try { try (FileOutputStream fOut = new FileOutputStream(tmp)) {
FileOutputStream fOut = new FileOutputStream(tmp);
try { try {
OutputStream out = fOut; OutputStream out = fOut;
if (config.getFSyncObjectFiles()) if (config.getFSyncObjectFiles()) {
out = Channels.newOutputStream(fOut.getChannel()); out = Channels.newOutputStream(fOut.getChannel());
}
DeflaterOutputStream cOut = compress(out); DeflaterOutputStream cOut = compress(out);
SHA1OutputStream dOut = new SHA1OutputStream(cOut, md); SHA1OutputStream dOut = new SHA1OutputStream(cOut, md);
writeHeader(dOut, type, len); writeHeader(dOut, type, len);
@ -182,53 +179,54 @@ class ObjectDirectoryInserter extends ObjectInserter {
final byte[] buf = buffer(); final byte[] buf = buffer();
while (len > 0) { while (len > 0) {
int n = is.read(buf, 0, (int) Math.min(len, buf.length)); int n = is.read(buf, 0, (int) Math.min(len, buf.length));
if (n <= 0) if (n <= 0) {
throw shortInput(len); throw shortInput(len);
}
dOut.write(buf, 0, n); dOut.write(buf, 0, n);
len -= n; len -= n;
} }
dOut.flush(); dOut.flush();
cOut.finish(); cOut.finish();
} finally { } finally {
if (config.getFSyncObjectFiles()) if (config.getFSyncObjectFiles()) {
fOut.getChannel().force(true); fOut.getChannel().force(true);
fOut.close(); }
} }
delete = false; delete = false;
return tmp; return tmp;
} finally { } finally {
if (delete) if (delete) {
FileUtils.delete(tmp, FileUtils.RETRY); FileUtils.delete(tmp, FileUtils.RETRY);
}
} }
} }
@SuppressWarnings("resource" /* java 7 */)
private File toTemp(final int type, final byte[] buf, final int pos, private File toTemp(final int type, final byte[] buf, final int pos,
final int len) throws IOException, FileNotFoundException { final int len) throws IOException {
boolean delete = true; boolean delete = true;
File tmp = newTempFile(); File tmp = newTempFile();
try { try (FileOutputStream fOut = new FileOutputStream(tmp)) {
FileOutputStream fOut = new FileOutputStream(tmp);
try { try {
OutputStream out = fOut; OutputStream out = fOut;
if (config.getFSyncObjectFiles()) if (config.getFSyncObjectFiles()) {
out = Channels.newOutputStream(fOut.getChannel()); out = Channels.newOutputStream(fOut.getChannel());
}
DeflaterOutputStream cOut = compress(out); DeflaterOutputStream cOut = compress(out);
writeHeader(cOut, type, len); writeHeader(cOut, type, len);
cOut.write(buf, pos, len); cOut.write(buf, pos, len);
cOut.finish(); cOut.finish();
} finally { } finally {
if (config.getFSyncObjectFiles()) if (config.getFSyncObjectFiles()) {
fOut.getChannel().force(true); fOut.getChannel().force(true);
fOut.close(); }
} }
delete = false; delete = false;
return tmp; return tmp;
} finally { } finally {
if (delete) if (delete) {
FileUtils.delete(tmp, FileUtils.RETRY); FileUtils.delete(tmp, FileUtils.RETRY);
}
} }
} }

Loading…
Cancel
Save