This commit was manufactured by cvs2svn to create branch 'fedora'.
[linux-2.6.git] / net / tux / logger.c
1 /*
2  * TUX - Integrated Application Protocols Layer and Object Cache
3  *
4  * Copyright (C) 2000, 2001, Ingo Molnar <mingo@redhat.com>
5  *
6  * Cleaned up logger output for Alpha.
7  * -- Phil Ezolt (Phillip.Ezolt@compaq.com) & Bill Carr (wcarr92@yahoo.com)
8  *
9  * logger.c: log requests finished by TUX.
10  */
11
12 #define __KERNEL_SYSCALLS__
13 #include <net/tux.h>
14
15 /****************************************************************
16  *      This program is free software; you can redistribute it and/or modify
17  *      it under the terms of the GNU General Public License as published by
18  *      the Free Software Foundation; either version 2, or (at your option)
19  *      any later version.
20  *
21  *      This program is distributed in the hope that it will be useful,
22  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
23  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24  *      GNU General Public License for more details.
25  *
26  *      You should have received a copy of the GNU General Public License
27  *      along with this program; if not, write to the Free Software
28  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29  *
30  ****************************************************************/
31
32 static spinlock_t log_lock = SPIN_LOCK_UNLOCKED;
33 static unsigned int log_head, log_tail;
34 static char * log_buffer = NULL;
35 static DECLARE_WAIT_QUEUE_HEAD(log_wait);
36 static DECLARE_WAIT_QUEUE_HEAD(log_full);
37 static int logger_pid = 0;
38
39 /*
40  * High-speed TUX logging architecture:
41  *
42  * All fast threads share a common log-ringbuffer. (default size 1MB)
43  * Log entries are binary and are padded to be cacheline aligned, this
44  * ensures that there is no cache-pingpong between fast threads.
45  *
46  * The logger thread writes out pending log entries within 1 second
47  * (buffer-cache writes data out within 5 seconds). The logger thread
48  * gets activated once we have more than 25% of the log ringbuffer
49  * filled - or the 1 second log timeout expires. Fast threads block
50  * if if more than 95% of the ringbuffer is filled and unblock only
51  * if used logbuffer space drops below 90%.
52  *
53  * This architecture guarantees that 1) logging is reliable (no
54  * log entry is ever lost), 2) timely (touches disk within 6 seconds),
55  * 3) in the log-contention case the saturation behavior is still
56  * write-clustered, but 4) if the logger thread can keep up then
57  * the coupling is completely asynchron and parallel.
58  *
59  * The binary log format gives us about 50% saved IO/memory bandwith
60  * and 50% less on-disk used log space than the traditional W3C ASCII
61  * format.
62  *
63  * (We might switch to raw IO though to write the logfile.)
64  */
65
66 #define SOFT_LIMIT              (LOG_LEN*25/100)
67 #define HARD_LIMIT              (LOG_LEN*95/100)
68 #define HARD_RELAX_LIMIT        (LOG_LEN*90/100)
69
70 unsigned int tux_logentry_align_order = 5;
71
72 #if SMP_CACHE_BYTES == 8
73 # define TUX_LOGENTRY_ALIGN 3
74 #else
75 #if SMP_CACHE_BYTES == 16
76 # define TUX_LOGENTRY_ALIGN 4
77 #else
78 #if SMP_CACHE_BYTES == 32
79 # define TUX_LOGENTRY_ALIGN 5
80 #else
81 #if SMP_CACHE_BYTES == 64
82 # define TUX_LOGENTRY_ALIGN 6
83 #else
84 #if SMP_CACHE_BYTES == 128
85 # define TUX_LOGENTRY_ALIGN 7
86 #else
87 #if SMP_CACHE_BYTES == 256
88 # define TUX_LOGENTRY_ALIGN 8
89 #else
90 #error Add entry!
91 #endif
92 #endif
93 #endif
94 #endif
95 #endif
96 #endif
97
98 #define ROUND_UP(x) (((((x)-1) >> TUX_LOGENTRY_ALIGN) + 1) \
99                                         << TUX_LOGENTRY_ALIGN)
100
101 static void __throttle_logging (void)
102 {
103         DECLARE_WAITQUEUE(wait, current);
104         int pending;
105
106         add_wait_queue(&log_full, &wait);
107         for (;;) {
108                 static unsigned long last_warning = 0;
109
110                 if (jiffies - last_warning > 10*HZ) {
111                         last_warning = jiffies;
112                         printk(KERN_NOTICE "TUX: log buffer overflow, have to throttle TUX thread!\n");
113                 }
114
115                 current->state = TASK_INTERRUPTIBLE;
116
117                 spin_lock(&log_lock);
118                 pending = log_head-log_tail;
119                 spin_unlock(&log_lock);
120
121                 if ((pending % LOG_LEN) < HARD_LIMIT)
122                         break;
123
124                 schedule();
125         }
126         current->state = TASK_RUNNING;
127         remove_wait_queue(&log_full, &wait);
128 }
129
130 #if CONFIG_TUX_DEBUG
131 #define CHECK_LOGPTR(ptr) \
132 do { \
133         if ((ptr < log_buffer) || (ptr > log_buffer + LOG_LEN)) { \
134                 printk(KERN_ERR "TUX: ouch: log ptr %p > %p + %ld!\n", \
135                         ptr, log_buffer, LOG_LEN); \
136                 TUX_BUG(); \
137         } \
138 } while (0)
139 #else
140 #define CHECK_LOGPTR(ptr) do { } while (0)
141 #endif
142
143 void __log_request (tux_req_t *req)
144 {
145         char *str, *next;
146         const char *uri_str;
147         unsigned int inc, len, uri_len, pending, next_head, def_vhost_len = 0;
148         unsigned long flags;
149
150         if (req->proto->pre_log)
151                 req->proto->pre_log(req);
152         /*
153          * Log the reply status (success, or type of failure)
154          */
155         if (!tux_log_incomplete && (!req->status || (req->bytes_sent == -1))) {
156                 
157                 Dprintk("not logging req %p: {%s} [%d/%d]\n", req, req->uri_str, req->status, req->bytes_sent);
158                 return;
159         }
160         Dprintk("uri: {%s} [%d]\n", req->uri_str, req->uri_len);
161
162 #define NO_URI "<none>"
163         if (req->uri_len) {
164                 uri_len = req->uri_len;
165                 uri_str = req->uri_str;
166         } else {
167                 uri_str = NO_URI;
168                 uri_len = sizeof(NO_URI)-1;
169         }
170         len = uri_len + 1;
171
172         if (req->virtual) {
173                 if (req->host_len)
174                         len += req->host_len;
175                 else {
176                         def_vhost_len = strlen(tux_default_vhost);
177                         len += def_vhost_len;
178                 }
179         }
180
181         Dprintk("method_str: {%s} [%d]\n", req->method_str, req->method_len);
182         len += req->method_len + 1;
183
184         Dprintk("version_str: {%s} [%d]\n", req->version_str, req->version_len);
185         len += req->version_len + 1;
186
187 #if CONFIG_TUX_EXTENDED_LOG
188         Dprintk("user_agent_str: {%s} [%d]\n", req->user_agent_str, req->user_agent_len);
189         len += req->user_agent_len + 1;
190 #endif
191         if (tux_referer_logging) {
192                 Dprintk("referer_str: {%s} [%d]\n", req->referer_str, req->referer_len);
193                 len += req->referer_len;
194         }
195         len++;
196
197         inc = 5*sizeof(u32) + len;
198 #if CONFIG_TUX_EXTENDED_LOG
199         inc += 7*sizeof(u32);
200 #endif
201
202         spin_lock_irqsave(&log_lock, flags);
203
204         next_head = ROUND_UP(log_head + inc);
205
206         if (next_head < LOG_LEN) {
207                 str = log_buffer + log_head;
208                 if (str > log_buffer + LOG_LEN)
209                         TUX_BUG();
210                 log_head = next_head;
211         } else {
212                 if (log_head < LOG_LEN)
213                         memset(log_buffer+log_head, 0, LOG_LEN-log_head);
214                 str = log_buffer;
215                 log_head = ROUND_UP(inc);
216         }
217
218         if (str < log_buffer || str+inc >= log_buffer+LOG_LEN)
219                 TUX_BUG();
220
221         /*
222          * Log record signature - this makes finding the next entry
223          * easier (since record length is variable), and makes the
224          * binary logfile more robust against potential data corruption
225          * and other damage. The signature also servers as a log format
226          * version identifier.
227          */
228 #if CONFIG_TUX_EXTENDED_LOG
229         *(u32 *)str = 0x2223beef;
230 #else
231         *(u32 *)str = 0x1112beef;
232 #endif
233         str += sizeof(u32);
234         CHECK_LOGPTR(str);
235
236         *(u32 *)str = 0;
237         /*
238          * Log the client IP address:
239          */
240         if (tux_ip_logging)
241                 *(u32 *)str = req->client_addr;
242         str += sizeof(u32);
243         CHECK_LOGPTR(str);
244
245 #if CONFIG_TUX_EXTENDED_LOG
246         /*
247          * Log the client port number:
248          */
249         *(u32 *)str = 0;
250         if (tux_ip_logging)
251                 *(u32 *)str = req->client_port;
252         str += sizeof(u32);
253         CHECK_LOGPTR(str);
254 #endif
255
256         /*
257          * Log the request timestamp, in units of 'seconds since 1970'.
258          */
259         *(u32 *)str = CURRENT_TIME.tv_sec;
260         str += sizeof(u32);
261         CHECK_LOGPTR(str);
262
263 #if CONFIG_TUX_EXTENDED_LOG
264         *(u32 *)str = req->accept_timestamp; str += sizeof(u32);
265         *(u32 *)str = req->parse_timestamp; str += sizeof(u32);
266         *(u32 *)str = req->output_timestamp; str += sizeof(u32);
267         *(u32 *)str = req->flush_timestamp; str += sizeof(u32);
268         *(u32 *)str = req->had_cachemiss; str += sizeof(u32);
269         *(u32 *)str = req->keep_alive; str += sizeof(u32);
270 #endif
271         /*
272          * Log the requested file size (in fact, log actual bytes sent.)
273          */
274         *(u32 *)str = req->bytes_sent;
275         str += sizeof(u32);
276         CHECK_LOGPTR(str);
277
278         *(u32 *)str = req->status;
279         str += sizeof(u32);
280         CHECK_LOGPTR(str);
281
282         /*
283          * Zero-terminated method, (base) URI, query and version string.
284          */
285         if (req->method_len) {
286                 memcpy(str, req->method_str, req->method_len);
287                 str += req->method_len;
288                 CHECK_LOGPTR(str);
289         }
290         *str++ = 0;
291
292         if (req->virtual) {
293                 if (req->host_len) {
294                         memcpy(str, req->host, req->host_len);
295                         str += req->host_len;
296                 } else {
297                         memcpy(str, tux_default_vhost, def_vhost_len);
298                         str += def_vhost_len;
299                 }
300                 CHECK_LOGPTR(str);
301         }
302
303         memcpy(str, uri_str, uri_len);
304         str += uri_len;
305         *str++ = 0;
306
307         CHECK_LOGPTR(str);
308
309         if (req->version_len) {
310                 memcpy(str, req->version_str, req->version_len);
311                 str += req->version_len;
312                 CHECK_LOGPTR(str);
313         }
314         *str++ = 0;
315 #if CONFIG_TUX_EXTENDED_LOG
316         if (req->user_agent_len) {
317                 memcpy(str, req->user_agent_str, req->user_agent_len);
318                 str += req->user_agent_len;
319                 CHECK_LOGPTR(str);
320         }
321         *str++ = 0;
322 #endif
323         CHECK_LOGPTR(str);
324
325         if (tux_referer_logging && req->referer_len) {
326                 memcpy(str, req->referer_str, req->referer_len);
327                 str += req->referer_len;
328                 CHECK_LOGPTR(str);
329         }
330         *str++ = 0;
331         CHECK_LOGPTR(str);
332         /*
333          * pad with spaces to next cacheline, with an ending newline.
334          * (not needed for the user-space log utility, but results in
335          * a more readable binary log file, and reduces the amount
336          * of cache pingpong.)
337          */
338         next = (char *)ROUND_UP((unsigned long)str);
339
340         CHECK_LOGPTR(next);
341         len = next-str;
342         memset(str, ' ', len);
343
344         pending = (log_head-log_tail) % LOG_LEN;
345         spin_unlock_irqrestore(&log_lock, flags);
346
347         if (pending >= SOFT_LIMIT)
348                 wake_up(&log_wait);
349
350         if (pending >= HARD_LIMIT)
351                 __throttle_logging();
352 }
353
354 void tux_push_pending (struct sock *sk)
355 {
356         struct tcp_opt *tp = tcp_sk(sk);
357
358         Dprintk("pushing pending frames on sock %p.\n", sk);
359         lock_sock(sk);
360         if ((sk->sk_state == TCP_ESTABLISHED) && !sk->sk_err) {
361                 tp->ack.pingpong = tux_ack_pingpong;
362                 tp->nonagle = 1;
363                 __tcp_push_pending_frames(sk, tp, tcp_current_mss(sk, 0), TCP_NAGLE_OFF);
364         }
365         release_sock(sk);
366 }
367
368 inline void tux_push_req (tux_req_t *req)
369 {
370         if (req->sock)
371                 tux_push_pending(req->sock->sk);
372         if (req->data_sock)
373                 tux_push_pending(req->data_sock->sk);
374 }
375
376 void __put_data_sock (tux_req_t *req)
377 {
378         unlink_tux_data_socket(req);
379         if (req->data_sock->file)
380                 fput(req->data_sock->file);
381         else
382                 sock_release(req->data_sock);
383         req->data_sock = NULL;
384 }
385
386 /* open-coded sys_close */
387
388 long tux_close(unsigned int fd)
389 {
390         struct file * filp;
391         struct files_struct *files = current->files;
392
393         spin_lock(&files->file_lock);
394         if (fd >= files->max_fds)
395                 goto out_unlock;
396         filp = files->fd[fd];
397         if (!filp)
398                 goto out_unlock;
399         files->fd[fd] = NULL;
400         FD_CLR(fd, files->close_on_exec);
401         /* __put_unused_fd(files, fd); */
402         __FD_CLR(fd, files->open_fds);
403         if (fd < files->next_fd)
404                 files->next_fd = fd;
405         spin_unlock(&files->file_lock);
406         return filp_close(filp, files);
407
408 out_unlock:
409         spin_unlock(&files->file_lock);
410         return -EBADF;
411 }
412
413 void flush_request (tux_req_t *req, int cachemiss)
414 {
415         struct socket *sock;
416         struct sock *sk;
417         int keep_alive;
418
419         if (cachemiss)
420                 TUX_BUG();
421         __set_task_state(current, TASK_RUNNING);
422
423         if (req->magic != TUX_MAGIC)
424                 TUX_BUG();
425         if (req->ti->thread != current)
426                 TUX_BUG();
427 #if CONFIG_TUX_DEBUG
428         if (req->bytes_expected && (req->bytes_sent != req->bytes_expected)) {
429                 printk("hm, bytes_expected: %d != bytes_sent: %d!\n",
430                         req->bytes_expected, req->bytes_sent);
431                 TUX_BUG();
432         }
433 #endif
434         SET_TIMESTAMP(req->flush_timestamp);
435
436         log_request(req);
437         sock = req->sock;
438         sk = NULL;
439         if (sock)
440                 sk = sock->sk;
441         Dprintk("FLUSHING req %p <%p> (sock %p, sk %p) (keepalive: %d, status: %d)\n", req, __builtin_return_address(0), sock, sk, req->keep_alive, req->status);
442         if (req->in_file.f_pos)
443                 /*TUX_BUG()*/;
444         release_req_dentry(req);
445         req->private = 0;
446
447         if (req->docroot_dentry) {
448                 dput(req->docroot_dentry);
449                 req->docroot_dentry = NULL;
450                 if (!req->docroot_mnt)
451                         TUX_BUG();
452         }
453         if (req->docroot_mnt) {
454                 mntput(req->docroot_mnt);
455                 req->docroot_mnt = NULL;
456         }
457
458         req->offset_start = 0;
459         req->offset_end = 0;
460         req->output_len = 0;
461         req->total_file_len = 0;
462         req->lendigits = 0;
463         req->mtime = 0;
464         req->etaglen = 0;
465         req->etag[0] = 0;
466         req->ftp_command = 0;
467
468         if (req->postponed)
469                 TUX_BUG();
470         if (test_bit(0, &req->idle_input))
471                 TUX_BUG();
472         if (test_bit(0, &req->wait_output_space))
473                 TUX_BUG();
474         if (req->parsed_len)
475                 trunc_headers(req);
476         if (req->parsed_len)
477                 TUX_BUG();
478         req->attr = NULL;
479         req->usermode = 0;
480         req->usermodule_idx = 0;
481         req->atom_idx = 0;
482         if (req->module_dentry) {
483                 dput(req->module_dentry);
484                 req->module_dentry = NULL;
485         }
486         if (req->headers)
487                 kfree(req->headers);
488         req->headers = NULL;
489         req->headers_len = 0;
490
491         req->method = METHOD_NONE;
492         req->method_len = 0;
493         req->method_str = NULL;
494         req->version = 0;
495         req->version_str = NULL;
496         req->version_len = 0;
497
498         req->uri_str = NULL;
499         req->uri_len = 0;
500
501         req->objectname[0] = 0;
502         req->objectname_len = 0;
503
504         req->query_str = NULL;
505         req->query_len = 0;
506
507         req->cookies_str = NULL;
508         req->cookies_len = 0;
509         req->parse_cookies = 0;
510
511         req->contentlen_str = NULL;
512         req->contentlen_len = 0;
513         req->content_len = 0;
514
515         req->user_agent_str = NULL;
516         req->user_agent_len = 0;
517
518         req->may_send_gzip = 0;
519         req->content_gzipped = 0;
520
521         req->content_type_str = NULL;
522         req->content_type_len = 0;
523
524         req->accept_str = NULL;
525         req->accept_len = 0;
526
527         req->accept_charset_str = NULL;
528         req->accept_charset_len = 0;
529
530         req->accept_encoding_str = NULL;
531         req->accept_encoding_len = 0;
532
533         req->accept_language_str = NULL;
534         req->accept_language_len = 0;
535
536         req->cache_control_str = NULL;
537         req->cache_control_len = 0;
538
539         req->if_modified_since_str = NULL;
540         req->if_modified_since_len = 0;
541
542         req->if_none_match_str = NULL;
543         req->if_none_match_len = 0;
544
545         req->if_range_str = NULL;
546         req->if_range_len = 0;
547
548         req->negotiate_str = NULL;
549         req->negotiate_len = 0;
550
551         req->pragma_str = NULL;
552         req->pragma_len = 0;
553
554         req->referer_str = NULL;
555         req->referer_len = 0;
556
557         req->post_data_str = NULL;
558         req->post_data_len = 0;
559
560         SET_TIMESTAMP(req->accept_timestamp);
561 #if CONFIG_TUX_EXTENDED_LOG
562         req->parse_timestamp = 0;
563         req->output_timestamp = 0;
564         req->flush_timestamp = 0;
565 #endif
566         req->status = 0;
567
568         req->total_bytes += req->bytes_sent;
569         req->bytes_sent = 0;
570 #if CONFIG_TUX_DEBUG
571         req->bytes_expected = 0;
572 #endif
573         req->body_len = 0;
574         keep_alive = req->keep_alive;
575         clear_keepalive(req);
576         req->had_cachemiss = 0;
577         // first_timestamp and total_bytes is kept!
578         req->event = 0;
579         req->lookup_dir = 0;
580         req->lookup_404 = 0;
581
582         req->error = 0;
583         req->user_error = 0;
584
585         if (req->abuf.page)
586                 __free_page(req->abuf.page);
587         memset(&req->abuf, 0, sizeof(req->abuf));
588
589         if (sk && keep_alive) {
590                 add_tux_atom(req, parse_request);
591                 if (skb_queue_empty(&sk->sk_receive_queue)) {
592                         spin_lock_irq(&req->ti->work_lock);
593                         add_keepalive_timer(req);
594                         if (test_and_set_bit(0, &req->idle_input))
595                                 TUX_BUG();
596                         /*
597                          * Avoid the race with the event callback:
598                          */
599                         if (skb_queue_empty(&sk->sk_receive_queue) ||
600                                    !test_and_clear_bit(0, &req->idle_input)) {
601                                 INC_STAT(nr_idle_input_pending);
602                                 spin_unlock_irq(&req->ti->work_lock);
603                                 tux_push_req(req);
604                                 goto out;
605                         }
606                         del_keepalive_timer(req);
607                         spin_unlock_irq(&req->ti->work_lock);
608                 }
609                 Dprintk("KEEPALIVE PENDING req %p <%p> (sock %p, sk %p) (keepalive: %d, status: %d)\n", req, __builtin_return_address(0), req->sock, req->sock->sk, req->keep_alive, req->status);
610                 add_req_to_workqueue(req);
611                 INC_STAT(nr_keepalive_optimized);
612                 goto out;
613         }
614
615         del_timer_sync(&req->keepalive_timer);
616         del_timer_sync(&req->output_timer);
617
618         if (timer_pending(&req->keepalive_timer))
619                 TUX_BUG();
620         if (timer_pending(&req->output_timer))
621                 TUX_BUG();
622         if (!list_empty(&req->lru))
623                 TUX_BUG();
624         req->nr_keepalives = 0;
625         req->client_addr = 0;
626         req->client_port = 0;
627         req->virtual = 0;
628         req->ftp_offset_start = 0;
629
630         req->host[0] = 0;
631         req->host_len = 0;
632
633         if (req->cwd_dentry) {
634                 dput(req->cwd_dentry);
635                 req->cwd_dentry = NULL;
636                 if (!req->cwd_mnt)
637                         TUX_BUG();
638         }
639         if (req->cwd_mnt) {
640                 mntput(req->cwd_mnt);
641                 req->cwd_mnt = NULL;
642         }
643         put_data_sock(req);
644         req->prev_pos = 0;
645         req->curroff = 0;
646         req->total = 0;
647         if (req->dirp0) {
648                 kfree(req->dirp0);
649                 req->dirp0 = NULL;
650         }
651
652         if (sk)
653                 unlink_tux_socket(req);
654         req->sock = NULL;
655         /*
656          * Close potential user-space file descriptors.
657          */
658         {
659                 int fd = req->fd, ret;
660
661                 if (fd != -1) {
662                         req->fd = -1;
663                         ret = tux_close(fd);
664                         if (ret)
665                                 TUX_BUG();
666                 } else
667                         if (sock)
668                                 sock_release(sock);
669         }
670         kfree_req(req);
671 out:
672         ;
673 }
674
675 static int warn_once = 1;
676
677 static unsigned int writeout_log (void)
678 {
679         unsigned int len, pending, next_log_tail;
680         mm_segment_t oldmm = get_fs();
681         struct file *log_filp;
682         char * str;
683         unsigned int ret;
684
685         if (tux_logging)
686                 Dprintk("TUX logger: opening log file {%s}.\n", tux_logfile);
687         log_filp = tux_open_file(tux_logfile, O_CREAT|O_APPEND|O_WRONLY|O_LARGEFILE);
688         if (!log_filp) {
689                 if (warn_once) {
690                         printk(KERN_ERR "TUX: could not open log file {%s}!\n",
691                                 tux_logfile);
692                         warn_once = 0;
693                 }
694                 __set_current_state(TASK_INTERRUPTIBLE);
695                 schedule_timeout(HZ);
696                 return 0;
697         }
698         spin_lock(&log_lock);
699         str = log_buffer + log_tail;
700         if (log_head < log_tail) {
701                 len = LOG_LEN-log_tail;
702                 next_log_tail = 0;
703         } else {
704                 len = log_head-log_tail;
705                 next_log_tail = log_head;
706         }
707         if (!len)
708                 goto out;
709         spin_unlock(&log_lock);
710
711         set_fs(KERNEL_DS);
712         ret = log_filp->f_op->write(log_filp, str, len, &log_filp->f_pos);
713         set_fs(oldmm);
714
715         if (len != ret) {
716                 if (ret == -ENOSPC) {
717                         printk(KERN_ERR "TUX: trying to write TUX logfile %s, but filesystem is full! Lost %d bytes of log data.\n", tux_logfile, len);
718                 } else {
719                         printk(KERN_ERR "TUX: log write %d != %d.\n", ret, len);
720                         printk(KERN_ERR "TUX: log_filp: %p, str: %p, len: %d str[len-1]: %d.\n", log_filp, str, len, str[len-1]);
721                 }
722                 goto out_lock;
723         }
724
725         /*
726          * Sync log data to disk:
727          */
728         if (log_filp->f_op && log_filp->f_op->fsync) {
729                 down(&log_filp->f_dentry->d_inode->i_sem);
730                 log_filp->f_op->fsync(log_filp, log_filp->f_dentry, 1);
731                 up(&log_filp->f_dentry->d_inode->i_sem);
732         }
733
734         /*
735          * Reduce the cache footprint of the logger file - it's
736          * typically write-once.
737          */
738         invalidate_inode_pages(log_filp->f_dentry->d_inode->i_mapping);
739
740 out_lock:
741         spin_lock(&log_lock);
742 out:
743         log_tail = next_log_tail;
744         pending = (log_head-log_tail) % LOG_LEN;
745         spin_unlock(&log_lock);
746
747         if (pending < HARD_LIMIT)
748                 wake_up(&log_full);
749
750         fput(log_filp);
751         return pending;
752 }
753
754 static DECLARE_WAIT_QUEUE_HEAD(stop_logger_wait);
755 static int stop_logger = 0;
756
757 static int logger_thread (void *data)
758 {
759         DECLARE_WAITQUEUE(wait, current);
760         mm_segment_t oldmm;
761
762         daemonize("TUX logger");
763
764         oldmm = get_fs();
765         set_fs(KERNEL_DS);
766         printk(KERN_NOTICE "TUX: logger thread started.\n");
767 #if CONFIG_SMP
768         {
769                 cpumask_t log_mask, map;
770
771                 mask_to_cpumask(log_cpu_mask, &log_mask);
772                 cpus_and(map, cpu_online_map, log_mask);
773                 if(!(cpus_empty(map)))
774                         set_cpus_allowed(current, map);
775
776         }
777 #endif
778
779
780         spin_lock_irq(&current->sighand->siglock);
781         siginitsetinv(&current->blocked, 0);
782         recalc_sigpending();
783         spin_unlock_irq(&current->sighand->siglock);
784
785         if (log_buffer)
786                 TUX_BUG();
787         log_buffer = vmalloc(LOG_LEN);
788         memset(log_buffer, 0, LOG_LEN);
789         log_head = log_tail = 0;
790
791         current->rlim[RLIMIT_FSIZE].rlim_cur = RLIM_INFINITY;
792
793         add_wait_queue(&log_wait, &wait);
794         for (;;) {
795                 if (tux_logging)
796                         Dprintk("logger does writeout - stop:%d.\n", stop_logger);
797
798                 while (writeout_log() >= SOFT_LIMIT) {
799                         if (stop_logger)
800                                 break;
801                 }
802                 if (stop_logger)
803                         break;
804                         /* nothing */;
805
806                 if (tux_logging)
807                         Dprintk("logger does sleep - stop:%d.\n", stop_logger);
808                 __set_current_state(TASK_INTERRUPTIBLE);
809                 if (log_head != log_tail) {
810                         __set_current_state(TASK_RUNNING);
811                         continue;
812                 }
813                 schedule_timeout(HZ);
814                 if (tux_logging)
815                         Dprintk("logger back from sleep - stop:%d.\n", stop_logger);
816                 if (signal_pending(current))
817                         flush_all_signals();
818         }
819         remove_wait_queue(&log_wait, &wait);
820
821         vfree(log_buffer);
822         log_buffer = NULL;
823         stop_logger = 0;
824         wake_up(&stop_logger_wait);
825
826         set_fs(oldmm);
827
828         return 0;
829 }
830
831 void start_log_thread (void)
832 {
833         warn_once = 1;
834
835         logger_pid = kernel_thread(logger_thread, NULL, 0);
836         if (logger_pid < 0)
837                 TUX_BUG();
838 }
839
840 void stop_log_thread (void)
841 {
842         DECLARE_WAITQUEUE(wait, current);
843
844         Dprintk("stopping logger thread %d ...\n", logger_pid);
845
846         __set_current_state(TASK_UNINTERRUPTIBLE);
847         add_wait_queue(&stop_logger_wait, &wait);
848         stop_logger = 1;
849         wake_up(&log_wait);
850         schedule();
851         __set_current_state(TASK_RUNNING);
852         remove_wait_queue(&stop_logger_wait, &wait);
853
854         Dprintk("logger thread stopped!\n");
855 }