- updated to 2.6.0-test4.
[opensuse:kernel-source.git] / patches.uml / uml-patch-2.6.0-test3-1
1 --- linux-2.6.0-test4/arch/um/kernel/tt/ptproxy/proxy.c.uml     2003-08-25 09:29:10.000000000 +0200
2 +++ linux-2.6.0-test4/arch/um/kernel/tt/ptproxy/proxy.c 2003-08-25 10:19:28.000000000 +0200
3 @@ -293,10 +293,10 @@
4  }
5  
6  char gdb_init_string[] = 
7 -"att 1
8 -b panic
9 -b stop
10 -handle SIGWINCH nostop noprint pass
11 +"att 1 \n\
12 +b panic \n\
13 +b stop \n\
14 +handle SIGWINCH nostop noprint pass \n\
15  ";
16  
17  int start_debugger(char *prog, int startup, int stop, int *fd_out)
18 --- linux-2.6.0-test4/arch/um/kernel/tt/include/uaccess.h.uml   2003-08-25 09:29:15.000000000 +0200
19 +++ linux-2.6.0-test4/arch/um/kernel/tt/include/uaccess.h       2003-08-25 10:19:28.000000000 +0200
20 @@ -46,18 +46,20 @@
21  
22  static inline int copy_from_user_tt(void *to, const void *from, int n)
23  {
24 -       return(access_ok_tt(VERIFY_READ, from, n) ?
25 -              __do_copy_from_user(to, from, n, 
26 -                                  &current->thread.fault_addr,
27 -                                  &current->thread.fault_catcher) : n);
28 +       if(!access_ok_tt(VERIFY_READ, from, n)) 
29 +               return(n);
30 +
31 +       return(__do_copy_from_user(to, from, n, &current->thread.fault_addr,
32 +                                  &current->thread.fault_catcher));
33  }
34  
35  static inline int copy_to_user_tt(void *to, const void *from, int n)
36  {
37 -       return(access_ok_tt(VERIFY_WRITE, to, n) ?
38 -              __do_copy_to_user(to, from, n, 
39 -                                  &current->thread.fault_addr,
40 -                                  &current->thread.fault_catcher) : n);
41 +       if(!access_ok_tt(VERIFY_WRITE, to, n))
42 +               return(n);
43 +               
44 +       return(__do_copy_to_user(to, from, n, &current->thread.fault_addr,
45 +                                &current->thread.fault_catcher));
46  }
47  
48  extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
49 @@ -67,7 +69,9 @@
50  {
51         int n;
52  
53 -       if(!access_ok_tt(VERIFY_READ, src, 1)) return(-EFAULT);
54 +       if(!access_ok_tt(VERIFY_READ, src, 1)) 
55 +               return(-EFAULT);
56 +
57         n = __do_strncpy_from_user(dst, src, count, 
58                                    &current->thread.fault_addr,
59                                    &current->thread.fault_catcher);
60 @@ -87,10 +91,11 @@
61  
62  static inline int clear_user_tt(void *mem, int len)
63  {
64 -       return(access_ok_tt(VERIFY_WRITE, mem, len) ? 
65 -              __do_clear_user(mem, len, 
66 -                              &current->thread.fault_addr,
67 -                              &current->thread.fault_catcher) : len);
68 +       if(!access_ok_tt(VERIFY_WRITE, mem, len))
69 +               return(len);
70 +
71 +       return(__do_clear_user(mem, len, &current->thread.fault_addr,
72 +                              &current->thread.fault_catcher));
73  }
74  
75  extern int __do_strnlen_user(const char *str, unsigned long n,
76 --- linux-2.6.0-test4/arch/um/kernel/tt/process_kern.c.uml      2003-08-25 09:29:40.000000000 +0200
77 +++ linux-2.6.0-test4/arch/um/kernel/tt/process_kern.c  2003-08-25 10:19:28.000000000 +0200
78 @@ -104,7 +104,10 @@
79  
80  void release_thread_tt(struct task_struct *task)
81  {
82 -       os_kill_process(task->thread.mode.tt.extern_pid, 0);
83 +       int pid = task->thread.mode.tt.extern_pid;
84 +
85 +       if(os_getpid() != pid)
86 +               os_kill_process(pid, 0);
87  }
88  
89  void exit_thread_tt(void)
90 @@ -125,27 +128,27 @@
91         UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
92         suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
93  
94 -       block_signals();
95 +       force_flush_all();
96 +       if(current->thread.prev_sched != NULL)
97 +               schedule_tail(current->thread.prev_sched);
98 +       current->thread.prev_sched = NULL;
99 +
100         init_new_thread_signals(1);
101 -#ifdef CONFIG_SMP
102 -       schedule_tail(current->thread.prev_sched);
103 -#endif
104         enable_timer();
105         free_page(current->thread.temp_stack);
106         set_cmdline("(kernel thread)");
107 -       force_flush_all();
108  
109 -       current->thread.prev_sched = NULL;
110         change_sig(SIGUSR1, 1);
111         change_sig(SIGVTALRM, 1);
112         change_sig(SIGPROF, 1);
113 -       unblock_signals();
114 +       local_irq_enable();
115         if(!run_kernel_thread(fn, arg, &current->thread.exec_buf))
116                 do_exit(0);
117  }
118  
119  static int new_thread_proc(void *stack)
120  {
121 +       local_irq_disable();
122         init_new_thread_stack(stack, new_thread_handler);
123         os_usr1_process(os_getpid());
124         return(0);
125 @@ -165,35 +168,32 @@
126         UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
127         suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
128  
129 -#ifdef CONFIG_SMP      
130 -       schedule_tail(NULL);
131 -#endif
132 +       force_flush_all();
133 +       if(current->thread.prev_sched != NULL)
134 +               schedule_tail(current->thread.prev_sched);
135 +       current->thread.prev_sched = NULL;
136 +
137         enable_timer();
138         change_sig(SIGVTALRM, 1);
139         local_irq_enable();
140 -       force_flush_all();
141         if(current->mm != current->parent->mm)
142                 protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 
143                                1, 0, 1);
144         task_protections((unsigned long) current->thread_info);
145  
146 -       current->thread.prev_sched = NULL;
147 -
148         free_page(current->thread.temp_stack);
149 +       local_irq_disable();
150         change_sig(SIGUSR1, 0);
151         set_user_mode(current);
152  }
153  
154 -static int sigusr1 = SIGUSR1;
155 -
156  int fork_tramp(void *stack)
157  {
158 -       int sig = sigusr1;
159 -
160         local_irq_disable();
161 +       arch_init_thread();
162         init_new_thread_stack(stack, finish_fork_handler);
163  
164 -       kill(os_getpid(), sig);
165 +       os_usr1_process(os_getpid());
166         return(0);
167  }
168  
169 --- linux-2.6.0-test4/arch/um/kernel/tt/tracer.c.uml    2003-08-25 09:28:10.000000000 +0200
170 +++ linux-2.6.0-test4/arch/um/kernel/tt/tracer.c        2003-08-25 10:19:28.000000000 +0200
171 @@ -39,7 +39,7 @@
172                 return(0);
173  
174         register_winch_irq(tracer_winch[0], fd, -1, data);
175 -       return(0);
176 +       return(1);
177  }
178  
179  static void tracer_winch_handler(int sig)
180 @@ -401,7 +401,7 @@
181                 
182                 if(!strcmp(line, "go")) debug_stop = 0;
183                 else if(!strcmp(line, "parent")) debug_parent = 1;
184 -               else printk("Unknown debug option : '%s'\n", line);
185 +               else printf("Unknown debug option : '%s'\n", line);
186  
187                 line = next;
188         }
189 --- linux-2.6.0-test4/arch/um/kernel/tt/uaccess_user.c.uml      2003-08-25 09:28:39.000000000 +0200
190 +++ linux-2.6.0-test4/arch/um/kernel/tt/uaccess_user.c  2003-08-25 10:19:28.000000000 +0200
191 @@ -8,15 +8,20 @@
192  #include <string.h>
193  #include "user_util.h"
194  #include "uml_uaccess.h"
195 +#include "task.h"
196 +#include "kern_util.h"
197  
198  int __do_copy_from_user(void *to, const void *from, int n,
199                         void **fault_addr, void **fault_catcher)
200  {
201 +       struct tt_regs save = TASK_REGS(get_current())->tt;
202         unsigned long fault;
203         int faulted;
204  
205         fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
206                                __do_copy, &faulted);
207 +       TASK_REGS(get_current())->tt = save;
208 +
209         if(!faulted) return(0);
210         else return(n - (fault - (unsigned long) from));
211  }
212 @@ -29,11 +34,14 @@
213  int __do_strncpy_from_user(char *dst, const char *src, unsigned long count,
214                            void **fault_addr, void **fault_catcher)
215  {
216 +       struct tt_regs save = TASK_REGS(get_current())->tt;
217         unsigned long fault;
218         int faulted;
219  
220         fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher,
221                                __do_strncpy, &faulted);
222 +       TASK_REGS(get_current())->tt = save;
223 +
224         if(!faulted) return(strlen(dst));
225         else return(-1);
226  }
227 @@ -46,11 +54,14 @@
228  int __do_clear_user(void *mem, unsigned long len,
229                     void **fault_addr, void **fault_catcher)
230  {
231 +       struct tt_regs save = TASK_REGS(get_current())->tt;
232         unsigned long fault;
233         int faulted;
234  
235         fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher,
236                                __do_clear, &faulted);
237 +       TASK_REGS(get_current())->tt = save;
238 +
239         if(!faulted) return(0);
240         else return(len - (fault - (unsigned long) mem));
241  }
242 @@ -58,6 +69,7 @@
243  int __do_strnlen_user(const char *str, unsigned long n,
244                       void **fault_addr, void **fault_catcher)
245  {
246 +       struct tt_regs save = TASK_REGS(get_current())->tt;
247         int ret;
248         unsigned long *faddrp = (unsigned long *)fault_addr;
249         jmp_buf jbuf;
250 @@ -71,6 +83,8 @@
251         }
252         *fault_addr = NULL;
253         *fault_catcher = NULL;
254 +
255 +       TASK_REGS(get_current())->tt = save;
256         return ret;
257  }
258  
259 --- linux-2.6.0-test4/arch/um/kernel/skas/include/mode.h.uml    2003-08-25 09:29:05.000000000 +0200
260 +++ linux-2.6.0-test4/arch/um/kernel/skas/include/mode.h        2003-08-25 10:19:28.000000000 +0200
261 @@ -20,6 +20,7 @@
262  extern void halt_skas(void);
263  extern void reboot_skas(void);
264  extern void kill_off_processes_skas(void);
265 +extern int is_skas_winch(int pid, int fd, void *data);
266  
267  #endif
268  
269 --- linux-2.6.0-test4/arch/um/kernel/skas/include/uaccess.h.uml 2003-08-25 09:28:51.000000000 +0200
270 +++ linux-2.6.0-test4/arch/um/kernel/skas/include/uaccess.h     2003-08-25 10:19:28.000000000 +0200
271 @@ -19,7 +19,7 @@
272  #define access_ok_skas(type, addr, size) \
273         ((segment_eq(get_fs(), KERNEL_DS)) || \
274          (((unsigned long) (addr) < TASK_SIZE) && \
275 -         ((unsigned long) (addr) + (size) < TASK_SIZE)))
276 +         ((unsigned long) (addr) + (size) <= TASK_SIZE)))
277  
278  static inline int verify_area_skas(int type, const void * addr, 
279                                    unsigned long size)
280 --- linux-2.6.0-test4/arch/um/kernel/skas/util/mk_ptregs.c.uml  2003-08-25 09:28:49.000000000 +0200
281 +++ linux-2.6.0-test4/arch/um/kernel/skas/util/mk_ptregs.c      2003-08-25 10:19:28.000000000 +0200
282 @@ -1,3 +1,4 @@
283 +#include <stdio.h>
284  #include <asm/ptrace.h>
285  #include <asm/user.h>
286  
287 --- linux-2.6.0-test4/arch/um/kernel/skas/Makefile.uml  2003-08-25 09:28:39.000000000 +0200
288 +++ linux-2.6.0-test4/arch/um/kernel/skas/Makefile      2003-08-25 10:19:28.000000000 +0200
289 @@ -7,18 +7,22 @@
290         process_kern.o syscall_kern.o syscall_user.o time.o tlb.o trap_user.o \
291         sys-$(SUBARCH)/
292  
293 +host-progs     := util/mk_ptregs
294 +clean-files    := include/skas_ptregs.h
295 +
296  USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o
297  USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
298  
299 -include/skas_ptregs.h : util/mk_ptregs
300 -       util/mk_ptregs > $@
301 -
302 -util/mk_ptregs :
303 -       $(MAKE) -C util
304 +$(TOPDIR)/arch/um/include/skas_ptregs.h : $(src)/util/mk_ptregs
305 +       @echo -n '  Generating $@'
306 +       @$< > $@.tmp
307 +       @if [ -r $@ ] && cmp -s $@ $@.tmp; then \
308 +               echo ' (unchanged)'; \
309 +               rm -f $@.tmp; \
310 +       else \
311 +               echo ' (updated)'; \
312 +               mv -f $@.tmp $@; \
313 +       fi
314  
315  $(USER_OBJS) : %.o: %.c
316         $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
317 -
318 -clean :
319 -       $(MAKE) -C util clean
320 -       $(RM) -f include/skas_ptregs.h
321 --- linux-2.6.0-test4/arch/um/kernel/skas/process.c.uml 2003-08-25 09:29:54.000000000 +0200
322 +++ linux-2.6.0-test4/arch/um/kernel/skas/process.c     2003-08-25 10:19:28.000000000 +0200
323 @@ -4,6 +4,7 @@
324   */
325  
326  #include <stdlib.h>
327 +#include <unistd.h>
328  #include <errno.h>
329  #include <signal.h>
330  #include <setjmp.h>
331 @@ -24,6 +25,16 @@
332  #include "os.h"
333  #include "proc_mm.h"
334  #include "skas_ptrace.h"
335 +#include "chan_user.h"
336 +
337 +int is_skas_winch(int pid, int fd, void *data)
338 +{
339 +       if(pid != getpid())
340 +               return(0);
341 +
342 +       register_winch_irq(-1, fd, -1, data);
343 +       return(1);
344 +}
345  
346  unsigned long exec_regs[FRAME_SIZE];
347  unsigned long exec_fp_regs[HOST_FP_SIZE];
348 @@ -72,8 +83,6 @@
349         handle_syscall(regs);
350  }
351  
352 -int userspace_pid;
353 -
354  static int userspace_tramp(void *arg)
355  {
356         init_new_thread_signals(0);
357 @@ -83,6 +92,8 @@
358         return(0);
359  }
360  
361 +int userspace_pid;
362 +
363  void start_userspace(void)
364  {
365         void *stack;
366 @@ -149,6 +160,7 @@
367                         case SIGILL:
368                         case SIGBUS:
369                         case SIGFPE:
370 +                       case SIGWINCH:
371                                 user_signal(WSTOPSIG(status), regs);
372                                 break;
373                         default:
374 @@ -328,7 +340,8 @@
375  int new_mm(int from)
376  {
377         struct proc_mm_op copy;
378 -       int n, fd = os_open_file("/proc/mm", of_write(OPENFLAGS()), 0);
379 +       int n, fd = os_open_file("/proc/mm", 
380 +                                of_cloexec(of_write(OPENFLAGS())), 0);
381  
382         if(fd < 0)
383                 return(-errno);
384 @@ -342,6 +355,7 @@
385                         printk("new_mm : /proc/mm copy_segments failed, "
386                                "errno = %d\n", errno);
387         }
388 +
389         return(fd);
390  }
391  
392 --- linux-2.6.0-test4/arch/um/kernel/skas/process_kern.c.uml    2003-08-25 09:28:25.000000000 +0200
393 +++ linux-2.6.0-test4/arch/um/kernel/skas/process_kern.c        2003-08-25 10:19:28.000000000 +0200
394 @@ -61,9 +61,8 @@
395         thread_wait(&current->thread.mode.skas.switch_buf, 
396                     current->thread.mode.skas.fork_buf);
397  
398 -#ifdef CONFIG_SMP
399 -       schedule_tail(NULL);
400 -#endif
401 +       if(current->thread.prev_sched != NULL)
402 +               schedule_tail(current->thread.prev_sched);
403         current->thread.prev_sched = NULL;
404  
405         n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
406 @@ -93,9 +92,8 @@
407                     current->thread.mode.skas.fork_buf);
408         
409         force_flush_all();
410 -#ifdef CONFIG_SMP
411 -       schedule_tail(current->thread.prev_sched);
412 -#endif
413 +       if(current->thread.prev_sched != NULL)
414 +               schedule_tail(current->thread.prev_sched);
415         current->thread.prev_sched = NULL;
416         unblock_signals();
417  
418 @@ -164,7 +162,7 @@
419         capture_signal_stack();
420  
421         init_new_thread_signals(1);
422 -       idle_timer();
423 +       uml_idle_timer();
424  
425         init_task.thread.request.u.thread.proc = start_kernel_proc;
426         init_task.thread.request.u.thread.arg = NULL;
427 --- linux-2.6.0-test4/arch/um/kernel/Makefile.uml       2003-08-25 09:29:17.000000000 +0200
428 +++ linux-2.6.0-test4/arch/um/kernel/Makefile   2003-08-25 10:19:28.000000000 +0200
429 @@ -21,6 +21,8 @@
430  obj-$(CONFIG_MODE_TT) += tt/
431  obj-$(CONFIG_MODE_SKAS) += skas/
432  
433 +clean-files    := config.c
434 +
435  user-objs-$(CONFIG_TTY_LOG) += tty_log.o
436  
437  USER_OBJS := $(filter %_user.o,$(obj-y))  $(user-objs-y) config.o helper.o \
438 @@ -45,17 +47,13 @@
439  $(obj)/frame.o: $(src)/frame.c
440         $(CC) $(CFLAGS_$(notdir $@)) -c -o $@ $<
441  
442 -QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
443 +QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; $$config =~ s/\n/\\n"\n"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
444  
445  $(obj)/config.c : $(src)/config.c.in $(TOPDIR)/.config
446         $(PERL) -e $(QUOTE) < $(src)/config.c.in > $@
447  
448  $(obj)/config.o : $(obj)/config.c
449  
450 -clean:
451 -       rm -f config.c
452 -       for dir in $(subdir-y) ; do $(MAKE) -C $$dir clean; done
453 -
454  modules:
455  
456  fastdep:
457 --- linux-2.6.0-test4/arch/um/kernel/config.c.in.uml    2003-08-25 09:29:30.000000000 +0200
458 +++ linux-2.6.0-test4/arch/um/kernel/config.c.in        2003-08-25 10:19:28.000000000 +0200
459 @@ -7,9 +7,7 @@
460  #include <stdlib.h>
461  #include "init.h"
462  
463 -static __initdata char *config = "
464 -CONFIG
465 -";
466 +static __initdata char *config = "CONFIG";
467  
468  static int __init print_config(char *line, int *add)
469  {
470 --- linux-2.6.0-test4/arch/um/kernel/exec_kern.c.uml    2003-08-25 09:28:26.000000000 +0200
471 +++ linux-2.6.0-test4/arch/um/kernel/exec_kern.c        2003-08-25 10:19:28.000000000 +0200
472 @@ -32,10 +32,15 @@
473         CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp);
474  }
475  
476 +extern void log_exec(char **argv, void *tty);
477 +
478  static int execve1(char *file, char **argv, char **env)
479  {
480          int error;
481  
482 +#ifdef CONFIG_TTY_LOG
483 +       log_exec(argv, current->tty);
484 +#endif
485          error = do_execve(file, argv, env, &current->thread.regs);
486          if (error == 0){
487                  current->ptrace &= ~PT_DTRACE;
488 --- linux-2.6.0-test4/arch/um/kernel/init_task.c.uml    2003-08-25 09:30:04.000000000 +0200
489 +++ linux-2.6.0-test4/arch/um/kernel/init_task.c        2003-08-25 10:19:28.000000000 +0200
490 @@ -17,6 +17,7 @@
491  struct mm_struct init_mm = INIT_MM(init_mm);
492  static struct files_struct init_files = INIT_FILES;
493  static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
494 +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
495  
496  /*
497   * Initial task structure.
498 @@ -38,26 +39,12 @@
499  __attribute__((__section__(".data.init_task"))) = 
500  { INIT_THREAD_INFO(init_task) };
501  
502 -struct task_struct *alloc_task_struct(void)
503 -{
504 -       return((struct task_struct *) 
505 -              __get_free_pages(GFP_KERNEL, CONFIG_KERNEL_STACK_ORDER));
506 -}
507 -
508  void unprotect_stack(unsigned long stack)
509  {
510         protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE, 
511                        1, 1, 0, 1);
512  }
513  
514 -void free_task_struct(struct task_struct *task)
515 -{
516 -       /* free_pages decrements the page counter and only actually frees
517 -        * the pages if they are now not accessed by anything.
518 -        */
519 -       free_pages((unsigned long) task, CONFIG_KERNEL_STACK_ORDER);
520 -}
521 -
522  /*
523   * Overrides for Emacs so that we follow Linus's tabbing style.
524   * Emacs will notice this stuff at the end of the file and automatically
525 --- linux-2.6.0-test4/arch/um/kernel/irq.c.uml  2003-08-25 09:29:39.000000000 +0200
526 +++ linux-2.6.0-test4/arch/um/kernel/irq.c      2003-08-25 10:19:28.000000000 +0200
527 @@ -28,6 +28,7 @@
528  #include "user_util.h"
529  #include "kern_util.h"
530  #include "irq_user.h"
531 +#include "irq_kern.h"
532  
533  static void register_irq_proc (unsigned int irq);
534  
535 @@ -82,65 +83,52 @@
536         end_none
537  };
538  
539 -/* Not changed */
540 -volatile unsigned long irq_err_count;
541 -
542  /*
543   * Generic, controller-independent functions:
544   */
545  
546 -int get_irq_list(char *buf)
547 +int show_interrupts(struct seq_file *p, void *v)
548  {
549         int i, j;
550 -       unsigned long flags;
551         struct irqaction * action;
552 -       char *p = buf;
553 +       unsigned long flags;
554  
555 -       p += sprintf(p, "           ");
556 -       for (j=0; j<num_online_cpus(); j++)
557 -               p += sprintf(p, "CPU%d       ",j);
558 -       *p++ = '\n';
559 +       seq_printf(p, "           ");
560 +       for (j=0; j<NR_CPUS; j++)
561 +               if (cpu_online(j))
562 +                       seq_printf(p, "CPU%d       ",j);
563 +       seq_putc(p, '\n');
564  
565         for (i = 0 ; i < NR_IRQS ; i++) {
566                 spin_lock_irqsave(&irq_desc[i].lock, flags);
567                 action = irq_desc[i].action;
568                 if (!action) 
569 -                       goto end;
570 -               p += sprintf(p, "%3d: ",i);
571 +                       goto skip;
572 +               seq_printf(p, "%3d: ",i);
573  #ifndef CONFIG_SMP
574 -               p += sprintf(p, "%10u ", kstat_irqs(i));
575 +               seq_printf(p, "%10u ", kstat_irqs(i));
576  #else
577 -               for (j = 0; j < num_online_cpus(); j++)
578 -                       p += sprintf(p, "%10u ",
579 -                               kstat_cpu(cpu_logical_map(j)).irqs[i]);
580 +               for (j = 0; j < NR_CPUS; j++)
581 +                       if (cpu_online(j))
582 +                               seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
583  #endif
584 -               p += sprintf(p, " %14s", irq_desc[i].handler->typename);
585 -               p += sprintf(p, "  %s", action->name);
586 +               seq_printf(p, " %14s", irq_desc[i].handler->typename);
587 +               seq_printf(p, "  %s", action->name);
588  
589                 for (action=action->next; action; action = action->next)
590 -                       p += sprintf(p, ", %s", action->name);
591 -               *p++ = '\n';
592 -       end:
593 +                       seq_printf(p, ", %s", action->name);
594 +
595 +               seq_putc(p, '\n');
596 +skip:
597                 spin_unlock_irqrestore(&irq_desc[i].lock, flags);
598         }
599 -       p += sprintf(p, "\n");
600 -#ifdef notdef
601 -#ifdef CONFIG_SMP
602 -       p += sprintf(p, "LOC: ");
603 -       for (j = 0; j < num_online_cpus(); j++)
604 -               p += sprintf(p, "%10u ",
605 -                       apic_timer_irqs[cpu_logical_map(j)]);
606 -       p += sprintf(p, "\n");
607 -#endif
608 -#endif
609 -       p += sprintf(p, "ERR: %10lu\n", irq_err_count);
610 -       return p - buf;
611 -}
612 -
613 +       seq_printf(p, "NMI: ");
614 +       for (j = 0; j < NR_CPUS; j++)
615 +               if (cpu_online(j))
616 +                       seq_printf(p, "%10u ", nmi_count(j));
617 +       seq_putc(p, '\n');
618  
619 -int show_interrupts(struct seq_file *p, void *v)
620 -{
621 -       return(0);
622 +       return 0;
623  }
624  
625  /*
626 @@ -281,13 +269,12 @@
627          * 0 return value means that this irq is already being
628          * handled by some other CPU. (or is disabled)
629          */
630 -       int cpu = smp_processor_id();
631         irq_desc_t *desc = irq_desc + irq;
632         struct irqaction * action;
633         unsigned int status;
634  
635         irq_enter();
636 -       kstat_cpu(cpu).irqs[irq]++;
637 +       kstat_this_cpu.irqs[irq]++;
638         spin_lock(&desc->lock);
639         desc->handler->ack(irq);
640         /*
641 @@ -384,7 +371,7 @@
642   */
643   
644  int request_irq(unsigned int irq,
645 -               void (*handler)(int, void *, struct pt_regs *),
646 +               irqreturn_t (*handler)(int, void *, struct pt_regs *),
647                 unsigned long irqflags, 
648                 const char * devname,
649                 void *dev_id)
650 @@ -430,15 +417,19 @@
651  }
652  
653  int um_request_irq(unsigned int irq, int fd, int type,
654 -                  void (*handler)(int, void *, struct pt_regs *),
655 +                  irqreturn_t (*handler)(int, void *, struct pt_regs *),
656                    unsigned long irqflags, const char * devname,
657                    void *dev_id)
658  {
659 -       int retval;
660 +       int err;
661  
662 -       retval = request_irq(irq, handler, irqflags, devname, dev_id);
663 -       if(retval) return(retval);
664 -       return(activate_fd(irq, fd, type, dev_id));
665 +       err = request_irq(irq, handler, irqflags, devname, dev_id);
666 +       if(err) 
667 +               return(err);
668 +
669 +       if(fd != -1)
670 +               err = activate_fd(irq, fd, type, dev_id);
671 +       return(err);
672  }
673  
674  /* this was setup_x86_irq but it seems pretty generic */
675 --- linux-2.6.0-test4/arch/um/kernel/mem.c.uml  2003-08-25 09:28:47.000000000 +0200
676 +++ linux-2.6.0-test4/arch/um/kernel/mem.c      2003-08-25 10:19:28.000000000 +0200
677 @@ -119,11 +119,6 @@
678         return(kmem_top);
679  }
680  
681 -void set_kmem_end(unsigned long new)
682 -{
683 -       kmem_top = new;
684 -}
685 -
686  #ifdef CONFIG_HIGHMEM
687  /* Changed during early boot */
688  pte_t *kmap_pte;
689 @@ -218,7 +213,7 @@
690                 if(regions[i] == NULL) break;           
691         }
692         if(i == NREGIONS){
693 -               printk("setup_range : no free regions\n");
694 +               printk("setup_one_range : no free regions\n");
695                 i = -1;
696                 goto out;
697         }
698 @@ -227,7 +222,9 @@
699                 fd = create_mem_file(len);
700  
701         if(region == NULL){
702 -               region = alloc_bootmem_low_pages(sizeof(*region));
703 +               if(kmalloc_ok)
704 +                       region = kmalloc(sizeof(*region), GFP_KERNEL);
705 +               else region = alloc_bootmem_low_pages(sizeof(*region));
706                 if(region == NULL)
707                         panic("Failed to allocating mem_region");
708         }
709 @@ -528,9 +525,9 @@
710         return(NREGIONS);
711  }
712  
713 -void setup_range(int fd, char *driver, unsigned long start, unsigned long pfn,
714 -                unsigned long len, int need_vm, struct mem_region *region, 
715 -                void *reserved)
716 +static void setup_range(int fd, char *driver, unsigned long start, 
717 +                       unsigned long pfn, unsigned long len, int need_vm, 
718 +                       struct mem_region *region, void *reserved)
719  {
720         int i, cur;
721  
722 --- linux-2.6.0-test4/arch/um/kernel/mem_user.c.uml     2003-08-25 09:29:04.000000000 +0200
723 +++ linux-2.6.0-test4/arch/um/kernel/mem_user.c 2003-08-25 10:19:28.000000000 +0200
724 @@ -111,6 +111,11 @@
725                 offset = 0;
726         }
727  
728 +       if(offset >= region->len){
729 +               printf("%d bytes of physical memory is insufficient\n",
730 +                      region->len);
731 +               exit(1);
732 +       }
733         loc = mmap(start, region->len - offset, PROT_READ | PROT_WRITE, 
734                    MAP_SHARED | MAP_FIXED, region->fd, offset);
735         if(loc != start){
736 @@ -122,26 +127,26 @@
737  
738  static int __init parse_iomem(char *str, int *add)
739  {
740 -       struct stat buf;
741 +       struct stat64 buf;
742         char *file, *driver;
743         int fd;
744  
745         driver = str;
746         file = strchr(str,',');
747         if(file == NULL){
748 -               printk("parse_iomem : failed to parse iomem\n");
749 +               printf("parse_iomem : failed to parse iomem\n");
750                 return(1);
751         }
752         *file = '\0';
753         file++;
754         fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0);
755         if(fd < 0){
756 -               printk("parse_iomem - Couldn't open io file, errno = %d\n", 
757 +               printf("parse_iomem - Couldn't open io file, errno = %d\n", 
758                        errno);
759                 return(1);
760         }
761 -       if(fstat(fd, &buf) < 0) {
762 -               printk("parse_iomem - cannot fstat file, errno = %d\n", errno);
763 +       if(fstat64(fd, &buf) < 0) {
764 +               printf("parse_iomem - cannot fstat file, errno = %d\n", errno);
765                 return(1);
766         }
767         add_iomem(driver, fd, buf.st_size);
768 --- linux-2.6.0-test4/arch/um/kernel/process.c.uml      2003-08-25 09:29:42.000000000 +0200
769 +++ linux-2.6.0-test4/arch/um/kernel/process.c  2003-08-25 10:19:28.000000000 +0200
770 @@ -72,7 +72,6 @@
771                     SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
772         set_handler(SIGUSR2, (__sighandler_t) sig_handler, 
773                     SA_NOMASK | flags, -1);
774 -       (void) CHOOSE_MODE(signal(SIGCHLD, SIG_IGN), (void *) 0);
775         signal(SIGHUP, SIG_IGN);
776  
777         init_irq_signals(altstack);
778 @@ -127,7 +126,8 @@
779         if(err < 0) panic("Waiting for outer trampoline failed - errno = %d", 
780                           errno);
781         if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL))
782 -               panic("outer trampoline didn't exit with SIGKILL");
783 +               panic("outer trampoline didn't exit with SIGKILL, "
784 +                     "status = %d", status);
785  
786         return(arg.pid);
787  }
788 --- linux-2.6.0-test4/arch/um/kernel/process_kern.c.uml 2003-08-25 09:29:02.000000000 +0200
789 +++ linux-2.6.0-test4/arch/um/kernel/process_kern.c     2003-08-25 10:19:28.000000000 +0200
790 @@ -52,17 +52,12 @@
791  
792  struct task_struct *get_task(int pid, int require)
793  {
794 -        struct task_struct *task, *ret;
795 +        struct task_struct *ret;
796  
797 -        ret = NULL;
798          read_lock(&tasklist_lock);
799 -        for_each_process(task){
800 -                if(task->pid == pid){
801 -                        ret = task;
802 -                        break;
803 -                }
804 -        }
805 +       ret = find_task_by_pid(pid);
806          read_unlock(&tasklist_lock);
807 +
808          if(require && (ret == NULL)) panic("get_task couldn't find a task\n");
809          return(ret);
810  }
811 @@ -103,13 +98,14 @@
812  
813  int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
814  {
815 -       struct task_struct *p;
816 +       int pid;
817  
818         current->thread.request.u.thread.proc = fn;
819         current->thread.request.u.thread.arg = arg;
820 -       p = do_fork(CLONE_VM | flags, 0, NULL, 0, NULL, NULL);
821 -       if(IS_ERR(p)) panic("do_fork failed in kernel_thread");
822 -       return(p->pid);
823 +       pid = do_fork(CLONE_VM | flags, 0, NULL, 0, NULL, NULL);
824 +       if(pid < 0)
825 +               panic("do_fork failed in kernel_thread, errno = %d", pid);
826 +       return(pid);
827  }
828  
829  void switch_mm(struct mm_struct *prev, struct mm_struct *next, 
830 @@ -157,6 +153,10 @@
831         return(current);
832  }
833  
834 +void prepare_to_copy(struct task_struct *tsk)
835 +{
836 +}
837 +
838  int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
839                 unsigned long stack_top, struct task_struct * p, 
840                 struct pt_regs *regs)
841 @@ -190,7 +190,7 @@
842  
843  void default_idle(void)
844  {
845 -       idle_timer();
846 +       uml_idle_timer();
847  
848         atomic_inc(&init_mm.mm_count);
849         current->mm = &init_mm;
850 @@ -363,6 +363,11 @@
851         return(clear_user(buf, size));
852  }
853  
854 +int strlen_user_proc(char *str)
855 +{
856 +       return(strlen_user(str));
857 +}
858 +
859  int smp_sigio_handler(void)
860  {
861  #ifdef CONFIG_SMP
862 --- linux-2.6.0-test4/arch/um/kernel/ptrace.c.uml       2003-08-25 09:28:16.000000000 +0200
863 +++ linux-2.6.0-test4/arch/um/kernel/ptrace.c   2003-08-25 10:19:28.000000000 +0200
864 @@ -311,11 +311,8 @@
865  
866         /* the 0x80 provides a way for the tracing parent to distinguish
867            between a syscall stop and SIGTRAP delivery */
868 -       current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
869 -                                       ? 0x80 : 0);
870 -       current->state = TASK_STOPPED;
871 -       notify_parent(current, SIGCHLD);
872 -       schedule();
873 +       ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
874 +                                ? 0x80 : 0));
875  
876         /*
877          * this isn't the same as continuing with a signal, but it will do
878 --- linux-2.6.0-test4/arch/um/kernel/sigio_kern.c.uml   2003-08-25 09:28:26.000000000 +0200
879 +++ linux-2.6.0-test4/arch/um/kernel/sigio_kern.c       2003-08-25 10:19:28.000000000 +0200
880 @@ -6,18 +6,21 @@
881  #include "linux/kernel.h"
882  #include "linux/list.h"
883  #include "linux/slab.h"
884 -#include "asm/irq.h"
885 +#include "linux/signal.h"
886 +#include "linux/interrupt.h"
887  #include "init.h"
888  #include "sigio.h"
889  #include "irq_user.h"
890 +#include "irq_kern.h"
891  
892  /* Protected by sigio_lock() called from write_sigio_workaround */
893  static int sigio_irq_fd = -1;
894  
895 -void sigio_interrupt(int irq, void *data, struct pt_regs *unused)
896 +irqreturn_t sigio_interrupt(int irq, void *data, struct pt_regs *unused)
897  {
898         read_sigio_fd(sigio_irq_fd);
899         reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ);
900 +       return(IRQ_HANDLED);
901  }
902  
903  int write_sigio_irq(int fd)
904 --- linux-2.6.0-test4/arch/um/kernel/signal_kern.c.uml  2003-08-25 09:29:06.000000000 +0200
905 +++ linux-2.6.0-test4/arch/um/kernel/signal_kern.c      2003-08-25 10:19:28.000000000 +0200
906 @@ -36,7 +36,7 @@
907         if(sig == SIGSEGV){
908                 struct k_sigaction *ka;
909  
910 -               ka = &current->sig->action[SIGSEGV - 1];
911 +               ka = &current->sighand->action[SIGSEGV - 1];
912                 ka->sa.sa_handler = SIG_DFL;
913         }
914         force_sig(SIGSEGV, current);
915 @@ -142,7 +142,7 @@
916                 return(0);
917  
918         /* Whee!  Actually deliver the signal.  */
919 -       ka = &current->sig->action[sig -1 ];
920 +       ka = &current->sighand->action[sig -1 ];
921         err = handle_signal(regs, sig, ka, &info, oldset, error);
922         if(!err) return(1);
923  
924 @@ -201,7 +201,7 @@
925         }
926  }
927  
928 -int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
929 +int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
930  {
931         sigset_t saveset, newset;
932  
933 @@ -227,6 +227,42 @@
934         }
935  }
936  
937 +int sys_sigaction(int sig, const struct old_sigaction __user *act,
938 +                        struct old_sigaction __user *oact)
939 +{
940 +       struct k_sigaction new_ka, old_ka;
941 +       int ret;
942 +
943 +       if (act) {
944 +               old_sigset_t mask;
945 +               if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
946 +                   __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
947 +                   __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
948 +                       return -EFAULT;
949 +               __get_user(new_ka.sa.sa_flags, &act->sa_flags);
950 +               __get_user(mask, &act->sa_mask);
951 +               siginitset(&new_ka.sa.sa_mask, mask);
952 +       }
953 +
954 +       ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
955 +
956 +       if (!ret && oact) {
957 +               if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
958 +                   __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
959 +                   __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
960 +                       return -EFAULT;
961 +               __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
962 +               __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
963 +       }
964 +
965 +       return ret;
966 +}
967 +
968 +int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
969 +{
970 +       return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
971 +}
972 +
973  static int copy_sc_from_user(struct pt_regs *to, void *from, 
974                              struct arch_frame_data *arch)
975  {
976 @@ -239,8 +275,8 @@
977  
978  int sys_sigreturn(struct pt_regs regs)
979  {
980 -       void *sc = sp_to_sc(PT_REGS_SP(&current->thread.regs));
981 -       void *mask = sp_to_mask(PT_REGS_SP(&current->thread.regs));
982 +       void __user *sc = sp_to_sc(PT_REGS_SP(&current->thread.regs));
983 +       void __user *mask = sp_to_mask(PT_REGS_SP(&current->thread.regs));
984         int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
985  
986         spin_lock_irq(&current->sighand->siglock);
987 @@ -257,7 +293,8 @@
988  
989  int sys_rt_sigreturn(struct pt_regs regs)
990  {
991 -       struct ucontext *uc = sp_to_uc(PT_REGS_SP(&current->thread.regs));
992 +       unsigned long sp = PT_REGS_SP(&current->thread.regs);
993 +       struct ucontext __user *uc = sp_to_uc(sp);
994         void *fp;
995         int sig_size = _NSIG_WORDS * sizeof(unsigned long);
996  
997 --- linux-2.6.0-test4/arch/um/kernel/smp.c.uml  2003-08-25 09:28:22.000000000 +0200
998 +++ linux-2.6.0-test4/arch/um/kernel/smp.c      2003-08-25 10:19:28.000000000 +0200
999 @@ -140,8 +140,10 @@
1000  
1001          current->thread.request.u.thread.proc = idle_proc;
1002          current->thread.request.u.thread.arg = (void *) cpu;
1003 -       new_task = do_fork(CLONE_VM | CLONE_IDLETASK, 0, NULL, 0, NULL, NULL);
1004 -       if(IS_ERR(new_task)) panic("do_fork failed in idle_thread");
1005 +       new_task = copy_process(CLONE_VM | CLONE_IDLETASK, 0, NULL, 0, NULL, 
1006 +                               NULL);
1007 +       if(IS_ERR(new_task)) 
1008 +               panic("copy_process failed in idle_thread");
1009  
1010         cpu_tasks[cpu] = ((struct cpu_task) 
1011                           { .pid =      new_task->thread.mode.tt.extern_pid,
1012 @@ -150,6 +152,7 @@
1013         CHOOSE_MODE(write(new_task->thread.mode.tt.switch_pipe[1], &c, 
1014                           sizeof(c)),
1015                     ({ panic("skas mode doesn't support SMP"); }));
1016 +       wake_up_forked_process(new_task);
1017         return(new_task);
1018  }
1019  
1020 @@ -254,15 +257,19 @@
1021         atomic_inc(&scf_finished);
1022  }
1023  
1024 -int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic, 
1025 -                     int wait)
1026 +int smp_call_function_on_cpu(void (*_func)(void *info), void *_info, int wait,
1027 +                               unsigned long mask)
1028  {
1029 -       int cpus = num_online_cpus() - 1;
1030 -       int i;
1031 -
1032 -       if (!cpus)
1033 -               return 0;
1034 +       int i, cpu, num_cpus;
1035  
1036 +       cpu = get_cpu();
1037 +       mask &= ~(1UL << cpu);
1038 +       num_cpus = hweight32(mask);
1039 +       if(num_cpus == 0){
1040 +               put_cpu_no_resched();
1041 +               return(0);
1042 +       }
1043 +       
1044         spin_lock_bh(&call_lock);
1045         atomic_set(&scf_started, 0);
1046         atomic_set(&scf_finished, 0);
1047 --- linux-2.6.0-test4/arch/um/kernel/sys_call_table.c.uml       2003-08-25 09:29:40.000000000 +0200
1048 +++ linux-2.6.0-test4/arch/um/kernel/sys_call_table.c   2003-08-25 10:19:28.000000000 +0200
1049 @@ -219,6 +219,18 @@
1050  extern syscall_handler_t sys_gettid;
1051  extern syscall_handler_t sys_readahead;
1052  extern syscall_handler_t sys_tkill;
1053 +extern syscall_handler_t sys_setxattr;
1054 +extern syscall_handler_t sys_lsetxattr;
1055 +extern syscall_handler_t sys_fsetxattr;
1056 +extern syscall_handler_t sys_getxattr;
1057 +extern syscall_handler_t sys_lgetxattr;
1058 +extern syscall_handler_t sys_fgetxattr;
1059 +extern syscall_handler_t sys_listxattr;
1060 +extern syscall_handler_t sys_llistxattr;
1061 +extern syscall_handler_t sys_flistxattr;
1062 +extern syscall_handler_t sys_removexattr;
1063 +extern syscall_handler_t sys_lremovexattr;
1064 +extern syscall_handler_t sys_fremovexattr;
1065  extern syscall_handler_t sys_sendfile64;
1066  extern syscall_handler_t sys_futex;
1067  extern syscall_handler_t sys_sched_setaffinity;
1068 @@ -235,6 +247,19 @@
1069  extern syscall_handler_t sys_epoll_wait;
1070  extern syscall_handler_t sys_remap_file_pages;
1071  extern syscall_handler_t sys_set_tid_address;
1072 +extern syscall_handler_t sys_timer_create;
1073 +extern syscall_handler_t sys_timer_settime;
1074 +extern syscall_handler_t sys_timer_gettime;
1075 +extern syscall_handler_t sys_timer_getoverrun;
1076 +extern syscall_handler_t sys_timer_delete;
1077 +extern syscall_handler_t sys_clock_settime;
1078 +extern syscall_handler_t sys_clock_gettime;
1079 +extern syscall_handler_t sys_clock_getres;
1080 +extern syscall_handler_t sys_clock_nanosleep;
1081 +extern syscall_handler_t sys_statfs64;
1082 +extern syscall_handler_t sys_fstatfs64;
1083 +extern syscall_handler_t sys_tgkill;
1084 +extern syscall_handler_t sys_utimes;
1085  
1086  #ifdef CONFIG_NFSD
1087  #define NFSSERVCTL sys_nfsservctl
1088 @@ -459,18 +484,18 @@
1089         [ __NR_getdents64 ] = sys_getdents64,
1090         [ __NR_gettid ] = sys_gettid,
1091         [ __NR_readahead ] = sys_readahead,
1092 -       [ __NR_setxattr ] = sys_ni_syscall,
1093 -       [ __NR_lsetxattr ] = sys_ni_syscall,
1094 -       [ __NR_fsetxattr ] = sys_ni_syscall,
1095 -       [ __NR_getxattr ] = sys_ni_syscall,
1096 -       [ __NR_lgetxattr ] = sys_ni_syscall,
1097 -       [ __NR_fgetxattr ] = sys_ni_syscall,
1098 -       [ __NR_listxattr ] = sys_ni_syscall,
1099 -       [ __NR_llistxattr ] = sys_ni_syscall,
1100 -       [ __NR_flistxattr ] = sys_ni_syscall,
1101 -       [ __NR_removexattr ] = sys_ni_syscall,
1102 -       [ __NR_lremovexattr ] = sys_ni_syscall,
1103 -       [ __NR_fremovexattr ] = sys_ni_syscall,
1104 +       [ __NR_setxattr ] = sys_setxattr,
1105 +       [ __NR_lsetxattr ] = sys_lsetxattr,
1106 +       [ __NR_fsetxattr ] = sys_fsetxattr,
1107 +       [ __NR_getxattr ] = sys_getxattr,
1108 +       [ __NR_lgetxattr ] = sys_lgetxattr,
1109 +       [ __NR_fgetxattr ] = sys_fgetxattr,
1110 +       [ __NR_listxattr ] = sys_listxattr,
1111 +       [ __NR_llistxattr ] = sys_llistxattr,
1112 +       [ __NR_flistxattr ] = sys_flistxattr,
1113 +       [ __NR_removexattr ] = sys_removexattr,
1114 +       [ __NR_lremovexattr ] = sys_lremovexattr,
1115 +       [ __NR_fremovexattr ] = sys_fremovexattr,
1116         [ __NR_tkill ] = sys_tkill,
1117         [ __NR_sendfile64 ] = sys_sendfile64,
1118         [ __NR_futex ] = sys_futex,
1119 @@ -488,6 +513,19 @@
1120         [ __NR_epoll_wait ] = sys_epoll_wait,
1121          [ __NR_remap_file_pages ] = sys_remap_file_pages,
1122          [ __NR_set_tid_address ] = sys_set_tid_address,
1123 +       [ __NR_timer_create ] = sys_timer_create,
1124 +       [ __NR_timer_settime ] = sys_timer_settime,
1125 +       [ __NR_timer_gettime ] = sys_timer_gettime,
1126 +       [ __NR_timer_getoverrun ] = sys_timer_getoverrun,
1127 +       [ __NR_timer_delete ] = sys_timer_delete,
1128 +       [ __NR_clock_settime ] = sys_clock_settime,
1129 +       [ __NR_clock_gettime ] = sys_clock_gettime,
1130 +       [ __NR_clock_getres ] = sys_clock_getres,
1131 +       [ __NR_clock_nanosleep ] = sys_clock_nanosleep,
1132 +       [ __NR_statfs64 ] = sys_statfs64,
1133 +       [ __NR_fstatfs64 ] = sys_fstatfs64,
1134 +       [ __NR_tgkill ] = sys_tgkill,
1135 +       [ __NR_utimes ] = sys_utimes,
1136  
1137         ARCH_SYSCALLS
1138         [ LAST_SYSCALL + 1 ... NR_syscalls ] = 
1139 --- linux-2.6.0-test4/arch/um/kernel/syscall_kern.c.uml 2003-08-25 09:29:22.000000000 +0200
1140 +++ linux-2.6.0-test4/arch/um/kernel/syscall_kern.c     2003-08-25 10:19:28.000000000 +0200
1141 @@ -35,39 +35,40 @@
1142  
1143  long sys_fork(void)
1144  {
1145 -       struct task_struct *p;
1146 +       long ret;
1147  
1148         current->thread.forking = 1;
1149 -        p = do_fork(SIGCHLD, 0, NULL, 0, NULL, NULL);
1150 +        ret = do_fork(SIGCHLD, 0, NULL, 0, NULL, NULL);
1151         current->thread.forking = 0;
1152 -       return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
1153 +       return(ret);
1154  }
1155  
1156 -long sys_clone(unsigned long clone_flags, unsigned long newsp)
1157 +long sys_clone(unsigned long clone_flags, unsigned long newsp, 
1158 +              int *parent_tid, int *child_tid)
1159  {
1160 -       struct task_struct *p;
1161 +       long ret;
1162  
1163         current->thread.forking = 1;
1164 -       p = do_fork(clone_flags, newsp, NULL, 0, NULL, NULL);
1165 +       ret = do_fork(clone_flags, newsp, NULL, 0, parent_tid, child_tid);
1166         current->thread.forking = 0;
1167 -       return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
1168 +       return(ret);
1169  }
1170  
1171  long sys_vfork(void)
1172  {
1173 -       struct task_struct *p;
1174 +       long ret;
1175  
1176         current->thread.forking = 1;
1177 -       p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0, NULL, NULL);
1178 +       ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0, NULL, 
1179 +                     NULL);
1180         current->thread.forking = 0;
1181 -       return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
1182 +       return(ret);
1183  }
1184  
1185  /* common code for old and new mmaps */
1186 -static inline long do_mmap2(
1187 -       unsigned long addr, unsigned long len,
1188 -       unsigned long prot, unsigned long flags,
1189 -       unsigned long fd, unsigned long pgoff)
1190 +long do_mmap2(struct mm_struct *mm, unsigned long addr, unsigned long len,
1191 +             unsigned long prot, unsigned long flags, unsigned long fd,
1192 +             unsigned long pgoff)
1193  {
1194         int error = -EBADF;
1195         struct file * file = NULL;
1196 @@ -79,9 +80,9 @@
1197                         goto out;
1198         }
1199  
1200 -       down_write(&current->mm->mmap_sem);
1201 -       error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
1202 -       up_write(&current->mm->mmap_sem);
1203 +       down_write(&mm->mmap_sem);
1204 +       error = do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
1205 +       up_write(&mm->mmap_sem);
1206  
1207         if (file)
1208                 fput(file);
1209 @@ -93,7 +94,7 @@
1210                unsigned long prot, unsigned long flags,
1211                unsigned long fd, unsigned long pgoff)
1212  {
1213 -       return do_mmap2(addr, len, prot, flags, fd, pgoff);
1214 +       return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
1215  }
1216  
1217  /*
1218 @@ -120,7 +121,8 @@
1219         if (offset & ~PAGE_MASK)
1220                 goto out;
1221  
1222 -       err = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
1223 +       err = do_mmap2(current->mm, addr, len, prot, flags, fd, 
1224 +                      offset >> PAGE_SHIFT);
1225   out:
1226         return err;
1227  }
1228 @@ -141,37 +143,6 @@
1229          return error;
1230  }
1231  
1232 -int sys_sigaction(int sig, const struct old_sigaction *act,
1233 -                        struct old_sigaction *oact)
1234 -{
1235 -       struct k_sigaction new_ka, old_ka;
1236 -       int ret;
1237 -
1238 -       if (act) {
1239 -               old_sigset_t mask;
1240 -               if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
1241 -                   __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
1242 -                   __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
1243 -                       return -EFAULT;
1244 -               __get_user(new_ka.sa.sa_flags, &act->sa_flags);
1245 -               __get_user(mask, &act->sa_mask);
1246 -               siginitset(&new_ka.sa.sa_mask, mask);
1247 -       }
1248 -
1249 -       ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
1250 -
1251 -       if (!ret && oact) {
1252 -               if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
1253 -                   __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
1254 -                   __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
1255 -                       return -EFAULT;
1256 -               __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
1257 -               __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
1258 -       }
1259 -
1260 -       return ret;
1261 -}
1262 -
1263  /*
1264   * sys_ipc() is the de-multiplexer for the SysV IPC calls..
1265   *
1266 @@ -253,7 +224,7 @@
1267                 return sys_shmctl (first, second,
1268                                    (struct shmid_ds *) ptr);
1269         default:
1270 -               return -EINVAL;
1271 +               return -ENOSYS;
1272         }
1273  }
1274  
1275 @@ -302,11 +273,6 @@
1276         return error;
1277  }
1278  
1279 -int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
1280 -{
1281 -       return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
1282 -}
1283 -
1284  long execute_syscall(void *r)
1285  {
1286         return(CHOOSE_MODE_PROC(execute_syscall_tt, execute_syscall_skas, r));
1287 --- linux-2.6.0-test4/arch/um/kernel/sysrq.c.uml        2003-08-25 09:28:41.000000000 +0200
1288 +++ linux-2.6.0-test4/arch/um/kernel/sysrq.c    2003-08-25 10:19:28.000000000 +0200
1289 @@ -11,6 +11,14 @@
1290  #include "sysrq.h"
1291  #include "user_util.h"
1292  
1293 +void show_stack(struct task_struct *task, unsigned long *sp)
1294 +{
1295 +       if(task)
1296 +               show_trace_task(task);
1297 +       else
1298 +               show_trace(sp);
1299 +}
1300 +
1301  void show_trace(unsigned long * stack)
1302  {
1303          int i;
1304 --- linux-2.6.0-test4/arch/um/kernel/time.c.uml 2003-08-25 09:28:21.000000000 +0200
1305 +++ linux-2.6.0-test4/arch/um/kernel/time.c     2003-08-25 10:19:28.000000000 +0200
1306 @@ -15,12 +15,16 @@
1307  #include "process.h"
1308  #include "signal_user.h"
1309  #include "time_user.h"
1310 +#include "kern_constants.h"
1311  
1312  extern struct timeval xtime;
1313  
1314 +struct timeval local_offset = { 0, 0 };
1315 +
1316  void timer(void)
1317  {
1318         gettimeofday(&xtime, NULL);
1319 +       timeradd(&xtime, &local_offset, &xtime);
1320  }
1321  
1322  void set_interval(int timer_type)
1323 @@ -65,7 +69,7 @@
1324                        errno);
1325  }
1326  
1327 -void idle_timer(void)
1328 +void uml_idle_timer(void)
1329  {
1330         if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
1331                 panic("Couldn't unset SIGVTALRM handler");
1332 @@ -82,8 +86,6 @@
1333         set_interval(ITIMER_VIRTUAL);
1334  }
1335  
1336 -struct timeval local_offset = { 0, 0 };
1337 -
1338  void do_gettimeofday(struct timeval *tv)
1339  {
1340         unsigned long flags;
1341 @@ -100,7 +102,7 @@
1342         unsigned long flags;
1343         struct timeval tv_in;
1344  
1345 -       if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
1346 +       if ((unsigned long) tv->tv_nsec >= UM_NSEC_PER_SEC)
1347                 return -EINVAL;
1348  
1349         tv_in.tv_sec = tv->tv_sec;
1350 @@ -110,6 +112,8 @@
1351         gettimeofday(&now, NULL);
1352         timersub(&tv_in, &now, &local_offset);
1353         time_unlock(flags);
1354 +
1355 +       return(0);
1356  }
1357  
1358  void idle_sleep(int secs)
1359 --- linux-2.6.0-test4/arch/um/kernel/time_kern.c.uml    2003-08-25 09:29:12.000000000 +0200
1360 +++ linux-2.6.0-test4/arch/um/kernel/time_kern.c        2003-08-25 10:19:28.000000000 +0200
1361 @@ -55,12 +55,13 @@
1362         do_timer(&regs);
1363  }
1364  
1365 -void um_timer(int irq, void *dev, struct pt_regs *regs)
1366 +irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs)
1367  {
1368         do_timer(regs);
1369 -       write_seqlock(&xtime_lock);
1370 +       write_seqlock_irq(&xtime_lock);
1371         timer();
1372 -       write_sequnlock(&xtime_lock);
1373 +       write_sequnlock_irq(&xtime_lock);
1374 +       return(IRQ_HANDLED);
1375  }
1376  
1377  long um_time(int * tloc)
1378 @@ -78,12 +79,12 @@
1379  long um_stime(int * tptr)
1380  {
1381         int value;
1382 -       struct timeval new;
1383 +       struct timespec new;
1384  
1385         if (get_user(value, tptr))
1386                  return -EFAULT;
1387         new.tv_sec = value;
1388 -       new.tv_usec = 0;
1389 +       new.tv_nsec = 0;
1390         do_settimeofday(&new);
1391         return 0;
1392  }
1393 @@ -122,7 +123,9 @@
1394  void timer_handler(int sig, union uml_pt_regs *regs)
1395  {
1396  #ifdef CONFIG_SMP
1397 +       local_irq_disable();
1398         update_process_times(user_context(UPT_SP(regs)));
1399 +       local_irq_enable();
1400  #endif
1401         if(current->thread_info->cpu == 0)
1402                 timer_irq(regs);
1403 --- linux-2.6.0-test4/arch/um/kernel/trap_kern.c.uml    2003-08-25 09:28:11.000000000 +0200
1404 +++ linux-2.6.0-test4/arch/um/kernel/trap_kern.c        2003-08-25 10:19:28.000000000 +0200
1405 @@ -16,6 +16,7 @@
1406  #include "asm/tlbflush.h"
1407  #include "asm/a.out.h"
1408  #include "asm/current.h"
1409 +#include "asm/irq.h"
1410  #include "user_util.h"
1411  #include "kern_util.h"
1412  #include "kern.h"
1413 @@ -180,6 +181,11 @@
1414         else relay_signal(sig, regs);
1415  }
1416  
1417 +void winch(int sig, union uml_pt_regs *regs)
1418 +{
1419 +       do_IRQ(WINCH_IRQ, regs);
1420 +}
1421 +
1422  void trap_init(void)
1423  {
1424  }
1425 --- linux-2.6.0-test4/arch/um/kernel/trap_user.c.uml    2003-08-25 09:28:55.000000000 +0200
1426 +++ linux-2.6.0-test4/arch/um/kernel/trap_user.c        2003-08-25 10:19:28.000000000 +0200
1427 @@ -82,6 +82,8 @@
1428                      .is_irq            = 0 },
1429         [ SIGILL ] { .handler           = relay_signal,
1430                      .is_irq            = 0 },
1431 +       [ SIGWINCH ] { .handler         = winch,
1432 +                      .is_irq          = 1 },
1433         [ SIGBUS ] { .handler           = bus_handler,
1434                      .is_irq            = 0 },
1435         [ SIGSEGV] { .handler           = segv_handler,
1436 --- linux-2.6.0-test4/arch/um/kernel/tty_log.c.uml      2003-08-25 09:29:11.000000000 +0200
1437 +++ linux-2.6.0-test4/arch/um/kernel/tty_log.c  2003-08-25 10:19:28.000000000 +0200
1438 @@ -13,6 +13,7 @@
1439  #include <sys/time.h>
1440  #include "init.h"
1441  #include "user.h"
1442 +#include "kern_util.h"
1443  #include "os.h"
1444  
1445  #define TTY_LOG_DIR "./"
1446 @@ -24,29 +25,40 @@
1447  #define TTY_LOG_OPEN 1
1448  #define TTY_LOG_CLOSE 2
1449  #define TTY_LOG_WRITE 3
1450 +#define TTY_LOG_EXEC 4
1451 +
1452 +#define TTY_READ 1
1453 +#define TTY_WRITE 2
1454  
1455  struct tty_log_buf {
1456         int what;
1457         unsigned long tty;
1458         int len;
1459 +       int direction;
1460 +       unsigned long sec;
1461 +       unsigned long usec;
1462  };
1463  
1464 -int open_tty_log(void *tty)
1465 +int open_tty_log(void *tty, void *current_tty)
1466  {
1467         struct timeval tv;
1468         struct tty_log_buf data;
1469         char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")];
1470         int fd;
1471  
1472 +       gettimeofday(&tv, NULL);
1473         if(tty_log_fd != -1){
1474 -               data = ((struct tty_log_buf) { what :   TTY_LOG_OPEN,
1475 -                                              tty : (unsigned long) tty,
1476 -                                              len : 0 });
1477 +               data = ((struct tty_log_buf) { .what    = TTY_LOG_OPEN,
1478 +                                              .tty  = (unsigned long) tty,
1479 +                                              .len  = sizeof(current_tty),
1480 +                                              .direction = 0,
1481 +                                              .sec = tv.tv_sec,
1482 +                                              .usec = tv.tv_usec } );
1483                 write(tty_log_fd, &data, sizeof(data));
1484 +               write(tty_log_fd, &current_tty, data.len);
1485                 return(tty_log_fd);
1486         }
1487  
1488 -       gettimeofday(&tv, NULL);
1489         sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec, 
1490                 (unsigned int) tv.tv_usec);
1491  
1492 @@ -62,30 +74,114 @@
1493  void close_tty_log(int fd, void *tty)
1494  {
1495         struct tty_log_buf data;
1496 +       struct timeval tv;
1497  
1498         if(tty_log_fd != -1){
1499 -               data = ((struct tty_log_buf) { what :   TTY_LOG_CLOSE,
1500 -                                              tty : (unsigned long) tty,
1501 -                                              len : 0 });
1502 +               gettimeofday(&tv, NULL);
1503 +               data = ((struct tty_log_buf) { .what    = TTY_LOG_CLOSE,
1504 +                                              .tty  = (unsigned long) tty,
1505 +                                              .len  = 0,
1506 +                                              .direction = 0,
1507 +                                              .sec = tv.tv_sec,
1508 +                                              .usec = tv.tv_usec } );
1509                 write(tty_log_fd, &data, sizeof(data));
1510                 return;
1511         }
1512         close(fd);
1513  }
1514  
1515 -int write_tty_log(int fd, char *buf, int len, void *tty)
1516 +static int log_chunk(int fd, const char *buf, int len)
1517  {
1518 +       int total = 0, try, missed, n;
1519 +       char chunk[64];
1520 +
1521 +       while(len > 0){
1522 +               try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
1523 +               missed = copy_from_user_proc(chunk, (char *) buf, try);
1524 +               try -= missed;
1525 +               n = write(fd, chunk, try);
1526 +               if(n != try)
1527 +                       return(-errno);
1528 +               if(missed != 0)
1529 +                       return(-EFAULT);
1530 +
1531 +               len -= try;
1532 +               total += try;
1533 +               buf += try;
1534 +       }
1535 +
1536 +       return(total);
1537 +}
1538 +
1539 +int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
1540 +{
1541 +       struct timeval tv;
1542         struct tty_log_buf data;
1543 +       int direction;
1544  
1545         if(fd == tty_log_fd){
1546 -               data = ((struct tty_log_buf) { what :   TTY_LOG_WRITE,
1547 -                                              tty : (unsigned long) tty,
1548 -                                              len : len });
1549 +               gettimeofday(&tv, NULL);
1550 +               direction = is_read ? TTY_READ : TTY_WRITE;
1551 +               data = ((struct tty_log_buf) { .what    = TTY_LOG_WRITE,
1552 +                                              .tty  = (unsigned long) tty,
1553 +                                              .len  = len,
1554 +                                              .direction = direction,
1555 +                                              .sec = tv.tv_sec,
1556 +                                              .usec = tv.tv_usec } );
1557                 write(tty_log_fd, &data, sizeof(data));
1558         }
1559 -       return(write(fd, buf, len));
1560 +
1561 +       return(log_chunk(fd, buf, len));
1562  }
1563  
1564 +void log_exec(char **argv, void *tty)
1565 +{
1566 +       struct timeval tv;
1567 +       struct tty_log_buf data;
1568 +       char **ptr,*arg;
1569 +       int len;
1570 +       
1571 +       if(tty_log_fd == -1) return;
1572 +
1573 +       gettimeofday(&tv, NULL);
1574 +
1575 +       len = 0;
1576 +       for(ptr = argv; ; ptr++){
1577 +               if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
1578 +                       return;
1579 +               if(arg == NULL) break;
1580 +               len += strlen_user_proc(arg);
1581 +       }
1582 +
1583 +       data = ((struct tty_log_buf) { .what    = TTY_LOG_EXEC,
1584 +                                      .tty  = (unsigned long) tty,
1585 +                                      .len  = len,
1586 +                                      .direction = 0,
1587 +                                      .sec = tv.tv_sec,
1588 +                                      .usec = tv.tv_usec } );
1589 +       write(tty_log_fd, &data, sizeof(data));
1590 +
1591 +       for(ptr = argv; ; ptr++){
1592 +               if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
1593 +                       return;
1594 +               if(arg == NULL) break;
1595 +               log_chunk(tty_log_fd, arg, strlen_user_proc(arg));
1596 +       }
1597 +}
1598 +
1599 +extern void register_tty_logger(int (*opener)(void *, void *),
1600 +                               int (*writer)(int, const char *, int, 
1601 +                                             void *, int),
1602 +                               void (*closer)(int, void *));
1603 +
1604 +static int register_logger(void)
1605 +{
1606 +       register_tty_logger(open_tty_log, write_tty_log, close_tty_log);
1607 +       return(0);
1608 +}
1609 +
1610 +__uml_initcall(register_logger);
1611 +
1612  static int __init set_tty_log_dir(char *name, int *add)
1613  {
1614         tty_log_dir = name;
1615 @@ -104,7 +200,7 @@
1616  
1617         tty_log_fd = strtoul(name, &end, 0);
1618         if((*end != '\0') || (end == name)){
1619 -               printk("set_tty_log_fd - strtoul failed on '%s'\n", name);
1620 +               printf("set_tty_log_fd - strtoul failed on '%s'\n", name);
1621                 tty_log_fd = -1;
1622         }
1623         return 0;
1624 --- linux-2.6.0-test4/arch/um/kernel/um_arch.c.uml      2003-08-25 09:29:36.000000000 +0200
1625 +++ linux-2.6.0-test4/arch/um/kernel/um_arch.c  2003-08-25 10:19:28.000000000 +0200
1626 @@ -38,13 +38,18 @@
1627  #include "mode_kern.h"
1628  #include "mode.h"
1629  
1630 -#define DEFAULT_COMMAND_LINE "root=6200"
1631 +#define DEFAULT_COMMAND_LINE "root=ubd0"
1632  
1633  struct cpuinfo_um boot_cpu_data = { 
1634         .loops_per_jiffy        = 0,
1635         .ipi_pipe               = { -1, -1 }
1636  };
1637  
1638 +/* Placeholder to make UML link until the vsyscall stuff is actually 
1639 + * implemented
1640 + */
1641 +void *__kernel_vsyscall;
1642 +
1643  unsigned long thread_saved_pc(struct task_struct *task)
1644  {
1645         return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
1646 @@ -61,10 +66,14 @@
1647                 return 0;
1648  #endif
1649  
1650 -       seq_printf(m, "bogomips\t: %lu.%02lu\n",
1651 +       seq_printf(m, "processor\t: %d\n", index);
1652 +       seq_printf(m, "vendor_id\t: User Mode Linux\n");
1653 +       seq_printf(m, "model name\t: UML\n");
1654 +       seq_printf(m, "mode\t\t: %s\n", CHOOSE_MODE("tt", "skas"));
1655 +       seq_printf(m, "host\t\t: %s\n", host_info);
1656 +       seq_printf(m, "bogomips\t: %lu.%02lu\n\n",
1657                    loops_per_jiffy/(500000/HZ),
1658                    (loops_per_jiffy/(5000/HZ)) % 100);
1659 -       seq_printf(m, "host\t\t: %s\n", host_info);
1660  
1661         return(0);
1662  }
1663 @@ -134,12 +143,12 @@
1664         if(umid != NULL){
1665                 snprintf(argv1_begin, 
1666                          (argv1_end - argv1_begin) * sizeof(*ptr), 
1667 -                        "(%s)", umid);
1668 +                        "(%s) ", umid);
1669                 ptr = &argv1_begin[strlen(argv1_begin)];
1670         }
1671         else ptr = argv1_begin;
1672  
1673 -       snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), " [%s]", cmd);
1674 +       snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd);
1675         memset(argv1_begin + strlen(argv1_begin), '\0', 
1676                argv1_end - argv1_begin - strlen(argv1_begin));
1677  #endif
1678 @@ -179,7 +188,7 @@
1679  static int __init uml_ncpus_setup(char *line, int *add)
1680  {
1681         if (!sscanf(line, "%d", &ncpus)) {
1682 -               printk("Couldn't parse [%s]\n", line);
1683 +               printf("Couldn't parse [%s]\n", line);
1684                 return -1;
1685         }
1686  
1687 @@ -210,7 +219,7 @@
1688  
1689  static int __init mode_tt_setup(char *line, int *add)
1690  {
1691 -       printk("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
1692 +       printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
1693         return(0);
1694  }
1695  
1696 @@ -221,7 +230,7 @@
1697  
1698  static int __init mode_tt_setup(char *line, int *add)
1699  {
1700 -       printk("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
1701 +       printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
1702         return(0);
1703  }
1704  
1705 @@ -369,6 +378,7 @@
1706                 2 * PAGE_SIZE;
1707  
1708         task_protections((unsigned long) &init_thread_info);
1709 +       os_flush_stdout();
1710  
1711         return(CHOOSE_MODE(start_uml_tt(), start_uml_skas()));
1712  }
1713 --- linux-2.6.0-test4/arch/um/kernel/umid.c.uml 2003-08-25 09:29:50.000000000 +0200
1714 +++ linux-2.6.0-test4/arch/um/kernel/umid.c     2003-08-25 10:19:28.000000000 +0200
1715 @@ -33,18 +33,19 @@
1716  static int umid_is_random = 1;
1717  static int umid_inited = 0;
1718  
1719 -static int make_umid(void);
1720 +static int make_umid(int (*printer)(const char *fmt, ...));
1721  
1722 -static int __init set_umid(char *name, int is_random)
1723 +static int __init set_umid(char *name, int is_random, 
1724 +                          int (*printer)(const char *fmt, ...))
1725  {
1726         if(umid_inited){
1727 -               printk("Unique machine name can't be set twice\n");
1728 +               (*printer)("Unique machine name can't be set twice\n");
1729                 return(-1);
1730         }
1731  
1732         if(strlen(name) > UMID_LEN - 1)
1733 -               printk("Unique machine name is being truncated to %s "
1734 -                      "characters\n", UMID_LEN);
1735 +               (*printer)("Unique machine name is being truncated to %s "
1736 +                          "characters\n", UMID_LEN);
1737         strlcpy(umid, name, sizeof(umid));
1738  
1739         umid_is_random = is_random;
1740 @@ -54,7 +55,7 @@
1741  
1742  static int __init set_umid_arg(char *name, int *add)
1743  {
1744 -       return(set_umid(name, 0));
1745 +       return(set_umid(name, 0, printf));
1746  }
1747  
1748  __uml_setup("umid=", set_umid_arg,
1749 @@ -67,7 +68,7 @@
1750  {
1751         int n;
1752  
1753 -       if(!umid_inited && make_umid()) return(-1);
1754 +       if(!umid_inited && make_umid(printk)) return(-1);
1755  
1756         n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1;
1757         if(n > len){
1758 @@ -92,14 +93,14 @@
1759         fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), 
1760                           0644);
1761         if(fd < 0){
1762 -               printk("Open of machine pid file \"%s\" failed - "
1763 +               printf("Open of machine pid file \"%s\" failed - "
1764                        "errno = %d\n", file, -fd);
1765                 return 0;
1766         }
1767  
1768         sprintf(pid, "%d\n", os_getpid());
1769         if(write(fd, pid, strlen(pid)) != strlen(pid))
1770 -               printk("Write of pid file failed - errno = %d\n", errno);
1771 +               printf("Write of pid file failed - errno = %d\n", errno);
1772         close(fd);
1773         return 0;
1774  }
1775 @@ -197,7 +198,7 @@
1776         if((strlen(name) > 0) && (name[strlen(name) - 1] != '/')){
1777                 uml_dir = malloc(strlen(name) + 1);
1778                 if(uml_dir == NULL){
1779 -                       printk("Failed to malloc uml_dir - error = %d\n",
1780 +                       printf("Failed to malloc uml_dir - error = %d\n",
1781                                errno);
1782                         uml_dir = name;
1783                         return(0);
1784 @@ -217,7 +218,7 @@
1785                 char *home = getenv("HOME");
1786  
1787                 if(home == NULL){
1788 -                       printk("make_uml_dir : no value in environment for "
1789 +                       printf("make_uml_dir : no value in environment for "
1790                                "$HOME\n");
1791                         exit(1);
1792                 }
1793 @@ -239,25 +240,25 @@
1794         strcpy(uml_dir, dir);
1795         
1796         if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
1797 -               printk("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
1798 +               printf("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
1799                 return(-1);
1800         }
1801         return 0;
1802  }
1803  
1804 -static int __init make_umid(void)
1805 +static int __init make_umid(int (*printer)(const char *fmt, ...))
1806  {
1807         int fd, err;
1808         char tmp[strlen(uml_dir) + UMID_LEN + 1];
1809  
1810         strlcpy(tmp, uml_dir, sizeof(tmp));
1811  
1812 -       if(*umid == 0){
1813 +       if(!umid_inited){
1814                 strcat(tmp, "XXXXXX");
1815                 fd = mkstemp(tmp);
1816                 if(fd < 0){
1817 -                       printk("make_umid - mkstemp failed, errno = %d\n",
1818 -                              errno);
1819 +                       (*printer)("make_umid - mkstemp failed, errno = %d\n",
1820 +                                  errno);
1821                         return(1);
1822                 }
1823  
1824 @@ -267,7 +268,7 @@
1825                  * for directories.
1826                  */
1827                 unlink(tmp);
1828 -               set_umid(&tmp[strlen(uml_dir)], 1);
1829 +               set_umid(&tmp[strlen(uml_dir)], 1, printer);
1830         }
1831         
1832         sprintf(tmp, "%s%s", uml_dir, umid);
1833 @@ -275,14 +276,14 @@
1834         if((err = mkdir(tmp, 0777)) < 0){
1835                 if(errno == EEXIST){
1836                         if(not_dead_yet(tmp)){
1837 -                               printk("umid '%s' is in use\n", umid);
1838 +                               (*printer)("umid '%s' is in use\n", umid);
1839                                 return(-1);
1840                         }
1841                         err = mkdir(tmp, 0777);
1842                 }
1843         }
1844         if(err < 0){
1845 -               printk("Failed to create %s - errno = %d\n", umid, errno);
1846 +               (*printer)("Failed to create %s - errno = %d\n", umid, errno);
1847                 return(-1);
1848         }
1849  
1850 @@ -295,7 +296,13 @@
1851  );
1852  
1853  __uml_postsetup(make_uml_dir);
1854 -__uml_postsetup(make_umid);
1855 +
1856 +static int __init make_umid_setup(void)
1857 +{
1858 +       return(make_umid(printf));
1859 +}
1860 +
1861 +__uml_postsetup(make_umid_setup);
1862  __uml_postsetup(create_pid_file);
1863  
1864  /*
1865 --- linux-2.6.0-test4/arch/um/kernel/user_util.c.uml    2003-08-25 09:28:19.000000000 +0200
1866 +++ linux-2.6.0-test4/arch/um/kernel/user_util.c        2003-08-25 10:19:28.000000000 +0200
1867 @@ -119,17 +119,6 @@
1868         }
1869  }
1870  
1871 -int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags)
1872 -{
1873 -       int pid;
1874 -
1875 -       pid = clone(fn, sp, flags, arg);
1876 -       if(pid < 0) return(-1);
1877 -       wait_for_stop(pid, SIGSTOP, PTRACE_CONT, NULL);
1878 -       ptrace(PTRACE_CONT, pid, 0, 0);
1879 -       return(pid);
1880 -}
1881 -
1882  int raw(int fd, int complain)
1883  {
1884         struct termios tt;
1885 --- linux-2.6.0-test4/arch/um/drivers/Makefile.uml      2003-08-25 09:29:06.000000000 +0200
1886 +++ linux-2.6.0-test4/arch/um/drivers/Makefile  2003-08-25 10:19:28.000000000 +0200
1887 @@ -1,5 +1,5 @@
1888  # 
1889 -# Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
1890 +# Copyright (C) 2000, 2002, 2003 Jeff Dike (jdike@karaya.com)
1891  # Licensed under the GPL
1892  #
1893  
1894 @@ -39,6 +39,8 @@
1895  obj-$(CONFIG_TTY_CHAN) += tty.o 
1896  obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o
1897  obj-$(CONFIG_UML_WATCHDOG) += harddog.o
1898 +obj-$(CONFIG_BLK_DEV_COW) += cow_kern.o
1899 +obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
1900  
1901  obj-y += stdio_console.o $(CHAN_OBJS)
1902  
1903 @@ -46,7 +48,7 @@
1904  
1905  USER_OBJS := $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) fd.o \
1906         null.o pty.o tty.o xterm.o
1907 -USER_OBJS := $(foreach file,$(USER_OBJS),arch/um/drivers/$(file))
1908 +USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
1909  
1910  $(USER_OBJS) : %.o: %.c
1911         $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
1912 --- linux-2.6.0-test4/arch/um/drivers/chan_kern.c.uml   2003-08-25 09:29:57.000000000 +0200
1913 +++ linux-2.6.0-test4/arch/um/drivers/chan_kern.c       2003-08-25 10:19:28.000000000 +0200
1914 @@ -8,6 +8,7 @@
1915  #include <linux/list.h>
1916  #include <linux/slab.h>
1917  #include <linux/tty.h>
1918 +#include <linux/string.h>
1919  #include <linux/tty_flip.h>
1920  #include <asm/irq.h>
1921  #include "chan_kern.h"
1922 --- linux-2.6.0-test4/arch/um/drivers/chan_user.c.uml   2003-08-25 09:28:09.000000000 +0200
1923 +++ linux-2.6.0-test4/arch/um/drivers/chan_user.c       2003-08-25 10:19:28.000000000 +0200
1924 @@ -188,8 +188,8 @@
1925         if(!isatty(fd)) return;
1926  
1927         pid = tcgetpgrp(fd);
1928 -       if(!CHOOSE_MODE(is_tracer_winch(pid, fd, device_data), 0) && 
1929 -          (pid == -1)){
1930 +       if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd, 
1931 +                            device_data) && (pid == -1)){
1932                 thread = winch_tramp(fd, device_data, &thread_fd);
1933                 if(fd != -1){
1934                         register_winch_irq(thread_fd, fd, thread, device_data);
1935 --- /dev/null   2003-08-17 16:10:07.000000000 +0200
1936 +++ linux-2.6.0-test4/arch/um/drivers/cow.h     2003-08-25 10:19:28.000000000 +0200
1937 @@ -0,0 +1,40 @@
1938 +#ifndef __COW_H__
1939 +#define __COW_H__
1940 +
1941 +#include <asm/types.h>
1942 +
1943 +#if __BYTE_ORDER == __BIG_ENDIAN
1944 +# define ntohll(x) (x)
1945 +# define htonll(x) (x)
1946 +#elif __BYTE_ORDER == __LITTLE_ENDIAN
1947 +# define ntohll(x)  bswap_64(x)
1948 +# define htonll(x)  bswap_64(x)
1949 +#else
1950 +#error "__BYTE_ORDER not defined"
1951 +#endif
1952 +
1953 +extern int init_cow_file(int fd, char *cow_file, char *backing_file, 
1954 +                        int sectorsize, int *bitmap_offset_out, 
1955 +                        unsigned long *bitmap_len_out, int *data_offset_out);
1956 +
1957 +extern int file_reader(__u64 offset, char *buf, int len, void *arg);
1958 +extern int read_cow_header(int (*reader)(__u64, char *, int, void *), 
1959 +                          void *arg, __u32 *magic_out, 
1960 +                          char **backing_file_out, time_t *mtime_out, 
1961 +                          __u64 *size_out, int *sectorsize_out, 
1962 +                          int *bitmap_offset_out);
1963 +
1964 +extern int write_cow_header(char *cow_file, int fd, char *backing_file, 
1965 +                           int sectorsize, long long *size);
1966 +
1967 +extern void cow_sizes(__u64 size, int sectorsize, int bitmap_offset, 
1968 +                     unsigned long *bitmap_len_out, int *data_offset_out);
1969 +
1970 +#endif
1971 +
1972 +/*
1973 + * ---------------------------------------------------------------------------
1974 + * Local variables:
1975 + * c-file-style: "linux"
1976 + * End:
1977 + */
1978 --- /dev/null   2003-08-17 16:10:07.000000000 +0200
1979 +++ linux-2.6.0-test4/arch/um/drivers/cow_kern.c        2003-08-25 10:19:28.000000000 +0200
1980 @@ -0,0 +1,628 @@
1981 +#define COW_MAJOR 60
1982 +#define MAJOR_NR COW_MAJOR
1983 +
1984 +#include <linux/stddef.h>
1985 +#include <linux/kernel.h>
1986 +#include <linux/ctype.h>
1987 +#include <linux/stat.h>
1988 +#include <linux/vmalloc.h>
1989 +#include <linux/blkdev.h>
1990 +#include <linux/blk.h>
1991 +#include <linux/fs.h>
1992 +#include <linux/genhd.h>
1993 +#include <linux/devfs_fs.h>
1994 +#include <asm/uaccess.h>
1995 +#include "2_5compat.h"
1996 +#include "cow.h"
1997 +#include "ubd_user.h"
1998 +
1999 +#define COW_SHIFT 4
2000 +
2001 +struct cow {
2002 +       int count;
2003 +       char *cow_path;
2004 +       dev_t cow_dev;
2005 +       struct block_device *cow_bdev;
2006 +       char *backing_path;
2007 +       dev_t backing_dev;
2008 +       struct block_device *backing_bdev;
2009 +       int sectorsize;
2010 +       unsigned long *bitmap;
2011 +       unsigned long bitmap_len;
2012 +       int bitmap_offset;
2013 +       int data_offset;
2014 +       devfs_handle_t devfs;
2015 +       struct semaphore sem;
2016 +       struct semaphore io_sem;
2017 +       atomic_t working;
2018 +       spinlock_t io_lock;
2019 +       struct buffer_head *bh;
2020 +       struct buffer_head *bhtail;
2021 +       void *end_io;
2022 +};
2023 +
2024 +#define DEFAULT_COW { \
2025 +       .count                  = 0, \
2026 +       .cow_path               = NULL, \
2027 +       .cow_dev                = 0, \
2028 +       .backing_path           = NULL, \
2029 +       .backing_dev            = 0, \
2030 +        .bitmap                        = NULL, \
2031 +       .bitmap_len             = 0, \
2032 +       .bitmap_offset          = 0, \
2033 +        .data_offset           = 0, \
2034 +       .devfs                  = NULL, \
2035 +       .working                = ATOMIC_INIT(0), \
2036 +       .io_lock                = SPIN_LOCK_UNLOCKED, \
2037 +}
2038 +
2039 +#define MAX_DEV (8)
2040 +#define MAX_MINOR (MAX_DEV << COW_SHIFT)
2041 +
2042 +struct cow cow_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_COW };
2043 +
2044 +/* Not modified by this driver */
2045 +static int blk_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = BLOCK_SIZE };
2046 +static int hardsect_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 512 };
2047 +
2048 +/* Protected by cow_lock */
2049 +static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 };
2050 +
2051 +static struct hd_struct        cow_part[MAX_MINOR] =
2052 +       { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } };
2053 +
2054 +/* Protected by io_request_lock */
2055 +static request_queue_t *cow_queue;
2056 +
2057 +static int cow_open(struct inode *inode, struct file *filp);
2058 +static int cow_release(struct inode * inode, struct file * file);
2059 +static int cow_ioctl(struct inode * inode, struct file * file,
2060 +                    unsigned int cmd, unsigned long arg);
2061 +static int cow_revalidate(kdev_t rdev);
2062 +
2063 +static struct block_device_operations cow_blops = {
2064 +       .open           = cow_open,
2065 +       .release        = cow_release,
2066 +       .ioctl          = cow_ioctl,
2067 +       .revalidate     = cow_revalidate,
2068 +};
2069 +
2070 +/* Initialized in an initcall, and unchanged thereafter */
2071 +devfs_handle_t cow_dir_handle;
2072 +
2073 +#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \
2074 +{ \
2075 +       .major          = maj, \
2076 +       .major_name     = name, \
2077 +       .minor_shift    = shift, \
2078 +       .max_p          = 1 << shift, \
2079 +       .part           = parts, \
2080 +       .sizes          = bsizes, \
2081 +       .nr_real        = max, \
2082 +       .real_devices   = NULL, \
2083 +       .next           = NULL, \
2084 +       .fops           = blops, \
2085 +       .de_arr         = NULL, \
2086 +       .flags          = 0 \
2087 +}
2088 +
2089 +static spinlock_t cow_lock = SPIN_LOCK_UNLOCKED;
2090 +
2091 +static struct gendisk cow_gendisk = INIT_GENDISK(MAJOR_NR, "cow", cow_part,
2092 +                                                COW_SHIFT, sizes, MAX_DEV, 
2093 +                                                &cow_blops);
2094 +
2095 +static int cow_add(int n)
2096 +{
2097 +       struct cow *dev = &cow_dev[n];
2098 +       char name[sizeof("nnnnnn\0")];
2099 +       int err = -ENODEV;
2100 +
2101 +       if(dev->cow_path == NULL)
2102 +               goto out;
2103 +
2104 +       sprintf(name, "%d", n);
2105 +       dev->devfs = devfs_register(cow_dir_handle, name, DEVFS_FL_REMOVABLE,
2106 +                                   MAJOR_NR, n << COW_SHIFT, S_IFBLK | 
2107 +                                   S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
2108 +                                   &cow_blops, NULL);
2109 +
2110 +       init_MUTEX_LOCKED(&dev->sem);
2111 +       init_MUTEX(&dev->io_sem);
2112 +
2113 +       return(0);
2114 +
2115 +out:
2116 +       return(err);
2117 +}
2118 +
2119 +/*
2120 +* Add buffer_head to back of pending list
2121 +*/
2122 +static void cow_add_bh(struct cow *cow, struct buffer_head *bh)
2123 +{
2124 +       unsigned long flags;
2125 +
2126 +       spin_lock_irqsave(&cow->io_lock, flags);
2127 +       if(cow->bhtail != NULL){
2128 +               cow->bhtail->b_reqnext = bh;
2129 +               cow->bhtail = bh;
2130 +       }
2131 +       else {
2132 +               cow->bh = bh;
2133 +               cow->bhtail = bh;
2134 +       }
2135 +       spin_unlock_irqrestore(&cow->io_lock, flags);
2136 +}
2137 +
2138 +/*
2139 +* Grab first pending buffer
2140 +*/
2141 +static struct buffer_head *cow_get_bh(struct cow *cow)
2142 +{
2143 +       struct buffer_head *bh;
2144 +
2145 +       spin_lock_irq(&cow->io_lock);
2146 +       bh = cow->bh;
2147 +       if(bh != NULL){
2148 +               if(bh == cow->bhtail)
2149 +                       cow->bhtail = NULL;
2150 +               cow->bh = bh->b_reqnext;
2151 +               bh->b_reqnext = NULL;
2152 +       }
2153 +       spin_unlock_irq(&cow->io_lock);
2154 +
2155 +       return(bh);
2156 +}
2157 +
2158 +static void cow_handle_bh(struct cow *cow, struct buffer_head *bh, 
2159 +                         struct buffer_head **cow_bh, int ncow_bh)
2160 +{
2161 +       int i;
2162 +
2163 +       if(ncow_bh > 0)
2164 +               ll_rw_block(WRITE, ncow_bh, cow_bh);
2165 +
2166 +       for(i = 0; i < ncow_bh ; i++){
2167 +               wait_on_buffer(cow_bh[i]);
2168 +               brelse(cow_bh[i]);
2169 +       }
2170 +
2171 +       ll_rw_block(WRITE, 1, &bh);
2172 +       brelse(bh);
2173 +}
2174 +
2175 +static struct buffer_head *cow_new_bh(struct cow *dev, int sector)
2176 +{
2177 +       struct buffer_head *bh;
2178 +
2179 +       sector = (dev->bitmap_offset + sector / 8) / dev->sectorsize;
2180 +       bh = getblk(dev->cow_dev, sector, dev->sectorsize);
2181 +       memcpy(bh->b_data, dev->bitmap + sector / (8 * sizeof(dev->bitmap[0])),
2182 +              dev->sectorsize);
2183 +       return(bh);
2184 +}
2185 +
2186 +/* Copied from loop.c, needed to avoid deadlocking in make_request. */
2187 +
2188 +static int cow_thread(void *data)
2189 +{
2190 +       struct cow *dev = data;
2191 +       struct buffer_head *bh;
2192 +
2193 +       daemonize();
2194 +       exit_files(current);
2195 +
2196 +       sprintf(current->comm, "cow%d", dev - cow_dev);
2197 +
2198 +       spin_lock_irq(&current->sigmask_lock);
2199 +       sigfillset(&current->blocked);
2200 +       flush_signals(current);
2201 +       spin_unlock_irq(&current->sigmask_lock);
2202 +
2203 +       atomic_inc(&dev->working);
2204 +
2205 +       current->policy = SCHED_OTHER;
2206 +       current->nice = -20;
2207 +
2208 +       current->flags |= PF_NOIO;
2209 +
2210 +       /*
2211 +        * up sem, we are running
2212 +        */
2213 +       up(&dev->sem);
2214 +
2215 +       for(;;){
2216 +               int start, len, nbh, i, update_bitmap = 0;
2217 +               struct buffer_head *cow_bh[2];
2218 +
2219 +               down_interruptible(&dev->io_sem);
2220 +               /*
2221 +                * could be upped because of tear-down, not because of
2222 +                * pending work
2223 +                */
2224 +               if(!atomic_read(&dev->working))
2225 +                       break;
2226 +
2227 +               bh = cow_get_bh(dev);
2228 +               if(bh == NULL){
2229 +                       printk(KERN_ERR "cow: missing bh\n");
2230 +                       continue;
2231 +               }
2232 +
2233 +               start = bh->b_blocknr * bh->b_size / dev->sectorsize;
2234 +               len = bh->b_size / dev->sectorsize;
2235 +               for(i = 0; i < len ; i++){
2236 +                       if(ubd_test_bit(start +ni, 
2237 +                                       (unsigned char *) dev->bitmap))
2238 +                               continue;
2239 +
2240 +                       update_bitmap = 1;
2241 +                       ubd_set_bit(start + i, (unsigned char *) dev->bitmap);
2242 +               }
2243 +
2244 +               cow_bh[0] = NULL;
2245 +               cow_bh[1] = NULL;
2246 +               nbh = 0;
2247 +               if(update_bitmap){
2248 +                       cow_bh[0] = cow_new_bh(dev, start);
2249 +                       nbh++;
2250 +                       if(start / dev->sectorsize != 
2251 +                          (start + len) / dev->sectorsize){
2252 +                               cow_bh[1] = cow_new_bh(dev, start + len);
2253 +                               nbh++;
2254 +                       }
2255 +               }
2256 +               
2257 +               bh->b_dev = dev->cow_dev;
2258 +               bh->b_blocknr += dev->data_offset / dev->sectorsize;
2259 +
2260 +               cow_handle_bh(dev, bh, cow_bh, nbh);
2261 +
2262 +               /*
2263 +                * upped both for pending work and tear-down, lo_pending
2264 +                * will hit zero then
2265 +                */
2266 +               if(atomic_dec_and_test(&dev->working))
2267 +                       break;
2268 +       }
2269 +
2270 +       up(&dev->sem);
2271 +       return(0);
2272 +}
2273 +
2274 +static int cow_make_request(request_queue_t *q, int rw, struct buffer_head *bh)
2275 +{
2276 +       struct cow *dev;
2277 +       int n, minor;
2278 +
2279 +       minor = MINOR(bh->b_rdev);
2280 +       n = minor >> COW_SHIFT;
2281 +       dev = &cow_dev[n];
2282 +
2283 +       dev->end_io = NULL;
2284 +       if(ubd_test_bit(bh->b_rsector, (unsigned char *) dev->bitmap)){
2285 +               bh->b_rdev = dev->cow_dev;
2286 +               bh->b_rsector += dev->data_offset / dev->sectorsize;
2287 +       }
2288 +       else if(rw == WRITE){
2289 +               bh->b_dev = dev->cow_dev;
2290 +               bh->b_blocknr += dev->data_offset / dev->sectorsize;
2291 +
2292 +               cow_add_bh(dev, bh);
2293 +               up(&dev->io_sem);
2294 +               return(0);
2295 +       }
2296 +       else {
2297 +               bh->b_rdev = dev->backing_dev;
2298 +       }
2299 +
2300 +       return(1);
2301 +}
2302 +
2303 +int cow_init(void)
2304 +{
2305 +       int i;
2306 +
2307 +       cow_dir_handle = devfs_mk_dir (NULL, "cow", NULL);
2308 +       if (devfs_register_blkdev(MAJOR_NR, "cow", &cow_blops)) {
2309 +               printk(KERN_ERR "cow: unable to get major %d\n", MAJOR_NR);
2310 +               return -1;
2311 +       }
2312 +       read_ahead[MAJOR_NR] = 8;               /* 8 sector (4kB) read-ahead */
2313 +       blksize_size[MAJOR_NR] = blk_sizes;
2314 +       blk_size[MAJOR_NR] = sizes;
2315 +       INIT_HARDSECT(hardsect_size, MAJOR_NR, hardsect_sizes);
2316 +
2317 +       cow_queue = BLK_DEFAULT_QUEUE(MAJOR_NR);
2318 +       blk_init_queue(cow_queue, NULL);
2319 +       INIT_ELV(cow_queue, &cow_queue->elevator);
2320 +       blk_queue_make_request(cow_queue, cow_make_request);
2321 +
2322 +       add_gendisk(&cow_gendisk);
2323 +
2324 +       for(i=0;i<MAX_DEV;i++) 
2325 +               cow_add(i);
2326 +
2327 +       return(0);
2328 +}
2329 +
2330 +__initcall(cow_init);
2331 +
2332 +static int reader(__u64 start, char *buf, int count, void *arg)
2333 +{
2334 +       dev_t dev = *((dev_t *) arg);
2335 +       struct buffer_head *bh;
2336 +       __u64 block;
2337 +       int cur, offset, left, n, blocksize = get_hardsect_size(dev);
2338 +
2339 +       if(blocksize == 0)
2340 +               panic("Zero blocksize");
2341 +
2342 +       block = start / blocksize;
2343 +       offset = start % blocksize;
2344 +       left = count;
2345 +       cur = 0;
2346 +       while(left > 0){
2347 +               n = (left > blocksize) ? blocksize : left;
2348 +
2349 +               bh = bread(dev, block, (n < 512) ? 512 : n);
2350 +               if(bh == NULL)
2351 +                       return(-EIO);
2352 +
2353 +               n -= offset;
2354 +               memcpy(&buf[cur], bh->b_data + offset, n);
2355 +               block++;
2356 +               left -= n;
2357 +               cur += n;
2358 +               offset = 0;
2359 +               brelse(bh);
2360 +       }
2361 +
2362 +       return(count);
2363 +}
2364 +
2365 +static int cow_open(struct inode *inode, struct file *filp)
2366 +{
2367 +       int (*dev_ioctl)(struct inode *, struct file *, unsigned int, 
2368 +                        unsigned long);
2369 +       mm_segment_t fs;
2370 +       struct cow *dev;
2371 +       __u64 size;
2372 +       __u32 magic;
2373 +       time_t mtime;
2374 +       char *backing_file;
2375 +       int n, offset, err = 0;
2376 +
2377 +       n = DEVICE_NR(inode->i_rdev);
2378 +       if(n >= MAX_DEV)
2379 +               return(-ENODEV);
2380 +       dev = &cow_dev[n];
2381 +       offset = n << COW_SHIFT;
2382 +
2383 +       spin_lock(&cow_lock);
2384 +
2385 +       if(dev->count == 0){
2386 +               dev->cow_dev = name_to_kdev_t(dev->cow_path);
2387 +               if(dev->cow_dev == 0){
2388 +                       printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") "
2389 +                              "failed\n", dev->cow_path);
2390 +                       err = -ENODEV;
2391 +               }
2392 +
2393 +               dev->backing_dev = name_to_kdev_t(dev->backing_path);
2394 +               if(dev->backing_dev == 0){
2395 +                       printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") "
2396 +                              "failed\n", dev->backing_path);
2397 +                       err = -ENODEV;
2398 +               }
2399 +
2400 +               if(err) 
2401 +                       goto out;
2402 +
2403 +               dev->cow_bdev = bdget(dev->cow_dev);
2404 +               if(dev->cow_bdev == NULL){
2405 +                       printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", 
2406 +                              dev->cow_path);
2407 +                       err = -ENOMEM;
2408 +               }
2409 +               dev->backing_bdev = bdget(dev->backing_dev);
2410 +               if(dev->backing_bdev == NULL){
2411 +                       printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", 
2412 +                              dev->backing_path);
2413 +                       err = -ENOMEM;
2414 +               }
2415 +
2416 +               if(err) 
2417 +                       goto out;
2418 +
2419 +               err = blkdev_get(dev->cow_bdev, FMODE_READ|FMODE_WRITE, 0, 
2420 +                                BDEV_RAW);
2421 +               if(err){
2422 +                       printk("cow_open - blkdev_get of COW device failed, "
2423 +                              "error = %d\n", err);
2424 +                       goto out;
2425 +               }
2426 +               
2427 +               err = blkdev_get(dev->backing_bdev, FMODE_READ, 0, BDEV_RAW);
2428 +               if(err){
2429 +                       printk("cow_open - blkdev_get of backing device "
2430 +                              "failed, error = %d\n", err);
2431 +                       goto out;
2432 +               }
2433 +               
2434 +               err = read_cow_header(reader, &dev->cow_dev, &magic, 
2435 +                                     &backing_file, &mtime, &size,
2436 +                                     &dev->sectorsize, &dev->bitmap_offset);
2437 +               if(err){
2438 +                       printk(KERN_ERR "cow_open - read_cow_header failed, "
2439 +                              "err = %d\n", err);
2440 +                       goto out;
2441 +               }
2442 +
2443 +               cow_sizes(size, dev->sectorsize, dev->bitmap_offset, 
2444 +                         &dev->bitmap_len, &dev->data_offset);
2445 +               dev->bitmap = (void *) vmalloc(dev->bitmap_len);
2446 +               if(dev->bitmap == NULL){
2447 +                       err = -ENOMEM;
2448 +                       printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
2449 +                       goto out;
2450 +               }
2451 +               flush_tlb_kernel_vm();
2452 +               
2453 +               err = reader(dev->bitmap_offset, (char *) dev->bitmap, 
2454 +                            dev->bitmap_len, &dev->cow_dev);
2455 +               if(err < 0){
2456 +                       printk(KERN_ERR "Failed to read COW bitmap\n");
2457 +                       vfree(dev->bitmap);
2458 +                       goto out;
2459 +               }
2460 +
2461 +               dev_ioctl = dev->backing_bdev->bd_op->ioctl;
2462 +               fs = get_fs();
2463 +               set_fs(KERNEL_DS);
2464 +               err = (*dev_ioctl)(inode, filp, BLKGETSIZE, 
2465 +                                  (unsigned long) &sizes[offset]);
2466 +               set_fs(fs);
2467 +               if(err){
2468 +                       printk(KERN_ERR "cow_open - BLKGETSIZE failed, "
2469 +                              "error = %d\n", err);
2470 +                       goto out;
2471 +               }
2472 +
2473 +               kernel_thread(cow_thread, dev, 
2474 +                             CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
2475 +               down(&dev->sem);
2476 +       }
2477 +       dev->count++;
2478 +out:
2479 +       spin_unlock(&cow_lock);
2480 +       return(err);
2481 +}
2482 +
2483 +static int cow_release(struct inode * inode, struct file * file)
2484 +{
2485 +       struct cow *dev;
2486 +       int n, err;
2487 +
2488 +       n = DEVICE_NR(inode->i_rdev);
2489 +       if(n >= MAX_DEV)
2490 +               return(-ENODEV);
2491 +       dev = &cow_dev[n];
2492 +
2493 +       spin_lock(&cow_lock);
2494 +
2495 +       if(--dev->count > 0)
2496 +               goto out;
2497 +
2498 +       err = blkdev_put(dev->cow_bdev, BDEV_RAW);
2499 +       if(err)
2500 +               printk("cow_release - blkdev_put of cow device failed, "
2501 +                      "error = %d\n", err);
2502 +       bdput(dev->cow_bdev);
2503 +       dev->cow_bdev = 0;
2504 +
2505 +       err = blkdev_put(dev->backing_bdev, BDEV_RAW);
2506 +       if(err)
2507 +               printk("cow_release - blkdev_put of backing device failed, "
2508 +                      "error = %d\n", err);
2509 +       bdput(dev->backing_bdev);
2510 +       dev->backing_bdev = 0;
2511 +
2512 +out:
2513 +       spin_unlock(&cow_lock);
2514 +       return(0);
2515 +}
2516 +
2517 +static int cow_ioctl(struct inode * inode, struct file * file,
2518 +                    unsigned int cmd, unsigned long arg)
2519 +{
2520 +       struct cow *dev;
2521 +       int (*dev_ioctl)(struct inode *, struct file *, unsigned int, 
2522 +                        unsigned long);
2523 +       int n;
2524 +
2525 +       n = DEVICE_NR(inode->i_rdev);
2526 +       if(n >= MAX_DEV)
2527 +               return(-ENODEV);
2528 +       dev = &cow_dev[n];
2529 +
2530 +       dev_ioctl = dev->backing_bdev->bd_op->ioctl;
2531 +       return((*dev_ioctl)(inode, file, cmd, arg));
2532 +}
2533 +
2534 +static int cow_revalidate(kdev_t rdev)
2535 +{
2536 +       printk(KERN_ERR "Need to implement cow_revalidate\n");
2537 +       return(0);
2538 +}
2539 +
2540 +static int parse_unit(char **ptr)
2541 +{
2542 +       char *str = *ptr, *end;
2543 +       int n = -1;
2544 +
2545 +       if(isdigit(*str)) {
2546 +               n = simple_strtoul(str, &end, 0);
2547 +               if(end == str)
2548 +                       return(-1);
2549 +               *ptr = end;
2550 +       }
2551 +       else if (('a' <= *str) && (*str <= 'h')) {
2552 +               n = *str - 'a';
2553 +               str++;
2554 +               *ptr = str;
2555 +       }
2556 +       return(n);
2557 +}
2558 +
2559 +static int cow_setup(char *str)
2560 +{
2561 +       struct cow *dev;
2562 +       char *cow_name, *backing_name;
2563 +       int unit;
2564 +
2565 +       unit = parse_unit(&str);
2566 +       if(unit < 0){
2567 +               printk(KERN_ERR "cow_setup - Couldn't parse unit number\n");
2568 +               return(1);
2569 +       }
2570 +
2571 +       if(*str != '='){
2572 +               printk(KERN_ERR "cow_setup - Missing '=' after unit "
2573 +                      "number\n");
2574 +               return(1);
2575 +       }
2576 +       str++;
2577 +
2578 +       cow_name = str;
2579 +       backing_name = strchr(str, ',');
2580 +       if(backing_name == NULL){
2581 +               printk(KERN_ERR "cow_setup - missing backing device name\n");
2582 +               return(0);
2583 +       }
2584 +       *backing_name = '\0';
2585 +       backing_name++;
2586 +
2587 +       spin_lock(&cow_lock);
2588 +
2589 +       dev = &cow_dev[unit];
2590 +       dev->cow_path = cow_name;
2591 +       dev->backing_path = backing_name;
2592 +       
2593 +       spin_unlock(&cow_lock);
2594 +       return(0);
2595 +}
2596 +
2597 +__setup("cow", cow_setup);
2598 +
2599 +/*
2600 + * Overrides for Emacs so that we follow Linus's tabbing style.
2601 + * Emacs will notice this stuff at the end of the file and automatically
2602 + * adjust the settings for this buffer only.  This must remain at the end
2603 + * of the file.
2604 + * ---------------------------------------------------------------------------
2605 + * Local variables:
2606 + * c-file-style: "linux"
2607 + * End:
2608 + */
2609 --- /dev/null   2003-08-17 16:10:07.000000000 +0200
2610 +++ linux-2.6.0-test4/arch/um/drivers/cow_sys.h 2003-08-25 10:19:28.000000000 +0200
2611 @@ -0,0 +1,48 @@
2612 +#ifndef __COW_SYS_H__
2613 +#define __COW_SYS_H__
2614 +
2615 +#include "kern_util.h"
2616 +#include "user_util.h"
2617 +#include "os.h"
2618 +#include "user.h"
2619 +
2620 +static inline void *cow_malloc(int size)
2621 +{
2622 +       return(um_kmalloc(size));
2623 +}
2624 +
2625 +static inline void cow_free(void *ptr)
2626 +{
2627 +       kfree(ptr);
2628 +}
2629 +
2630 +#define cow_printf printk
2631 +
2632 +static inline char *cow_strdup(char *str)
2633 +{
2634 +       return(uml_strdup(str));
2635 +}
2636 +
2637 +static inline int cow_seek_file(int fd, __u64 offset)
2638 +{
2639 +       return(os_seek_file(fd, offset));
2640 +}
2641 +
2642 +static inline int cow_file_size(char *file, __u64 *size_out)
2643 +{
2644 +       return(os_file_size(file, size_out));
2645 +}
2646 +
2647 +static inline int cow_write_file(int fd, char *buf, int size)
2648 +{
2649 +       return(os_write_file(fd, buf, size));
2650 +}
2651 +
2652 +#endif
2653 +
2654 +/*
2655 + * ---------------------------------------------------------------------------
2656 + * Local variables:
2657 + * c-file-style: "linux"
2658 + * End:
2659 + */
2660 --- /dev/null   2003-08-17 16:10:07.000000000 +0200
2661 +++ linux-2.6.0-test4/arch/um/drivers/cow_user.c        2003-08-25 10:19:28.000000000 +0200
2662 @@ -0,0 +1,296 @@
2663 +#include <stddef.h>
2664 +#include <string.h>
2665 +#include <errno.h>
2666 +#include <unistd.h>
2667 +#include <byteswap.h>
2668 +#include <sys/stat.h>
2669 +#include <sys/time.h>
2670 +#include <sys/param.h>
2671 +#include <netinet/in.h>
2672 +
2673 +#include "cow.h"
2674 +#include "cow_sys.h"
2675 +
2676 +#define PATH_LEN_V1 256
2677 +
2678 +struct cow_header_v1 {
2679 +       int magic;
2680 +       int version;
2681 +       char backing_file[PATH_LEN_V1];
2682 +       time_t mtime;
2683 +       __u64 size;
2684 +       int sectorsize;
2685 +};
2686 +
2687 +#define PATH_LEN_V2 MAXPATHLEN
2688 +
2689 +struct cow_header_v2 {
2690 +       unsigned long magic;
2691 +       unsigned long version;
2692 +       char backing_file[PATH_LEN_V2];
2693 +       time_t mtime;
2694 +       __u64 size;
2695 +       int sectorsize;
2696 +};
2697 +
2698 +union cow_header {
2699 +       struct cow_header_v1 v1;
2700 +       struct cow_header_v2 v2;
2701 +};
2702 +
2703 +#define COW_MAGIC 0x4f4f4f4d  /* MOOO */
2704 +#define COW_VERSION 2
2705 +
2706 +void cow_sizes(__u64 size, int sectorsize, int bitmap_offset, 
2707 +              unsigned long *bitmap_len_out, int *data_offset_out)
2708 +{
2709 +       *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
2710 +
2711 +       *data_offset_out = bitmap_offset + *bitmap_len_out;
2712 +       *data_offset_out = (*data_offset_out + sectorsize - 1) / sectorsize;
2713 +       *data_offset_out *= sectorsize;
2714 +}
2715 +
2716 +static int absolutize(char *to, int size, char *from)
2717 +{
2718 +       char save_cwd[256], *slash;
2719 +       int remaining;
2720 +
2721 +       if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
2722 +               cow_printf("absolutize : unable to get cwd - errno = %d\n", 
2723 +                          errno);
2724 +               return(-1);
2725 +       }
2726 +       slash = strrchr(from, '/');
2727 +       if(slash != NULL){
2728 +               *slash = '\0';
2729 +               if(chdir(from)){
2730 +                       *slash = '/';
2731 +                       cow_printf("absolutize : Can't cd to '%s' - " 
2732 +                                  "errno = %d\n", from, errno);
2733 +                       return(-1);
2734 +               }
2735 +               *slash = '/';
2736 +               if(getcwd(to, size) == NULL){
2737 +                       cow_printf("absolutize : unable to get cwd of '%s' - "
2738 +                              "errno = %d\n", from, errno);
2739 +                       return(-1);
2740 +               }
2741 +               remaining = size - strlen(to);
2742 +               if(strlen(slash) + 1 > remaining){
2743 +                       cow_printf("absolutize : unable to fit '%s' into %d "
2744 +                              "chars\n", from, size);
2745 +                       return(-1);
2746 +               }
2747 +               strcat(to, slash);
2748 +       }
2749 +       else {
2750 +               if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
2751 +                       cow_printf("absolutize : unable to fit '%s' into %d "
2752 +                              "chars\n", from, size);
2753 +                       return(-1);
2754 +               }
2755 +               strcpy(to, save_cwd);
2756 +               strcat(to, "/");
2757 +               strcat(to, from);
2758 +       }
2759 +       chdir(save_cwd);
2760 +       return(0);
2761 +}
2762 +
2763 +int write_cow_header(char *cow_file, int fd, char *backing_file, 
2764 +                    int sectorsize, long long *size)
2765 +{
2766 +       struct cow_header_v2 *header;
2767 +       struct stat64 buf;
2768 +       int err;
2769 +
2770 +       err = cow_seek_file(fd, 0);
2771 +       if(err != 0){
2772 +               cow_printf("write_cow_header - lseek failed, errno = %d\n", 
2773 +                          errno);
2774 +               return(-errno);
2775 +       }
2776 +
2777 +       err = -ENOMEM;
2778 +       header = cow_malloc(sizeof(*header));
2779 +       if(header == NULL){
2780 +               cow_printf("Failed to allocate COW V2 header\n");
2781 +               goto out;
2782 +       }
2783 +       header->magic = htonl(COW_MAGIC);
2784 +       header->version = htonl(COW_VERSION);
2785 +
2786 +       err = -EINVAL;
2787 +       if(strlen(backing_file) > sizeof(header->backing_file) - 1){
2788 +               cow_printf("Backing file name \"%s\" is too long - names are "
2789 +                          "limited to %d characters\n", backing_file, 
2790 +                          sizeof(header->backing_file) - 1);
2791 +               goto out_free;
2792 +       }
2793 +
2794 +       if(absolutize(header->backing_file, sizeof(header->backing_file), 
2795 +                     backing_file))
2796 +               goto out_free;
2797 +
2798 +       err = stat64(header->backing_file, &buf);
2799 +       if(err < 0){
2800 +               cow_printf("Stat of backing file '%s' failed, errno = %d\n",
2801 +                          header->backing_file, errno);
2802 +               err = -errno;
2803 +               goto out_free;
2804 +       }
2805 +
2806 +       err = cow_file_size(header->backing_file, size);
2807 +       if(err){
2808 +               cow_printf("Couldn't get size of backing file '%s', "
2809 +                          "errno = %d\n", header->backing_file, -*size);
2810 +               goto out_free;
2811 +       }
2812 +
2813 +       header->mtime = htonl(buf.st_mtime);
2814 +       header->size = htonll(*size);
2815 +       header->sectorsize = htonl(sectorsize);
2816 +
2817 +       err = write(fd, header, sizeof(*header));
2818 +       if(err != sizeof(*header)){
2819 +               cow_printf("Write of header to new COW file '%s' failed, "
2820 +                          "errno = %d\n", cow_file, errno);
2821 +               goto out_free;
2822 +       }
2823 +       err = 0;
2824 + out_free:
2825 +       cow_free(header);
2826 + out:
2827 +       return(err);
2828 +}
2829 +
2830 +int file_reader(__u64 offset, char *buf, int len, void *arg)
2831 +{
2832 +       int fd = *((int *) arg);
2833 +
2834 +       return(pread(fd, buf, len, offset));
2835 +}
2836 +
2837 +int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, 
2838 +                   __u32 *magic_out, char **backing_file_out, 
2839 +                   time_t *mtime_out, __u64 *size_out, 
2840 +                   int *sectorsize_out, int *bitmap_offset_out)
2841 +{
2842 +       union cow_header *header;
2843 +       char *file;
2844 +       int err, n;
2845 +       unsigned long version, magic;
2846 +
2847 +       header = cow_malloc(sizeof(*header));
2848 +       if(header == NULL){
2849 +               cow_printf("read_cow_header - Failed to allocate header\n");
2850 +               return(-ENOMEM);
2851 +       }
2852 +       err = -EINVAL;
2853 +       n = (*reader)(0, (char *) header, sizeof(*header), arg);
2854 +       if(n < offsetof(typeof(header->v1), backing_file)){
2855 +               cow_printf("read_cow_header - short header\n");
2856 +               goto out;
2857 +       }
2858 +
2859 +       magic = header->v1.magic;
2860 +       if(magic == COW_MAGIC) {
2861 +               version = header->v1.version;
2862 +       }
2863 +       else if(magic == ntohl(COW_MAGIC)){
2864 +               version = ntohl(header->v1.version);
2865 +       }
2866 +       /* No error printed because the non-COW case comes through here */
2867 +       else goto out;
2868 +
2869 +       *magic_out = COW_MAGIC;
2870 +
2871 +       if(version == 1){
2872 +               if(n < sizeof(header->v1)){
2873 +                       cow_printf("read_cow_header - failed to read V1 "
2874 +                                  "header\n");
2875 +                       goto out;
2876 +               }
2877 +               *mtime_out = header->v1.mtime;
2878 +               *size_out = header->v1.size;
2879 +               *sectorsize_out = header->v1.sectorsize;
2880 +               *bitmap_offset_out = sizeof(header->v1);
2881 +               file = header->v1.backing_file;
2882 +       }
2883 +       else if(version == 2){
2884 +               if(n < sizeof(header->v2)){
2885 +                       cow_printf("read_cow_header - failed to read V2 "
2886 +                                  "header\n");
2887 +                       goto out;
2888 +               }
2889 +               *mtime_out = ntohl(header->v2.mtime);
2890 +               *size_out = ntohll(header->v2.size);
2891 +               *sectorsize_out = ntohl(header->v2.sectorsize);
2892 +               *bitmap_offset_out = sizeof(header->v2);
2893 +               file = header->v2.backing_file;
2894 +       }
2895 +       else {
2896 +               cow_printf("read_cow_header - invalid COW version\n");
2897 +               goto out;
2898 +       }
2899 +       err = -ENOMEM;
2900 +       *backing_file_out = cow_strdup(file);
2901 +       if(*backing_file_out == NULL){
2902 +               cow_printf("read_cow_header - failed to allocate backing "
2903 +                          "file\n");
2904 +               goto out;
2905 +       }
2906 +       err = 0;
2907 + out:
2908 +       cow_free(header);
2909 +       return(err);
2910 +}
2911 +
2912 +int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
2913 +                 int *bitmap_offset_out, unsigned long *bitmap_len_out, 
2914 +                 int *data_offset_out)
2915 +{
2916 +       __u64 size, offset;
2917 +       char zero = 0;
2918 +       int err;
2919 +
2920 +       err = write_cow_header(cow_file, fd, backing_file, sectorsize, &size);
2921 +       if(err) 
2922 +               goto out;
2923 +       
2924 +       cow_sizes(size, sectorsize, sizeof(struct cow_header_v2), 
2925 +                 bitmap_len_out, data_offset_out);
2926 +       *bitmap_offset_out = sizeof(struct cow_header_v2);
2927 +
2928 +       offset = *data_offset_out + size - sizeof(zero);
2929 +       err = cow_seek_file(fd, offset);
2930 +       if(err != 0){
2931 +               cow_printf("cow bitmap lseek failed : errno = %d\n", errno);
2932 +               goto out;
2933 +       }
2934 +
2935 +       /* does not really matter how much we write it is just to set EOF 
2936 +        * this also sets the entire COW bitmap
2937 +        * to zero without having to allocate it 
2938 +        */
2939 +       err = cow_write_file(fd, &zero, sizeof(zero));
2940 +       if(err != sizeof(zero)){
2941 +               err = -EINVAL;
2942 +               cow_printf("Write of bitmap to new COW file '%s' failed, "
2943 +                          "errno = %d\n", cow_file, errno);
2944 +               goto out;
2945 +       }
2946 +
2947 +       return(0);
2948 +
2949 + out:
2950 +       return(err);
2951 +}
2952 +
2953 +/*
2954 + * ---------------------------------------------------------------------------
2955 + * Local variables:
2956 + * c-file-style: "linux"
2957 + * End:
2958 + */
2959 --- linux-2.6.0-test4/arch/um/drivers/hostaudio_kern.c.uml      2003-08-25 09:29:56.000000000 +0200
2960 +++ linux-2.6.0-test4/arch/um/drivers/hostaudio_kern.c  2003-08-25 10:19:28.000000000 +0200
2961 @@ -11,6 +11,7 @@
2962  #include "linux/fs.h"
2963  #include "linux/sound.h"
2964  #include "linux/soundcard.h"
2965 +#include "asm/uaccess.h"
2966  #include "kern_util.h"
2967  #include "init.h"
2968  #include "hostaudio.h"
2969 @@ -22,7 +23,7 @@
2970  #ifndef MODULE
2971  static int set_dsp(char *name, int *add)
2972  {
2973 -       dsp = uml_strdup(name);
2974 +       dsp = name;
2975         return(0);
2976  }
2977  
2978 @@ -34,7 +35,7 @@
2979  
2980  static int set_mixer(char *name, int *add)
2981  {
2982 -       mixer = uml_strdup(name);
2983 +       mixer = name;
2984         return(0);
2985  }
2986  
2987 @@ -51,23 +52,55 @@
2988                               loff_t *ppos)
2989  {
2990          struct hostaudio_state *state = file->private_data;
2991 +       void *kbuf;
2992 +       int err;
2993  
2994  #ifdef DEBUG
2995          printk("hostaudio: read called, count = %d\n", count);
2996  #endif
2997  
2998 -        return(hostaudio_read_user(state, buffer, count, ppos));
2999 +       kbuf = kmalloc(count, GFP_KERNEL);
3000 +       if(kbuf == NULL)
3001 +               return(-ENOMEM);
3002 +
3003 +        err = hostaudio_read_user(state, kbuf, count, ppos);
3004 +       if(err < 0)
3005 +               goto out;
3006 +
3007 +       if(copy_to_user(buffer, kbuf, err))
3008 +               err = -EFAULT;
3009 +
3010 + out:
3011 +       kfree(kbuf);
3012 +       return(err);
3013  }
3014  
3015  static ssize_t hostaudio_write(struct file *file, const char *buffer, 
3016                                size_t count, loff_t *ppos)
3017  {
3018          struct hostaudio_state *state = file->private_data;
3019 +       void *kbuf;
3020 +       int err;
3021  
3022  #ifdef DEBUG
3023          printk("hostaudio: write called, count = %d\n", count);
3024  #endif
3025 -        return(hostaudio_write_user(state, buffer, count, ppos));
3026 +
3027 +       kbuf = kmalloc(count, GFP_KERNEL);
3028 +       if(kbuf == NULL)
3029 +               return(-ENOMEM);
3030 +
3031 +       err = -EFAULT;
3032 +       if(copy_from_user(kbuf, buffer, count))
3033 +               goto out;
3034 +
3035 +        err = hostaudio_write_user(state, kbuf, count, ppos);
3036 +       if(err < 0)
3037 +               goto out;
3038 +
3039 + out:
3040 +       kfree(kbuf);
3041 +       return(err);
3042  }
3043  
3044  static unsigned int hostaudio_poll(struct file *file, 
3045 @@ -86,12 +119,43 @@
3046                            unsigned int cmd, unsigned long arg)
3047  {
3048          struct hostaudio_state *state = file->private_data;
3049 +       unsigned long data = 0;
3050 +       int err;
3051  
3052  #ifdef DEBUG
3053          printk("hostaudio: ioctl called, cmd = %u\n", cmd);
3054  #endif
3055 +       switch(cmd){
3056 +       case SNDCTL_DSP_SPEED:
3057 +       case SNDCTL_DSP_STEREO:
3058 +       case SNDCTL_DSP_GETBLKSIZE:
3059 +       case SNDCTL_DSP_CHANNELS:
3060 +       case SNDCTL_DSP_SUBDIVIDE:
3061 +       case SNDCTL_DSP_SETFRAGMENT:
3062 +               if(get_user(data, (int *) arg))
3063 +                       return(-EFAULT);
3064 +               break;
3065 +       default:
3066 +               break;
3067 +       }
3068 +
3069 +        err = hostaudio_ioctl_user(state, cmd, (unsigned long) &data);
3070 +
3071 +       switch(cmd){
3072 +       case SNDCTL_DSP_SPEED:
3073 +       case SNDCTL_DSP_STEREO:
3074 +       case SNDCTL_DSP_GETBLKSIZE:
3075 +       case SNDCTL_DSP_CHANNELS:
3076 +       case SNDCTL_DSP_SUBDIVIDE:
3077 +       case SNDCTL_DSP_SETFRAGMENT:
3078 +               if(put_user(data, (int *) arg))
3079 +                       return(-EFAULT);
3080 +               break;
3081 +       default:
3082 +               break;
3083 +       }
3084  
3085 -        return(hostaudio_ioctl_user(state, cmd, arg));
3086 +       return(err);
3087  }
3088  
3089  static int hostaudio_open(struct inode *inode, struct file *file)
3090 @@ -225,7 +289,8 @@
3091  
3092  static int __init hostaudio_init_module(void)
3093  {
3094 -        printk(KERN_INFO "UML Audio Relay\n");
3095 +        printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n",
3096 +              dsp, mixer);
3097  
3098         module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1);
3099          if(module_data.dev_audio < 0){
3100 --- linux-2.6.0-test4/arch/um/drivers/line.c.uml        2003-08-25 09:29:45.000000000 +0200
3101 +++ linux-2.6.0-test4/arch/um/drivers/line.c    2003-08-25 10:19:28.000000000 +0200
3102 @@ -6,8 +6,8 @@
3103  #include "linux/sched.h"
3104  #include "linux/slab.h"
3105  #include "linux/list.h"
3106 +#include "linux/interrupt.h"
3107  #include "linux/devfs_fs_kernel.h"
3108 -#include "asm/irq.h"
3109  #include "asm/uaccess.h"
3110  #include "chan_kern.h"
3111  #include "irq_user.h"
3112 @@ -16,16 +16,18 @@
3113  #include "user_util.h"
3114  #include "kern_util.h"
3115  #include "os.h"
3116 +#include "irq_kern.h"
3117  
3118  #define LINE_BUFSIZE 4096
3119  
3120 -void line_interrupt(int irq, void *data, struct pt_regs *unused)
3121 +irqreturn_t line_interrupt(int irq, void *data, struct pt_regs *unused)
3122  {
3123         struct line *dev = data;
3124  
3125         if(dev->count > 0) 
3126                 chan_interrupt(&dev->chan_list, &dev->task, dev->tty, irq, 
3127                                dev);
3128 +       return IRQ_HANDLED;
3129  }
3130  
3131  void line_timer_cb(void *arg)
3132 @@ -136,20 +138,22 @@
3133         return(len);
3134  }
3135  
3136 -void line_write_interrupt(int irq, void *data, struct pt_regs *unused)
3137 +irqreturn_t line_write_interrupt(int irq, void *data, struct pt_regs *unused)
3138  {
3139         struct line *dev = data;
3140         struct tty_struct *tty = dev->tty;
3141         int err;
3142  
3143         err = flush_buffer(dev);
3144 -       if(err == 0) return;
3145 +       if(err == 0) 
3146 +               return(IRQ_NONE);
3147         else if(err < 0){
3148                 dev->head = dev->buffer;
3149                 dev->tail = dev->buffer;
3150         }
3151  
3152 -       if(tty == NULL) return;
3153 +       if(tty == NULL) 
3154 +               return(IRQ_NONE);
3155  
3156         if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
3157            (tty->ldisc.write_wakeup != NULL))
3158 @@ -161,9 +165,9 @@
3159          * writes.
3160          */
3161  
3162 -       if (waitqueue_active(&tty->write_wait))
3163 +       if(waitqueue_active(&tty->write_wait))
3164                 wake_up_interruptible(&tty->write_wait);
3165 -
3166 +       return(IRQ_HANDLED);
3167  }
3168  
3169  int line_write_room(struct tty_struct *tty)
3170 @@ -369,7 +373,7 @@
3171  
3172         dev = simple_strtoul(name, &end, 0);
3173         if((*end != '\0') || (end == name)){
3174 -               *error_out = "line_setup failed to parse device number";
3175 +               *error_out = "line_get_config failed to parse device number";
3176                 return(0);
3177         }
3178  
3179 @@ -379,15 +383,15 @@
3180         }
3181  
3182         line = &lines[dev];
3183 +
3184         down(&line->sem);
3185 -       
3186         if(!line->valid)
3187                 CONFIG_CHUNK(str, size, n, "none", 1);
3188         else if(line->count == 0)
3189                 CONFIG_CHUNK(str, size, n, line->init_str, 1);
3190         else n = chan_config_string(&line->chan_list, str, size, error_out);
3191 -
3192         up(&line->sem);
3193 +
3194         return(n);
3195  }
3196  
3197 @@ -412,7 +416,8 @@
3198                 return NULL;
3199  
3200         driver->driver_name = line_driver->name;
3201 -       driver->name = line_driver->devfs_name;
3202 +       driver->name = line_driver->device_name;
3203 +       driver->devfs_name = line_driver->devfs_name;
3204         driver->major = line_driver->major;
3205         driver->minor_start = line_driver->minor_start;
3206         driver->type = line_driver->type;
3207 @@ -432,7 +437,7 @@
3208  
3209         for(i = 0; i < nlines; i++){
3210                 if(!lines[i].valid) 
3211 -                       tty_unregister_devfs(driver, i);
3212 +                       tty_unregister_device(driver, i);
3213         }
3214  
3215         mconsole_register_dev(&line_driver->mc);
3216 @@ -465,24 +470,25 @@
3217         struct line *line;
3218  };
3219  
3220 -void winch_interrupt(int irq, void *data, struct pt_regs *unused)
3221 +irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused)
3222  {
3223         struct winch *winch = data;
3224         struct tty_struct *tty;
3225         int err;
3226         char c;
3227  
3228 -       err = generic_read(winch->fd, &c, NULL);
3229 -       if(err < 0){
3230 -               if(err != -EAGAIN){
3231 -                       printk("winch_interrupt : read failed, errno = %d\n", 
3232 -                              -err);
3233 -                       printk("fd %d is losing SIGWINCH support\n", 
3234 -                              winch->tty_fd);
3235 -                       free_irq(irq, data);
3236 -                       return;
3237 +       if(winch->fd != -1){
3238 +               err = generic_read(winch->fd, &c, NULL);