]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs_repair: coordinate parallel updates to the rt bitmap
authorDarrick J. Wong <darrick.wong@oracle.com>
Mon, 12 Oct 2020 19:40:01 +0000 (15:40 -0400)
committerEric Sandeen <sandeen@sandeen.net>
Mon, 12 Oct 2020 19:40:01 +0000 (15:40 -0400)
Actually take the rt lock before updating the bitmap from multiple
threads.  This fixes an infrequent corruption problem when running
generic/013 and rtinherit=1 is set on the root dir.

Fixes: 2556c98bd9e6 ("Perform true sequential bulk read prefetching in xfs_repair Merge of master-melb:xfs-cmds:29147a by kenmcd.")
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
repair/dinode.c
repair/globals.c
repair/globals.h
repair/incore.c

index f65a614702fd91bbba50b796e4f24109387aaa8b..c89f21e08373a7f12203c6594672d464f632f61d 100644 (file)
@@ -323,6 +323,7 @@ process_bmbt_reclist_int(
        xfs_extlen_t            blen;
        xfs_agnumber_t          locked_agno = -1;
        int                     error = 1;
+       int                     error2;
 
        if (type == XR_INO_RTDATA)
                ftype = ftype_real_time;
@@ -383,14 +384,14 @@ _("zero length extent (off = %" PRIu64 ", fsbno = %" PRIu64 ") in ino %" PRIu64
                }
 
                if (type == XR_INO_RTDATA && whichfork == XFS_DATA_FORK) {
+                       pthread_mutex_lock(&rt_lock.lock);
+                       error2 = process_rt_rec(mp, &irec, ino, tot, check_dups);
+                       pthread_mutex_unlock(&rt_lock.lock);
+                       if (error2)
+                               return error2;
+
                        /*
-                        * realtime bitmaps don't use AG locks, so returning
-                        * immediately is fine for this code path.
-                        */
-                       if (process_rt_rec(mp, &irec, ino, tot, check_dups))
-                               return 1;
-                       /*
-                        * skip rest of loop processing since that'irec.br_startblock
+                        * skip rest of loop processing since the rest is
                         * all for regular file forks and attr forks
                         */
                        continue;
@@ -442,7 +443,6 @@ _("inode %" PRIu64 " - extent exceeds max offset - start %" PRIu64 ", "
                }
 
                if (blkmapp && *blkmapp) {
-                       int     error2;
                        error2 = blkmap_set_ext(blkmapp, irec.br_startoff,
                                        irec.br_startblock, irec.br_blockcount);
                        if (error2) {
index 299bacd131329fb5a8d6842496da97a0ec22580a..110d98b6681e81f4d29ad0a84eeeb733fa4ac8e2 100644 (file)
@@ -110,6 +110,7 @@ uint32_t    sb_unit;
 uint32_t       sb_width;
 
 struct aglock  *ag_locks;
+struct aglock  rt_lock;
 
 int            report_interval;
 uint64_t       *prog_rpt_done;
index 953e3dfbb4f2a10cdd4422d45d0623e0e7238be7..1d397b351276b9359c7aa4cc3ba0724f8db67e4c 100644 (file)
@@ -154,6 +154,7 @@ struct aglock {
        pthread_mutex_t lock __attribute__((__aligned__(64)));
 };
 extern struct aglock   *ag_locks;
+extern struct aglock   rt_lock;
 
 extern int             report_interval;
 extern uint64_t                *prog_rpt_done;
index 1374ddefe06e42b4266dcfd2da061e42ab11f287..4ffe18aba839b8c022057e4607a44523d9e5371b 100644 (file)
@@ -290,6 +290,7 @@ init_bmaps(xfs_mount_t *mp)
                btree_init(&ag_bmap[i]);
                pthread_mutex_init(&ag_locks[i].lock, NULL);
        }
+       pthread_mutex_init(&rt_lock.lock, NULL);
 
        init_rt_bmap(mp);
        reset_bmaps(mp);