Whamcloud - gitweb
ext2obd/ext2obd.c, obdfs/namei.c: fixed inline flag to be o_obdflag, not o_flag
[fs/lustre-release.git] / lustre / obdfs / flushd.c
1 /*
2  * OBDFS Super operations - also used for Lustre file system
3  *
4  *
5  *  Copyright (C) 1991, 1992  Linus Torvalds
6  * Copryright (C) 1999 Stelias Computing Inc. <braam@stelias.com>
7  * Copryright (C) 1999 Seagate Technology Inc.
8  *
9  */
10 #define __NO_VERSION__
11 #include <linux/module.h>
12 #include <linux/sched.h>
13 #include <linux/fs.h>
14 #include <linux/malloc.h>
15 #include <linux/locks.h>
16 #include <linux/errno.h>
17 #include <linux/swap.h>
18 #include <linux/smp_lock.h>
19 #include <linux/vmalloc.h>
20 #include <linux/blkdev.h>
21 #include <linux/sysrq.h>
22 #include <linux/file.h>
23 #include <linux/init.h>
24 #include <linux/quotaops.h>
25 #include <linux/iobuf.h>
26 #include <linux/highmem.h>
27
28 #include <asm/uaccess.h>
29 #include <asm/io.h>
30 #include <asm/bitops.h>
31 #include <asm/mmu_context.h>
32
33 #include <linux/obd_support.h>
34 #include <linux/obd_class.h>
35 #include <linux/obdfs.h>
36
37
38
39 struct {
40         int nfract;  /* Percentage of buffer cache dirty to 
41                         activate bdflush */
42         int ndirty;  /* Maximum number of dirty blocks to write out per
43                         wake-cycle */
44         int nrefill; /* Number of clean buffers to try to obtain
45                                 each time we call refill */
46         int nref_dirt; /* Dirty buffer threshold for activating bdflush
47                           when trying to refill buffers. */
48         int interval; /* jiffies delay between kupdate flushes */
49         int age_buffer;  /* Time for normal buffer to age before we flush it */
50         int age_super;  /* Time for superblock to age before we flush it */
51 } pupd_prm = {40, 500, 64, 256, 5*HZ, 30*HZ, 5*HZ }; 
52
53 /* static void obdfs_flush_reqs(struct obdfs_super_info *sbi, int wait, 
54                              
55 */
56 static void obdfs_flush_reqs(struct obdfs_super_info *sbi, int check_time) 
57 {
58         struct list_head *wr;
59         struct obdfs_pgrq *req;
60         
61         wr = &sbi->s_wr_head;
62         while ( (wr = wr->next) != &sbi->s_wr_head ) {
63                 req = list_entry(wr, struct obdfs_pgrq, rq_list);
64
65                 if (!check_time || 
66                     req->rq_jiffies <= (jiffies - pupd_prm.age_buffer)) {
67                         /* write request out to disk */
68                         obdfs_do_writepage(req->rq_inode, req->rq_page, 1);
69                 }
70
71         }
72
73 }
74
75
76 static void obdfs_flush_dirty_pages(int check_time)
77 {
78         struct list_head *sl;
79         struct obdfs_super_info *sbi;
80
81         sl = &obdfs_super_list;
82         while ( (sl = sl->next) != &obdfs_super_list ) {
83                 struct obdfs_super_entry *entry = 
84                         list_entry(sl, struct obdfs_super_entry, sl_chain);
85                 sbi = entry->sl_sbi;
86
87                 /* walk write requests here */
88                 obdfs_flush_reqs(sbi, jiffies);
89         }
90
91         /* again, but now we wait for completion */
92         sl = &obdfs_super_list;
93         while ( (sl = sl->next) != &obdfs_super_list ) {
94                 struct obdfs_super_entry *entry = 
95                         list_entry(sl, struct obdfs_super_entry, sl_chain);
96                 sbi = entry->sl_sbi;
97
98                 /* walk write requests here */
99                 /* XXX should jiffies be 0 here? */
100                 obdfs_flush_reqs(sbi, jiffies);
101         }
102 }
103
104 static struct task_struct *pupdated;
105
106 static int pupdate(void *unused) 
107 {
108         struct task_struct * tsk = current;
109         int interval;
110         
111         pupdated = current;
112
113         exit_files(current);
114         exit_mm(current);
115
116         tsk->session = 1;
117         tsk->pgrp = 1;
118         sprintf(tsk->comm, "pupd");
119         pupdated = current;
120
121         printk("pupdate() activated...\n");
122
123         /* sigstop and sigcont will stop and wakeup pupdate */
124         spin_lock_irq(&tsk->sigmask_lock);
125         sigfillset(&tsk->blocked);
126         siginitsetinv(&tsk->blocked, sigmask(SIGCONT) | sigmask(SIGSTOP));
127         recalc_sigpending(tsk);
128         spin_unlock_irq(&tsk->sigmask_lock);
129
130         for (;;) {
131                 /* update interval */
132                 interval = pupd_prm.interval;
133                 if (interval)
134                 {
135                         tsk->state = TASK_INTERRUPTIBLE;
136                         schedule_timeout(interval);
137                 }
138                 else
139                 {
140                 stop_pupdate:
141                         printk("pupdate() stopped...\n");
142                         tsk->state = TASK_STOPPED;
143                         MOD_DEC_USE_COUNT;
144                         printk("RETURN from PUPD\n");
145                         return 0;
146                 }
147                 /* check for sigstop */
148                 if (signal_pending(tsk))
149                 {
150                         int stopped = 0;
151                         spin_lock_irq(&tsk->sigmask_lock);
152                         if (sigismember(&tsk->signal, SIGTERM))
153                         {
154                                 sigdelset(&tsk->signal, SIGTERM);
155                                 stopped = 1;
156                         }
157                         recalc_sigpending(tsk);
158                         spin_unlock_irq(&tsk->sigmask_lock);
159                         if (stopped)
160                                 goto stop_pupdate;
161                 }
162                 /* flush_inodes(); */
163                 obdfs_flush_dirty_pages(1);
164         }
165 }
166
167
168 int flushd_init(void)
169 {
170         /*      kernel_thread(bdflush, NULL, CLONE_FS | CLONE_FILES | CLONE_SIGHAND); */
171         MOD_INC_USE_COUNT;
172         kernel_thread(pupdate, NULL, 0);
173         printk("flushd inited\n");
174         return 0;
175 }
176
177 int flushd_cleanup(void)
178 {
179         /* this should deliver a signal to */
180         
181
182         /* XXX Andreas, we will do this later, for now, you must kill
183            pupdated with a SIGSTOP from userland, before unloading obdfs.o
184         */
185         if (pupdated) {
186                 /* send updated a STOP signal */
187                 /* then let it run at least once, before continuing */
188
189                 1;
190         }
191
192         /* not reached */
193         return 0;
194
195 }