]> git.ipfire.org Git - thirdparty/xfsprogs-dev.git/commitdiff
xfs: consider shutdown in bmapbt cursor delete assert
authorBrian Foster <bfoster@redhat.com>
Wed, 7 Apr 2021 16:00:33 +0000 (12:00 -0400)
committerEric Sandeen <sandeen@sandeen.net>
Wed, 7 Apr 2021 16:00:33 +0000 (12:00 -0400)
Source kernel commit: 1cd738b13ae9b29e03d6149f0246c61f76e81fcf

The assert in xfs_btree_del_cursor() checks that the bmapbt block
allocation field has been handled correctly before the cursor is
freed. This field is used for accurate calculation of indirect block
reservation requirements (for delayed allocations), for example.
generic/019 reproduces a scenario where this assert fails because
the filesystem has shutdown while in the middle of a bmbt record
insertion. This occurs after a bmbt block has been allocated via the
cursor but before the higher level bmap function (i.e.
xfs_bmap_add_extent_hole_real()) completes and resets the field.

Update the assert to accommodate the transient state if the
filesystem has shutdown. While here, clean up the indentation and
comments in the function.

Signed-off-by: Brian Foster <bfoster@redhat.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Eric Sandeen <sandeen@sandeen.net>
include/kmem.h
libxfs/xfs_btree.c

index c8e25953fd9f31bf2faa960f8169fc0396e4f8fa..383284eaafb1ef60378251fa1730bfac93d9e784 100644 (file)
@@ -42,8 +42,8 @@ extern void   *kmem_alloc_large(size_t, int);
 extern void    *kmem_zalloc(size_t, int);
 
 static inline void
-kmem_free(void *ptr) {
-       free(ptr);
+kmem_free(const void *ptr) {
+       free((void *)ptr);
 }
 
 extern void    *krealloc(void *, size_t, int);
index a2356df6a097c804ca6c5598040edf08b6350ed3..d1ac742b50f57ec74059cafec23ac9f053974c61 100644 (file)
@@ -350,20 +350,17 @@ xfs_btree_free_block(
  */
 void
 xfs_btree_del_cursor(
-       xfs_btree_cur_t *cur,           /* btree cursor */
-       int             error)          /* del because of error */
+       struct xfs_btree_cur    *cur,           /* btree cursor */
+       int                     error)          /* del because of error */
 {
-       int             i;              /* btree level */
+       int                     i;              /* btree level */
 
        /*
-        * Clear the buffer pointers, and release the buffers.
-        * If we're doing this in the face of an error, we
-        * need to make sure to inspect all of the entries
-        * in the bc_bufs array for buffers to be unlocked.
-        * This is because some of the btree code works from
-        * level n down to 0, and if we get an error along
-        * the way we won't have initialized all the entries
-        * down to 0.
+        * Clear the buffer pointers and release the buffers. If we're doing
+        * this because of an error, inspect all of the entries in the bc_bufs
+        * array for buffers to be unlocked. This is because some of the btree
+        * code works from level n down to 0, and if we get an error along the
+        * way we won't have initialized all the entries down to 0.
         */
        for (i = 0; i < cur->bc_nlevels; i++) {
                if (cur->bc_bufs[i])
@@ -371,17 +368,11 @@ xfs_btree_del_cursor(
                else if (!error)
                        break;
        }
-       /*
-        * Can't free a bmap cursor without having dealt with the
-        * allocated indirect blocks' accounting.
-        */
-       ASSERT(cur->bc_btnum != XFS_BTNUM_BMAP ||
-              cur->bc_ino.allocated == 0);
-       /*
-        * Free the cursor.
-        */
+
+       ASSERT(cur->bc_btnum != XFS_BTNUM_BMAP || cur->bc_ino.allocated == 0 ||
+              XFS_FORCED_SHUTDOWN(cur->bc_mp));
        if (unlikely(cur->bc_flags & XFS_BTREE_STAGING))
-               kmem_free((void *)cur->bc_ops);
+               kmem_free(cur->bc_ops);
        kmem_cache_free(xfs_btree_cur_zone, cur);
 }