2 * linux/fs/nfs/flushd.c
4 * For each NFS mount, there is a separate cache object that contains
5 * a hash table of all clusters. With this cache, an async RPC task
6 * (`flushd') is associated, which wakes up occasionally to inspect
7 * its list of dirty buffers.
8 * (Note that RPC tasks aren't kernel threads. Take a look at the
9 * rpciod code to understand what they are).
11 * Inside the cache object, we also maintain a count of the current number
12 * of dirty pages, which may not exceed a certain threshold.
13 * (FIXME: This threshold should be configurable).
15 * The code is streamlined for what I think is the prevalent case for
16 * NFS traffic, which is sequential write access without concurrent
17 * access by different processes.
19 * Copyright (C) 1996, 1997, Olaf Kirch <okir@monad.swb.de>
21 * Rewritten 6/3/2000 by Trond Myklebust
22 * Copyright (C) 1999, 2000, Trond Myklebust <trond.myklebust@fys.uio.no>
25 #include <linux/config.h>
26 #include <linux/types.h>
27 #include <linux/slab.h>
28 #include <linux/pagemap.h>
29 #include <linux/file.h>
31 #include <linux/sched.h>
33 #include <linux/sunrpc/auth.h>
34 #include <linux/sunrpc/clnt.h>
35 #include <linux/sunrpc/sched.h>
37 #include <linux/smp_lock.h>
39 #include <linux/nfs.h>
40 #include <linux/nfs_fs.h>
41 #include <linux/nfs_page.h>
42 #include <linux/nfs_fs_sb.h>
43 #include <linux/nfs_flushd.h>
48 #define NFSDBG_FACILITY NFSDBG_PAGECACHE
51 * This is the wait queue all cluster daemons sleep on
53 static RPC_WAITQ(flushd_queue, "nfs_flushd");
56 * Local function declarations.
58 static void nfs_flushd(struct rpc_task *);
59 static void nfs_flushd_exit(struct rpc_task *);
62 static int nfs_reqlist_init(struct nfs_server *server)
64 struct nfs_reqlist *cache;
65 struct rpc_task *task;
68 dprintk("NFS: writecache_init\n");
72 /* Create the RPC task */
73 if (!(task = rpc_new_task(server->client, NULL, RPC_TASK_ASYNC)))
76 cache = server->rw_requests;
82 task->tk_calldata = server;
87 cache->runat = jiffies;
89 cache->auth = server->client->cl_auth;
90 task->tk_action = nfs_flushd;
91 task->tk_exit = nfs_flushd_exit;
98 rpc_release_task(task);
103 void nfs_reqlist_exit(struct nfs_server *server)
105 struct nfs_reqlist *cache;
108 cache = server->rw_requests;
112 dprintk("NFS: reqlist_exit (ptr %p rpc %p)\n", cache, cache->task);
114 while (cache->task) {
115 rpc_exit(cache->task, 0);
116 rpc_wake_up_task(cache->task);
118 interruptible_sleep_on_timeout(&cache->request_wait, 1 * HZ);
124 int nfs_reqlist_alloc(struct nfs_server *server)
126 struct nfs_reqlist *cache;
127 if (server->rw_requests)
130 cache = (struct nfs_reqlist *)kmalloc(sizeof(*cache), GFP_KERNEL);
134 memset(cache, 0, sizeof(*cache));
135 atomic_set(&cache->nr_requests, 0);
136 init_waitqueue_head(&cache->request_wait);
137 server->rw_requests = cache;
139 return nfs_reqlist_init(server);
142 void nfs_reqlist_free(struct nfs_server *server)
144 if (server->rw_requests) {
145 kfree(server->rw_requests);
146 server->rw_requests = NULL;
150 #define NFS_FLUSHD_TIMEOUT (30*HZ)
152 nfs_flushd(struct rpc_task *task)
154 struct nfs_server *server;
155 struct nfs_reqlist *cache;
158 dprintk("NFS: %4d flushd starting\n", task->tk_pid);
159 server = (struct nfs_server *) task->tk_calldata;
160 cache = server->rw_requests;
163 spin_lock(&nfs_wreq_lock);
164 if (nfs_scan_lru_dirty_timeout(server, &head)) {
165 spin_unlock(&nfs_wreq_lock);
166 nfs_flush_list(&head, server->wpages, FLUSH_AGING);
169 if (nfs_scan_lru_read_timeout(server, &head)) {
170 spin_unlock(&nfs_wreq_lock);
171 nfs_pagein_list(&head, server->rpages);
175 if (nfs_scan_lru_commit_timeout(server, &head)) {
176 spin_unlock(&nfs_wreq_lock);
177 nfs_commit_list(&head, FLUSH_AGING);
181 spin_unlock(&nfs_wreq_lock);
185 dprintk("NFS: %4d flushd back to sleep\n", task->tk_pid);
186 if (task->tk_action) {
187 task->tk_timeout = NFS_FLUSHD_TIMEOUT;
188 cache->runat = jiffies + task->tk_timeout;
189 rpc_sleep_on(&flushd_queue, task, NULL, NULL);
194 nfs_flushd_exit(struct rpc_task *task)
196 struct nfs_server *server;
197 struct nfs_reqlist *cache;
198 server = (struct nfs_server *) task->tk_calldata;
199 cache = server->rw_requests;
201 if (cache->task == task)
203 wake_up(&cache->request_wait);