Skip to content

Commit 7914153

Browse files
committed
8338696: (fs) BasicFileAttributes.creationTime() falls back to epoch if birth time is unavailable (Linux)
Backport-of: c89a1c35bda9002ee687b3fa267f3ef9cba78b00
1 parent 15d3b60 commit 7914153

File tree

1 file changed

+21
-9
lines changed

1 file changed

+21
-9
lines changed

src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -154,9 +154,10 @@ struct my_statx
154154
#define STATX_MODE 0x00000002U
155155
#endif
156156

157-
#ifndef STATX_ALL
158-
#define STATX_ALL (STATX_BTIME | STATX_BASIC_STATS)
159-
#endif
157+
//
158+
// STATX_ALL is deprecated; use a different name to avoid confusion.
159+
//
160+
#define LOCAL_STATX_ALL (STATX_BASIC_STATS | STATX_BTIME)
160161

161162
#ifndef AT_FDCWD
162163
#define AT_FDCWD -100
@@ -632,8 +633,19 @@ static void copy_statx_attributes(JNIEnv* env, struct my_statx* buf, jobject att
632633
(*env)->SetLongField(env, attrs, attrs_st_atime_sec, (jlong)buf->stx_atime.tv_sec);
633634
(*env)->SetLongField(env, attrs, attrs_st_mtime_sec, (jlong)buf->stx_mtime.tv_sec);
634635
(*env)->SetLongField(env, attrs, attrs_st_ctime_sec, (jlong)buf->stx_ctime.tv_sec);
635-
(*env)->SetLongField(env, attrs, attrs_st_birthtime_sec, (jlong)buf->stx_btime.tv_sec);
636-
(*env)->SetLongField(env, attrs, attrs_st_birthtime_nsec, (jlong)buf->stx_btime.tv_nsec);
636+
if ((buf->stx_mask & STATX_BTIME) != 0) {
637+
// Birth time was filled in so use it
638+
(*env)->SetLongField(env, attrs, attrs_st_birthtime_sec,
639+
(jlong)buf->stx_btime.tv_sec);
640+
(*env)->SetLongField(env, attrs, attrs_st_birthtime_nsec,
641+
(jlong)buf->stx_btime.tv_nsec);
642+
} else {
643+
// Birth time was not filled in: fall back to last modification time
644+
(*env)->SetLongField(env, attrs, attrs_st_birthtime_sec,
645+
(jlong)buf->stx_mtime.tv_sec);
646+
(*env)->SetLongField(env, attrs, attrs_st_birthtime_nsec,
647+
(jlong)buf->stx_mtime.tv_nsec);
648+
}
637649
(*env)->SetLongField(env, attrs, attrs_st_atime_nsec, (jlong)buf->stx_atime.tv_nsec);
638650
(*env)->SetLongField(env, attrs, attrs_st_mtime_nsec, (jlong)buf->stx_mtime.tv_nsec);
639651
(*env)->SetLongField(env, attrs, attrs_st_ctime_nsec, (jlong)buf->stx_ctime.tv_nsec);
@@ -687,7 +699,7 @@ Java_sun_nio_fs_UnixNativeDispatcher_stat0(JNIEnv* env, jclass this,
687699
#if defined(__linux__)
688700
struct my_statx statx_buf;
689701
int flags = AT_STATX_SYNC_AS_STAT;
690-
unsigned int mask = STATX_ALL;
702+
unsigned int mask = LOCAL_STATX_ALL;
691703

692704
if (my_statx_func != NULL) {
693705
// Prefer statx over stat64 on Linux if it's available
@@ -748,7 +760,7 @@ Java_sun_nio_fs_UnixNativeDispatcher_lstat0(JNIEnv* env, jclass this,
748760
#if defined(__linux__)
749761
struct my_statx statx_buf;
750762
int flags = AT_STATX_SYNC_AS_STAT | AT_SYMLINK_NOFOLLOW;
751-
unsigned int mask = STATX_ALL;
763+
unsigned int mask = LOCAL_STATX_ALL;
752764

753765
if (my_statx_func != NULL) {
754766
// Prefer statx over stat64 on Linux if it's available
@@ -779,7 +791,7 @@ Java_sun_nio_fs_UnixNativeDispatcher_fstat(JNIEnv* env, jclass this, jint fd,
779791
#if defined(__linux__)
780792
struct my_statx statx_buf;
781793
int flags = AT_EMPTY_PATH | AT_STATX_SYNC_AS_STAT;
782-
unsigned int mask = STATX_ALL;
794+
unsigned int mask = LOCAL_STATX_ALL;
783795

784796
if (my_statx_func != NULL) {
785797
// statx supports FD use via dirfd iff pathname is an empty string and the
@@ -812,7 +824,7 @@ Java_sun_nio_fs_UnixNativeDispatcher_fstatat0(JNIEnv* env, jclass this, jint dfd
812824
#if defined(__linux__)
813825
struct my_statx statx_buf;
814826
int flags = AT_STATX_SYNC_AS_STAT;
815-
unsigned int mask = STATX_ALL;
827+
unsigned int mask = LOCAL_STATX_ALL;
816828

817829
if (my_statx_func != NULL) {
818830
// Prefer statx over stat64 on Linux if it's available

0 commit comments

Comments
 (0)