Skip to content

Commit 679fa3d

Browse files
committed
HADOOP-16644. Do a HEAD after a PUT to get the modtime.
WiP: no tests. What would a test look like? best to use some mock to fix the remote time to always be slightly different from the local. Or we make the clock of the S3A FS patchable, which is potentially the most flexible Change-Id: I2c99752647f522991b1f89dd9c43f3a2e9b98bf5
1 parent 91320b4 commit 679fa3d

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/S3AFileSystem.java

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3420,9 +3420,32 @@ void finishedWrite(String key, long length, String eTag, String versionId,
34203420
activeState = stateToClose;
34213421
}
34223422
S3Guard.addAncestors(metadataStore, p, ttlTimeProvider, activeState);
3423-
S3AFileStatus status = createUploadFileStatus(p,
3424-
S3AUtils.objectRepresentsDirectory(key, length), length,
3425-
getDefaultBlockSize(p), username, eTag, versionId);
3423+
boolean isDir = objectRepresentsDirectory(key, length);
3424+
S3AFileStatus status = null;
3425+
status = createUploadFileStatus(p,
3426+
isDir, length,
3427+
getDefaultBlockSize(p), username, , versionId);
3428+
// do a HEAD to pick up the real timestamp. This is a PITA but
3429+
// it is the only way to defend against clock drift and timestamp
3430+
// inconsistencies, which can cause surprises later.
3431+
S3AFileStatus remoteStatus = null;
3432+
if (!isDir && eTag != null) {
3433+
// we need to pass down the version ID/etag so on an update we
3434+
// can discard previous results
3435+
try {
3436+
remoteStatus = innerGetFileStatus(p, false,
3437+
StatusProbeEnum.HEAD_ONLY);
3438+
if (eTag.equals(remoteStatus.getETag())) {
3439+
status = new S3AFileStatus(status.getLen(),
3440+
remoteStatus.getModificationTime(),
3441+
status.getPath(), status.getBlockSize(), status.getOwner(),
3442+
eTag, status.getVersionId());
3443+
}
3444+
} catch (IOException ignored) {
3445+
// we don't worry if the file isn't visible or some other
3446+
// failure occurs.
3447+
}
3448+
}
34263449
S3Guard.putAndReturn(metadataStore, status,
34273450
instrumentation,
34283451
ttlTimeProvider,

hadoop-tools/hadoop-aws/src/main/java/org/apache/hadoop/fs/s3a/impl/StatusProbeEnum.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,16 @@ public enum StatusProbeEnum {
4141
public static final Set<StatusProbeEnum> DIRECTORIES =
4242
EnumSet.of(DirMarker, List);
4343

44+
/** We only want the HEAD or dir marker. */
45+
public static final Set<StatusProbeEnum> HEAD_OR_DIR_MARKER =
46+
EnumSet.of(Head, DirMarker);
47+
48+
/** We only want the HEAD. */
49+
public static final Set<StatusProbeEnum> HEAD_ONLY =
50+
EnumSet.of(Head);
51+
52+
/** We only want the dir marker. */
53+
public static final Set<StatusProbeEnum> DIR_MARKER_ONLY =
54+
EnumSet.of(DirMarker);
55+
4456
}

0 commit comments

Comments
 (0)