patch-2.4.15 linux/fs/nfs/flushd.c

Next file: linux/fs/nfs/inode.c
Previous file: linux/fs/nfs/Makefile
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.14/linux/fs/nfs/flushd.c linux/fs/nfs/flushd.c
@@ -38,9 +38,9 @@
 
 #include <linux/nfs.h>
 #include <linux/nfs_fs.h>
+#include <linux/nfs_page.h>
 #include <linux/nfs_fs_sb.h>
 #include <linux/nfs_flushd.h>
-#include <linux/nfs_mount.h>
 
 /*
  * Various constants
@@ -111,13 +111,10 @@
 
 	dprintk("NFS: reqlist_exit (ptr %p rpc %p)\n", cache, cache->task);
 
-	while (cache->task || cache->inodes) {
-		if (!cache->task) {
-			nfs_reqlist_init(server);
-		} else {
-			cache->task->tk_status = -ENOMEM;
-			rpc_wake_up_task(cache->task);
-		}
+	while (cache->task) {
+		rpc_exit(cache->task, 0);
+		rpc_wake_up_task(cache->task);
+
 		interruptible_sleep_on_timeout(&cache->request_wait, 1 * HZ);
 	}
  out:
@@ -150,133 +147,47 @@
 	}
 }
 
-void nfs_wake_flushd()
-{
-	rpc_wake_up_status(&flushd_queue, -ENOMEM);
-}
-
-static void inode_append_flushd(struct inode *inode)
-{
-	struct nfs_reqlist	*cache = NFS_REQUESTLIST(inode);
-	struct inode		**q;
-
-	if (NFS_FLAGS(inode) & NFS_INO_FLUSH)
-		goto out;
-	inode->u.nfs_i.hash_next = NULL;
-
-	q = &cache->inodes;
-	while (*q)
-		q = &(*q)->u.nfs_i.hash_next;
-	*q = inode;
-
-	/* Note: we increase the inode i_count in order to prevent
-	 *	 it from disappearing when on the flush list
-	 */
-	NFS_FLAGS(inode) |= NFS_INO_FLUSH;
-	atomic_inc(&inode->i_count);
-out:;
-}
-
-/* Protect me using the BKL */
-void inode_remove_flushd(struct inode *inode)
-{
-	struct nfs_reqlist	*cache = NFS_REQUESTLIST(inode);
-	struct inode		**q;
-
-	if (!(NFS_FLAGS(inode) & NFS_INO_FLUSH))
-		return;
-
-	q = &cache->inodes;
-	while (*q && *q != inode)
-		q = &(*q)->u.nfs_i.hash_next;
-	if (*q) {
-		*q = inode->u.nfs_i.hash_next;
-		NFS_FLAGS(inode) &= ~NFS_INO_FLUSH;
-		iput(inode);
-	}
-}
-
-void inode_schedule_scan(struct inode *inode, unsigned long time)
-{
-	struct nfs_reqlist	*cache = NFS_REQUESTLIST(inode);
-	struct rpc_task		*task;
-	unsigned long		mintimeout;
-
-	lock_kernel();
-	if (time_after(NFS_NEXTSCAN(inode), time))
-		NFS_NEXTSCAN(inode) = time;
-	mintimeout = jiffies + 1 * HZ;
-	if (time_before(mintimeout, NFS_NEXTSCAN(inode)))
-		mintimeout = NFS_NEXTSCAN(inode);
-	inode_append_flushd(inode);
-
-	task = cache->task;
-	if (!task) {
-		nfs_reqlist_init(NFS_SERVER(inode));
-	} else {
-		if (time_after(cache->runat, mintimeout))
-			rpc_wake_up_task(task);
-	}
-	unlock_kernel();
-}
-
-
+#define NFS_FLUSHD_TIMEOUT	(30*HZ)
 static void
 nfs_flushd(struct rpc_task *task)
 {
 	struct nfs_server	*server;
 	struct nfs_reqlist	*cache;
-	struct inode		*inode, *next;
-	unsigned long		delay = jiffies + NFS_WRITEBACK_LOCKDELAY;
-	int			flush = (task->tk_status == -ENOMEM);
+	LIST_HEAD(head);
 
         dprintk("NFS: %4d flushd starting\n", task->tk_pid);
 	server = (struct nfs_server *) task->tk_calldata;
         cache = server->rw_requests;
 
-	next = cache->inodes;
-	cache->inodes = NULL;
-
-	while ((inode = next) != NULL) {
-		next = next->u.nfs_i.hash_next;
-		inode->u.nfs_i.hash_next = NULL;
-		NFS_FLAGS(inode) &= ~NFS_INO_FLUSH;
-
-		if (flush) {
-			nfs_pagein_inode(inode, 0, 0);
-			nfs_sync_file(inode, NULL, 0, 0, FLUSH_AGING);
-		} else if (time_after(jiffies, NFS_NEXTSCAN(inode))) {
-			NFS_NEXTSCAN(inode) = jiffies + NFS_WRITEBACK_LOCKDELAY;
-			nfs_pagein_timeout(inode);
-			nfs_flush_timeout(inode, FLUSH_AGING);
-#ifdef CONFIG_NFS_V3
-			nfs_commit_timeout(inode, FLUSH_AGING);
-#endif
+	for(;;) {
+		spin_lock(&nfs_wreq_lock);
+		if (nfs_scan_lru_dirty_timeout(server, &head)) {
+			spin_unlock(&nfs_wreq_lock);
+			nfs_flush_list(&head, server->wpages, FLUSH_AGING);
+			continue;
 		}
-
-		if (nfs_have_writebacks(inode) || nfs_have_read(inode)) {
-			inode_append_flushd(inode);
-			if (time_after(delay, NFS_NEXTSCAN(inode)))
-				delay = NFS_NEXTSCAN(inode);
+		if (nfs_scan_lru_read_timeout(server, &head)) {
+			spin_unlock(&nfs_wreq_lock);
+			nfs_pagein_list(&head, server->rpages);
+			continue;
 		}
-		iput(inode);
+#ifdef CONFIG_NFS_V3
+		if (nfs_scan_lru_commit_timeout(server, &head)) {
+			spin_unlock(&nfs_wreq_lock);
+			nfs_commit_list(&head, FLUSH_AGING);
+			continue;
+		}
+#endif
+		spin_unlock(&nfs_wreq_lock);
+		break;
 	}
 
 	dprintk("NFS: %4d flushd back to sleep\n", task->tk_pid);
-	if (time_after(jiffies + 1 * HZ, delay))
-		delay = 1 * HZ;
-	else
-		delay = delay - jiffies;
-	task->tk_status = 0;
-	task->tk_action = nfs_flushd;
-	task->tk_timeout = delay;
-	cache->runat = jiffies + task->tk_timeout;
-
-	if (!atomic_read(&cache->nr_requests) && !cache->inodes) {
-		cache->task = NULL;
-		task->tk_action = NULL;
-	} else
+	if (task->tk_action) {
+		task->tk_timeout = NFS_FLUSHD_TIMEOUT;
+		cache->runat = jiffies + task->tk_timeout;
 		rpc_sleep_on(&flushd_queue, task, NULL, NULL);
+	}
 }
 
 static void

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)