* 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