public inbox for linux-xfs@vger.kernel.org
 help / color / mirror / Atom feed
From: tinguely@sgi.com
To: xfs@oss.sgi.com
Subject: [PATCH] xfs: synchronously write the superblock on unmount
Date: Tue, 26 Jun 2012 11:00:52 -0500	[thread overview]
Message-ID: <20120626160102.898671754@sgi.com> (raw)
In-Reply-To: 20120626160051.364635296@sgi.com

[-- Attachment #1: xfs-unmountfs_write_superblock.patch --]
[-- Type: text/plain, Size: 4086 bytes --]

xfs_wait_buftarg() does not wait for the completion of the write of the uncached
superblock. This write can race with the shutdown of the log and cause a panic if the
write does not win the race. Per Dave's suggestion, turn the final write of the
superblock into a syncronous write.

Signed-off-by: Mark Tinguely <tinguely@sgi.com>

---
 fs/xfs/xfs_mount.c |   43 +++++++++++++++++++------------------------
 fs/xfs/xfs_mount.h |    4 +++-
 fs/xfs/xfs_sync.c  |    8 +-------
 3 files changed, 23 insertions(+), 32 deletions(-)

Index: b/fs/xfs/xfs_mount.c
===================================================================
--- a/fs/xfs/xfs_mount.c
+++ b/fs/xfs/xfs_mount.c
@@ -1517,11 +1517,6 @@ xfs_unmountfs(
 		xfs_warn(mp, "Unable to free reserved block pool. "
 				"Freespace may not be correct on next mount.");
 
-	error = xfs_log_sbcount(mp);
-	if (error)
-		xfs_warn(mp, "Unable to update superblock counters. "
-				"Freespace may not be correct on next mount.");
-
 	/*
 	 * At this point we might have modified the superblock again and thus
 	 * added an item to the AIL, thus flush it again.
@@ -1529,6 +1524,11 @@ xfs_unmountfs(
 	xfs_ail_push_all_sync(mp->m_ail);
 	xfs_wait_buftarg(mp->m_ddev_targp);
 
+	error = xfs_write_sbcount(mp);
+	if (error)
+		xfs_warn(mp, "Unable to update superblock counters. "
+				"Freespace may not be correct on next mount.");
+
 	xfs_log_unmount_write(mp);
 	xfs_log_unmount(mp);
 	xfs_uuid_unmount(mp);
@@ -1547,19 +1547,17 @@ xfs_fs_writable(xfs_mount_t *mp)
 }
 
 /*
- * xfs_log_sbcount
+ * xfs_write_sbcount
  *
  * Sync the superblock counters to disk.
  *
- * Note this code can be called during the process of freezing, so
- * we may need to use the transaction allocator which does not
- * block when the transaction subsystem is in its frozen state.
  */
 int
-xfs_log_sbcount(xfs_mount_t *mp)
+xfs_write_sbcount(
+	struct xfs_mount	*mp)
 {
-	xfs_trans_t	*tp;
-	int		error;
+	struct xfs_buf		*bp;
+	int			error;
 
 	if (!xfs_fs_writable(mp))
 		return 0;
@@ -1571,19 +1569,16 @@ xfs_log_sbcount(xfs_mount_t *mp)
 	 * counters on every modification.
 	 */
 	if (!xfs_sb_version_haslazysbcount(&mp->m_sb))
-		return 0;
+	return 0;
 
-	tp = _xfs_trans_alloc(mp, XFS_TRANS_SB_COUNT, KM_SLEEP);
-	error = xfs_trans_reserve(tp, 0, mp->m_sb.sb_sectsize + 128, 0, 0,
-					XFS_DEFAULT_LOG_COUNT);
-	if (error) {
-		xfs_trans_cancel(tp, 0);
-		return error;
-	}
-
-	xfs_mod_sb(tp, XFS_SB_IFREE | XFS_SB_ICOUNT | XFS_SB_FDBLOCKS);
-	xfs_trans_set_sync(tp);
-	error = xfs_trans_commit(tp, 0);
+	bp = xfs_getsb(mp, 0);
+	xfs_sb_to_disk(XFS_BUF_TO_SBP(bp), &mp->m_sb,
+		XFS_SB_IFREE | XFS_SB_ICOUNT | XFS_SB_FDBLOCKS);
+
+	if (xfs_buf_ispinned(bp))
+		xfs_log_force(mp, 0);
+	error = xfs_bwrite(bp);
+	xfs_buf_relse(bp);
 	return error;
 }
 
Index: b/fs/xfs/xfs_mount.h
===================================================================
--- a/fs/xfs/xfs_mount.h
+++ b/fs/xfs/xfs_mount.h
@@ -371,7 +371,9 @@ typedef struct xfs_mod_sb {
 	int64_t		msb_delta;	/* Change to make to specified field */
 } xfs_mod_sb_t;
 
-extern int	xfs_log_sbcount(xfs_mount_t *);
+extern int
+xfs_write_sbcount(
+	struct xfs_mount *mp);
 extern __uint64_t xfs_default_resblks(xfs_mount_t *mp);
 extern int	xfs_mountfs(xfs_mount_t *mp);
 
Index: b/fs/xfs/xfs_sync.c
===================================================================
--- a/fs/xfs/xfs_sync.c
+++ b/fs/xfs/xfs_sync.c
@@ -348,17 +348,11 @@ xfs_quiesce_attr(
 	WARN_ON(atomic_read(&mp->m_active_trans) != 0);
 
 	/* Push the superblock and write an unmount record */
-	error = xfs_log_sbcount(mp);
+	error = xfs_write_sbcount(mp);
 	if (error)
 		xfs_warn(mp, "xfs_attr_quiesce: failed to log sb changes. "
 				"Frozen image may not be consistent.");
 	xfs_log_unmount_write(mp);
-
-	/*
-	 * At this point we might have modified the superblock again and thus
-	 * added an item to the AIL, thus flush it again.
-	 */
-	xfs_ail_push_all_sync(mp->m_ail);
 }
 
 static void

_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs

       reply	other threads:[~2012-06-26 16:40 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20120626160051.364635296@sgi.com>
2012-06-26 16:00 ` tinguely [this message]
2012-06-26 18:09   ` [PATCH] xfs: synchronously write the superblock on unmount Carlos Maiolino
2012-06-26 21:06   ` Christoph Hellwig
2012-06-27 10:08   ` Dave Chinner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20120626160102.898671754@sgi.com \
    --to=tinguely@sgi.com \
    --cc=xfs@oss.sgi.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox