1 /*
2  * linux/fs/nfs/flushd.c
3  *
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).
10  *
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).
14  *
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.
18  *
19  * Copyright (C) 1996, 1997, Olaf Kirch <okir@monad.swb.de>
20  *
21  * Rewritten 6/3/2000 by Trond Myklebust
22  * Copyright (C) 1999, 2000, Trond Myklebust <trond.myklebust@fys.uio.no>
23  */
24 
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>
30 
31 #include <linux/sched.h>
32 
33 #include <linux/sunrpc/auth.h>
34 #include <linux/sunrpc/clnt.h>
35 #include <linux/sunrpc/sched.h>
36 
37 #include <linux/smp_lock.h>
38 
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>
44 
45 /*
46  * Various constants
47  */
48 #define NFSDBG_FACILITY         NFSDBG_PAGECACHE
49 
50 /*
51  * This is the wait queue all cluster daemons sleep on
52  */
53 static RPC_WAITQ(flushd_queue, "nfs_flushd");
54 
55 /*
56  * Local function declarations.
57  */
58 static void	nfs_flushd(struct rpc_task *);
59 static void	nfs_flushd_exit(struct rpc_task *);
60 
61 
nfs_reqlist_init(struct nfs_server * server)62 static int nfs_reqlist_init(struct nfs_server *server)
63 {
64 	struct nfs_reqlist	*cache;
65 	struct rpc_task		*task;
66 	int			status;
67 
68 	dprintk("NFS: writecache_init\n");
69 
70 	lock_kernel();
71 	status = -ENOMEM;
72 	/* Create the RPC task */
73 	if (!(task = rpc_new_task(server->client, NULL, RPC_TASK_ASYNC)))
74 		goto out_unlock;
75 
76 	cache = server->rw_requests;
77 
78 	status = 0;
79 	if (cache->task)
80 		goto out_unlock;
81 
82 	task->tk_calldata = server;
83 
84 	cache->task = task;
85 
86 	/* Run the task */
87 	cache->runat = jiffies;
88 
89 	cache->auth = server->client->cl_auth;
90 	task->tk_action   = nfs_flushd;
91 	task->tk_exit   = nfs_flushd_exit;
92 
93 	rpc_execute(task);
94 	unlock_kernel();
95 	return 0;
96  out_unlock:
97 	if (task)
98 		rpc_release_task(task);
99 	unlock_kernel();
100 	return status;
101 }
102 
nfs_reqlist_exit(struct nfs_server * server)103 void nfs_reqlist_exit(struct nfs_server *server)
104 {
105 	struct nfs_reqlist      *cache;
106 
107 	lock_kernel();
108 	cache = server->rw_requests;
109 	if (!cache)
110 		goto out;
111 
112 	dprintk("NFS: reqlist_exit (ptr %p rpc %p)\n", cache, cache->task);
113 
114 	while (cache->task) {
115 		rpc_exit(cache->task, 0);
116 		rpc_wake_up_task(cache->task);
117 
118 		interruptible_sleep_on_timeout(&cache->request_wait, 1 * HZ);
119 	}
120  out:
121 	unlock_kernel();
122 }
123 
nfs_reqlist_alloc(struct nfs_server * server)124 int nfs_reqlist_alloc(struct nfs_server *server)
125 {
126 	struct nfs_reqlist	*cache;
127 	if (server->rw_requests)
128 		return 0;
129 
130 	cache = (struct nfs_reqlist *)kmalloc(sizeof(*cache), GFP_KERNEL);
131 	if (!cache)
132 		return -ENOMEM;
133 
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;
138 
139 	return nfs_reqlist_init(server);
140 }
141 
nfs_reqlist_free(struct nfs_server * server)142 void nfs_reqlist_free(struct nfs_server *server)
143 {
144 	if (server->rw_requests) {
145 		kfree(server->rw_requests);
146 		server->rw_requests = NULL;
147 	}
148 }
149 
150 #define NFS_FLUSHD_TIMEOUT	(30*HZ)
151 static void
nfs_flushd(struct rpc_task * task)152 nfs_flushd(struct rpc_task *task)
153 {
154 	struct nfs_server	*server;
155 	struct nfs_reqlist	*cache;
156 	LIST_HEAD(head);
157 
158         dprintk("NFS: %4d flushd starting\n", task->tk_pid);
159 	server = (struct nfs_server *) task->tk_calldata;
160         cache = server->rw_requests;
161 
162 	for(;;) {
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);
167 			continue;
168 		}
169 		if (nfs_scan_lru_read_timeout(server, &head)) {
170 			spin_unlock(&nfs_wreq_lock);
171 			nfs_pagein_list(&head, server->rpages);
172 			continue;
173 		}
174 #ifdef CONFIG_NFS_V3
175 		if (nfs_scan_lru_commit_timeout(server, &head)) {
176 			spin_unlock(&nfs_wreq_lock);
177 			nfs_commit_list(&head, FLUSH_AGING);
178 			continue;
179 		}
180 #endif
181 		spin_unlock(&nfs_wreq_lock);
182 		break;
183 	}
184 
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);
190 	}
191 }
192 
193 static void
nfs_flushd_exit(struct rpc_task * task)194 nfs_flushd_exit(struct rpc_task *task)
195 {
196 	struct nfs_server	*server;
197 	struct nfs_reqlist	*cache;
198 	server = (struct nfs_server *) task->tk_calldata;
199 	cache = server->rw_requests;
200 
201 	if (cache->task == task)
202 		cache->task = NULL;
203 	wake_up(&cache->request_wait);
204 }
205 
206