Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnthony Iliopoulos <ailiopoulos@suse.com>2019-05-18 01:30:44 +0200
committerAnthony Iliopoulos <ailiopoulos@suse.com>2019-05-18 01:30:44 +0200
commitfd58dbe068841c8a13e3a12dd65d330f26ca8421 (patch)
tree8121cd30649f3c491245189f55a51132635fbbc9
parent269d9c363c2168c1f30af0f643b3cceba71e6ea3 (diff)
xfs: refactor unmount record write (bsc#1114427).
-rw-r--r--patches.fixes/xfs-refactor-unmount-record-write.patch203
-rw-r--r--series.conf1
2 files changed, 204 insertions, 0 deletions
diff --git a/patches.fixes/xfs-refactor-unmount-record-write.patch b/patches.fixes/xfs-refactor-unmount-record-write.patch
new file mode 100644
index 0000000000..6a4a6c6804
--- /dev/null
+++ b/patches.fixes/xfs-refactor-unmount-record-write.patch
@@ -0,0 +1,203 @@
+From 53235f22151ea7229e1251e46e68098bcf74922d Mon Sep 17 00:00:00 2001
+From: "Darrick J. Wong" <darrick.wong@oracle.com>
+Date: Fri, 20 Jul 2018 09:28:39 -0700
+Subject: [PATCH] xfs: refactor unmount record write
+Git-commit: 53235f22151ea7229e1251e46e68098bcf74922d
+Patch-mainline: v4.19-rc1
+References: bsc#1114427
+
+Refactor the writing of the unmount record into a separate helper. No
+functionality changes.
+
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Reviewed-by: Christoph Hellwig <hch@lst.de>
+Acked-by: Anthony Iliopoulos <ailiopoulos@suse.com>
+
+---
+ fs/xfs/libxfs/xfs_log_format.h | 13 ++++
+ fs/xfs/xfs_log.c | 131 ++++++++++++++++++++++-------------------
+ 2 files changed, 82 insertions(+), 62 deletions(-)
+
+diff --git a/fs/xfs/libxfs/xfs_log_format.h b/fs/xfs/libxfs/xfs_log_format.h
+index 79bb79853c9f..e5f97c69b320 100644
+--- a/fs/xfs/libxfs/xfs_log_format.h
++++ b/fs/xfs/libxfs/xfs_log_format.h
+@@ -77,6 +77,19 @@ static inline uint xlog_get_cycle(char *ptr)
+
+ #define XLOG_UNMOUNT_TYPE 0x556e /* Un for Unmount */
+
++/*
++ * Log item for unmount records.
++ *
++ * The unmount record used to have a string "Unmount filesystem--" in the
++ * data section where the "Un" was really a magic number (XLOG_UNMOUNT_TYPE).
++ * We just write the magic number now; see xfs_log_unmount_write.
++ */
++struct xfs_unmount_log_format {
++ uint16_t magic; /* XLOG_UNMOUNT_TYPE */
++ uint16_t pad1;
++ uint32_t pad2; /* may as well make it 64 bits */
++};
++
+ /* Region types for iovec's i_type */
+ #define XLOG_REG_TYPE_BFORMAT 1
+ #define XLOG_REG_TYPE_BCHUNK 2
+diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
+index 5e56f3b93d4b..bac586cbc54e 100644
+--- a/fs/xfs/xfs_log.c
++++ b/fs/xfs/xfs_log.c
+@@ -826,6 +826,74 @@ xfs_log_mount_cancel(
+ * deallocation must not be done until source-end.
+ */
+
++/* Actually write the unmount record to disk. */
++static void
++xfs_log_write_unmount_record(
++ struct xfs_mount *mp)
++{
++ /* the data section must be 32 bit size aligned */
++ struct xfs_unmount_log_format magic = {
++ .magic = XLOG_UNMOUNT_TYPE,
++ };
++ struct xfs_log_iovec reg = {
++ .i_addr = &magic,
++ .i_len = sizeof(magic),
++ .i_type = XLOG_REG_TYPE_UNMOUNT,
++ };
++ struct xfs_log_vec vec = {
++ .lv_niovecs = 1,
++ .lv_iovecp = &reg,
++ };
++ struct xlog *log = mp->m_log;
++ struct xlog_in_core *iclog;
++ struct xlog_ticket *tic = NULL;
++ xfs_lsn_t lsn;
++ int error;
++
++ error = xfs_log_reserve(mp, 600, 1, &tic, XFS_LOG, 0);
++ if (error)
++ goto out_err;
++
++ /* remove inited flag, and account for space used */
++ tic->t_flags = 0;
++ tic->t_curr_res -= sizeof(magic);
++ error = xlog_write(log, &vec, tic, &lsn, NULL, XLOG_UNMOUNT_TRANS);
++ /*
++ * At this point, we're umounting anyway, so there's no point in
++ * transitioning log state to IOERROR. Just continue...
++ */
++out_err:
++ if (error)
++ xfs_alert(mp, "%s: unmount record failed", __func__);
++
++ spin_lock(&log->l_icloglock);
++ iclog = log->l_iclog;
++ atomic_inc(&iclog->ic_refcnt);
++ xlog_state_want_sync(log, iclog);
++ spin_unlock(&log->l_icloglock);
++ error = xlog_state_release_iclog(log, iclog);
++
++ spin_lock(&log->l_icloglock);
++ switch (iclog->ic_state) {
++ default:
++ if (!XLOG_FORCED_SHUTDOWN(log)) {
++ xlog_wait(&iclog->ic_force_wait, &log->l_icloglock);
++ break;
++ }
++ /* fall through */
++ case XLOG_STATE_ACTIVE:
++ case XLOG_STATE_DIRTY:
++ spin_unlock(&log->l_icloglock);
++ break;
++ }
++
++ if (tic) {
++ trace_xfs_log_umount_write(log, tic);
++ xlog_ungrant_log_space(log, tic);
++ xfs_log_ticket_put(tic);
++ }
++}
++
+ /*
+ * Unmount record used to have a string "Unmount filesystem--" in the
+ * data section where the "Un" was really a magic number (XLOG_UNMOUNT_TYPE).
+@@ -842,8 +910,6 @@ xfs_log_unmount_write(xfs_mount_t *mp)
+ #ifdef DEBUG
+ xlog_in_core_t *first_iclog;
+ #endif
+- xlog_ticket_t *tic = NULL;
+- xfs_lsn_t lsn;
+ int error;
+
+ /*
+@@ -870,66 +936,7 @@ xfs_log_unmount_write(xfs_mount_t *mp)
+ } while (iclog != first_iclog);
+ #endif
+ if (! (XLOG_FORCED_SHUTDOWN(log))) {
+- error = xfs_log_reserve(mp, 600, 1, &tic, XFS_LOG, 0);
+- if (!error) {
+- /* the data section must be 32 bit size aligned */
+- struct {
+- uint16_t magic;
+- uint16_t pad1;
+- uint32_t pad2; /* may as well make it 64 bits */
+- } magic = {
+- .magic = XLOG_UNMOUNT_TYPE,
+- };
+- struct xfs_log_iovec reg = {
+- .i_addr = &magic,
+- .i_len = sizeof(magic),
+- .i_type = XLOG_REG_TYPE_UNMOUNT,
+- };
+- struct xfs_log_vec vec = {
+- .lv_niovecs = 1,
+- .lv_iovecp = &reg,
+- };
+-
+- /* remove inited flag, and account for space used */
+- tic->t_flags = 0;
+- tic->t_curr_res -= sizeof(magic);
+- error = xlog_write(log, &vec, tic, &lsn,
+- NULL, XLOG_UNMOUNT_TRANS);
+- /*
+- * At this point, we're umounting anyway,
+- * so there's no point in transitioning log state
+- * to IOERROR. Just continue...
+- */
+- }
+-
+- if (error)
+- xfs_alert(mp, "%s: unmount record failed", __func__);
+-
+-
+- spin_lock(&log->l_icloglock);
+- iclog = log->l_iclog;
+- atomic_inc(&iclog->ic_refcnt);
+- xlog_state_want_sync(log, iclog);
+- spin_unlock(&log->l_icloglock);
+- error = xlog_state_release_iclog(log, iclog);
+-
+- spin_lock(&log->l_icloglock);
+- if (!(iclog->ic_state == XLOG_STATE_ACTIVE ||
+- iclog->ic_state == XLOG_STATE_DIRTY)) {
+- if (!XLOG_FORCED_SHUTDOWN(log)) {
+- xlog_wait(&iclog->ic_force_wait,
+- &log->l_icloglock);
+- } else {
+- spin_unlock(&log->l_icloglock);
+- }
+- } else {
+- spin_unlock(&log->l_icloglock);
+- }
+- if (tic) {
+- trace_xfs_log_umount_write(log, tic);
+- xlog_ungrant_log_space(log, tic);
+- xfs_log_ticket_put(tic);
+- }
++ xfs_log_write_unmount_record(mp);
+ } else {
+ /*
+ * We're already in forced_shutdown mode, couldn't
+--
+2.16.4
+
diff --git a/series.conf b/series.conf
index b74cde713b..950cc2b34a 100644
--- a/series.conf
+++ b/series.conf
@@ -18056,6 +18056,7 @@
patches.fixes/ext4-check-for-NUL-characters-in-extended-attribute-.patch
patches.fixes/ext4-fix-spectre-gadget-in-ext4_mb_regular_allocator.patch
patches.fixes/xfs-detect-and-fix-bad-summary-counts-at-mount.patch
+ patches.fixes/xfs-refactor-unmount-record-write.patch
patches.suse/xfs-fix-a-null-pointer-dereference-in-xfs_bmap_exten.patch
patches.arch/x86-l1tf-01-increase-32bitPAE-__PHYSICAL_PAGE_MASK.patch
patches.arch/x86-l1tf-02-change-order-of-offset-type.patch