--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/components/coreutils/patches/stat-birthtime.patch Fri Jan 08 12:18:38 2016 -0800
@@ -0,0 +1,178 @@
+Changes to implement:
+16575074 stat could support birthtime/crtime on ZFS
+
+These changes have already been accepted upstream. See:
+http://git.savannah.gnu.org/gitweb/?p=coreutils.git;a=commitdiff;h=ea916c70a5fc47ee6036a05416bc7462fd8dc1cd
+
+--- coreutils-8.16/configure.ac.orig 2014-03-18 20:12:23.362356112 -0700
++++ coreutils-8.16/configure.ac 2014-03-18 20:13:47.327463395 -0700
+@@ -240,6 +240,13 @@
+ AC_DEFINE([LOCALTIME_CACHE], [1], [FIXME])
+ fi
+
++# Assume that if getattrat exists, it's compatible with Solaris 11.
++AC_CHECK_FUNCS([getattrat])
++if test $ac_cv_func_getattrat = yes; then
++ LIB_NVPAIR=-lnvpair
++ AC_SUBST([LIB_NVPAIR])
++fi
++
+ # SCO-ODT-3.0 is reported to need -los to link programs using initgroups
+ AC_CHECK_FUNCS([initgroups])
+ if test $ac_cv_func_initgroups = no; then
+--- coreutils-8.16/src/Makefile.am.orig 2014-03-18 20:19:34.447566111 -0700
++++ coreutils-8.16/src/Makefile.am 2014-03-18 20:20:20.876086076 -0700
+@@ -326,6 +326,9 @@
+ runcon_LDADD += $(LIB_SELINUX)
+ stat_LDADD += $(LIB_SELINUX)
+
++# for nvlist_lookup_uint64_array
++stat_LDADD += $(LIB_NVPAIR)
++
+ # for gettime, settime, utimecmp, utimens
+ copy_LDADD += $(LIB_CLOCK_GETTIME)
+ date_LDADD += $(LIB_CLOCK_GETTIME)
+--- coreutils-8.16/src/stat.c.orig 2014-03-16 16:55:52.605732676 -0700
++++ coreutils-8.16/src/stat.c 2014-03-18 20:27:04.302699124 -0700
+@@ -148,6 +148,11 @@
+ # endif
+ #endif
+
++#if HAVE_GETATTRAT
++# include <attr.h>
++# include <sys/nvpair.h>
++#endif
++
+ /* FIXME: these are used by printf.c, too */
+ #define isodigit(c) ('0' <= (c) && (c) <= '7')
+ #define octtobin(c) ((c) - '0')
+@@ -689,7 +694,7 @@
+ /* Print statfs info. Return zero upon success, nonzero upon failure. */
+ static bool ATTRIBUTE_WARN_UNUSED_RESULT
+ print_statfs (char *pformat, size_t prefix_len, unsigned int m,
+- char const *filename,
++ int fd, char const *filename,
+ void const *data)
+ {
+ STRUCT_STATVFS const *statfsbuf = data;
+@@ -861,6 +866,38 @@
+ return fail;
+ }
+
++static struct timespec
++get_birthtime (int fd, char const *filename, struct stat const *st)
++{
++ struct timespec ts = get_stat_birthtime (st);
++
++#if HAVE_GETATTRAT
++ if (ts.tv_nsec < 0)
++ {
++ nvlist_t *response;
++ if ((fd < 0
++ ? getattrat (AT_FDCWD, XATTR_VIEW_READWRITE, filename, &response)
++ : fgetattr (fd, XATTR_VIEW_READWRITE, &response))
++ == 0)
++ {
++ uint64_t *val;
++ uint_t n;
++ if (nvlist_lookup_uint64_array (response, A_CRTIME, &val, &n) == 0
++ && 2 <= n
++ && val[0] <= TYPE_MAXIMUM (time_t)
++ && val[1] < 1000000000 * 2 /* for leap seconds */)
++ {
++ ts.tv_sec = val[0];
++ ts.tv_nsec = val[1];
++ }
++ nvlist_free (response);
++ }
++ }
++#endif
++
++ return ts;
++}
++
+ /* Map a TS with negative TS.tv_nsec to {0,0}. */
+ static inline struct timespec
+ neg_to_zero (struct timespec ts)
+@@ -874,7 +911,7 @@
+ /* Print stat info. Return zero upon success, nonzero upon failure. */
+ static bool
+ print_stat (char *pformat, size_t prefix_len, unsigned int m,
+- char const *filename, void const *data)
++ int fd, char const *filename, void const *data)
+ {
+ struct stat *statbuf = (struct stat *) data;
+ struct passwd *pw_ent;
+@@ -967,7 +1004,7 @@
+ break;
+ case 'w':
+ {
+- struct timespec t = get_stat_birthtime (statbuf);
++ struct timespec t = get_birthtime (fd, filename, statbuf);
+ if (t.tv_nsec < 0)
+ out_string (pformat, prefix_len, "-");
+ else
+@@ -976,7 +1013,7 @@
+ break;
+ case 'W':
+ out_epoch_sec (pformat, prefix_len, statbuf,
+- neg_to_zero (get_stat_birthtime (statbuf)));
++ neg_to_zero (get_birthtime (fd, filename, statbuf)));
+ break;
+ case 'x':
+ out_string (pformat, prefix_len, human_time (get_stat_atime (statbuf)));
+@@ -1051,9 +1088,9 @@
+ calling PRINT_FUNC for each %-directive encountered.
+ Return zero upon success, nonzero upon failure. */
+ static bool ATTRIBUTE_WARN_UNUSED_RESULT
+-print_it (char const *format, char const *filename,
++print_it (char const *format, int fd, char const *filename,
+ bool (*print_func) (char *, size_t, unsigned int,
+- char const *, void const *),
++ int, char const *, void const *),
+ void const *data)
+ {
+ bool fail = false;
+@@ -1102,7 +1139,8 @@
+ putchar ('%');
+ break;
+ default:
+- fail |= print_func (dest, len + 1, fmt_code, filename, data);
++ fail |= print_func (dest, len + 1, fmt_code,
++ fd, filename, data);
+ break;
+ }
+ break;
+@@ -1185,7 +1223,7 @@
+ return false;
+ }
+
+- bool fail = print_it (format, filename, print_statfs, &statfsbuf);
++ bool fail = print_it (format, -1, filename, print_statfs, &statfsbuf);
+ return ! fail;
+ }
+
+@@ -1194,11 +1232,12 @@
+ do_stat (char const *filename, char const *format,
+ char const *format2)
+ {
++ int fd = STREQ (filename, "-") ? 0 : -1;
+ struct stat statbuf;
+
+- if (STREQ (filename, "-"))
++ if (0 <= fd)
+ {
+- if (fstat (STDIN_FILENO, &statbuf) != 0)
++ if (fstat (fd, &statbuf) != 0)
+ {
+ error (0, errno, _("cannot stat standard input"));
+ return false;
+@@ -1218,7 +1257,7 @@
+ if (S_ISBLK (statbuf.st_mode) || S_ISCHR (statbuf.st_mode))
+ format = format2;
+
+- bool fail = print_it (format, filename, print_stat, &statbuf);
++ bool fail = print_it (format, fd, filename, print_stat, &statbuf);
+ return ! fail;
+ }
+