]> Git Repo - linux.git/commitdiff
xfs: force summary counter recalc at next mount
authorDarrick J. Wong <[email protected]>
Fri, 20 Jul 2018 16:28:40 +0000 (09:28 -0700)
committerDarrick J. Wong <[email protected]>
Mon, 23 Jul 2018 16:08:01 +0000 (09:08 -0700)
Use the "bad summary count" mount flag from the previous patch to skip
writing the unmount record to force log recovery at the next mount,
which will recalculate the summary counters for us.

Signed-off-by: Darrick J. Wong <[email protected]>
Reviewed-by: Christoph Hellwig <[email protected]>
fs/xfs/libxfs/xfs_errortag.h
fs/xfs/xfs_error.c
fs/xfs/xfs_log.c
fs/xfs/xfs_mount.c
fs/xfs/xfs_mount.h

index b9974e7a8e6eaa76b8e01063ca49db5eafa01814..66077a105cbb7408131a6b9d5580e6a0c12599ca 100644 (file)
@@ -53,7 +53,8 @@
 #define XFS_ERRTAG_LOG_ITEM_PIN                                30
 #define XFS_ERRTAG_BUF_LRU_REF                         31
 #define XFS_ERRTAG_FORCE_SCRUB_REPAIR                  32
-#define XFS_ERRTAG_MAX                                 33
+#define XFS_ERRTAG_FORCE_SUMMARY_RECALC                        33
+#define XFS_ERRTAG_MAX                                 34
 
 /*
  * Random factors for above tags, 1 means always, 2 means 1/2 time, etc.
@@ -91,5 +92,6 @@
 #define XFS_RANDOM_LOG_ITEM_PIN                                1
 #define XFS_RANDOM_BUF_LRU_REF                         2
 #define XFS_RANDOM_FORCE_SCRUB_REPAIR                  1
+#define XFS_RANDOM_FORCE_SUMMARY_RECALC                        1
 
 #endif /* __XFS_ERRORTAG_H_ */
index 0470114a8d80c1cf4e1382cdda423a439d4566c0..9866f542e77b18f20689531821856be972c39bdf 100644 (file)
@@ -50,6 +50,7 @@ static unsigned int xfs_errortag_random_default[] = {
        XFS_RANDOM_LOG_ITEM_PIN,
        XFS_RANDOM_BUF_LRU_REF,
        XFS_RANDOM_FORCE_SCRUB_REPAIR,
+       XFS_RANDOM_FORCE_SUMMARY_RECALC,
 };
 
 struct xfs_errortag_attr {
@@ -157,6 +158,7 @@ XFS_ERRORTAG_ATTR_RW(log_bad_crc,   XFS_ERRTAG_LOG_BAD_CRC);
 XFS_ERRORTAG_ATTR_RW(log_item_pin,     XFS_ERRTAG_LOG_ITEM_PIN);
 XFS_ERRORTAG_ATTR_RW(buf_lru_ref,      XFS_ERRTAG_BUF_LRU_REF);
 XFS_ERRORTAG_ATTR_RW(force_repair,     XFS_ERRTAG_FORCE_SCRUB_REPAIR);
+XFS_ERRORTAG_ATTR_RW(bad_summary,      XFS_ERRTAG_FORCE_SUMMARY_RECALC);
 
 static struct attribute *xfs_errortag_attrs[] = {
        XFS_ERRORTAG_ATTR_LIST(noerror),
@@ -192,6 +194,7 @@ static struct attribute *xfs_errortag_attrs[] = {
        XFS_ERRORTAG_ATTR_LIST(log_item_pin),
        XFS_ERRORTAG_ATTR_LIST(buf_lru_ref),
        XFS_ERRORTAG_ATTR_LIST(force_repair),
+       XFS_ERRORTAG_ATTR_LIST(bad_summary),
        NULL,
 };
 
index bac586cbc54e432f7269270741eef83d2aa2d176..fd10b14263820c84dc4b16d4b3a9760aaf9e7c42 100644 (file)
@@ -848,16 +848,30 @@ xfs_log_write_unmount_record(
        struct xlog_in_core     *iclog;
        struct xlog_ticket      *tic = NULL;
        xfs_lsn_t               lsn;
+       uint                    flags = XLOG_UNMOUNT_TRANS;
        int                     error;
 
        error = xfs_log_reserve(mp, 600, 1, &tic, XFS_LOG, 0);
        if (error)
                goto out_err;
 
+       /*
+        * If we think the summary counters are bad, clear the unmount header
+        * flag in the unmount record so that the summary counters will be
+        * recalculated during log recovery at next mount.  Refer to
+        * xlog_check_unmount_rec for more details.
+        */
+       if (XFS_TEST_ERROR((mp->m_flags & XFS_MOUNT_BAD_SUMMARY), mp,
+                       XFS_ERRTAG_FORCE_SUMMARY_RECALC)) {
+               xfs_alert(mp, "%s: will fix summary counters at next mount",
+                               __func__);
+               flags &= ~XLOG_UNMOUNT_TRANS;
+       }
+
        /* 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);
+       error = xlog_write(log, &vec, tic, &lsn, NULL, flags);
        /*
         * At this point, we're umounting anyway, so there's no point in
         * transitioning log state to IOERROR. Just continue...
index 60462c35ad4bdda7e9d926682f6ba95fdcaccaba..4fb361cde32a12e59c64bbe9b840b526d8eaf921 100644 (file)
@@ -1423,3 +1423,16 @@ xfs_dev_is_read_only(
        }
        return 0;
 }
+
+/* Force the summary counters to be recalculated at next mount. */
+void
+xfs_force_summary_recalc(
+       struct xfs_mount        *mp)
+{
+       if (!xfs_sb_version_haslazysbcount(&mp->m_sb))
+               return;
+
+       spin_lock(&mp->m_sb_lock);
+       mp->m_flags |= XFS_MOUNT_BAD_SUMMARY;
+       spin_unlock(&mp->m_sb_lock);
+}
index f08907db9c613ab06d627a939b73c4c060583809..540353a514783008897c856abbb48f77e9df95dc 100644 (file)
@@ -435,5 +435,6 @@ int xfs_zero_extent(struct xfs_inode *ip, xfs_fsblock_t start_fsb,
 
 struct xfs_error_cfg * xfs_error_get_cfg(struct xfs_mount *mp,
                int error_class, int error);
+void xfs_force_summary_recalc(struct xfs_mount *mp);
 
 #endif /* __XFS_MOUNT_H__ */
This page took 0.058912 seconds and 4 git commands to generate.