OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [fs/] [nfs/] [flushd.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
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
 
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
 
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
 
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
 
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
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
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
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.