+create_xattr_item(const char *path, struct wim_inode *inode,
+ const char *names, size_t names_size)
+{
+ char _entries[1024] _aligned_attribute(4);
+ char *entries = _entries;
+ size_t entries_avail = ARRAY_LEN(_entries);
+ ssize_t entries_size;
+ int ret;
+
+retry:
+ /* Serialize the xattrs into @entries */
+ entries_size = gather_xattr_entries(path, names, names_size,
+ entries, entries_avail);
+ if (entries_size < 0) {
+ ret = WIMLIB_ERR_STAT;
+ if (errno != ERANGE)
+ goto out;
+ /* Not enough space in @entries. Reallocate it. */
+ if (entries != _entries)
+ FREE(entries);
+ ret = WIMLIB_ERR_NOMEM;
+ entries_avail *= 2;
+ entries = MALLOC(entries_avail);
+ if (!entries)
+ goto out;
+ goto retry;
+ }
+
+ /* Copy @entries into an xattr item associated with @inode */
+ if ((u32)entries_size != entries_size) {
+ ERROR("\"%s\": too much xattr data!", path);
+ ret = WIMLIB_ERR_STAT;
+ goto out;
+ }
+ ret = WIMLIB_ERR_NOMEM;
+ if (!inode_set_linux_xattrs(inode, entries, entries_size))
+ goto out;
+
+ ret = 0;
+out:
+ if (entries != _entries)
+ FREE(entries);
+ return ret;
+}
+
+/*
+ * If the file at @path has Linux-style extended attributes, read them into
+ * memory and add them to @inode as a tagged item.
+ */
+static noinline_for_stack int
+scan_linux_xattrs(const char *path, struct wim_inode *inode)
+{
+ char _names[256];
+ char *names = _names;
+ ssize_t names_size = ARRAY_LEN(_names);
+ int ret = 0;
+
+retry:
+ /* Gather the names of the xattrs of the file at @path */
+ names_size = llistxattr(path, names, names_size);
+ if (names_size == 0) /* No xattrs? */
+ goto out;
+ if (names_size < 0) {
+ /* xattrs unsupported or disabled? */
+ if (errno == ENOTSUP || errno == ENOSYS)
+ goto out;
+ if (errno == ERANGE) {
+ /*
+ * Not enough space in @names. Ask for how much space
+ * we need, then try again.
+ */
+ names_size = llistxattr(path, NULL, 0);
+ if (names_size == 0)
+ goto out;
+ if (names_size > 0) {
+ if (names != _names)
+ FREE(names);
+ names = MALLOC(names_size);
+ if (!names) {
+ ret = WIMLIB_ERR_NOMEM;
+ goto out;
+ }
+ goto retry;
+ }
+ }
+ /* Some other error occurred. */
+ ERROR_WITH_ERRNO("\"%s\": unable to list extended attributes",
+ path);
+ ret = WIMLIB_ERR_STAT;
+ goto out;
+ }
+
+ /*
+ * We have a nonempty list of xattr names. Gather the xattr values and
+ * add them as a tagged item.
+ */
+ ret = create_xattr_item(path, inode, names, names_size);
+out:
+ if (names != _names)
+ FREE(names);
+ return ret;
+}
+#endif /* HAVE_XATTR_SUPPORT */
+
+static int
+unix_scan_regular_file(const char *path, u64 blocks, u64 size,
+ struct wim_inode *inode,