patch-1.3.58 linux/include/linux/locks.h

Next file: linux/include/linux/mcdx.h
Previous file: linux/include/linux/iso_fs.h
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v1.3.57/linux/include/linux/locks.h linux/include/linux/locks.h
@@ -1,6 +1,16 @@
 #ifndef _LINUX_LOCKS_H
 #define _LINUX_LOCKS_H
 
+#ifndef _LINUX_MM_H
+#include <linux/mm.h>
+#endif
+
+/*
+ * Unlocked, temporary IO buffer_heads gets moved to the reuse_list
+ * once their page becomes unlocked.  
+ */
+extern struct buffer_head *reuse_list;
+
 /*
  * Buffer cache locking - note that interrupts may only unlock, not
  * lock buffers.
@@ -21,8 +31,36 @@
 
 extern inline void unlock_buffer(struct buffer_head * bh)
 {
+	struct buffer_head *tmp = bh;
+	int page_locked = 0;
+	unsigned long flags;
+	
 	clear_bit(BH_Lock, &bh->b_state);
 	wake_up(&bh->b_wait);
+	do {
+		if (test_bit(BH_Lock, &tmp->b_state)) {
+			page_locked = 1;
+			break;
+		}
+		tmp=tmp->b_this_page;
+	} while (tmp && tmp != bh);
+	save_flags(flags);
+	if (!page_locked) {
+		struct page *page = mem_map + MAP_NR(bh->b_data);
+		page->locked = 0;
+		wake_up(&page->wait);
+		tmp = bh;
+		cli();
+		do {
+			if (test_bit(BH_FreeOnIO, &tmp->b_state)) {
+				tmp->b_next_free = reuse_list;
+				reuse_list = tmp;
+				clear_bit(BH_FreeOnIO, &tmp->b_state);
+			}
+			tmp = tmp->b_this_page;
+		} while (tmp && tmp != bh);
+		restore_flags(flags);
+	}
 }
 
 /*

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov with Sam's (original) version
of this