[PATCH] fix livelock waiting for stale metapage (2 of 7)

[email protected] (Dave Kleikamp) Fri, 18 Feb 2005 17:07:18 -0600 (CST)
Newsgroups gmane.comp.file-systems.jfs.patches
Message-ID <[email protected]>
# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2005/01/20 14:14:19-06:00 [email protected] 
#   JFS: fix livelock waiting for stale metapage
#   
#   Several waitors were keeping mp->count from going to zero, so we
#   would never release the page.  Simplify the logic by doing a busy
#   wait without locking the metapage.
#   
#   Signed-off-by: Dave Kleikamp <[email protected]>
# 
diff -Nru a/fs/jfs/jfs_metapage.c b/fs/jfs/jfs_metapage.c
--- a/fs/jfs/jfs_metapage.c	2005-02-18 17:02:01 -06:00
+++ b/fs/jfs/jfs_metapage.c	2005-02-18 17:02:01 -06:00
@@ -242,14 +242,14 @@
 	mp = search_hash(hash_ptr, mapping, lblock);
 	if (mp) {
 	      page_found:
-		mp->count++;
-		lock_metapage(mp);
-		spin_unlock(&meta_lock);
 		if (test_bit(META_stale, &mp->flag)) {
-			release_metapage(mp);
-			yield();	/* Let other waiters release it, too */
+			spin_unlock(&meta_lock);
+			msleep(1);
 			goto again;
 		}
+		mp->count++;
+		lock_metapage(mp);
+		spin_unlock(&meta_lock);
 		if (test_bit(META_discard, &mp->flag)) {
 			if (!new) {
 				jfs_error(inode->i_sb,
@@ -461,7 +461,6 @@
 	}
 
 	if (mp->page) {
-		/* Releasing spinlock, we have to check mp->count later */
 		set_bit(META_stale, &mp->flag);
 		spin_unlock(&meta_lock);
 		kunmap(mp->page);
@@ -498,12 +497,6 @@
 		list_del(&mp->synclist);
 		LOGSYNC_UNLOCK(log);
 	}
-	if (mp->count) {
-		/* Someone else is trying to get this metpage */
-		unlock_metapage(mp);
-		spin_unlock(&meta_lock);
-		return;
-	}
 	remove_from_hash(mp, meta_hash(mp->mapping, mp->index));
 	spin_unlock(&meta_lock);
 
@@ -532,12 +525,8 @@
 		mp = search_hash(hash_ptr, mapping, lblock);
 		if (mp) {
 			if (test_bit(META_stale, &mp->flag)) {
-				/* Racing with release_metapage */
-				mp->count++;
-				lock_metapage(mp);
 				spin_unlock(&meta_lock);
-				/* racing release_metapage should be done now */
-				release_metapage(mp);
+				msleep(1);
 				goto again;
 			}