- add FIEMAP support into zipl

This commit is contained in:
Dan Horák 2018-09-14 16:06:45 +02:00
parent 4b248d8445
commit 7ffae6dc71
2 changed files with 113 additions and 1 deletions

View File

@ -0,0 +1,106 @@
From 0318dfbc726a82ce1e9309e55186f3c4faae72f1 Mon Sep 17 00:00:00 2001
From: Eric Sandeen <sandeen@sandeen.net>
Date: Wed, 12 Sep 2018 09:40:22 -0500
Subject: [PATCH] zipl: use FIEMAP mapping ioctl if it exists
zipl currently uses the FIBMAP ioctl to map blocks for the bootloader;
on XFS, if FIBMAP is requested on a reflinked file, it will fail -
and FIBMAP returns 0 in this case, which is indistinguishable from a
hole. This causes boot to fail because the file is not mapped.
We can use the FIEMAP ioctl instead, which is able to map reflinked
files. While FIEMAP is able to map entire extents at once, here we
simply use it to obtain the mapping block-by-block so that it fits
in with the current FIBMAP calls.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---
zipl/src/disk.c | 57 +++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 53 insertions(+), 4 deletions(-)
diff --git a/zipl/src/disk.c b/zipl/src/disk.c
index 0d8e7796..43092bf1 100644
--- a/zipl/src/disk.c
+++ b/zipl/src/disk.c
@@ -21,6 +21,8 @@
#include <sys/sysmacros.h>
#include <sys/vfs.h>
#include <unistd.h>
+#include <linux/fs.h>
+#include <linux/fiemap.h>
#include "lib/util_proc.h"
@@ -550,8 +552,12 @@ disk_get_blocknum(int fd, int fd_is_basedisk, blocknum_t logical,
{
struct statfs buf;
blocknum_t phy_per_fs;
- int mapped;
+ blocknum_t mapped;
+ int block;
int subblock;
+ int fiemap_size;
+ int map_offset;
+ struct fiemap *fiemap;
/* No file system: partition or raw disk */
if (info->fs_block_size == -1) {
@@ -576,12 +582,55 @@ disk_get_blocknum(int fd, int fd_is_basedisk, blocknum_t logical,
}
/* Get mapping in file system blocks */
phy_per_fs = info->fs_block_size / info->phy_block_size;
- mapped = logical / phy_per_fs;
subblock = logical % phy_per_fs;
- if (ioctl(fd, FIBMAP, &mapped)) {
- error_reason("Could not get file mapping");
+
+ /* First try FIEMAP, more complicated to set up */
+ fiemap_size = sizeof(struct fiemap) + sizeof(struct fiemap_extent);
+
+ fiemap = misc_malloc(fiemap_size);
+ if (!fiemap)
return -1;
+ memset(fiemap, 0, fiemap_size);
+
+ fiemap->fm_extent_count = 1;
+ fiemap->fm_flags = FIEMAP_FLAG_SYNC;
+ /* fm_start, fm_length in bytes; logical is in physical block units */
+ fiemap->fm_start = logical * info->phy_block_size;
+ fiemap->fm_length = info->phy_block_size;
+
+ if (ioctl(fd, FS_IOC_FIEMAP, (unsigned long)fiemap)) {
+ /* FIEMAP failed, fall back to FIBMAP */
+ block = logical / phy_per_fs;
+ if (ioctl(fd, FIBMAP, &block)) {
+ error_reason("Could not get file mapping");
+ free(fiemap);
+ return -1;
+ }
+ mapped = block;
+ } else {
+ if (fiemap->fm_mapped_extents) {
+ if (fiemap->fm_extents[0].fe_flags &
+ FIEMAP_EXTENT_ENCODED) {
+ error_reason("File mapping is encoded");
+ free(fiemap);
+ return -1;
+ }
+ /*
+ * returned extent may start prior to our request
+ */
+ map_offset = fiemap->fm_start -
+ fiemap->fm_extents[0].fe_logical;
+ mapped = fiemap->fm_extents[0].fe_physical +
+ map_offset;
+ /* set mapped to fs block units */
+ mapped = mapped / info->fs_block_size;
+ } else {
+ mapped = 0;
+ }
}
+
+ free(fiemap);
+
if (mapped == 0) {
/* This is a hole in the file */
*physical = 0;

View File

@ -5,7 +5,7 @@ Name: s390utils
Summary: Utilities and daemons for IBM z Systems Summary: Utilities and daemons for IBM z Systems
Group: System Environment/Base Group: System Environment/Base
Version: 2.6.0 Version: 2.6.0
Release: 2%{?dist} Release: 3%{?dist}
Epoch: 2 Epoch: 2
License: MIT License: MIT
ExclusiveArch: s390 s390x ExclusiveArch: s390 s390x
@ -31,6 +31,8 @@ Source24: 91-zipl.install
# change the defaults to match Fedora environment # change the defaults to match Fedora environment
Patch0: s390-tools-zipl-invert-script-options.patch Patch0: s390-tools-zipl-invert-script-options.patch
# https://github.com/ibm-s390-tools/s390-tools/pull/36
Patch1: s390-tools-zipl-fiemap.patch
Patch1000: cmsfs-1.1.8-warnings.patch Patch1000: cmsfs-1.1.8-warnings.patch
Patch1001: cmsfs-1.1.8-kernel26.patch Patch1001: cmsfs-1.1.8-kernel26.patch
@ -59,6 +61,7 @@ be used together with the zSeries (s390) Linux kernel and device drivers.
# Fedora/RHEL changes # Fedora/RHEL changes
%patch0 -p1 -b .zipl-invert-script-options %patch0 -p1 -b .zipl-invert-script-options
%patch1 -p0 -b .zipl-fiemap
# #
# cmsfs # cmsfs
@ -814,6 +817,9 @@ User-space development files for the s390/s390x architecture.
%changelog %changelog
* Fri Sep 14 2018 Dan Horák <dan[at]danny.cz> - 2:2.6.0-3
- add FIEMAP support into zipl
* Tue Aug 14 2018 Dan Horák <dan[at]danny.cz> - 2:2.6.0-2 * Tue Aug 14 2018 Dan Horák <dan[at]danny.cz> - 2:2.6.0-2
- fix R:/BR: perl - fix R:/BR: perl