Home Home > GIT Browse > openSUSE-15.1
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2019-08-15 13:05:54 +0200
committerTakashi Iwai <tiwai@suse.de>2019-08-15 13:05:54 +0200
commit1c726d3fa7197474a18ab7fa8f4eec8862293cbc (patch)
treedf51110373407de955443b2b772f58a6cb1c2bd2
parentff722c49f36a22e81e8ae3ed4aae3f379174b568 (diff)
parentacbefc7076e520f0fdf24563b3f9fc8c9635db05 (diff)
Merge branch 'users/nborisov/SLE15/for-next' into SLE15
Pull xfs fixes from Nikolay Borisov
-rw-r--r--patches.suse/xfs-dump-transaction-usage-details-on-log-reservation-overrun.patch162
-rw-r--r--patches.suse/xfs-eliminate-duplicate-icreate-tx-reservation-functions.patch143
-rw-r--r--patches.suse/xfs-fix-semicolon-cocci-warnings.patch39
-rw-r--r--patches.suse/xfs-fix-up-agi-unlinked-list-reservations.patch62
-rw-r--r--patches.suse/xfs-include-an-allocfree-res-for-inobt-modifications.patch214
-rw-r--r--patches.suse/xfs-include-inobt-buffers-in-ifree-tx-log-reservation.patch84
-rw-r--r--patches.suse/xfs-print-transaction-log-reservation-on-overrun.patch47
-rw-r--r--patches.suse/xfs-refactor-inode-chunk-alloc-free-tx-reservation.patch169
-rw-r--r--patches.suse/xfs-refactor-xlog_cil_insert_items-to-facilitate-transaction-dump.patch134
-rw-r--r--patches.suse/xfs-separate-shutdown-from-ticket-reservation-print-helper.patch81
-rw-r--r--patches.suse/xfs-truncate-transaction-does-not-modify-the-inobt.patch49
-rw-r--r--series.conf11
12 files changed, 1195 insertions, 0 deletions
diff --git a/patches.suse/xfs-dump-transaction-usage-details-on-log-reservation-overrun.patch b/patches.suse/xfs-dump-transaction-usage-details-on-log-reservation-overrun.patch
new file mode 100644
index 0000000000..e0e3d666fd
--- /dev/null
+++ b/patches.suse/xfs-dump-transaction-usage-details-on-log-reservation-overrun.patch
@@ -0,0 +1,162 @@
+From: Brian Foster <bfoster@redhat.com>
+Date: Wed, 14 Jun 2017 21:29:50 -0700
+Subject: xfs: dump transaction usage details on log reservation overrun
+Git-commit: d4ca1d550d052accec85ae26ac5b9d3d8b8f81f1
+Patch-mainline: v4.13-rc1
+References: bsc#1145235
+
+If a transaction log reservation overrun occurs, the ticket data
+associated with the reservation is dumped in xfs_log_commit_cil().
+This occurs long after the transaction items and details have been
+removed from the transaction and effectively lost. This limited set
+of ticket data provides very little information to support debugging
+transaction overruns based on the typical report.
+
+To improve transaction log reservation overrun reporting, create a
+helper to dump transaction details such as log items, log vector
+data, etc., as well as the underlying ticket data for the
+transaction. Move the overrun detection from xfs_log_commit_cil() to
+xlog_cil_insert_items() so it occurs prior to migration of the
+logged items to the CIL. Call the new helper such that it is able to
+dump this transaction data before it is lost.
+
+Also, warn on overrun to provide callstack context for the offending
+transaction and include a few additional messages from
+xlog_cil_insert_items() to display the reservation consumed locally
+for overhead such as log vector headers, split region headers and
+the context ticket. This provides a complete general breakdown of
+the reservation consumption of a transaction when/if it happens to
+overrun the reservation.
+
+Signed-off-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Nikolay Borisov <nborisov@suse.com>
+---
+ fs/xfs/xfs_log.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
+ fs/xfs/xfs_log_cil.c | 24 ++++++++++++++++++------
+ fs/xfs/xfs_log_priv.h | 1 +
+ 3 files changed, 68 insertions(+), 6 deletions(-)
+
+diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
+index 8b283f7cefea..c8d048103347 100644
+--- a/fs/xfs/xfs_log.c
++++ b/fs/xfs/xfs_log.c
+@@ -2047,6 +2047,55 @@ xlog_print_tic_res(
+ }
+ }
+
++/*
++ * Print a summary of the transaction.
++ */
++void
++xlog_print_trans(
++ struct xfs_trans *tp)
++{
++ struct xfs_mount *mp = tp->t_mountp;
++ struct xfs_log_item_desc *lidp;
++
++ /* dump core transaction and ticket info */
++ xfs_warn(mp, "transaction summary:");
++ xfs_warn(mp, " flags = 0x%x", tp->t_flags);
++
++ xlog_print_tic_res(mp, tp->t_ticket);
++
++ /* dump each log item */
++ list_for_each_entry(lidp, &tp->t_items, lid_trans) {
++ struct xfs_log_item *lip = lidp->lid_item;
++ struct xfs_log_vec *lv = lip->li_lv;
++ struct xfs_log_iovec *vec;
++ int i;
++
++ xfs_warn(mp, "log item: ");
++ xfs_warn(mp, " type = 0x%x", lip->li_type);
++ xfs_warn(mp, " flags = 0x%x", lip->li_flags);
++ if (!lv)
++ continue;
++ xfs_warn(mp, " niovecs = %d", lv->lv_niovecs);
++ xfs_warn(mp, " size = %d", lv->lv_size);
++ xfs_warn(mp, " bytes = %d", lv->lv_bytes);
++ xfs_warn(mp, " buf len = %d", lv->lv_buf_len);
++
++ /* dump each iovec for the log item */
++ vec = lv->lv_iovecp;
++ for (i = 0; i < lv->lv_niovecs; i++) {
++ int dumplen = min(vec->i_len, 32);
++
++ xfs_warn(mp, " iovec[%d]", i);
++ xfs_warn(mp, " type = 0x%x", vec->i_type);
++ xfs_warn(mp, " len = %d", vec->i_len);
++ xfs_warn(mp, " first %d bytes of iovec[%d]:", dumplen, i);
++ xfs_hex_dump(vec->i_addr, dumplen);;
++
++ vec++;
++ }
++ }
++}
++
+ /*
+ * Calculate the potential space needed by the log vector. Each region gets
+ * its own xlog_op_header_t and may need to be double word aligned.
+diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c
+index 8de3baa7d3f0..04b389210cc7 100644
+--- a/fs/xfs/xfs_log_cil.c
++++ b/fs/xfs/xfs_log_cil.c
+@@ -459,6 +459,21 @@ xlog_cil_insert_items(
+ tp->t_ticket->t_curr_res -= len;
+ ctx->space_used += len;
+
++ /*
++ * If we've overrun the reservation, dump the tx details before we move
++ * the log items. Shutdown is imminent...
++ */
++ if (WARN_ON(tp->t_ticket->t_curr_res < 0)) {
++ xfs_warn(log->l_mp, "Transaction log reservation overrun:");
++ xfs_warn(log->l_mp,
++ " log items: %d bytes (iov hdrs: %d bytes)",
++ len, iovhdr_res);
++ xfs_warn(log->l_mp, " split region headers: %d bytes",
++ split_res);
++ xfs_warn(log->l_mp, " ctx ticket: %d bytes", ctx_res);
++ xlog_print_trans(tp);
++ }
++
+ /*
+ * Now (re-)position everything modified at the tail of the CIL.
+ * We do this here so we only need to take the CIL lock once during
+@@ -481,6 +496,9 @@ xlog_cil_insert_items(
+ }
+
+ spin_unlock(&cil->xc_cil_lock);
++
++ if (tp->t_ticket->t_curr_res < 0)
++ xfs_force_shutdown(log->l_mp, SHUTDOWN_LOG_IO_ERROR);
+ }
+
+ static void
+@@ -988,12 +1006,6 @@ xfs_log_commit_cil(
+
+ xlog_cil_insert_items(log, tp);
+
+- /* check we didn't blow the reservation */
+- if (tp->t_ticket->t_curr_res < 0) {
+- xlog_print_tic_res(mp, tp->t_ticket);
+- xfs_force_shutdown(log->l_mp, SHUTDOWN_LOG_IO_ERROR);
+- }
+-
+ tp->t_commit_lsn = cil->xc_ctx->sequence;
+ if (commit_lsn)
+ *commit_lsn = tp->t_commit_lsn;
+diff --git a/fs/xfs/xfs_log_priv.h b/fs/xfs/xfs_log_priv.h
+index c2604a5366f2..62113a5d2504 100644
+--- a/fs/xfs/xfs_log_priv.h
++++ b/fs/xfs/xfs_log_priv.h
+@@ -456,6 +456,7 @@ xlog_write_adv_cnt(void **ptr, int *len, int *off, size_t bytes)
+ }
+
+ void xlog_print_tic_res(struct xfs_mount *mp, struct xlog_ticket *ticket);
++void xlog_print_trans(struct xfs_trans *);
+ int
+ xlog_write(
+ struct xlog *log,
+
diff --git a/patches.suse/xfs-eliminate-duplicate-icreate-tx-reservation-functions.patch b/patches.suse/xfs-eliminate-duplicate-icreate-tx-reservation-functions.patch
new file mode 100644
index 0000000000..281d636218
--- /dev/null
+++ b/patches.suse/xfs-eliminate-duplicate-icreate-tx-reservation-functions.patch
@@ -0,0 +1,143 @@
+From: Brian Foster <bfoster@redhat.com>
+Date: Mon, 8 Jan 2018 10:41:38 -0800
+Subject: xfs: eliminate duplicate icreate tx reservation functions
+Git-commit: c017cb5ddfd6326032570d5eba83308c8a9c13a9
+Patch-mainline: v4.16-rc1
+References: bsc#1145235
+
+The create transaction reservation calculation has two different
+branches of code depending on whether the filesystem is a v5 format
+fs or older. Each branch considers the max reservation between the
+allocation case (new chunk allocation + record insert) and the
+modify case (chunk exists, record modification) of inode allocation.
+
+The modify case is the same for both superblock versions with the
+exception of the finobt. The finobt helper checks the feature bit,
+however, and so the modify case already shares the same code.
+
+Now that inode chunk allocation has been refactored into a helper
+that checks the superblock version to calculate the appropriate
+reservation for the create transaction, the only remaining
+difference between the create and icreate branches is the call to
+the finobt helper. As noted above, the finobt helper is a no-op when
+the feature is not enabled. Therefore, these branches are
+effectively duplicate and can be condensed.
+
+Remove the xfs_calc_create_*() branch of functions and update the
+various callers to use the xfs_calc_icreate_*() variant. The latter
+creates the same reservation size for v4 create transactions as the
+removed branch. As such, this patch does not result in transaction
+reservation changes.
+
+Signed-off-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Dave Chinner <dchinner@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Nikolay Borisov <nborisov@suse.com>
+---
+ fs/xfs/libxfs/xfs_trans_resv.c | 52 +++++-------------------------------------
+ 1 file changed, 6 insertions(+), 46 deletions(-)
+
+diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c
+index 75259a1346eb..5f17641f040f 100644
+--- a/fs/xfs/libxfs/xfs_trans_resv.c
++++ b/fs/xfs/libxfs/xfs_trans_resv.c
+@@ -413,39 +413,13 @@ xfs_calc_create_resv_modify(
+ xfs_calc_finobt_res(mp);
+ }
+
+-/*
+- * For create we can allocate some inodes giving:
+- * the agi and agf of the ag getting the new inodes: 2 * sectorsize
+- * the superblock for the nlink flag: sector size
+- * the inode chunk (allocation/init)
+- * the inode btree (record insertion)
+- */
+-STATIC uint
+-xfs_calc_create_resv_alloc(
+- struct xfs_mount *mp)
+-{
+- return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
+- mp->m_sb.sb_sectsize +
+- xfs_calc_inode_chunk_res(mp, _ALLOC) +
+- xfs_calc_inobt_res(mp);
+-}
+-
+-STATIC uint
+-__xfs_calc_create_reservation(
+- struct xfs_mount *mp)
+-{
+- return XFS_DQUOT_LOGRES(mp) +
+- MAX(xfs_calc_create_resv_alloc(mp),
+- xfs_calc_create_resv_modify(mp));
+-}
+-
+ /*
+ * For icreate we can allocate some inodes giving:
+ * the agi and agf of the ag getting the new inodes: 2 * sectorsize
+ * the superblock for the nlink flag: sector size
+- * the inode chunk (allocation, no init)
++ * the inode chunk (allocation, optional init)
+ * the inobt (record insertion)
+- * the finobt (record insertion)
++ * the finobt (optional, record insertion)
+ */
+ STATIC uint
+ xfs_calc_icreate_resv_alloc(
+@@ -466,27 +440,13 @@ xfs_calc_icreate_reservation(xfs_mount_t *mp)
+ xfs_calc_create_resv_modify(mp));
+ }
+
+-STATIC uint
+-xfs_calc_create_reservation(
+- struct xfs_mount *mp)
+-{
+- if (xfs_sb_version_hascrc(&mp->m_sb))
+- return xfs_calc_icreate_reservation(mp);
+- return __xfs_calc_create_reservation(mp);
+-
+-}
+-
+ STATIC uint
+ xfs_calc_create_tmpfile_reservation(
+ struct xfs_mount *mp)
+ {
+ uint res = XFS_DQUOT_LOGRES(mp);
+
+- if (xfs_sb_version_hascrc(&mp->m_sb))
+- res += xfs_calc_icreate_resv_alloc(mp);
+- else
+- res += xfs_calc_create_resv_alloc(mp);
+-
++ res += xfs_calc_icreate_resv_alloc(mp);
+ return res + xfs_calc_iunlink_add_reservation(mp);
+ }
+
+@@ -497,7 +457,7 @@ STATIC uint
+ xfs_calc_mkdir_reservation(
+ struct xfs_mount *mp)
+ {
+- return xfs_calc_create_reservation(mp);
++ return xfs_calc_icreate_reservation(mp);
+ }
+
+
+@@ -510,7 +470,7 @@ STATIC uint
+ xfs_calc_symlink_reservation(
+ struct xfs_mount *mp)
+ {
+- return xfs_calc_create_reservation(mp) +
++ return xfs_calc_icreate_reservation(mp) +
+ xfs_calc_buf_res(1, XFS_SYMLINK_MAXLEN);
+ }
+
+@@ -869,7 +829,7 @@ xfs_trans_resv_calc(
+ resp->tr_symlink.tr_logcount = XFS_SYMLINK_LOG_COUNT;
+ resp->tr_symlink.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
+
+- resp->tr_create.tr_logres = xfs_calc_create_reservation(mp);
++ resp->tr_create.tr_logres = xfs_calc_icreate_reservation(mp);
+ resp->tr_create.tr_logcount = XFS_CREATE_LOG_COUNT;
+ resp->tr_create.tr_logflags |= XFS_TRANS_PERM_LOG_RES;
+
+
diff --git a/patches.suse/xfs-fix-semicolon-cocci-warnings.patch b/patches.suse/xfs-fix-semicolon-cocci-warnings.patch
new file mode 100644
index 0000000000..585d5c3390
--- /dev/null
+++ b/patches.suse/xfs-fix-semicolon-cocci-warnings.patch
@@ -0,0 +1,39 @@
+From: kbuild test robot <fengguang.wu@intel.com>
+Date: Mon, 26 Jun 2017 08:54:16 -0700
+Subject: xfs: fix semicolon.cocci warnings
+Git-commit: 244e3dea58818e9520bf3dbaf4404a60b105bfb1
+Patch-mainline: v4.13-rc1
+References: bsc#1145235
+
+fs/xfs/xfs_log.c:2092:38-39: Unneeded semicolon
+
+
+ Remove unneeded semicolon.
+
+Generated by: scripts/coccinelle/misc/semicolon.cocci
+
+Fixes: d4ca1d550d05 ("xfs: dump transaction usage details on log reservation overrun")
+CC: Brian Foster <bfoster@redhat.com>
+Signed-off-by: Fengguang Wu <fengguang.wu@intel.com>
+Reviewed-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Nikolay Borisov <nborisov@suse.com>
+---
+ fs/xfs/xfs_log.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
+index 31f11be42f01..0053bcf2b10a 100644
+--- a/fs/xfs/xfs_log.c
++++ b/fs/xfs/xfs_log.c
+@@ -2085,7 +2085,7 @@ xlog_print_trans(
+ xfs_warn(mp, " type = 0x%x", vec->i_type);
+ xfs_warn(mp, " len = %d", vec->i_len);
+ xfs_warn(mp, " first %d bytes of iovec[%d]:", dumplen, i);
+- xfs_hex_dump(vec->i_addr, dumplen);;
++ xfs_hex_dump(vec->i_addr, dumplen);
+
+ vec++;
+ }
+
diff --git a/patches.suse/xfs-fix-up-agi-unlinked-list-reservations.patch b/patches.suse/xfs-fix-up-agi-unlinked-list-reservations.patch
new file mode 100644
index 0000000000..48e787add4
--- /dev/null
+++ b/patches.suse/xfs-fix-up-agi-unlinked-list-reservations.patch
@@ -0,0 +1,62 @@
+From: Brian Foster <bfoster@redhat.com>
+Date: Mon, 8 Jan 2018 10:41:36 -0800
+Subject: xfs: fix up agi unlinked list reservations
+Git-commit: e8341d9f6348640dff01d8c4a33695dc82bab5a3
+Patch-mainline: v4.16-rc1
+References: bsc#1145235
+
+The current AGI unlinked list addition and removal reservations do
+not reflect the worst case log usage. An unlinked list removal can
+log up to two on-disk inode clusters but only includes reservation
+for one. An unlinked list addition logs the on-disk cluster but
+includes reservation for an in-core inode.
+
+Update the AGI unlinked list reservation helpers to calculate the
+correct worst case reservation for the associated operations.
+
+Signed-off-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Dave Chinner <dchinner@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Nikolay Borisov <nborisov@suse.com>
+---
+ fs/xfs/libxfs/xfs_trans_resv.c | 7 ++++---
+ 1 file changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c
+index 838566b85622..173b1bc13ffe 100644
+--- a/fs/xfs/libxfs/xfs_trans_resv.c
++++ b/fs/xfs/libxfs/xfs_trans_resv.c
+@@ -282,13 +282,14 @@ xfs_calc_rename_reservation(
+ * For removing an inode from unlinked list at first, we can modify:
+ * the agi hash list and counters: sector size
+ * the on disk inode before ours in the agi hash list: inode cluster size
++ * the on disk inode in the agi hash list: inode cluster size
+ */
+ STATIC uint
+ xfs_calc_iunlink_remove_reservation(
+ struct xfs_mount *mp)
+ {
+ return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
+- max_t(uint, XFS_FSB_TO_B(mp, 1), mp->m_inode_cluster_size);
++ 2 * max_t(uint, XFS_FSB_TO_B(mp, 1), mp->m_inode_cluster_size);
+ }
+
+ /*
+@@ -320,13 +321,13 @@ xfs_calc_link_reservation(
+ /*
+ * For adding an inode to unlinked list we can modify:
+ * the agi hash list: sector size
+- * the unlinked inode: inode size
++ * the on disk inode: inode cluster size
+ */
+ STATIC uint
+ xfs_calc_iunlink_add_reservation(xfs_mount_t *mp)
+ {
+ return xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
+- xfs_calc_inode_res(mp, 1);
++ max_t(uint, XFS_FSB_TO_B(mp, 1), mp->m_inode_cluster_size);
+ }
+
+ /*
+
diff --git a/patches.suse/xfs-include-an-allocfree-res-for-inobt-modifications.patch b/patches.suse/xfs-include-an-allocfree-res-for-inobt-modifications.patch
new file mode 100644
index 0000000000..9475c7b1b6
--- /dev/null
+++ b/patches.suse/xfs-include-an-allocfree-res-for-inobt-modifications.patch
@@ -0,0 +1,214 @@
+From: Brian Foster <bfoster@redhat.com>
+Date: Mon, 8 Jan 2018 10:41:37 -0800
+Subject: xfs: include an allocfree res for inobt modifications
+Git-commit: f03c78f39710995d2766236f229295d91b8de9dd
+Patch-mainline: v4.16-rc1
+References: bsc#1145235
+
+Analysis of recent reports of log reservation overruns and code
+inspection has uncovered that the reservations associated with inode
+operations may not cover the worst case scenarios. In particular,
+many cases only include one allocfree res. for a particular
+operation even though said operations may also entail AGFL fixups
+and inode btree block allocations in addition to the actual inode
+chunk allocation. This can easily turn into two or three block
+allocations (or frees) per operation.
+
+In theory, the only way to define the worst case reservation is to
+include an allocfree res for each individual allocation in a
+transaction. Since that is impractical (we can perform multiple agfl
+fixups per tx and not every allocation results in a full tree
+operation), we need to find a reasonable compromise that addresses
+the deficiency in practice without blowing out the size of the
+transactions.
+
+Since the inode btrees are not filled by the AGFL, record insertion
+and removal can directly result in block allocations and frees
+depending on the shape of the tree. These allocations and frees
+occur in the same transaction context as the inobt update itself,
+but are separate from the allocation/free that might be required for
+an inode chunk. Therefore, it makes sense to assume that an [f]inobt
+insert/remove can directly result in one or more block allocations
+on behalf of the tree.
+
+Refactor the inode transaction reservations to include one allocfree
+res. per inode btree modification to cover allocations required by
+the tree itself. This separates the reservation required to allocate
+the inode chunk from the reservation required for inobt record
+insertion/removal. Apply the same logic to the finobt. This results
+in killing off the finobt modify condition because we no longer
+assume that the broader transaction reservation will cover finobt
+block allocations and finobt shape changes can occur in either of
+the inobt allocation or modify situations.
+
+Suggested-by: Dave Chinner <david@fromorbit.com>
+Signed-off-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Dave Chinner <dchinner@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Nikolay Borisov <nborisov@suse.com>
+---
+ fs/xfs/libxfs/xfs_trans_resv.c | 84 +++++++++++++++++++++---------------------
+ 1 file changed, 43 insertions(+), 41 deletions(-)
+
+diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c
+index 037a1295d289..19f3a226a357 100644
+--- a/fs/xfs/libxfs/xfs_trans_resv.c
++++ b/fs/xfs/libxfs/xfs_trans_resv.c
+@@ -132,44 +132,43 @@ xfs_calc_inode_res(
+ }
+
+ /*
+- * The free inode btree is a conditional feature and the log reservation
+- * requirements differ slightly from that of the traditional inode allocation
+- * btree. The finobt tracks records for inode chunks with at least one free
+- * inode. A record can be removed from the tree for an inode allocation
+- * or free and thus the finobt reservation is unconditional across:
++ * Inode btree record insertion/removal modifies the inode btree and free space
++ * btrees (since the inobt does not use the agfl). This requires the following
++ * reservation:
+ *
+- * - inode allocation
+- * - inode free
+- * - inode chunk allocation
++ * the inode btree: max depth * blocksize
++ * the allocation btrees: 2 trees * (max depth - 1) * block size
+ *
+- * The 'modify' param indicates to include the record modification scenario. The
+- * 'alloc' param indicates to include the reservation for free space btree
+- * modifications on behalf of finobt modifications. This is required only for
+- * transactions that do not already account for free space btree modifications.
++ * The caller must account for SB and AG header modifications, etc.
++ */
++STATIC uint
++xfs_calc_inobt_res(
++ struct xfs_mount *mp)
++{
++ return xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) +
++ xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1),
++ XFS_FSB_TO_B(mp, 1));
++}
++
++/*
++ * The free inode btree is a conditional feature. The behavior differs slightly
++ * from that of the traditional inode btree in that the finobt tracks records
++ * for inode chunks with at least one free inode. A record can be removed from
++ * the tree during individual inode allocation. Therefore the finobt
++ * reservation is unconditional for both the inode chunk allocation and
++ * individual inode allocation (modify) cases.
+ *
+- * the free inode btree: max depth * block size
+- * the allocation btrees: 2 trees * (max depth - 1) * block size
+- * the free inode btree entry: block size
++ * Behavior aside, the reservation for finobt modification is equivalent to the
++ * traditional inobt: cover a full finobt shape change plus block allocation.
+ */
+ STATIC uint
+ xfs_calc_finobt_res(
+- struct xfs_mount *mp,
+- int alloc,
+- int modify)
++ struct xfs_mount *mp)
+ {
+- uint res;
+-
+ if (!xfs_sb_version_hasfinobt(&mp->m_sb))
+ return 0;
+
+- res = xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1));
+- if (alloc)
+- res += xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1),
+- XFS_FSB_TO_B(mp, 1));
+- if (modify)
+- res += (uint)XFS_FSB_TO_B(mp, 1);
+-
+- return res;
++ return xfs_calc_inobt_res(mp);
+ }
+
+ /*
+@@ -373,7 +372,7 @@ xfs_calc_create_resv_modify(
+ xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
+ (uint)XFS_FSB_TO_B(mp, 1) +
+ xfs_calc_buf_res(XFS_DIROP_LOG_COUNT(mp), XFS_FSB_TO_B(mp, 1)) +
+- xfs_calc_finobt_res(mp, 1, 1);
++ xfs_calc_finobt_res(mp);
+ }
+
+ /*
+@@ -381,8 +380,8 @@ xfs_calc_create_resv_modify(
+ * the agi and agf of the ag getting the new inodes: 2 * sectorsize
+ * the superblock for the nlink flag: sector size
+ * the inode blocks allocated: mp->m_ialloc_blks * blocksize
+- * the inode btree: max depth * blocksize
+ * the allocation btrees: 2 trees * (max depth - 1) * block size
++ * the inode btree (record insertion)
+ */
+ STATIC uint
+ xfs_calc_create_resv_alloc(
+@@ -391,9 +390,9 @@ xfs_calc_create_resv_alloc(
+ return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
+ mp->m_sb.sb_sectsize +
+ xfs_calc_buf_res(mp->m_ialloc_blks, XFS_FSB_TO_B(mp, 1)) +
+- xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) +
+ xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1),
+- XFS_FSB_TO_B(mp, 1));
++ XFS_FSB_TO_B(mp, 1)) +
++ xfs_calc_inobt_res(mp);
+ }
+
+ STATIC uint
+@@ -409,8 +408,8 @@ __xfs_calc_create_reservation(
+ * For icreate we can allocate some inodes giving:
+ * the agi and agf of the ag getting the new inodes: 2 * sectorsize
+ * the superblock for the nlink flag: sector size
+- * the inode btree: max depth * blocksize
+ * the allocation btrees: 2 trees * (max depth - 1) * block size
++ * the inobt (record insertion)
+ * the finobt (record insertion)
+ */
+ STATIC uint
+@@ -419,10 +418,10 @@ xfs_calc_icreate_resv_alloc(
+ {
+ return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
+ mp->m_sb.sb_sectsize +
+- xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) +
+ xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1),
+ XFS_FSB_TO_B(mp, 1)) +
+- xfs_calc_finobt_res(mp, 0, 0);
++ xfs_calc_inobt_res(mp) +
++ xfs_calc_finobt_res(mp);
+ }
+
+ STATIC uint
+@@ -487,9 +486,14 @@ xfs_calc_symlink_reservation(
+ * the super block free inode counter, AGF and AGFL: sector size
+ * the on disk inode (agi unlinked list removal)
+ * the inode chunk is marked stale (headers only)
+- * the inode btree: max depth * blocksize
+- * the allocation btrees: 2 trees * (max depth - 1) * block size
++ * the inode btree
+ * the finobt (record insertion, removal or modification)
++ *
++ * Note that the allocfree res. for the inode chunk itself is not included
++ * because the extent free occurs after a transaction roll. We could take the
++ * maximum of the pre/post roll operations, but the pre-roll reservation already
++ * includes at least one allocfree res. for the inobt and is thus guaranteed to
++ * be larger.
+ */
+ STATIC uint
+ xfs_calc_ifree_reservation(
+@@ -500,10 +504,8 @@ xfs_calc_ifree_reservation(
+ xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) +
+ xfs_calc_iunlink_remove_reservation(mp) +
+ xfs_calc_buf_res(mp->m_ialloc_blks, 0) +
+- xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) +
+- xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1),
+- XFS_FSB_TO_B(mp, 1)) +
+- xfs_calc_finobt_res(mp, 0, 1);
++ xfs_calc_inobt_res(mp) +
++ xfs_calc_finobt_res(mp);
+ }
+
+ /*
+
diff --git a/patches.suse/xfs-include-inobt-buffers-in-ifree-tx-log-reservation.patch b/patches.suse/xfs-include-inobt-buffers-in-ifree-tx-log-reservation.patch
new file mode 100644
index 0000000000..de75d36e6f
--- /dev/null
+++ b/patches.suse/xfs-include-inobt-buffers-in-ifree-tx-log-reservation.patch
@@ -0,0 +1,84 @@
+From: Brian Foster <bfoster@redhat.com>
+Date: Mon, 8 Jan 2018 10:41:36 -0800
+Subject: xfs: include inobt buffers in ifree tx log reservation
+Git-commit: a6f485908d5210a5662f7a031bd1deeb3867e466
+Patch-mainline: v4.16-rc1
+References: bsc#1145235
+
+The tr_ifree transaction handles inode unlinks and inode chunk
+frees. The current transaction calculation does not accurately
+reflect worst case changes to the inode btree, however. The inobt
+portion of the current transaction reservation only covers
+modification of a single inobt buffer (for the particular inode
+record). This is a historical artifact from the days before XFS
+supported full inode chunk removal.
+
+When support for inode chunk removal was added in commit
+254f6311ed1b ("Implement deletion of inode clusters in XFS."), the
+additional log reservation required for chunk removal was not added
+correctly. The new reservation only considered the header overhead
+of associated buffers rather than the full contents of the btrees
+and AGF and AGFL buffers affected by the transaction. The
+reservation for the free space btrees was subsequently fixed up in
+commit 5fe6abb82f76 ("Add space for inode and allocation btrees to
+ITRUNCATE log reservation"), but the res. for full inobt joins has
+never been added.
+
+Further review of the ifree reservation uncovered a couple more
+problems:
+
+- The undocumented +2 blocks are intended for the AGF and AGFL, but
+ are also not sized correctly and should be logged as full sectors
+ (not FSBs).
+- The additional single block header is undocumented and serves no
+ apparent purpose.
+
+Update xfs_calc_ifree_reservation() to include a full inobt join in
+the reservation calculation. Refactor the undocumented blocks
+appropriately and fix up the comments to reflect the current
+calculation.
+
+Signed-off-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Dave Chinner <dchinner@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Nikolay Borisov <nborisov@suse.com>
+---
+ fs/xfs/libxfs/xfs_trans_resv.c | 15 ++++++---------
+ 1 file changed, 6 insertions(+), 9 deletions(-)
+
+diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c
+index 6bd916bd35e2..838566b85622 100644
+--- a/fs/xfs/libxfs/xfs_trans_resv.c
++++ b/fs/xfs/libxfs/xfs_trans_resv.c
+@@ -490,10 +490,9 @@ xfs_calc_symlink_reservation(
+ /*
+ * In freeing an inode we can modify:
+ * the inode being freed: inode size
+- * the super block free inode counter: sector size
+- * the agi hash list and counters: sector size
+- * the inode btree entry: block size
+- * the on disk inode before ours in the agi hash list: inode cluster size
++ * the super block free inode counter, AGF and AGFL: sector size
++ * the on disk inode (agi unlinked list removal)
++ * the inode chunk is marked stale (headers only)
+ * the inode btree: max depth * blocksize
+ * the allocation btrees: 2 trees * (max depth - 1) * block size
+ * the finobt (record insertion, removal or modification)
+@@ -504,12 +503,10 @@ xfs_calc_ifree_reservation(
+ {
+ return XFS_DQUOT_LOGRES(mp) +
+ xfs_calc_inode_res(mp, 1) +
+- xfs_calc_buf_res(1, mp->m_sb.sb_sectsize) +
+- xfs_calc_buf_res(1, XFS_FSB_TO_B(mp, 1)) +
++ xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) +
+ xfs_calc_iunlink_remove_reservation(mp) +
+- xfs_calc_buf_res(1, 0) +
+- xfs_calc_buf_res(2 + mp->m_ialloc_blks +
+- mp->m_in_maxlevels, 0) +
++ xfs_calc_buf_res(mp->m_ialloc_blks, 0) +
++ xfs_calc_buf_res(mp->m_in_maxlevels, XFS_FSB_TO_B(mp, 1)) +
+ xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1),
+ XFS_FSB_TO_B(mp, 1)) +
+ xfs_calc_finobt_res(mp, 0, 1);
+
diff --git a/patches.suse/xfs-print-transaction-log-reservation-on-overrun.patch b/patches.suse/xfs-print-transaction-log-reservation-on-overrun.patch
new file mode 100644
index 0000000000..d191d5db19
--- /dev/null
+++ b/patches.suse/xfs-print-transaction-log-reservation-on-overrun.patch
@@ -0,0 +1,47 @@
+From: Brian Foster <bfoster@redhat.com>
+Date: Mon, 8 Jan 2018 10:41:35 -0800
+Subject: xfs: print transaction log reservation on overrun
+Git-commit: 2c8f6265397642bb150d933fa46b1f7c294f4ffe
+Patch-mainline: v4.16-rc1
+References: bsc#1145235
+
+The transaction dump code displays the content and reservation
+consumption of a particular transaction in the event of an overrun.
+It currently displays the reservation associated with the
+transaction ticket, but not the original reservation attached to the
+transaction.
+
+The latter value reflects the original transaction reservation
+calculation before additional reservation overhead is assigned, such
+as for the CIL context header and potential split region headers.
+
+Update xlog_print_trans() to also print the original transaction
+reservation in the event of overrun. This provides a reference point
+to identify how much reservation overhead was added to a particular
+ticket by xfs_log_calc_unit_res().
+
+Signed-off-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Dave Chinner <dchinner@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Nikolay Borisov <nborisov@suse.com>
+---
+ fs/xfs/xfs_log.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
+index a503af96d780..047df85528b0 100644
+--- a/fs/xfs/xfs_log.c
++++ b/fs/xfs/xfs_log.c
+@@ -2117,7 +2117,9 @@ xlog_print_trans(
+
+ /* dump core transaction and ticket info */
+ xfs_warn(mp, "transaction summary:");
+- xfs_warn(mp, " flags = 0x%x", tp->t_flags);
++ xfs_warn(mp, " log res = %d", tp->t_log_res);
++ xfs_warn(mp, " log count = %d", tp->t_log_count);
++ xfs_warn(mp, " flags = 0x%x", tp->t_flags);
+
+ xlog_print_tic_res(mp, tp->t_ticket);
+
+
diff --git a/patches.suse/xfs-refactor-inode-chunk-alloc-free-tx-reservation.patch b/patches.suse/xfs-refactor-inode-chunk-alloc-free-tx-reservation.patch
new file mode 100644
index 0000000000..36a8507176
--- /dev/null
+++ b/patches.suse/xfs-refactor-inode-chunk-alloc-free-tx-reservation.patch
@@ -0,0 +1,169 @@
+From: Brian Foster <bfoster@redhat.com>
+Date: Mon, 8 Jan 2018 10:41:38 -0800
+Subject: xfs: refactor inode chunk alloc/free tx reservation
+Git-commit: 57af33e451b73f56feb428f5856cdf6e4e0c60cd
+Patch-mainline: v4.16-rc1
+References: bsc#1145235
+
+The reservation for the various forms of inode allocation is
+scattered across several different functions. This includes two
+variants of chunk allocation (v5 icreate transactions vs. older
+create transactions) and the inode free transaction.
+
+To clean up some of this code and clarify the purpose of specific
+allocfree reservations, continue the pattern of defining helper
+functions for smaller operational units of broader transactions.
+Refactor the reservation into an inode chunk alloc/free helper that
+considers the various conditions based on filesystem format.
+
+An inode chunk free involves an extent free and buffer
+invalidations. The latter requires reservation for log headers only.
+An inode chunk allocation modifies the free space btrees and logs
+the chunk on v4 supers. v5 supers initialize the inode chunk using
+ordered buffers and so do not log the chunk.
+
+As a side effect of this refactoring, add one more allocfree res to
+the ifree transaction. Technically this does not serve a specific
+purpose because inode chunks are freed via deferred operations and
+thus occur after a transaction roll. tr_ifree has a bit of a history
+of tx overruns caused by too many agfl fixups during sustained file
+deletion workloads, so add this extra reservation as a form of
+padding nonetheless.
+
+Signed-off-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Dave Chinner <dchinner@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Nikolay Borisov <nborisov@suse.com>
+---
+ fs/xfs/libxfs/xfs_trans_resv.c | 64 ++++++++++++++++++++++++++++++++----------
+ 1 file changed, 49 insertions(+), 15 deletions(-)
+
+diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c
+index 19f3a226a357..75259a1346eb 100644
+--- a/fs/xfs/libxfs/xfs_trans_resv.c
++++ b/fs/xfs/libxfs/xfs_trans_resv.c
+@@ -34,6 +34,9 @@
+ #include "xfs_trans_space.h"
+ #include "xfs_trace.h"
+
++#define _ALLOC true
++#define _FREE false
++
+ /*
+ * A buffer has a format structure overhead in the log in addition
+ * to the data, so we need to take this into account when reserving
+@@ -171,6 +174,41 @@ xfs_calc_finobt_res(
+ return xfs_calc_inobt_res(mp);
+ }
+
++/*
++ * Calculate the reservation required to allocate or free an inode chunk. This
++ * includes:
++ *
++ * the allocation btrees: 2 trees * (max depth - 1) * block size
++ * the inode chunk: m_ialloc_blks * N
++ *
++ * The size N of the inode chunk reservation depends on whether it is for
++ * allocation or free and which type of create transaction is in use. An inode
++ * chunk free always invalidates the buffers and only requires reservation for
++ * headers (N == 0). An inode chunk allocation requires a chunk sized
++ * reservation on v4 and older superblocks to initialize the chunk. No chunk
++ * reservation is required for allocation on v5 supers, which use ordered
++ * buffers to initialize.
++ */
++STATIC uint
++xfs_calc_inode_chunk_res(
++ struct xfs_mount *mp,
++ bool alloc)
++{
++ uint res, size = 0;
++
++ res = xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1),
++ XFS_FSB_TO_B(mp, 1));
++ if (alloc) {
++ /* icreate tx uses ordered buffers */
++ if (xfs_sb_version_hascrc(&mp->m_sb))
++ return res;
++ size = XFS_FSB_TO_B(mp, 1);
++ }
++
++ res += xfs_calc_buf_res(mp->m_ialloc_blks, size);
++ return res;
++}
++
+ /*
+ * Various log reservation values.
+ *
+@@ -379,8 +417,7 @@ xfs_calc_create_resv_modify(
+ * For create we can allocate some inodes giving:
+ * the agi and agf of the ag getting the new inodes: 2 * sectorsize
+ * the superblock for the nlink flag: sector size
+- * the inode blocks allocated: mp->m_ialloc_blks * blocksize
+- * the allocation btrees: 2 trees * (max depth - 1) * block size
++ * the inode chunk (allocation/init)
+ * the inode btree (record insertion)
+ */
+ STATIC uint
+@@ -389,9 +426,7 @@ xfs_calc_create_resv_alloc(
+ {
+ return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
+ mp->m_sb.sb_sectsize +
+- xfs_calc_buf_res(mp->m_ialloc_blks, XFS_FSB_TO_B(mp, 1)) +
+- xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1),
+- XFS_FSB_TO_B(mp, 1)) +
++ xfs_calc_inode_chunk_res(mp, _ALLOC) +
+ xfs_calc_inobt_res(mp);
+ }
+
+@@ -408,7 +443,7 @@ __xfs_calc_create_reservation(
+ * For icreate we can allocate some inodes giving:
+ * the agi and agf of the ag getting the new inodes: 2 * sectorsize
+ * the superblock for the nlink flag: sector size
+- * the allocation btrees: 2 trees * (max depth - 1) * block size
++ * the inode chunk (allocation, no init)
+ * the inobt (record insertion)
+ * the finobt (record insertion)
+ */
+@@ -418,8 +453,7 @@ xfs_calc_icreate_resv_alloc(
+ {
+ return xfs_calc_buf_res(2, mp->m_sb.sb_sectsize) +
+ mp->m_sb.sb_sectsize +
+- xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1),
+- XFS_FSB_TO_B(mp, 1)) +
++ xfs_calc_inode_chunk_res(mp, _ALLOC) +
+ xfs_calc_inobt_res(mp) +
+ xfs_calc_finobt_res(mp);
+ }
+@@ -485,15 +519,15 @@ xfs_calc_symlink_reservation(
+ * the inode being freed: inode size
+ * the super block free inode counter, AGF and AGFL: sector size
+ * the on disk inode (agi unlinked list removal)
+- * the inode chunk is marked stale (headers only)
++ * the inode chunk (invalidated, headers only)
+ * the inode btree
+ * the finobt (record insertion, removal or modification)
+ *
+- * Note that the allocfree res. for the inode chunk itself is not included
+- * because the extent free occurs after a transaction roll. We could take the
+- * maximum of the pre/post roll operations, but the pre-roll reservation already
+- * includes at least one allocfree res. for the inobt and is thus guaranteed to
+- * be larger.
++ * Note that the inode chunk res. includes an allocfree res. for freeing of the
++ * inode chunk. This is technically extraneous because the inode chunk free is
++ * deferred (it occurs after a transaction roll). Include the extra reservation
++ * anyways since we've had reports of ifree transaction overruns due to too many
++ * agfl fixups during inode chunk frees.
+ */
+ STATIC uint
+ xfs_calc_ifree_reservation(
+@@ -503,7 +537,7 @@ xfs_calc_ifree_reservation(
+ xfs_calc_inode_res(mp, 1) +
+ xfs_calc_buf_res(3, mp->m_sb.sb_sectsize) +
+ xfs_calc_iunlink_remove_reservation(mp) +
+- xfs_calc_buf_res(mp->m_ialloc_blks, 0) +
++ xfs_calc_inode_chunk_res(mp, _FREE) +
+ xfs_calc_inobt_res(mp) +
+ xfs_calc_finobt_res(mp);
+ }
+
diff --git a/patches.suse/xfs-refactor-xlog_cil_insert_items-to-facilitate-transaction-dump.patch b/patches.suse/xfs-refactor-xlog_cil_insert_items-to-facilitate-transaction-dump.patch
new file mode 100644
index 0000000000..39d8e36e13
--- /dev/null
+++ b/patches.suse/xfs-refactor-xlog_cil_insert_items-to-facilitate-transaction-dump.patch
@@ -0,0 +1,134 @@
+From: Brian Foster <bfoster@redhat.com>
+Date: Wed, 14 Jun 2017 21:29:49 -0700
+Subject: xfs: refactor xlog_cil_insert_items() to facilitate transaction dump
+Git-commit: e2f2342639a414b60de3876a8b437eac2b795dbe
+Patch-mainline: v4.13-rc1
+References: bsc#1145235
+
+Transaction reservation overrun detection currently occurs too late
+to print useful information about the offending transaction.
+Ideally, the transaction data is printed before the associated log
+items are moved from the transaction to the CIL, which occurs in
+xlog_cil_insert_items(), such that details of the items logged by
+the transaction are available for analysis.
+
+Refactor xlog_cil_insert_items() to facilitate moving tx overrun
+detection to this function. Update the function to track each bit of
+extra log reservation stolen from the transaction (i.e., such as for
+the CIL context ticket) and perform the log item migration as the
+last operation before the CIL lock is released. This creates a
+context where the transaction reservation consumption has been fully
+calculated when the log items are moved to the CIL. This patch makes
+no functional changes.
+
+Signed-off-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Nikolay Borisov <nborisov@suse.com>
+---
+ fs/xfs/xfs_log_cil.c | 62 +++++++++++++++++++++++++++-------------------------
+ 1 file changed, 32 insertions(+), 30 deletions(-)
+
+diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c
+index 52fe04229aa6..8de3baa7d3f0 100644
+--- a/fs/xfs/xfs_log_cil.c
++++ b/fs/xfs/xfs_log_cil.c
+@@ -410,6 +410,7 @@ xlog_cil_insert_items(
+ int len = 0;
+ int diff_iovecs = 0;
+ int iclog_space;
++ int iovhdr_res = 0, split_res = 0, ctx_res = 0;
+
+ ASSERT(tp);
+
+@@ -419,30 +420,11 @@ xlog_cil_insert_items(
+ */
+ xlog_cil_insert_format_items(log, tp, &len, &diff_iovecs);
+
+- /*
+- * Now (re-)position everything modified at the tail of the CIL.
+- * We do this here so we only need to take the CIL lock once during
+- * the transaction commit.
+- */
+ spin_lock(&cil->xc_cil_lock);
+- list_for_each_entry(lidp, &tp->t_items, lid_trans) {
+- struct xfs_log_item *lip = lidp->lid_item;
+-
+- /* Skip items which aren't dirty in this transaction. */
+- if (!(lidp->lid_flags & XFS_LID_DIRTY))
+- continue;
+-
+- /*
+- * Only move the item if it isn't already at the tail. This is
+- * to prevent a transient list_empty() state when reinserting
+- * an item that is already the only item in the CIL.
+- */
+- if (!list_is_last(&lip->li_cil, &cil->xc_cil))
+- list_move_tail(&lip->li_cil, &cil->xc_cil);
+- }
+
+ /* account for space used by new iovec headers */
+- len += diff_iovecs * sizeof(xlog_op_header_t);
++ iovhdr_res = diff_iovecs * sizeof(xlog_op_header_t);
++ len += iovhdr_res;
+ ctx->nvecs += diff_iovecs;
+
+ /* attach the transaction to the CIL if it has any busy extents */
+@@ -457,27 +439,47 @@ xlog_cil_insert_items(
+ * during the transaction commit.
+ */
+ if (ctx->ticket->t_curr_res == 0) {
+- ctx->ticket->t_curr_res = ctx->ticket->t_unit_res;
+- tp->t_ticket->t_curr_res -= ctx->ticket->t_unit_res;
++ ctx_res = ctx->ticket->t_unit_res;
++ ctx->ticket->t_curr_res = ctx_res;
++ tp->t_ticket->t_curr_res -= ctx_res;
+ }
+
+ /* do we need space for more log record headers? */
+ iclog_space = log->l_iclog_size - log->l_iclog_hsize;
+ if (len > 0 && (ctx->space_used / iclog_space !=
+ (ctx->space_used + len) / iclog_space)) {
+- int hdrs;
+-
+- hdrs = (len + iclog_space - 1) / iclog_space;
++ split_res = (len + iclog_space - 1) / iclog_space;
+ /* need to take into account split region headers, too */
+- hdrs *= log->l_iclog_hsize + sizeof(struct xlog_op_header);
+- ctx->ticket->t_unit_res += hdrs;
+- ctx->ticket->t_curr_res += hdrs;
+- tp->t_ticket->t_curr_res -= hdrs;
++ split_res *= log->l_iclog_hsize + sizeof(struct xlog_op_header);
++ ctx->ticket->t_unit_res += split_res;
++ ctx->ticket->t_curr_res += split_res;
++ tp->t_ticket->t_curr_res -= split_res;
+ ASSERT(tp->t_ticket->t_curr_res >= len);
+ }
+ tp->t_ticket->t_curr_res -= len;
+ ctx->space_used += len;
+
++ /*
++ * Now (re-)position everything modified at the tail of the CIL.
++ * We do this here so we only need to take the CIL lock once during
++ * the transaction commit.
++ */
++ list_for_each_entry(lidp, &tp->t_items, lid_trans) {
++ struct xfs_log_item *lip = lidp->lid_item;
++
++ /* Skip items which aren't dirty in this transaction. */
++ if (!(lidp->lid_flags & XFS_LID_DIRTY))
++ continue;
++
++ /*
++ * Only move the item if it isn't already at the tail. This is
++ * to prevent a transient list_empty() state when reinserting
++ * an item that is already the only item in the CIL.
++ */
++ if (!list_is_last(&lip->li_cil, &cil->xc_cil))
++ list_move_tail(&lip->li_cil, &cil->xc_cil);
++ }
++
+ spin_unlock(&cil->xc_cil_lock);
+ }
+
+
diff --git a/patches.suse/xfs-separate-shutdown-from-ticket-reservation-print-helper.patch b/patches.suse/xfs-separate-shutdown-from-ticket-reservation-print-helper.patch
new file mode 100644
index 0000000000..746f98c4ab
--- /dev/null
+++ b/patches.suse/xfs-separate-shutdown-from-ticket-reservation-print-helper.patch
@@ -0,0 +1,81 @@
+From: Brian Foster <bfoster@redhat.com>
+Date: Wed, 14 Jun 2017 21:29:48 -0700
+Subject: xfs: separate shutdown from ticket reservation print helper
+Git-commit: 7d2d5653460443e0586bd7d2e07811b4f4095e36
+Patch-mainline: v4.13-rc1
+References: bsc#1145235
+
+xlog_print_tic_res() pre-dates delayed logging and the committed
+items list (CIL) and thus retains some factoring warts, such as hard
+coded function names in the output and the fact that it induces a
+shutdown.
+
+In preparation for more detailed logging of regular transaction
+overrun situations, refactor xlog_print_tic_res() to be slightly
+more generic. Reword some of the warning messages and pull the
+shutdown into the callers.
+
+Signed-off-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Nikolay Borisov <nborisov@suse.com>
+---
+ fs/xfs/xfs_log.c | 12 ++++++------
+ fs/xfs/xfs_log_cil.c | 4 +++-
+ 2 files changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
+index 3731f13f63e9..8b283f7cefea 100644
+--- a/fs/xfs/xfs_log.c
++++ b/fs/xfs/xfs_log.c
+@@ -2024,7 +2024,7 @@ xlog_print_tic_res(
+ };
+ #undef REG_TYPE_STR
+
+- xfs_warn(mp, "xlog_write: reservation summary:");
++ xfs_warn(mp, "ticket reservation summary:");
+ xfs_warn(mp, " unit res = %d bytes",
+ ticket->t_unit_res);
+ xfs_warn(mp, " current res = %d bytes",
+@@ -2045,10 +2045,6 @@ xlog_print_tic_res(
+ "bad-rtype" : res_type_str[r_type]),
+ ticket->t_res_arr[i].r_len);
+ }
+-
+- xfs_alert_tag(mp, XFS_PTAG_LOGRES,
+- "xlog_write: reservation ran out. Need to up reservation");
+- xfs_force_shutdown(mp, SHUTDOWN_LOG_IO_ERROR);
+ }
+
+ /*
+@@ -2321,8 +2317,12 @@ xlog_write(
+ if (flags & (XLOG_COMMIT_TRANS | XLOG_UNMOUNT_TRANS))
+ ticket->t_curr_res -= sizeof(xlog_op_header_t);
+
+- if (ticket->t_curr_res < 0)
++ if (ticket->t_curr_res < 0) {
++ xfs_alert_tag(log->l_mp, XFS_PTAG_LOGRES,
++ "ctx ticket reservation ran out. Need to up reservation");
+ xlog_print_tic_res(log->l_mp, ticket);
++ xfs_force_shutdown(log->l_mp, SHUTDOWN_LOG_IO_ERROR);
++ }
+
+ index = 0;
+ lv = log_vector;
+diff --git a/fs/xfs/xfs_log_cil.c b/fs/xfs/xfs_log_cil.c
+index 82f1cbcc4de1..52fe04229aa6 100644
+--- a/fs/xfs/xfs_log_cil.c
++++ b/fs/xfs/xfs_log_cil.c
+@@ -987,8 +987,10 @@ xfs_log_commit_cil(
+ xlog_cil_insert_items(log, tp);
+
+ /* check we didn't blow the reservation */
+- if (tp->t_ticket->t_curr_res < 0)
++ if (tp->t_ticket->t_curr_res < 0) {
+ xlog_print_tic_res(mp, tp->t_ticket);
++ xfs_force_shutdown(log->l_mp, SHUTDOWN_LOG_IO_ERROR);
++ }
+
+ tp->t_commit_lsn = cil->xc_ctx->sequence;
+ if (commit_lsn)
+
diff --git a/patches.suse/xfs-truncate-transaction-does-not-modify-the-inobt.patch b/patches.suse/xfs-truncate-transaction-does-not-modify-the-inobt.patch
new file mode 100644
index 0000000000..5ddc43efa5
--- /dev/null
+++ b/patches.suse/xfs-truncate-transaction-does-not-modify-the-inobt.patch
@@ -0,0 +1,49 @@
+From: Brian Foster <bfoster@redhat.com>
+Date: Mon, 8 Jan 2018 10:41:37 -0800
+Subject: xfs: truncate transaction does not modify the inobt
+Git-commit: a606ebdb859e78beb757dfefa08001df366e2ef5
+Patch-mainline: v4.16-rc1
+References: bsc#1145235
+
+The truncate transaction does not ever modify the inode btree, but
+includes an associated log reservation. Update
+xfs_calc_itruncate_reservation() to remove the reservation
+associated with inobt updates.
+
+Signed-off-by: Brian Foster <bfoster@redhat.com>
+Reviewed-by: Dave Chinner <dchinner@redhat.com>
+Reviewed-by: Darrick J. Wong <darrick.wong@oracle.com>
+Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
+Acked-by: Nikolay Borisov <nborisov@suse.com>
+---
+ fs/xfs/libxfs/xfs_trans_resv.c | 9 +--------
+ 1 file changed, 1 insertion(+), 8 deletions(-)
+
+diff --git a/fs/xfs/libxfs/xfs_trans_resv.c b/fs/xfs/libxfs/xfs_trans_resv.c
+index 173b1bc13ffe..037a1295d289 100644
+--- a/fs/xfs/libxfs/xfs_trans_resv.c
++++ b/fs/xfs/libxfs/xfs_trans_resv.c
+@@ -232,8 +232,6 @@ xfs_calc_write_reservation(
+ * the super block to reflect the freed blocks: sector size
+ * worst case split in allocation btrees per extent assuming 4 extents:
+ * 4 exts * 2 trees * (2 * max depth - 1) * block size
+- * the inode btree: max depth * blocksize
+- * the allocation btrees: 2 trees * (max depth - 1) * block size
+ */
+ STATIC uint
+ xfs_calc_itruncate_reservation(
+@@ -245,12 +243,7 @@ xfs_calc_itruncate_reservation(
+ XFS_FSB_TO_B(mp, 1))),
+ (xfs_calc_buf_res(9, mp->m_sb.sb_sectsize) +
+ xfs_calc_buf_res(xfs_allocfree_log_count(mp, 4),
+- XFS_FSB_TO_B(mp, 1)) +
+- xfs_calc_buf_res(5, 0) +
+- xfs_calc_buf_res(xfs_allocfree_log_count(mp, 1),
+- XFS_FSB_TO_B(mp, 1)) +
+- xfs_calc_buf_res(2 + mp->m_ialloc_blks +
+- mp->m_in_maxlevels, 0)));
++ XFS_FSB_TO_B(mp, 1))));
+ }
+
+ /*
+
diff --git a/series.conf b/series.conf
index ab87b14fce..f9796de1fe 100644
--- a/series.conf
+++ b/series.conf
@@ -3575,6 +3575,9 @@
patches.drivers/HID-wacom-fix-mistake-in-printk.patch
patches.suse/0011-btrfs-nowait-aio-Correct-assignment-of-pos.patch
patches.fixes/0058-xfs-refactor-dir2-leaf-readahead-shadow-buffer-cleve.patch
+ patches.suse/xfs-separate-shutdown-from-ticket-reservation-print-helper.patch
+ patches.suse/xfs-refactor-xlog_cil_insert_items-to-facilitate-transaction-dump.patch
+ patches.suse/xfs-dump-transaction-usage-details-on-log-reservation-overrun.patch
patches.fixes/xfs-release-bli-from-transaction-properly-on-fs-shut.patch
patches.fixes/xfs-remove-bli-from-AIL-before-release-on-transactio.patch
patches.fixes/xfs-remove-double-underscore-integer-types.patch
@@ -3587,6 +3590,7 @@
patches.fixes/xfs-remove-unneeded-parameter-from-XFS_TEST_ERROR.patch
patches.fixes/xfs-convert-drop_writes-to-use-the-errortag-mechanis.patch
patches.fixes/xfs-replace-log_badcrc_factor-knob-with-error-inject.patch
+ patches.suse/xfs-fix-semicolon-cocci-warnings.patch
patches.fixes/xfs-rewrite-xfs_dq_get_next_id-using-xfs_iext_lookup.patch
patches.fixes/vfs-Add-page_cache_seek_hole_data-helper.patch
patches.fixes/vfs-Add-iomap_seek_hole-and-iomap_seek_data-helpers.patch
@@ -11977,6 +11981,13 @@
patches.fixes/iversion-make-inode_cmp_iversion-raw-return-bool-ins.patch
patches.fixes/fix-misannotated-out-of-line-copy_to_user
patches.fixes/0006-jffs2-Fix-use-after-free-bug-in-jffs2_iget-s-error-h.patch
+ patches.suse/xfs-print-transaction-log-reservation-on-overrun.patch
+ patches.suse/xfs-include-inobt-buffers-in-ifree-tx-log-reservation.patch
+ patches.suse/xfs-fix-up-agi-unlinked-list-reservations.patch
+ patches.suse/xfs-truncate-transaction-does-not-modify-the-inobt.patch
+ patches.suse/xfs-include-an-allocfree-res-for-inobt-modifications.patch
+ patches.suse/xfs-refactor-inode-chunk-alloc-free-tx-reservation.patch
+ patches.suse/xfs-eliminate-duplicate-icreate-tx-reservation-functions.patch
patches.fixes/0004-iomap-report-collisions-between-directio-and-buffere.patch
patches.fixes/xfs-call-xfs_qm_dqattach-before-performing-reflink-o.patch
patches.fixes/xfs-preserve-i_rdev-when-recycling-a-reclaimable-inode.patch