- add FIEMAP support into zipl
This commit is contained in:
parent
4b248d8445
commit
7ffae6dc71
106
s390-tools-zipl-fiemap.patch
Normal file
106
s390-tools-zipl-fiemap.patch
Normal 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;
|
@ -5,7 +5,7 @@ Name: s390utils
|
||||
Summary: Utilities and daemons for IBM z Systems
|
||||
Group: System Environment/Base
|
||||
Version: 2.6.0
|
||||
Release: 2%{?dist}
|
||||
Release: 3%{?dist}
|
||||
Epoch: 2
|
||||
License: MIT
|
||||
ExclusiveArch: s390 s390x
|
||||
@ -31,6 +31,8 @@ Source24: 91-zipl.install
|
||||
|
||||
# change the defaults to match Fedora environment
|
||||
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
|
||||
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
|
||||
%patch0 -p1 -b .zipl-invert-script-options
|
||||
%patch1 -p0 -b .zipl-fiemap
|
||||
|
||||
#
|
||||
# cmsfs
|
||||
@ -814,6 +817,9 @@ User-space development files for the s390/s390x architecture.
|
||||
|
||||
|
||||
%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
|
||||
- fix R:/BR: perl
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user