--- /dev/null
+From ddfb160353df14e9f88affe7498512a553146872 Mon Sep 17 00:00:00 2001
+From: Fedora Ninjas <grub2-owner@fedoraproject.org>
+Date: Tue, 22 Jan 2013 06:31:38 +0100
+Subject: [PATCH 101/152] blscfg: add blscfg module to parse Boot Loader
+ Specification snippets
+
+http://www.freedesktop.org/wiki/Specifications/BootLoaderSpec
+
+Works like this:
+
+ insmod blscfg
+ bls_import
+
+Done! You should now have menu items for your snippets in place.
+
+Signed-off-by: Peter Jones <grub2-owner@fedoraproject.org>
+---
+ grub-core/Makefile.core.def | 8 ++
+ grub-core/commands/blscfg.c | 201 ++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 209 insertions(+)
+ create mode 100644 grub-core/commands/blscfg.c
+
+diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
+index ec46506..7bf1c8a 100644
+--- a/grub-core/Makefile.core.def
++++ b/grub-core/Makefile.core.def
+@@ -747,6 +747,14 @@ module = {
+ };
+
+ module = {
++ name = blscfg;
++ common = commands/blscfg.c;
++ enable = i386_efi;
++ enable = x86_64_efi;
++ enable = i386_pc;
++};
++
++module = {
+ name = boot;
+ common = commands/boot.c;
+ i386_pc = lib/i386/pc/biosnum.c;
+diff --git a/grub-core/commands/blscfg.c b/grub-core/commands/blscfg.c
+new file mode 100644
+index 0000000..4274aca
+--- /dev/null
++++ b/grub-core/commands/blscfg.c
+@@ -0,0 +1,201 @@
++/*-*- Mode: C; c-basic-offset: 2; indent-tabs-mode: t -*-*/
++
++/* bls.c - implementation of the boot loader spec */
++
++/*
++ * GRUB -- GRand Unified Bootloader
++ *
++ * GRUB is free software: you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation, either version 3 of the License, or
++ * (at your option) any later version.
++ *
++ * GRUB is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
++ */
++
++#include <grub/types.h>
++#include <grub/misc.h>
++#include <grub/mm.h>
++#include <grub/err.h>
++#include <grub/dl.h>
++#include <grub/extcmd.h>
++#include <grub/i18n.h>
++#include <grub/fs.h>
++#include <grub/env.h>
++#include <grub/file.h>
++#include <grub/normal.h>
++
++GRUB_MOD_LICENSE ("GPLv3+");
++
++#ifdef GRUB_MACHINE_EFI
++#define GRUB_LINUX_CMD "linuxefi"
++#define GRUB_INITRD_CMD "initrdefi"
++#define GRUB_BLS_CONFIG_PATH "/EFI/fedora/loader/entries/"
++#define GRUB_BOOT_DEVICE "($boot)"
++#else
++#define GRUB_LINUX_CMD "linux"
++#define GRUB_INITRD_CMD "initrd"
++#define GRUB_BLS_CONFIG_PATH "/loader/entries/"
++#define GRUB_BOOT_DEVICE "($root)"
++#endif
++
++static int parse_entry (
++ const char *filename,
++ const struct grub_dirhook_info *info __attribute__ ((unused)),
++ void *data __attribute__ ((unused)))
++{
++ grub_size_t n;
++ char *p;
++ grub_file_t f = NULL;
++ grub_off_t sz;
++ char *title = NULL, *options = NULL, *clinux = NULL, *initrd = NULL, *src = NULL;
++ const char *args[2] = { NULL, NULL };
++
++ if (filename[0] == '.')
++ return 0;
++
++ n = grub_strlen (filename);
++ if (n <= 5)
++ return 0;
++
++ if (grub_strcmp (filename + n - 5, ".conf") != 0)
++ return 0;
++
++ p = grub_xasprintf (GRUB_BLS_CONFIG_PATH "%s", filename);
++
++ f = grub_file_open (p);
++ if (!f)
++ goto finish;
++
++ sz = grub_file_size (f);
++ if (sz == GRUB_FILE_SIZE_UNKNOWN || sz > 1024*1024)
++ goto finish;
++
++ for (;;)
++ {
++ char *buf;
++
++ buf = grub_file_getline (f);
++ if (!buf)
++ break;
++
++ if (grub_strncmp (buf, "title ", 6) == 0)
++ {
++ grub_free (title);
++ title = grub_strdup (buf + 6);
++ if (!title)
++ goto finish;
++ }
++ else if (grub_strncmp (buf, "options ", 8) == 0)
++ {
++ grub_free (options);
++ options = grub_strdup (buf + 8);
++ if (!options)
++ goto finish;
++ }
++ else if (grub_strncmp (buf, "linux ", 6) == 0)
++ {
++ grub_free (clinux);
++ clinux = grub_strdup (buf + 6);
++ if (!clinux)
++ goto finish;
++ }
++ else if (grub_strncmp (buf, "initrd ", 7) == 0)
++ {
++ grub_free (initrd);
++ initrd = grub_strdup (buf + 7);
++ if (!initrd)
++ goto finish;
++ }
++
++ grub_free(buf);
++ }
++
++ if (!linux)
++ {
++ grub_printf ("Skipping file %s with no 'linux' key.", p);
++ goto finish;
++ }
++
++ args[0] = title ? title : filename;
++
++ src = grub_xasprintf ("load_video\n"
++ "set gfx_payload=keep\n"
++ "insmod gzio\n"
++ GRUB_LINUX_CMD " %s%s%s%s\n"
++ "%s%s%s%s",
++ GRUB_BOOT_DEVICE, clinux, options ? " " : "", options ? options : "",
++ initrd ? GRUB_INITRD_CMD " " : "", initrd ? GRUB_BOOT_DEVICE : "", initrd ? initrd : "", initrd ? "\n" : "");
++
++ grub_normal_add_menu_entry (1, args, NULL, NULL, "bls", NULL, NULL, src, 0);
++
++finish:
++ grub_free (p);
++ grub_free (title);
++ grub_free (options);
++ grub_free (clinux);
++ grub_free (initrd);
++ grub_free (src);
++
++ if (f)
++ grub_file_close (f);
++
++ return 0;
++}
++
++static grub_err_t
++grub_cmd_bls_import (grub_extcmd_context_t ctxt __attribute__ ((unused)),
++ int argc __attribute__ ((unused)),
++ char **args __attribute__ ((unused)))
++{
++ grub_fs_t fs;
++ grub_device_t dev;
++ static grub_err_t r;
++ const char *devid;
++
++ devid = grub_env_get ("root");
++ if (!devid)
++ return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "root");
++
++ dev = grub_device_open (devid);
++ if (!dev)
++ return grub_errno;
++
++ fs = grub_fs_probe (dev);
++ if (!fs)
++ {
++ r = grub_errno;
++ goto finish;
++ }
++
++ r = fs->dir (dev, GRUB_BLS_CONFIG_PATH, parse_entry, NULL);
++
++finish:
++ if (dev)
++ grub_device_close (dev);
++
++ return r;
++}
++
++static grub_extcmd_t cmd;
++
++GRUB_MOD_INIT(bls)
++{
++ cmd = grub_register_extcmd ("bls_import",
++ grub_cmd_bls_import,
++ 0,
++ NULL,
++ N_("Import Boot Loader Specification snippets."),
++ NULL);
++}
++
++GRUB_MOD_FINI(bls)
++{
++ grub_unregister_extcmd (cmd);
++}
+--
+1.9.3
+
--- /dev/null
+From 886d93184b894a29b0bef1f2467230a20c7a33ce Mon Sep 17 00:00:00 2001
+From: Mark Salter <msalter@redhat.com>
+Date: Tue, 8 Apr 2014 10:58:11 -0400
+Subject: [PATCH] reopen SNP protocol for exclusive use by grub
+
+While working with pxeboot of grub on an ARM platform, I noticed
+very poor network performance while grub was loading a kernel
+and initramfs. The performance during the loading of grub itself
+seemed reasonable. Digging into the issue, I found that the UEFI
+firmware was periodically polling for network packets while grub
+was downloading files. This was causing timeouts and retries in
+the grub network stack.
+
+The solution I found was to reopen the SNP protocol for exclusive
+use. This forces UEFI to shutdown its use of SNP so that grub is
+not competing for incoming packets.
+
+Signed-off-by: Mark Salter <msalter@redhat.com>
+---
+ grub-core/net/drivers/efi/efinet.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c
+index 2b344d6..a6e4c79 100644
+--- a/grub-core/net/drivers/efi/efinet.c
++++ b/grub-core/net/drivers/efi/efinet.c
+@@ -223,6 +223,7 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device,
+ {
+ struct grub_net_card *card;
+ grub_efi_device_path_t *dp;
++ grub_efi_simple_network_t *net;
+
+ dp = grub_efi_get_device_path (hnd);
+ if (! dp)
+@@ -250,6 +251,21 @@ grub_efi_net_config_real (grub_efi_handle_t hnd, char **device,
+ &pxe_mode->dhcp_ack,
+ sizeof (pxe_mode->dhcp_ack),
+ 1, device, path);
++ net = grub_efi_open_protocol (card->efi_handle, &net_io_guid,
++ GRUB_EFI_OPEN_PROTOCOL_BY_EXCLUSIVE);
++ if (net) {
++ if (net->mode->state == GRUB_EFI_NETWORK_STOPPED
++ && efi_call_1 (net->start, net) != GRUB_EFI_SUCCESS)
++ continue;
++
++ if (net->mode->state == GRUB_EFI_NETWORK_STOPPED)
++ continue;
++
++ if (net->mode->state == GRUB_EFI_NETWORK_STARTED
++ && efi_call_3 (net->initialize, net, 0, 0) != GRUB_EFI_SUCCESS)
++ continue;
++ card->efi_net = net;
++ }
+ return;
+ }
+ }
+--
+1.8.5.3
+
#
# To disable auto generation of /boot/grub/grub.conf on kernel package
# install/upgrade, UPDATE_GRUB must be set to "no".
-#UPDATE_GRUB=yes
+#UPDATE_GRUB=no
# Default entry to boot. Numeric value starting with 0.
# Use special value 'saved' to stick with last booted entry. used with GRUB_SAVEDEFAULT
# save_default_entry
#GRUB_SAVEDEFAULT=true
+# Boot the default entry this many seconds after the menu is displayed, unless a key
+# is pressed. Set to 0 to boot immediately without displaying the menu, or to -1 to
+# wait indefinitely.
GRUB_TIMEOUT=15
+# Wait this many seconds for a key to be pressed before displaying the menu.
+#GRUB_HIDDEN_TIMEOUT=15
+
# Unless `GRUB_DISABLE_RECOVERY' is set to `true', two menu entries
# will be generated for each Linux kernel: one default entry and one
# entry for recovery mode. This option lists command-line arguments
# to add only to the default menu entry, after those listed in
# `GRUB_CMDLINE_LINUX'.
# To disable IPv6 in kernel, append: ipv6.disable=1
-GRUB_CMDLINE_LINUX_DEFAULT="panic=120 quiet"
+GRUB_CMDLINE_LINUX_DEFAULT="panic=300 quiet"
# Command-line arguments to add to menu entries for the Linux kernel.
GRUB_CMDLINE_LINUX=""
--- /dev/null
+From 34231b28cbb6b2e10d7668c5b6d2432e8563bd1d Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 5 Jun 2014 20:56:21 +0200
+Subject: [PATCH 1/4] xfs: Add helper for inode size
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+---
+ grub-core/fs/xfs.c | 17 +++++++++++------
+ 1 file changed, 11 insertions(+), 6 deletions(-)
+
+diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
+index 16ffd3f1ebd9..a2fc942707c1 100644
+--- a/grub-core/fs/xfs.c
++++ b/grub-core/fs/xfs.c
+@@ -255,6 +255,11 @@ grub_xfs_inode_offset (struct grub_xfs_data *data,
+ data->sblock.log2_inode);
+ }
+
++static inline int
++grub_xfs_inode_size(struct grub_xfs_data *data)
++{
++ return 1 << data->sblock.log2_inode;
++}
+
+ static grub_err_t
+ grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino,
+@@ -264,8 +269,8 @@ grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino,
+ int offset = grub_xfs_inode_offset (data, ino);
+
+ /* Read the inode. */
+- if (grub_disk_read (data->disk, block, offset,
+- 1 << data->sblock.log2_inode, inode))
++ if (grub_disk_read (data->disk, block, offset, grub_xfs_inode_size(data),
++ inode))
+ return grub_errno;
+
+ if (grub_strncmp ((char *) inode->magic, "IN", 2))
+@@ -297,7 +302,7 @@ grub_xfs_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
+ if (node->inode.fork_offset)
+ recoffset = (node->inode.fork_offset - 1) / 2;
+ else
+- recoffset = ((1 << node->data->sblock.log2_inode)
++ recoffset = (grub_xfs_inode_size(node->data)
+ - ((char *) &node->inode.data.btree.keys
+ - (char *) &node->inode))
+ / (2 * sizeof (grub_uint64_t));
+@@ -458,7 +463,7 @@ static int iterate_dir_call_hook (grub_uint64_t ino, const char *filename,
+
+ fdiro = grub_malloc (sizeof (struct grub_fshelp_node)
+ - sizeof (struct grub_xfs_inode)
+- + (1 << ctx->diro->data->sblock.log2_inode) + 1);
++ + grub_xfs_inode_size(ctx->diro->data) + 1);
+ if (!fdiro)
+ {
+ grub_print_error ();
+@@ -684,7 +689,7 @@ grub_xfs_mount (grub_disk_t disk)
+ data = grub_realloc (data,
+ sizeof (struct grub_xfs_data)
+ - sizeof (struct grub_xfs_inode)
+- + (1 << data->sblock.log2_inode) + 1);
++ + grub_xfs_inode_size(data) + 1);
+
+ if (! data)
+ goto fail;
+@@ -802,7 +807,7 @@ grub_xfs_open (struct grub_file *file, const char *name)
+ grub_memcpy (&data->diropen, fdiro,
+ sizeof (struct grub_fshelp_node)
+ - sizeof (struct grub_xfs_inode)
+- + (1 << data->sblock.log2_inode));
++ + grub_xfs_inode_size(data));
+ grub_free (fdiro);
+ }
+
+--
+1.8.1.4
+
--- /dev/null
+From 57ae4073cc28fa74014a62aca397a40ce1f73763 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Thu, 12 Jun 2014 11:01:11 +0200
+Subject: [PATCH 3/4] xfs: Convert inode numbers to cpu endianity immediately
+ after reading
+
+Currently XFS driver converted inode numbers to native endianity only
+when using them to compute inode position. Although this works, it is
+somewhat confusing. So convert inode numbers when reading them from disk
+structures as every other field.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+---
+ grub-core/fs/xfs.c | 13 ++++++-------
+ 1 file changed, 6 insertions(+), 7 deletions(-)
+
+diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
+index ef3bc787e968..7e247a32df5c 100644
+--- a/grub-core/fs/xfs.c
++++ b/grub-core/fs/xfs.c
+@@ -180,14 +180,14 @@ static inline grub_uint64_t
+ GRUB_XFS_INO_INOINAG (struct grub_xfs_data *data,
+ grub_uint64_t ino)
+ {
+- return (grub_be_to_cpu64 (ino) & ((1LL << GRUB_XFS_INO_AGBITS (data)) - 1));
++ return (ino & ((1LL << GRUB_XFS_INO_AGBITS (data)) - 1));
+ }
+
+ static inline grub_uint64_t
+ GRUB_XFS_INO_AG (struct grub_xfs_data *data,
+ grub_uint64_t ino)
+ {
+- return (grub_be_to_cpu64 (ino) >> GRUB_XFS_INO_AGBITS (data));
++ return (ino >> GRUB_XFS_INO_AGBITS (data));
+ }
+
+ static inline grub_disk_addr_t
+@@ -511,13 +511,12 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
+ if (smallino)
+ {
+ parent = grub_be_to_cpu32 (diro->inode.data.dir.dirhead.parent.i4);
+- parent = grub_cpu_to_be64 (parent);
+ /* The header is a bit smaller than usual. */
+ de = (struct grub_xfs_dir_entry *) ((char *) de - 4);
+ }
+ else
+ {
+- parent = diro->inode.data.dir.dirhead.parent.i8;
++ parent = grub_be_to_cpu64(diro->inode.data.dir.dirhead.parent.i8);
+ }
+
+ /* Synthesize the direntries for `.' and `..'. */
+@@ -550,7 +549,6 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
+ | (((grub_uint64_t) inopos[5]) << 16)
+ | (((grub_uint64_t) inopos[6]) << 8)
+ | (((grub_uint64_t) inopos[7]) << 0);
+- ino = grub_cpu_to_be64 (ino);
+
+ c = de->name[de->len];
+ de->name[de->len] = '\0';
+@@ -632,7 +630,8 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
+ is not used by GRUB. So it can be overwritten. */
+ filename[direntry->len] = '\0';
+
+- if (iterate_dir_call_hook (direntry->inode, filename, &ctx))
++ if (iterate_dir_call_hook (grub_be_to_cpu64(direntry->inode),
++ filename, &ctx))
+ {
+ grub_free (dirblock);
+ return 1;
+@@ -694,7 +693,7 @@ grub_xfs_mount (grub_disk_t disk)
+ goto fail;
+
+ data->diropen.data = data;
+- data->diropen.ino = data->sblock.rootino;
++ data->diropen.ino = grub_be_to_cpu64(data->sblock.rootino);
+ data->diropen.inode_read = 1;
+ data->bsize = grub_be_to_cpu32 (data->sblock.bsize);
+ data->agsize = grub_be_to_cpu32 (data->sblock.agsize);
+--
+1.8.1.4
+
--- /dev/null
+From a7d584c005bde09bb86475a79d714215b3480821 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Wed, 11 Jun 2014 18:36:59 +0200
+Subject: [PATCH 2/4] xfs: Fix termination loop for directory iteration
+
+Directory iteration used wrong position (sizeof wrong structure) for
+termination of iteration inside a directory block. Luckily the position
+ended up being wrong by just 1 byte and directory entries are larger so
+things worked out fine in practice. But fix the problem anyway.
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+---
+ grub-core/fs/xfs.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
+index a2fc942707c1..ef3bc787e968 100644
+--- a/grub-core/fs/xfs.c
++++ b/grub-core/fs/xfs.c
+@@ -608,8 +608,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t dir,
+ - grub_be_to_cpu32 (tail->leaf_stale));
+
+ /* Iterate over all entries within this block. */
+- while (pos < (dirblk_size
+- - (int) sizeof (struct grub_xfs_dir2_entry)))
++ while (pos < tail_start)
+ {
+ struct grub_xfs_dir2_entry *direntry;
+ grub_uint8_t *freetag;
+--
+1.8.1.4
+
--- /dev/null
+From 2f725e644d8ccf001a4dccddc8abb2c9479352a7 Mon Sep 17 00:00:00 2001
+From: Jan Kara <jack@suse.cz>
+Date: Wed, 11 Jun 2014 18:36:01 +0200
+Subject: [PATCH] xfs: V5 filesystem format support
+
+Signed-off-by: Jan Kara <jack@suse.cz>
+---
+ grub-core/fs/xfs.c | 245 +++++++++++++++++++++++++++++++++++++----------------
+ 1 file changed, 173 insertions(+), 72 deletions(-)
+
+Index: grub-2.02~beta2/grub-core/fs/xfs.c
+===================================================================
+--- grub-2.02~beta2.orig/grub-core/fs/xfs.c
++++ grub-2.02~beta2/grub-core/fs/xfs.c
+@@ -34,6 +34,15 @@ GRUB_MOD_LICENSE ("GPLv3+");
+ #define XFS_INODE_FORMAT_EXT 2
+ #define XFS_INODE_FORMAT_BTREE 3
+
++/* Superblock version field flags */
++#define XFS_SB_VERSION_NUMBITS 0x000f
++#define XFS_SB_VERSION_MOREBITSBIT 0x8000
++
++/* features2 field flags */
++#define XFS_SB_VERSION2_FTYPE 0x00000200 /* inode type in dir */
++
++/* incompat feature flags */
++#define XFS_SB_FEAT_INCOMPAT_FTYPE (1 << 0) /* filetype in dirent */
+
+ struct grub_xfs_sblock
+ {
+@@ -45,7 +54,9 @@ struct grub_xfs_sblock
+ grub_uint64_t rootino;
+ grub_uint8_t unused3[20];
+ grub_uint32_t agsize;
+- grub_uint8_t unused4[20];
++ grub_uint8_t unused4[12];
++ grub_uint16_t version;
++ grub_uint8_t unused5[6];
+ grub_uint8_t label[12];
+ grub_uint8_t log2_bsize;
+ grub_uint8_t log2_sect;
+@@ -54,12 +65,19 @@ struct grub_xfs_sblock
+ grub_uint8_t log2_agblk;
+ grub_uint8_t unused6[67];
+ grub_uint8_t log2_dirblk;
++ grub_uint8_t unused7[7];
++ grub_uint32_t features2;
++ grub_uint8_t unused8[4];
++ grub_uint32_t sb_features_compat;
++ grub_uint32_t sb_features_ro_compat;
++ grub_uint32_t sb_features_incompat;
++ grub_uint32_t sb_features_log_incompat;
+ } GRUB_PACKED;
+
+ struct grub_xfs_dir_header
+ {
+ grub_uint8_t count;
+- grub_uint8_t smallino;
++ grub_uint8_t largeino;
+ union
+ {
+ grub_uint32_t i4;
+@@ -67,14 +85,16 @@ struct grub_xfs_dir_header
+ } GRUB_PACKED parent;
+ } GRUB_PACKED;
+
++/* Structure for directory entry inlined in the inode */
+ struct grub_xfs_dir_entry
+ {
+ grub_uint8_t len;
+ grub_uint16_t offset;
+ char name[1];
+- /* Inode number follows, 32 bits. */
++ /* Inode number follows, 32 / 64 bits. */
+ } GRUB_PACKED;
+
++/* Structure for directory entry in a block */
+ struct grub_xfs_dir2_entry
+ {
+ grub_uint64_t inode;
+@@ -90,7 +110,8 @@ struct grub_xfs_btree_node
+ grub_uint16_t numrecs;
+ grub_uint64_t left;
+ grub_uint64_t right;
+- grub_uint64_t keys[1];
++ /* In V5 here follow crc, uuid, etc. */
++ /* Then follow keys and block pointers */
+ } GRUB_PACKED;
+
+ struct grub_xfs_btree_root
+@@ -123,17 +144,6 @@ struct grub_xfs_inode
+ grub_uint16_t unused3;
+ grub_uint8_t fork_offset;
+ grub_uint8_t unused4[17];
+- union
+- {
+- char raw[156];
+- struct dir
+- {
+- struct grub_xfs_dir_header dirhead;
+- struct grub_xfs_dir_entry direntry[1];
+- } dir;
+- grub_xfs_extent extents[XFS_INODE_EXTENTS];
+- struct grub_xfs_btree_root btree;
+- } GRUB_PACKED data;
+ } GRUB_PACKED;
+
+ struct grub_xfs_dirblock_tail
+@@ -157,6 +167,8 @@ struct grub_xfs_data
+ int pos;
+ int bsize;
+ grub_uint32_t agsize;
++ unsigned int hasftype:1;
++ unsigned int hascrc:1;
+ struct grub_fshelp_node diropen;
+ };
+
+@@ -164,6 +176,24 @@ static grub_dl_t my_mod;
+
+ \f
+
++static int grub_xfs_sb_hascrc(struct grub_xfs_data *data)
++{
++ return (grub_be_to_cpu16(data->sblock.version) & XFS_SB_VERSION_NUMBITS) == 5;
++}
++
++static int grub_xfs_sb_hasftype(struct grub_xfs_data *data)
++{
++ grub_uint32_t version = grub_be_to_cpu16(data->sblock.version);
++
++ if ((version & XFS_SB_VERSION_NUMBITS) == 5 &&
++ grub_be_to_cpu32(data->sblock.sb_features_incompat) & XFS_SB_FEAT_INCOMPAT_FTYPE)
++ return 1;
++ if (version & XFS_SB_VERSION_MOREBITSBIT &&
++ grub_be_to_cpu32(data->sblock.features2) & XFS_SB_VERSION2_FTYPE)
++ return 1;
++ return 0;
++}
++
+ /* Filetype information as used in inodes. */
+ #define FILETYPE_INO_MASK 0170000
+ #define FILETYPE_INO_REG 0100000
+@@ -219,18 +249,6 @@ GRUB_XFS_EXTENT_SIZE (grub_xfs_extent *e
+ return (grub_be_to_cpu32 (exts[ex][3]) & ((1 << 21) - 1));
+ }
+
+-static inline int
+-GRUB_XFS_ROUND_TO_DIRENT (int pos)
+-{
+- return ((((pos) + 8 - 1) / 8) * 8);
+-}
+-
+-static inline int
+-GRUB_XFS_NEXT_DIRENT (int pos, int len)
+-{
+- return (pos) + GRUB_XFS_ROUND_TO_DIRENT (8 + 1 + len + 2);
+-}
+-
+ \f
+ static inline grub_uint64_t
+ grub_xfs_inode_block (struct grub_xfs_data *data,
+@@ -261,6 +279,92 @@ grub_xfs_inode_size(struct grub_xfs_data
+ return 1 << data->sblock.log2_inode;
+ }
+
++static void *
++grub_xfs_inode_data(struct grub_xfs_inode *inode)
++{
++ if (inode->version <= 2)
++ return ((char *)inode) + 100;
++ return ((char *)inode) + 176;
++}
++
++static struct grub_xfs_dir_entry *
++grub_xfs_inline_de(struct grub_xfs_dir_header *head)
++{
++ /*
++ * With small inode numbers the header is 4 bytes smaller because of
++ * smaller parent pointer
++ */
++ return (void *)(((char *)head) + sizeof(struct grub_xfs_dir_header) -
++ (head->largeino ? 0 : sizeof(grub_uint32_t)));
++}
++
++static grub_uint8_t *
++grub_xfs_inline_de_inopos(struct grub_xfs_data *data,
++ struct grub_xfs_dir_entry *de)
++{
++ return ((grub_uint8_t *)(de + 1)) + de->len - 1 +
++ (data->hasftype ? 1 : 0);
++}
++
++static struct grub_xfs_dir_entry *
++grub_xfs_inline_next_de(struct grub_xfs_data *data,
++ struct grub_xfs_dir_header *head,
++ struct grub_xfs_dir_entry *de)
++{
++ char *p = (char *)de + sizeof(struct grub_xfs_dir_entry) - 1 + de->len;
++
++ p += head->largeino ? sizeof(grub_uint64_t) : sizeof(grub_uint32_t);
++ if (data->hasftype)
++ p++;
++
++ return (struct grub_xfs_dir_entry *)p;
++}
++
++static struct grub_xfs_dirblock_tail *
++grub_xfs_dir_tail(struct grub_xfs_data *data, void *dirblock)
++{
++ int dirblksize = 1 << (data->sblock.log2_bsize + data->sblock.log2_dirblk);
++
++ return (struct grub_xfs_dirblock_tail *)
++ ((char *)dirblock + dirblksize - sizeof (struct grub_xfs_dirblock_tail));
++}
++
++static struct grub_xfs_dir2_entry *
++grub_xfs_first_de(struct grub_xfs_data *data, void *dirblock)
++{
++ if (data->hascrc)
++ return (struct grub_xfs_dir2_entry *)((char *)dirblock + 64);
++ return (struct grub_xfs_dir2_entry *)((char *)dirblock + 16);
++}
++
++static inline int
++grub_xfs_round_dirent_size (int len)
++{
++ return (len + 7) & ~7;
++}
++
++static struct grub_xfs_dir2_entry *
++grub_xfs_next_de(struct grub_xfs_data *data, struct grub_xfs_dir2_entry *de)
++{
++ int size = sizeof (struct grub_xfs_dir2_entry) + de->len + 2 /* Tag */;
++
++ if (data->hasftype)
++ size++; /* File type */
++ return (struct grub_xfs_dir2_entry *)
++ (((char *)de) + grub_xfs_round_dirent_size (size));
++}
++
++static grub_uint64_t *
++grub_xfs_btree_keys(struct grub_xfs_data *data,
++ struct grub_xfs_btree_node *leaf)
++{
++ char *p = (char *)(leaf + 1);
++
++ if (data->hascrc)
++ p += 48; /* crc, uuid, ... */
++ return (grub_uint64_t *)(void*)p;
++}
++
+ static grub_err_t
+ grub_xfs_read_inode (struct grub_xfs_data *data, grub_uint64_t ino,
+ struct grub_xfs_inode *inode)
+@@ -268,6 +372,9 @@ grub_xfs_read_inode (struct grub_xfs_dat
+ grub_uint64_t block = grub_xfs_inode_block (data, ino);
+ int offset = grub_xfs_inode_offset (data, ino);
+
++ grub_dprintf("xfs", "Reading inode (%llu) - %llu, %d\n",
++ (unsigned long long) ino,
++ (unsigned long long) block, offset);
+ /* Read the inode. */
+ if (grub_disk_read (data->disk, block, offset, grub_xfs_inode_size(data),
+ inode))
+@@ -290,6 +397,7 @@ grub_xfs_read_block (grub_fshelp_node_t
+
+ if (node->inode.format == XFS_INODE_FORMAT_BTREE)
+ {
++ struct grub_xfs_btree_root *root;
+ const grub_uint64_t *keys;
+ int recoffset;
+
+@@ -297,15 +405,15 @@ grub_xfs_read_block (grub_fshelp_node_t
+ if (leaf == 0)
+ return 0;
+
+- nrec = grub_be_to_cpu16 (node->inode.data.btree.numrecs);
+- keys = &node->inode.data.btree.keys[0];
++ root = grub_xfs_inode_data(&node->inode);
++ nrec = grub_be_to_cpu16 (root->numrecs);
++ keys = &root->keys[0];
+ if (node->inode.fork_offset)
+ recoffset = (node->inode.fork_offset - 1) / 2;
+ else
+ recoffset = (grub_xfs_inode_size(node->data)
+- - ((char *) &node->inode.data.btree.keys
+- - (char *) &node->inode))
+- / (2 * sizeof (grub_uint64_t));
++ - ((char *) keys - (char *) &node->inode))
++ / (2 * sizeof (grub_uint64_t));
+ do
+ {
+ int i;
+@@ -327,7 +435,10 @@ grub_xfs_read_block (grub_fshelp_node_t
+ 0, node->data->bsize, leaf))
+ return 0;
+
+- if (grub_strncmp ((char *) leaf->magic, "BMAP", 4))
++ if ((!node->data->hascrc &&
++ grub_strncmp ((char *) leaf->magic, "BMAP", 4)) ||
++ (node->data->hascrc &&
++ grub_strncmp ((char *) leaf->magic, "BMA3", 4)))
+ {
+ grub_free (leaf);
+ grub_error (GRUB_ERR_BAD_FS, "not a correct XFS BMAP node");
+@@ -335,8 +446,8 @@ grub_xfs_read_block (grub_fshelp_node_t
+ }
+
+ nrec = grub_be_to_cpu16 (leaf->numrecs);
+- keys = &leaf->keys[0];
+- recoffset = ((node->data->bsize - ((char *) &leaf->keys
++ keys = grub_xfs_btree_keys(node->data, leaf);
++ recoffset = ((node->data->bsize - ((char *) keys
+ - (char *) leaf))
+ / (2 * sizeof (grub_uint64_t)));
+ }
+@@ -346,7 +457,7 @@ grub_xfs_read_block (grub_fshelp_node_t
+ else if (node->inode.format == XFS_INODE_FORMAT_EXT)
+ {
+ nrec = grub_be_to_cpu32 (node->inode.nextents);
+- exts = &node->inode.data.extents[0];
++ exts = grub_xfs_inode_data(&node->inode);
+ }
+ else
+ {
+@@ -404,7 +515,7 @@ grub_xfs_read_symlink (grub_fshelp_node_
+ switch (node->inode.format)
+ {
+ case XFS_INODE_FORMAT_INO:
+- return grub_strndup (node->inode.data.raw, size);
++ return grub_strndup (grub_xfs_inode_data(&node->inode), size);
+
+ case XFS_INODE_FORMAT_EXT:
+ {
+@@ -501,23 +612,18 @@ grub_xfs_iterate_dir (grub_fshelp_node_t
+ {
+ case XFS_INODE_FORMAT_INO:
+ {
+- struct grub_xfs_dir_entry *de = &diro->inode.data.dir.direntry[0];
+- int smallino = !diro->inode.data.dir.dirhead.smallino;
++ struct grub_xfs_dir_header *head = grub_xfs_inode_data(&diro->inode);
++ struct grub_xfs_dir_entry *de = grub_xfs_inline_de(head);
++ int smallino = !head->largeino;
+ int i;
+ grub_uint64_t parent;
+
+ /* If small inode numbers are used to pack the direntry, the
+ parent inode number is small too. */
+ if (smallino)
+- {
+- parent = grub_be_to_cpu32 (diro->inode.data.dir.dirhead.parent.i4);
+- /* The header is a bit smaller than usual. */
+- de = (struct grub_xfs_dir_entry *) ((char *) de - 4);
+- }
++ parent = grub_be_to_cpu32 (head->parent.i4);
+ else
+- {
+- parent = grub_be_to_cpu64(diro->inode.data.dir.dirhead.parent.i8);
+- }
++ parent = grub_be_to_cpu64 (head->parent.i8);
+
+ /* Synthesize the direntries for `.' and `..'. */
+ if (iterate_dir_call_hook (diro->ino, ".", &ctx))
+@@ -526,12 +632,10 @@ grub_xfs_iterate_dir (grub_fshelp_node_t
+ if (iterate_dir_call_hook (parent, "..", &ctx))
+ return 1;
+
+- for (i = 0; i < diro->inode.data.dir.dirhead.count; i++)
++ for (i = 0; i < head->count; i++)
+ {
+ grub_uint64_t ino;
+- grub_uint8_t *inopos = (((grub_uint8_t *) de)
+- + sizeof (struct grub_xfs_dir_entry)
+- + de->len - 1);
++ grub_uint8_t *inopos = grub_xfs_inline_de_inopos(dir->data, de);
+ grub_uint8_t c;
+
+ /* inopos might be unaligned. */
+@@ -556,10 +660,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t
+ return 1;
+ de->name[de->len] = c;
+
+- de = ((struct grub_xfs_dir_entry *)
+- (((char *) de)+ sizeof (struct grub_xfs_dir_entry) + de->len
+- + ((smallino ? sizeof (grub_uint32_t)
+- : sizeof (grub_uint64_t))) - 1));
++ de = grub_xfs_inline_next_de(dir->data, head, de);
+ }
+ break;
+ }
+@@ -586,15 +687,11 @@ grub_xfs_iterate_dir (grub_fshelp_node_t
+ >> dirblk_log2);
+ blk++)
+ {
+- /* The header is skipped, the first direntry is stored
+- from byte 16. */
+- int pos = 16;
++ struct grub_xfs_dir2_entry *direntry =
++ grub_xfs_first_de(dir->data, dirblock);
+ int entries;
+- int tail_start = (dirblk_size
+- - sizeof (struct grub_xfs_dirblock_tail));
+-
+- struct grub_xfs_dirblock_tail *tail;
+- tail = (struct grub_xfs_dirblock_tail *) &dirblock[tail_start];
++ struct grub_xfs_dirblock_tail *tail =
++ grub_xfs_dir_tail(dir->data, dirblock);
+
+ numread = grub_xfs_read_file (dir, 0, 0,
+ blk << dirblk_log2,
+@@ -606,13 +703,11 @@ grub_xfs_iterate_dir (grub_fshelp_node_t
+ - grub_be_to_cpu32 (tail->leaf_stale));
+
+ /* Iterate over all entries within this block. */
+- while (pos < tail_start)
++ while ((char *)direntry < (char *)tail)
+ {
+- struct grub_xfs_dir2_entry *direntry;
+ grub_uint8_t *freetag;
+ char *filename;
+
+- direntry = (struct grub_xfs_dir2_entry *) &dirblock[pos];
+ freetag = (grub_uint8_t *) direntry;
+
+ if (grub_get_unaligned16 (freetag) == 0XFFFF)
+@@ -620,14 +715,16 @@ grub_xfs_iterate_dir (grub_fshelp_node_t
+ grub_uint8_t *skip = (freetag + sizeof (grub_uint16_t));
+
+ /* This entry is not used, go to the next one. */
+- pos += grub_be_to_cpu16 (grub_get_unaligned16 (skip));
++ direntry = (struct grub_xfs_dir2_entry *)
++ (((char *)direntry) +
++ grub_be_to_cpu16 (grub_get_unaligned16 (skip)));
+
+ continue;
+ }
+
+- filename = &dirblock[pos + sizeof (*direntry)];
+- /* The byte after the filename is for the tag, which
+- is not used by GRUB. So it can be overwritten. */
++ filename = (char *)(direntry + 1);
++ /* The byte after the filename is for the filetype, padding, or
++ tag, which is not used by GRUB. So it can be overwritten. */
+ filename[direntry->len] = '\0';
+
+ if (iterate_dir_call_hook (grub_be_to_cpu64(direntry->inode),
+@@ -644,8 +741,7 @@ grub_xfs_iterate_dir (grub_fshelp_node_t
+ break;
+
+ /* Select the next directory entry. */
+- pos = GRUB_XFS_NEXT_DIRENT (pos, direntry->len);
+- pos = GRUB_XFS_ROUND_TO_DIRENT (pos);
++ direntry = grub_xfs_next_de(dir->data, direntry);
+ }
+ }
+ grub_free (dirblock);
+@@ -670,6 +766,7 @@ grub_xfs_mount (grub_disk_t disk)
+ if (!data)
+ return 0;
+
++ grub_dprintf("xfs", "Reading sb\n");
+ /* Read the superblock. */
+ if (grub_disk_read (disk, 0, 0,
+ sizeof (struct grub_xfs_sblock), &data->sblock))
+@@ -697,9 +794,13 @@ grub_xfs_mount (grub_disk_t disk)
+ data->diropen.inode_read = 1;
+ data->bsize = grub_be_to_cpu32 (data->sblock.bsize);
+ data->agsize = grub_be_to_cpu32 (data->sblock.agsize);
++ data->hasftype = grub_xfs_sb_hasftype(data);
++ data->hascrc = grub_xfs_sb_hascrc(data);
+
+ data->disk = disk;
+ data->pos = 0;
++ grub_dprintf("xfs", "Reading root ino %llu\n",
++ (unsigned long long) grub_cpu_to_be64(data->sblock.rootino));
+
+ grub_xfs_read_inode (data, data->diropen.ino, &data->diropen.inode);
+
%define platforms %{?with_efi:efi} %{?with_pc:pc}
%endif
+%define rel 6
Summary: GRand Unified Bootloader
Summary(de.UTF-8): GRUB2 - ein Bootloader für x86
Summary(hu.UTF-8): GRUB2 - rendszerbetöltő x86 gépekhez
%define beta beta2
Name: grub2
Version: 2.02
-Release: 0.%{beta}.5
+Release: 0.%{beta}.%{rel}
License: GPL v2
Group: Base
# 1. Download and unpack latest official beta snapshot from http://git.savannah.gnu.org/cgit/grub.git
# 2. Run ./autogen.sh and ./linguas.sh
# 3. Recompress and upload to DF
Source0: grub-%{version}-%{beta}.tar.xz
-# Source0-md5: f262e61eba2e76a6f60b39a810814284
+# Source0-md5: f262e61eba2e76a6f60b39a810814284
Source1: update-grub
Source2: update-grub.8
Source3: grub.sysconfig
Patch10: ignore-kernel-symlinks.patch
Patch11: choose-preferred-initrd.patch
Patch12: %{name}-cfg.patch
+Patch13: efi-net-fix.patch
+Patch14: grub2-xfs-Add-helper-for-inode-size.patch
+Patch15: grub2-xfs-Convert-inode-numbers-to-cpu-endianity-immediate.patch
+Patch16: grub2-xfs-Fix-termination-loop-for-directory-iteration.patch
+Patch17: grub2-xfs-V5-filesystem-format-support.patch
+Patch18: blscfg.patch
URL: http://www.gnu.org/software/grub/
BuildRequires: autoconf >= 2.53
BuildRequires: automake >= 1:1.11.1-1
BuildRequires: fonts-TTF-DejaVu
BuildRequires: freetype-devel >= 2
BuildRequires: gawk
-BuildRequires: gettext-devel
+BuildRequires: gcc >= 5:3.4
+BuildRequires: gettext-tools
BuildRequires: glibc-localedb-all
BuildRequires: glibc-static
BuildRequires: help2man
BuildRequires: xz-devel
%ifarch %{x8664}
BuildRequires: /usr/lib/libc.so
-%if "%{pld_release}" == "ac"
-BuildRequires: libgcc32
-%else
BuildRequires: gcc-multilib
%endif
-%endif
Requires: %{name}-platform = %{version}-%{release}
Requires: issue
Requires: which
Motyw starfield dla GRUB-a.
%prep
-%setup -q -n grub-%{version}-%{beta}
+%setup -q -n grub-%{version}~%{beta}
%patch1 -p1
%patch2 -p1
%patch3 -p1
%patch10 -p1
%patch11 -p1
%patch12 -p0
+%patch13 -p1
+%patch14 -p1
+%patch15 -p1
+%patch16 -p1
+%patch17 -p1
+%patch18 -p1
# we don't have C.utf-8 and need an UTF-8 locale for build
sed -i -e 's/LC_ALL=C.UTF-8/LC_ALL=en_US.utf-8/g' po/Makefile* po/Rules*
# https://savannah.gnu.org/bugs/?34539
# http://sourceware.org/bugzilla/show_bug.cgi?id=14196
install -d our-ld
-ln -s /usr/bin/ld.bfd our-ld/ld
+ln -f -s /usr/bin/ld.bfd our-ld/ld
export PATH=$(pwd)/our-ld:$PATH
## not only the typicall autotools stuff
#./autogen.sh
-%{__gettextize}
+#{__gettextize}
%{__aclocal} -I m4
%{__autoconf}
%{__autoheader}
platform_opts=""
fi
- ln -s ../configure .
+ ln -f -s ../configure .
# mawk stalls at ./genmoddep.awk, so force gawk
AWK=gawk \
%configure \