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
- Lines: 188
- Date:
Fri Nov 9 14:28:15 2001
- Orig file:
v2.4.14/linux/fs/nfs/flushd.c
- Orig date:
Sat May 19 17:47:55 2001
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)