* Mon Mar 15 2010 Eric Sandeen <sandeen@redhat.com> 3.1.1-6
- Fix missing locking for btree manipulation in xfs_repair
This commit is contained in:
parent
8ed7cf78f2
commit
f6dae0c6d0
108
xfsprogs-3.1.1-btree-locking.patch
Normal file
108
xfsprogs-3.1.1-btree-locking.patch
Normal file
@ -0,0 +1,108 @@
|
||||
From: Dave Chinner <dchinner@redhat.com>
|
||||
Date: Sun, 14 Mar 2010 22:52:08 +0000 (+1100)
|
||||
Subject: xfsprogs: duplicate extent btrees in xfs_repair need locking
|
||||
X-Git-Url: http://git.kernel.org/?p=fs%2Fxfs%2Fxfsprogs-dev.git;a=commitdiff_plain;h=853a75b3b30b0556fb5f100d4087f1ce46769bd1
|
||||
|
||||
xfsprogs: duplicate extent btrees in xfs_repair need locking
|
||||
|
||||
The per-ag duplicate extent btrees can be search concurrently from multiple
|
||||
threads. This occurs when inode extent lists are being processed and inodes
|
||||
with extents in the same AG are checked concurrently. The btrees have an
|
||||
internal traversal cursor, so doing concurrent searches can result in the
|
||||
cursor being corrupted for both searches.
|
||||
|
||||
Add an external lock for each duplicate extent tree and use it for searches,
|
||||
inserts and deletes to ensure that we don't trash the state of any operation.
|
||||
|
||||
Signed-off-by: Dave Chinner <dchinner@redhat.com>
|
||||
Reviewed-by: Christoph Hellwig <hch@lst.de>
|
||||
---
|
||||
|
||||
diff --git a/repair/incore_ext.c b/repair/incore_ext.c
|
||||
index a362e5a..60dd4c4 100644
|
||||
--- a/repair/incore_ext.c
|
||||
+++ b/repair/incore_ext.c
|
||||
@@ -74,6 +74,7 @@ static rt_ext_flist_t rt_ext_flist;
|
||||
static avl64tree_desc_t *rt_ext_tree_ptr; /* dup extent tree for rt */
|
||||
|
||||
static struct btree_root **dup_extent_trees; /* per ag dup extent trees */
|
||||
+static pthread_mutex_t *dup_extent_tree_locks;
|
||||
|
||||
static avltree_desc_t **extent_bno_ptrs; /*
|
||||
* array of extent tree ptrs
|
||||
@@ -108,7 +109,9 @@ void
|
||||
release_dup_extent_tree(
|
||||
xfs_agnumber_t agno)
|
||||
{
|
||||
+ pthread_mutex_lock(&dup_extent_tree_locks[agno]);
|
||||
btree_clear(dup_extent_trees[agno]);
|
||||
+ pthread_mutex_unlock(&dup_extent_tree_locks[agno]);
|
||||
}
|
||||
|
||||
int
|
||||
@@ -117,12 +120,16 @@ add_dup_extent(
|
||||
xfs_agblock_t startblock,
|
||||
xfs_extlen_t blockcount)
|
||||
{
|
||||
+ int ret;
|
||||
#ifdef XR_DUP_TRACE
|
||||
fprintf(stderr, "Adding dup extent - %d/%d %d\n", agno, startblock,
|
||||
blockcount);
|
||||
#endif
|
||||
- return btree_insert(dup_extent_trees[agno], startblock,
|
||||
+ pthread_mutex_lock(&dup_extent_tree_locks[agno]);
|
||||
+ ret = btree_insert(dup_extent_trees[agno], startblock,
|
||||
(void *)(uintptr_t)(startblock + blockcount));
|
||||
+ pthread_mutex_unlock(&dup_extent_tree_locks[agno]);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
int
|
||||
@@ -132,13 +139,22 @@ search_dup_extent(
|
||||
xfs_agblock_t end_agbno)
|
||||
{
|
||||
unsigned long bno;
|
||||
+ int ret;
|
||||
|
||||
- if (!btree_find(dup_extent_trees[agno], start_agbno, &bno))
|
||||
- return 0; /* this really shouldn't happen */
|
||||
- if (bno < end_agbno)
|
||||
- return 1;
|
||||
- return (uintptr_t)btree_peek_prev(dup_extent_trees[agno], NULL) >
|
||||
+ pthread_mutex_lock(&dup_extent_tree_locks[agno]);
|
||||
+ if (!btree_find(dup_extent_trees[agno], start_agbno, &bno)) {
|
||||
+ ret = 0;
|
||||
+ goto out; /* this really shouldn't happen */
|
||||
+ }
|
||||
+ if (bno < end_agbno) {
|
||||
+ ret = 1;
|
||||
+ goto out;
|
||||
+ }
|
||||
+ ret = (uintptr_t)btree_peek_prev(dup_extent_trees[agno], NULL) >
|
||||
start_agbno;
|
||||
+out:
|
||||
+ pthread_mutex_unlock(&dup_extent_tree_locks[agno]);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -856,6 +872,10 @@ incore_ext_init(xfs_mount_t *mp)
|
||||
if (!dup_extent_trees)
|
||||
do_error(_("couldn't malloc dup extent tree descriptor table\n"));
|
||||
|
||||
+ dup_extent_tree_locks = calloc(agcount, sizeof(pthread_mutex_t));
|
||||
+ if (!dup_extent_tree_locks)
|
||||
+ do_error(_("couldn't malloc dup extent tree descriptor table\n"));
|
||||
+
|
||||
if ((extent_bno_ptrs = malloc(agcount *
|
||||
sizeof(avltree_desc_t *))) == NULL)
|
||||
do_error(
|
||||
@@ -879,6 +899,7 @@ incore_ext_init(xfs_mount_t *mp)
|
||||
|
||||
for (i = 0; i < agcount; i++) {
|
||||
btree_init(&dup_extent_trees[i]);
|
||||
+ pthread_mutex_init(&dup_extent_tree_locks[i], NULL);
|
||||
avl_init_tree(extent_bno_ptrs[i], &avl_extent_tree_ops);
|
||||
avl_init_tree(extent_bcnt_ptrs[i], &avl_extent_bcnt_tree_ops);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
Summary: Utilities for managing the XFS filesystem
|
||||
Name: xfsprogs
|
||||
Version: 3.1.1
|
||||
Release: 5%{?dist}
|
||||
Release: 6%{?dist}
|
||||
# Licensing based on generic "GNU GENERAL PUBLIC LICENSE"
|
||||
# in source, with no mention of version.
|
||||
# doc/COPYING file specifies what is GPL and what is LGPL
|
||||
@ -21,6 +21,7 @@ Conflicts: xfsdump < 3.0.1
|
||||
Patch0: xfsprogs-3.1.0-glibc-fixes.patch
|
||||
Patch1: xfsprogs-3.1.1-fd-test-fix.patch
|
||||
Patch2: xfsprogs-3.1.1-empty-blkid-fix.patch
|
||||
Patch3: xfsprogs-3.1.1-btree-locking.patch
|
||||
|
||||
%description
|
||||
A set of commands to use the XFS filesystem, including mkfs.xfs.
|
||||
@ -68,6 +69,7 @@ in building or running the xfstests QA suite.
|
||||
%patch0 -p1
|
||||
%patch1 -p1
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
|
||||
%build
|
||||
export tagname=CC DEBUG=-DNDEBUG
|
||||
@ -193,6 +195,9 @@ rm -rf $RPM_BUILD_ROOT
|
||||
%{_includedir}/xfs/xfs_types.h
|
||||
|
||||
%changelog
|
||||
* Mon Mar 15 2010 Eric Sandeen <sandeen@redhat.com> 3.1.1-6
|
||||
- Fix missing locking for btree manipulation in xfs_repair
|
||||
|
||||
* Fri Feb 12 2010 Eric Sandeen <sandeen@redhat.com> 3.1.1-5
|
||||
- --enable-static=no doesn't work; just nuke static libs
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user