Whamcloud - gitweb
land b_v26 (20040316_1603)
[fs/lustre-release.git] / lustre / kernel_patches / patches / uml-patch-2.6.3-rc2-1.patch
1 diff -Naur a/arch/um/config.release b/arch/um/config.release
2 --- a/arch/um/config.release    2004-02-11 12:16:48.000000000 -0500
3 +++ b/arch/um/config.release    2004-02-11 12:29:03.000000000 -0500
4 @@ -228,7 +228,6 @@
5  CONFIG_EXT2_FS=y
6  CONFIG_SYSV_FS=m
7  CONFIG_UDF_FS=m
8 -# CONFIG_UDF_RW is not set
9  CONFIG_UFS_FS=m
10  # CONFIG_UFS_FS_WRITE is not set
11  
12 diff -Naur a/arch/um/defconfig b/arch/um/defconfig
13 --- a/arch/um/defconfig 2004-02-11 12:16:02.000000000 -0500
14 +++ b/arch/um/defconfig 2004-02-11 12:27:57.000000000 -0500
15 @@ -3,29 +3,19 @@
16  #
17  CONFIG_USERMODE=y
18  CONFIG_MMU=y
19 -CONFIG_SWAP=y
20  CONFIG_UID16=y
21  CONFIG_RWSEM_GENERIC_SPINLOCK=y
22 -CONFIG_CONFIG_LOG_BUF_SHIFT=14
23  
24  #
25 -# Code maturity level options
26 -#
27 -CONFIG_EXPERIMENTAL=y
28 -
29 -#
30 -# General Setup
31 +# UML-specific options
32  #
33  CONFIG_MODE_TT=y
34  CONFIG_MODE_SKAS=y
35  CONFIG_NET=y
36 -CONFIG_SYSVIPC=y
37 -CONFIG_BSD_PROCESS_ACCT=y
38 -CONFIG_SYSCTL=y
39 -CONFIG_BINFMT_AOUT=y
40  CONFIG_BINFMT_ELF=y
41  CONFIG_BINFMT_MISC=y
42  CONFIG_HOSTFS=y
43 +CONFIG_HPPFS=y
44  CONFIG_MCONSOLE=y
45  CONFIG_MAGIC_SYSRQ=y
46  # CONFIG_HOST_2G_2G is not set
47 @@ -36,12 +26,41 @@
48  # CONFIG_HIGHMEM is not set
49  CONFIG_PROC_MM=y
50  CONFIG_KERNEL_STACK_ORDER=2
51 +CONFIG_UML_REAL_TIME_CLOCK=y
52 +
53 +#
54 +# Code maturity level options
55 +#
56 +CONFIG_EXPERIMENTAL=y
57 +CONFIG_CLEAN_COMPILE=y
58 +CONFIG_STANDALONE=y
59 +CONFIG_BROKEN_ON_SMP=y
60 +
61 +#
62 +# General setup
63 +#
64 +CONFIG_SWAP=y
65 +CONFIG_SYSVIPC=y
66 +CONFIG_BSD_PROCESS_ACCT=y
67 +CONFIG_SYSCTL=y
68 +CONFIG_LOG_BUF_SHIFT=14
69 +# CONFIG_IKCONFIG is not set
70 +# CONFIG_EMBEDDED is not set
71 +CONFIG_KALLSYMS=y
72 +CONFIG_FUTEX=y
73 +CONFIG_EPOLL=y
74 +CONFIG_IOSCHED_NOOP=y
75 +CONFIG_IOSCHED_AS=y
76 +CONFIG_IOSCHED_DEADLINE=y
77  
78  #
79  # Loadable module support
80  #
81 -CONFIG_MODULES=y
82 -# CONFIG_KMOD is not set
83 +# CONFIG_MODULES is not set
84 +
85 +#
86 +# Generic Driver Options
87 +#
88  
89  #
90  # Character Devices
91 @@ -69,6 +88,7 @@
92  #
93  CONFIG_BLK_DEV_UBD=y
94  # CONFIG_BLK_DEV_UBD_SYNC is not set
95 +CONFIG_BLK_DEV_COW_COMMON=y
96  CONFIG_BLK_DEV_LOOP=y
97  CONFIG_BLK_DEV_NBD=y
98  CONFIG_BLK_DEV_RAM=y
99 @@ -78,7 +98,7 @@
100  CONFIG_NETDEVICES=y
101  
102  #
103 -# Network Devices
104 +# UML Network Devices
105  #
106  CONFIG_UML_NET=y
107  CONFIG_UML_NET_ETHERTAP=y
108 @@ -88,22 +108,6 @@
109  CONFIG_UML_NET_MCAST=y
110  # CONFIG_UML_NET_PCAP is not set
111  CONFIG_UML_NET_SLIRP=y
112 -CONFIG_DUMMY=y
113 -# CONFIG_BONDING is not set
114 -# CONFIG_EQUALIZER is not set
115 -CONFIG_TUN=y
116 -# CONFIG_ETHERTAP is not set
117 -CONFIG_PPP=y
118 -# CONFIG_PPP_MULTILINK is not set
119 -# CONFIG_PPP_ASYNC is not set
120 -# CONFIG_PPP_SYNC_TTY is not set
121 -# CONFIG_PPP_DEFLATE is not set
122 -# CONFIG_PPP_BSDCOMP is not set
123 -# CONFIG_PPPOE is not set
124 -CONFIG_SLIP=y
125 -# CONFIG_SLIP_COMPRESSED is not set
126 -# CONFIG_SLIP_SMART is not set
127 -# CONFIG_SLIP_MODE_SLIP6 is not set
128  
129  #
130  # Networking support
131 @@ -115,8 +119,6 @@
132  CONFIG_PACKET=y
133  CONFIG_PACKET_MMAP=y
134  # CONFIG_NETLINK_DEV is not set
135 -# CONFIG_NETFILTER is not set
136 -# CONFIG_FILTER is not set
137  CONFIG_UNIX=y
138  # CONFIG_NET_KEY is not set
139  CONFIG_INET=y
140 @@ -130,8 +132,11 @@
141  # CONFIG_SYN_COOKIES is not set
142  # CONFIG_INET_AH is not set
143  # CONFIG_INET_ESP is not set
144 -# CONFIG_XFRM_USER is not set
145 +# CONFIG_INET_IPCOMP is not set
146  # CONFIG_IPV6 is not set
147 +# CONFIG_DECNET is not set
148 +# CONFIG_BRIDGE is not set
149 +# CONFIG_NETFILTER is not set
150  
151  #
152  # SCTP Configuration (EXPERIMENTAL)
153 @@ -140,9 +145,9 @@
154  # CONFIG_IP_SCTP is not set
155  # CONFIG_ATM is not set
156  # CONFIG_VLAN_8021Q is not set
157 -# CONFIG_LLC is not set
158 -# CONFIG_DECNET is not set
159 -# CONFIG_BRIDGE is not set
160 +# CONFIG_LLC2 is not set
161 +# CONFIG_IPX is not set
162 +# CONFIG_ATALK is not set
163  # CONFIG_X25 is not set
164  # CONFIG_LAPB is not set
165  # CONFIG_NET_DIVERT is not set
166 @@ -160,6 +165,10 @@
167  # Network testing
168  #
169  # CONFIG_NET_PKTGEN is not set
170 +CONFIG_DUMMY=y
171 +# CONFIG_BONDING is not set
172 +# CONFIG_EQUALIZER is not set
173 +CONFIG_TUN=y
174  
175  #
176  # Ethernet (10 or 100Mbit)
177 @@ -171,12 +180,28 @@
178  #
179  
180  #
181 +# Ethernet (10000 Mbit)
182 +#
183 +CONFIG_PPP=y
184 +# CONFIG_PPP_MULTILINK is not set
185 +# CONFIG_PPP_FILTER is not set
186 +# CONFIG_PPP_ASYNC is not set
187 +# CONFIG_PPP_SYNC_TTY is not set
188 +# CONFIG_PPP_DEFLATE is not set
189 +# CONFIG_PPP_BSDCOMP is not set
190 +# CONFIG_PPPOE is not set
191 +CONFIG_SLIP=y
192 +# CONFIG_SLIP_COMPRESSED is not set
193 +# CONFIG_SLIP_SMART is not set
194 +# CONFIG_SLIP_MODE_SLIP6 is not set
195 +
196 +#
197  # Wireless LAN (non-hamradio)
198  #
199  # CONFIG_NET_RADIO is not set
200  
201  #
202 -# Token Ring devices (depends on LLC=y)
203 +# Token Ring devices
204  #
205  # CONFIG_SHAPER is not set
206  
207 @@ -186,68 +211,101 @@
208  # CONFIG_WAN is not set
209  
210  #
211 +# Amateur Radio support
212 +#
213 +# CONFIG_HAMRADIO is not set
214 +
215 +#
216 +# IrDA (infrared) support
217 +#
218 +# CONFIG_IRDA is not set
219 +
220 +#
221 +# Bluetooth support
222 +#
223 +# CONFIG_BT is not set
224 +
225 +#
226  # File systems
227  #
228 +CONFIG_EXT2_FS=y
229 +# CONFIG_EXT2_FS_XATTR is not set
230 +# CONFIG_EXT3_FS is not set
231 +# CONFIG_JBD is not set
232 +CONFIG_REISERFS_FS=y
233 +# CONFIG_REISERFS_CHECK is not set
234 +# CONFIG_REISERFS_PROC_INFO is not set
235 +# CONFIG_JFS_FS is not set
236 +# CONFIG_XFS_FS is not set
237 +CONFIG_MINIX_FS=y
238 +# CONFIG_ROMFS_FS is not set
239  CONFIG_QUOTA=y
240  # CONFIG_QFMT_V1 is not set
241  # CONFIG_QFMT_V2 is not set
242  CONFIG_QUOTACTL=y
243 -CONFIG_AUTOFS_FS=m
244 -CONFIG_AUTOFS4_FS=m
245 -CONFIG_REISERFS_FS=m
246 -# CONFIG_REISERFS_CHECK is not set
247 -# CONFIG_REISERFS_PROC_INFO is not set
248 +CONFIG_AUTOFS_FS=y
249 +CONFIG_AUTOFS4_FS=y
250 +
251 +#
252 +# CD-ROM/DVD Filesystems
253 +#
254 +CONFIG_ISO9660_FS=y
255 +# CONFIG_JOLIET is not set
256 +# CONFIG_ZISOFS is not set
257 +# CONFIG_UDF_FS is not set
258 +
259 +#
260 +# DOS/FAT/NT Filesystems
261 +#
262 +CONFIG_FAT_FS=y
263 +CONFIG_MSDOS_FS=y
264 +CONFIG_VFAT_FS=y
265 +# CONFIG_NTFS_FS is not set
266 +
267 +#
268 +# Pseudo filesystems
269 +#
270 +CONFIG_PROC_FS=y
271 +CONFIG_PROC_KCORE=y
272 +CONFIG_DEVFS_FS=y
273 +CONFIG_DEVFS_MOUNT=y
274 +# CONFIG_DEVFS_DEBUG is not set
275 +CONFIG_DEVPTS_FS=y
276 +# CONFIG_DEVPTS_FS_XATTR is not set
277 +# CONFIG_TMPFS is not set
278 +# CONFIG_HUGETLB_PAGE is not set
279 +CONFIG_RAMFS=y
280 +
281 +#
282 +# Miscellaneous filesystems
283 +#
284  # CONFIG_ADFS_FS is not set
285  # CONFIG_AFFS_FS is not set
286  # CONFIG_HFS_FS is not set
287  # CONFIG_BEFS_FS is not set
288  # CONFIG_BFS_FS is not set
289 -# CONFIG_EXT3_FS is not set
290 -# CONFIG_JBD is not set
291 -CONFIG_FAT_FS=m
292 -CONFIG_MSDOS_FS=m
293 -CONFIG_VFAT_FS=m
294  # CONFIG_EFS_FS is not set
295  CONFIG_JFFS_FS=y
296  CONFIG_JFFS_FS_VERBOSE=0
297 -CONFIG_JFFS_PROC_FS=y
298  # CONFIG_JFFS2_FS is not set
299  # CONFIG_CRAMFS is not set
300 -# CONFIG_TMPFS is not set
301 -CONFIG_RAMFS=y
302 -CONFIG_ISO9660_FS=m
303 -# CONFIG_JOLIET is not set
304 -# CONFIG_ZISOFS is not set
305 -# CONFIG_JFS_FS is not set
306 -CONFIG_MINIX_FS=m
307  # CONFIG_VXFS_FS is not set
308 -# CONFIG_NTFS_FS is not set
309  # CONFIG_HPFS_FS is not set
310 -CONFIG_PROC_FS=y
311 -CONFIG_DEVFS_FS=y
312 -CONFIG_DEVFS_MOUNT=y
313 -# CONFIG_DEVFS_DEBUG is not set
314 -CONFIG_DEVPTS_FS=y
315  # CONFIG_QNX4FS_FS is not set
316 -# CONFIG_ROMFS_FS is not set
317 -CONFIG_EXT2_FS=y
318 -# CONFIG_EXT2_FS_XATTR is not set
319  # CONFIG_SYSV_FS is not set
320 -# CONFIG_UDF_FS is not set
321  # CONFIG_UFS_FS is not set
322 -# CONFIG_XFS_FS is not set
323  
324  #
325  # Network File Systems
326  #
327 -# CONFIG_CODA_FS is not set
328 -# CONFIG_INTERMEZZO_FS is not set
329  # CONFIG_NFS_FS is not set
330  # CONFIG_NFSD is not set
331  # CONFIG_EXPORTFS is not set
332 -# CONFIG_CIFS is not set
333  # CONFIG_SMB_FS is not set
334 +# CONFIG_CIFS is not set
335  # CONFIG_NCP_FS is not set
336 +# CONFIG_CODA_FS is not set
337 +# CONFIG_INTERMEZZO_FS is not set
338  # CONFIG_AFS_FS is not set
339  
340  #
341 @@ -317,28 +375,7 @@
342  #
343  # SCSI support
344  #
345 -CONFIG_SCSI=y
346 -CONFIG_GENERIC_ISA_DMA=y
347 -
348 -#
349 -# SCSI support type (disk, tape, CD-ROM)
350 -#
351 -CONFIG_BLK_DEV_SD=y
352 -CONFIG_SD_EXTRA_DEVS=40
353 -CONFIG_CHR_DEV_ST=y
354 -CONFIG_BLK_DEV_SR=y
355 -CONFIG_BLK_DEV_SR_VENDOR=y
356 -CONFIG_SR_EXTRA_DEVS=2
357 -CONFIG_CHR_DEV_SG=y
358 -
359 -#
360 -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
361 -#
362 -CONFIG_SCSI_DEBUG_QUEUES=y
363 -CONFIG_SCSI_MULTI_LUN=y
364 -CONFIG_SCSI_CONSTANTS=y
365 -CONFIG_SCSI_LOGGING=y
366 -CONFIG_SCSI_DEBUG=y
367 +# CONFIG_SCSI is not set
368  
369  #
370  # Multi-device support (RAID and LVM)
371 @@ -360,6 +397,7 @@
372  CONFIG_MTD_BLOCK=y
373  # CONFIG_FTL is not set
374  # CONFIG_NFTL is not set
375 +# CONFIG_INFTL is not set
376  
377  #
378  # RAM/ROM/Flash chip drivers
379 @@ -374,20 +412,21 @@
380  #
381  # Mapping drivers for chip access
382  #
383 +# CONFIG_MTD_COMPLEX_MAPPINGS is not set
384  
385  #
386  # Self-contained MTD device drivers
387  #
388  # CONFIG_MTD_SLRAM is not set
389  # CONFIG_MTD_MTDRAM is not set
390 -CONFIG_MTD_BLKMTD=m
391 +CONFIG_MTD_BLKMTD=y
392  
393  #
394  # Disk-On-Chip Device Drivers
395  #
396 -# CONFIG_MTD_DOC1000 is not set
397  # CONFIG_MTD_DOC2000 is not set
398  # CONFIG_MTD_DOC2001 is not set
399 +# CONFIG_MTD_DOC2001PLUS is not set
400  
401  #
402  # NAND Flash Device Drivers
403 diff -Naur a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
404 --- a/arch/um/drivers/chan_kern.c       2004-02-11 12:16:50.000000000 -0500
405 +++ b/arch/um/drivers/chan_kern.c       2004-02-11 12:29:06.000000000 -0500
406 @@ -8,6 +8,7 @@
407  #include <linux/list.h>
408  #include <linux/slab.h>
409  #include <linux/tty.h>
410 +#include <linux/string.h>
411  #include <linux/tty_flip.h>
412  #include <asm/irq.h>
413  #include "chan_kern.h"
414 @@ -265,6 +266,11 @@
415  {
416         int n = 0;
417  
418 +       if(chan == NULL){
419 +               CONFIG_CHUNK(str, size, n, "none", 1);
420 +               return(n);
421 +       }
422 +
423         CONFIG_CHUNK(str, size, n, chan->ops->type, 0);
424  
425         if(chan->dev == NULL){
426 @@ -420,7 +426,8 @@
427                 INIT_LIST_HEAD(chans);
428         }
429  
430 -       if((out = strchr(str, ',')) != NULL){
431 +       out = strchr(str, ',');
432 +       if(out != NULL){
433                 in = str;
434                 *out = '\0';
435                 out++;
436 @@ -475,12 +482,15 @@
437                                 goto out;
438                         }
439                         err = chan->ops->read(chan->fd, &c, chan->data);
440 -                       if(err > 0) tty_receive_char(tty, c);
441 +                       if(err > 0) 
442 +                               tty_receive_char(tty, c);
443                 } while(err > 0);
444 +
445                 if(err == 0) reactivate_fd(chan->fd, irq);
446                 if(err == -EIO){
447                         if(chan->primary){
448 -                               if(tty != NULL) tty_hangup(tty);
449 +                               if(tty != NULL) 
450 +                                       tty_hangup(tty);
451                                 line_disable(dev, irq);
452                                 close_chan(chans);
453                                 free_chan(chans);
454 diff -Naur a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
455 --- a/arch/um/drivers/chan_user.c       2004-02-11 12:14:14.000000000 -0500
456 +++ b/arch/um/drivers/chan_user.c       2004-02-11 12:25:42.000000000 -0500
457 @@ -1,5 +1,5 @@
458  /* 
459 - * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
460 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
461   * Licensed under the GPL
462   */
463  
464 @@ -7,7 +7,6 @@
465  #include <stdlib.h>
466  #include <errno.h>
467  #include <termios.h>
468 -#include <fcntl.h>
469  #include <string.h>
470  #include <signal.h>
471  #include <sys/stat.h>
472 @@ -24,29 +23,27 @@
473  
474  void generic_close(int fd, void *unused)
475  {
476 -       close(fd);
477 +       os_close_file(fd);
478  }
479  
480  int generic_read(int fd, char *c_out, void *unused)
481  {
482         int n;
483  
484 -       n = read(fd, c_out, sizeof(*c_out));
485 -       if(n < 0){
486 -               if(errno == EAGAIN) return(0);
487 -               return(-errno);
488 -       }
489 -       else if(n == 0) return(-EIO);
490 -       return(1);
491 +       n = os_read_file(fd, c_out, sizeof(*c_out));
492 +
493 +       if(n == -EAGAIN) 
494 +               return(0);
495 +       else if(n == 0) 
496 +               return(-EIO);
497 +       return(n);
498  }
499  
500 +/* XXX Trivial wrapper around os_write_file */
501 +
502  int generic_write(int fd, const char *buf, int n, void *unused)
503  {
504 -       int count;
505 -
506 -       count = write(fd, buf, n);
507 -       if(count < 0) return(-errno);
508 -       return(count);
509 +       return(os_write_file(fd, buf, n));
510  }
511  
512  int generic_console_write(int fd, const char *buf, int n, void *unused)
513 @@ -68,15 +65,18 @@
514  int generic_window_size(int fd, void *unused, unsigned short *rows_out,
515                         unsigned short *cols_out)
516  {
517 -       struct winsize size;
518 -       int ret = 0;
519 +       int rows, cols;
520 +       int ret;
521 +
522 +       ret = os_window_size(fd, &rows, &cols);
523 +       if(ret < 0)
524 +               return(ret);
525 +
526 +       ret = ((*rows_out != rows) || (*cols_out != cols));
527 +
528 +       *rows_out = rows;
529 +       *cols_out = cols;
530  
531 -       if(ioctl(fd, TIOCGWINSZ, &size) == 0){
532 -               ret = ((*rows_out != size.ws_row) || 
533 -                      (*cols_out != size.ws_col));
534 -               *rows_out = size.ws_row;
535 -               *cols_out = size.ws_col;
536 -       }
537         return(ret);
538  }
539  
540 @@ -100,14 +100,16 @@
541         struct winch_data *data = arg;
542         sigset_t sigs;
543         int pty_fd, pipe_fd;
544 +       int count, err;
545         char c = 1;
546  
547 -       close(data->close_me);
548 +       os_close_file(data->close_me);
549         pty_fd = data->pty_fd;
550         pipe_fd = data->pipe_fd;
551 -       if(write(pipe_fd, &c, sizeof(c)) != sizeof(c))
552 +       count = os_write_file(pipe_fd, &c, sizeof(c));
553 +       if(count != sizeof(c))
554                 printk("winch_thread : failed to write synchronization "
555 -                      "byte, errno = %d\n", errno);
556 +                      "byte, err = %d\n", -count);
557  
558         signal(SIGWINCH, winch_handler);
559         sigfillset(&sigs);
560 @@ -123,26 +125,24 @@
561                 exit(1);
562         }
563  
564 -       if(ioctl(pty_fd, TIOCSCTTY, 0) < 0){
565 -               printk("winch_thread : TIOCSCTTY failed, errno = %d\n", errno);
566 -               exit(1);
567 -       }
568 -       if(tcsetpgrp(pty_fd, os_getpid()) < 0){
569 -               printk("winch_thread : tcsetpgrp failed, errno = %d\n", errno);
570 +       err = os_new_tty_pgrp(pty_fd, os_getpid());
571 +       if(err < 0){
572 +               printk("winch_thread : new_tty_pgrp failed, err = %d\n", -err);
573                 exit(1);
574         }
575  
576 -       if(read(pipe_fd, &c, sizeof(c)) != sizeof(c))
577 +       count = os_read_file(pipe_fd, &c, sizeof(c));
578 +       if(count != sizeof(c))
579                 printk("winch_thread : failed to read synchronization byte, "
580 -                      "errno = %d\n", errno);
581 +                      "err = %d\n", -count);
582  
583         while(1){
584                 pause();
585  
586 -               if(write(pipe_fd, &c, sizeof(c)) != sizeof(c)){
587 -                       printk("winch_thread : write failed, errno = %d\n",
588 -                              errno);
589 -               }
590 +               count = os_write_file(pipe_fd, &c, sizeof(c));
591 +               if(count != sizeof(c))
592 +                       printk("winch_thread : write failed, err = %d\n",
593 +                              -count);
594         }
595  }
596  
597 @@ -154,8 +154,8 @@
598         char c;
599  
600         err = os_pipe(fds, 1, 1);
601 -       if(err){
602 -               printk("winch_tramp : os_pipe failed, errno = %d\n", -err);
603 +       if(err < 0){
604 +               printk("winch_tramp : os_pipe failed, err = %d\n", -err);
605                 return(err);
606         }
607  
608 @@ -168,12 +168,12 @@
609                 return(pid);
610         }
611  
612 -       close(fds[1]);
613 +       os_close_file(fds[1]);
614         *fd_out = fds[0];
615 -       n = read(fds[0], &c, sizeof(c));
616 +       n = os_read_file(fds[0], &c, sizeof(c));
617         if(n != sizeof(c)){
618                 printk("winch_tramp : failed to read synchronization byte\n");
619 -               printk("read returned %d, errno = %d\n", n, errno);
620 +               printk("read failed, err = %d\n", -n);
621                 printk("fd %d will not support SIGWINCH\n", fd);
622                 *fd_out = -1;
623         }
624 @@ -183,20 +183,24 @@
625  void register_winch(int fd, void *device_data)
626  {
627         int pid, thread, thread_fd;
628 +       int count;
629         char c = 1;
630  
631 -       if(!isatty(fd)) return;
632 +       if(!isatty(fd)) 
633 +               return;
634  
635         pid = tcgetpgrp(fd);
636 -       if(!CHOOSE_MODE(is_tracer_winch(pid, fd, device_data), 0) && 
637 -          (pid == -1)){
638 +       if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd, 
639 +                            device_data) && (pid == -1)){
640                 thread = winch_tramp(fd, device_data, &thread_fd);
641                 if(fd != -1){
642                         register_winch_irq(thread_fd, fd, thread, device_data);
643  
644 -                       if(write(thread_fd, &c, sizeof(c)) != sizeof(c))
645 +                       count = os_write_file(thread_fd, &c, sizeof(c));
646 +                       if(count != sizeof(c))
647                                 printk("register_winch : failed to write "
648 -                                      "synchronization byte\n");
649 +                                      "synchronization byte, err = %d\n",
650 +                                       -count);
651                 }
652         }
653  }
654 diff -Naur a/arch/um/drivers/cow.h b/arch/um/drivers/cow.h
655 --- a/arch/um/drivers/cow.h     1969-12-31 19:00:00.000000000 -0500
656 +++ b/arch/um/drivers/cow.h     2004-02-11 12:26:08.000000000 -0500
657 @@ -0,0 +1,41 @@
658 +#ifndef __COW_H__
659 +#define __COW_H__
660 +
661 +#include <asm/types.h>
662 +
663 +#if __BYTE_ORDER == __BIG_ENDIAN
664 +# define ntohll(x) (x)
665 +# define htonll(x) (x)
666 +#elif __BYTE_ORDER == __LITTLE_ENDIAN
667 +# define ntohll(x)  bswap_64(x)
668 +# define htonll(x)  bswap_64(x)
669 +#else
670 +#error "__BYTE_ORDER not defined"
671 +#endif
672 +
673 +extern int init_cow_file(int fd, char *cow_file, char *backing_file, 
674 +                        int sectorsize, int alignment, int *bitmap_offset_out, 
675 +                        unsigned long *bitmap_len_out, int *data_offset_out);
676 +
677 +extern int file_reader(__u64 offset, char *buf, int len, void *arg);
678 +extern int read_cow_header(int (*reader)(__u64, char *, int, void *), 
679 +                          void *arg, __u32 *version_out, 
680 +                          char **backing_file_out, time_t *mtime_out, 
681 +                          __u64 *size_out, int *sectorsize_out, 
682 +                          __u32 *align_out, int *bitmap_offset_out);
683 +
684 +extern int write_cow_header(char *cow_file, int fd, char *backing_file, 
685 +                           int sectorsize, int alignment, long long *size);
686 +
687 +extern void cow_sizes(int version, __u64 size, int sectorsize, int align,
688 +                     int bitmap_offset, unsigned long *bitmap_len_out, 
689 +                     int *data_offset_out);
690 +
691 +#endif
692 +
693 +/*
694 + * ---------------------------------------------------------------------------
695 + * Local variables:
696 + * c-file-style: "linux"
697 + * End:
698 + */
699 diff -Naur a/arch/um/drivers/cow_kern.c b/arch/um/drivers/cow_kern.c
700 --- a/arch/um/drivers/cow_kern.c        1969-12-31 19:00:00.000000000 -0500
701 +++ b/arch/um/drivers/cow_kern.c        2004-02-11 12:29:06.000000000 -0500
702 @@ -0,0 +1,630 @@
703 +#define COW_MAJOR 60
704 +#define MAJOR_NR COW_MAJOR
705 +
706 +#include <linux/stddef.h>
707 +#include <linux/kernel.h>
708 +#include <linux/ctype.h>
709 +#include <linux/stat.h>
710 +#include <linux/vmalloc.h>
711 +#include <linux/blkdev.h>
712 +#include <linux/blk.h>
713 +#include <linux/fs.h>
714 +#include <linux/genhd.h>
715 +#include <linux/devfs_fs.h>
716 +#include <asm/uaccess.h>
717 +#include "2_5compat.h"
718 +#include "cow.h"
719 +#include "ubd_user.h"
720 +
721 +#define COW_SHIFT 4
722 +
723 +struct cow {
724 +       int count;
725 +       char *cow_path;
726 +       dev_t cow_dev;
727 +       struct block_device *cow_bdev;
728 +       char *backing_path;
729 +       dev_t backing_dev;
730 +       struct block_device *backing_bdev;
731 +       int sectorsize;
732 +       unsigned long *bitmap;
733 +       unsigned long bitmap_len;
734 +       int bitmap_offset;
735 +       int data_offset;
736 +       devfs_handle_t devfs;
737 +       struct semaphore sem;
738 +       struct semaphore io_sem;
739 +       atomic_t working;
740 +       spinlock_t io_lock;
741 +       struct buffer_head *bh;
742 +       struct buffer_head *bhtail;
743 +       void *end_io;
744 +};
745 +
746 +#define DEFAULT_COW { \
747 +       .count                  = 0, \
748 +       .cow_path               = NULL, \
749 +       .cow_dev                = 0, \
750 +       .backing_path           = NULL, \
751 +       .backing_dev            = 0, \
752 +        .bitmap                        = NULL, \
753 +       .bitmap_len             = 0, \
754 +       .bitmap_offset          = 0, \
755 +        .data_offset           = 0, \
756 +       .devfs                  = NULL, \
757 +       .working                = ATOMIC_INIT(0), \
758 +       .io_lock                = SPIN_LOCK_UNLOCKED, \
759 +}
760 +
761 +#define MAX_DEV (8)
762 +#define MAX_MINOR (MAX_DEV << COW_SHIFT)
763 +
764 +struct cow cow_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_COW };
765 +
766 +/* Not modified by this driver */
767 +static int blk_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = BLOCK_SIZE };
768 +static int hardsect_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 512 };
769 +
770 +/* Protected by cow_lock */
771 +static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 };
772 +
773 +static struct hd_struct        cow_part[MAX_MINOR] =
774 +       { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } };
775 +
776 +/* Protected by io_request_lock */
777 +static request_queue_t *cow_queue;
778 +
779 +static int cow_open(struct inode *inode, struct file *filp);
780 +static int cow_release(struct inode * inode, struct file * file);
781 +static int cow_ioctl(struct inode * inode, struct file * file,
782 +                    unsigned int cmd, unsigned long arg);
783 +static int cow_revalidate(kdev_t rdev);
784 +
785 +static struct block_device_operations cow_blops = {
786 +       .open           = cow_open,
787 +       .release        = cow_release,
788 +       .ioctl          = cow_ioctl,
789 +       .revalidate     = cow_revalidate,
790 +};
791 +
792 +/* Initialized in an initcall, and unchanged thereafter */
793 +devfs_handle_t cow_dir_handle;
794 +
795 +#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \
796 +{ \
797 +       .major          = maj, \
798 +       .major_name     = name, \
799 +       .minor_shift    = shift, \
800 +       .max_p          = 1 << shift, \
801 +       .part           = parts, \
802 +       .sizes          = bsizes, \
803 +       .nr_real        = max, \
804 +       .real_devices   = NULL, \
805 +       .next           = NULL, \
806 +       .fops           = blops, \
807 +       .de_arr         = NULL, \
808 +       .flags          = 0 \
809 +}
810 +
811 +static spinlock_t cow_lock = SPIN_LOCK_UNLOCKED;
812 +
813 +static struct gendisk cow_gendisk = INIT_GENDISK(MAJOR_NR, "cow", cow_part,
814 +                                                COW_SHIFT, sizes, MAX_DEV, 
815 +                                                &cow_blops);
816 +
817 +static int cow_add(int n)
818 +{
819 +       struct cow *dev = &cow_dev[n];
820 +       char name[sizeof("nnnnnn\0")];
821 +       int err = -ENODEV;
822 +
823 +       if(dev->cow_path == NULL)
824 +               goto out;
825 +
826 +       sprintf(name, "%d", n);
827 +       dev->devfs = devfs_register(cow_dir_handle, name, DEVFS_FL_REMOVABLE,
828 +                                   MAJOR_NR, n << COW_SHIFT, S_IFBLK | 
829 +                                   S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
830 +                                   &cow_blops, NULL);
831 +
832 +       init_MUTEX_LOCKED(&dev->sem);
833 +       init_MUTEX(&dev->io_sem);
834 +
835 +       return(0);
836 +
837 + out:
838 +       return(err);
839 +}
840 +
841 +/*
842 + * Add buffer_head to back of pending list
843 + */
844 +static void cow_add_bh(struct cow *cow, struct buffer_head *bh)
845 +{
846 +       unsigned long flags;
847 +
848 +       spin_lock_irqsave(&cow->io_lock, flags);
849 +       if(cow->bhtail != NULL){
850 +               cow->bhtail->b_reqnext = bh;
851 +               cow->bhtail = bh;
852 +       }
853 +       else {
854 +               cow->bh = bh;
855 +               cow->bhtail = bh;
856 +       }
857 +       spin_unlock_irqrestore(&cow->io_lock, flags);
858 +}
859 +
860 +/*
861 +* Grab first pending buffer
862 +*/
863 +static struct buffer_head *cow_get_bh(struct cow *cow)
864 +{
865 +       struct buffer_head *bh;
866 +
867 +       spin_lock_irq(&cow->io_lock);
868 +       bh = cow->bh;
869 +       if(bh != NULL){
870 +               if(bh == cow->bhtail)
871 +                       cow->bhtail = NULL;
872 +               cow->bh = bh->b_reqnext;
873 +               bh->b_reqnext = NULL;
874 +       }
875 +       spin_unlock_irq(&cow->io_lock);
876 +
877 +       return(bh);
878 +}
879 +
880 +static void cow_handle_bh(struct cow *cow, struct buffer_head *bh, 
881 +                         struct buffer_head **cow_bh, int ncow_bh)
882 +{
883 +       int i;
884 +
885 +       if(ncow_bh > 0)
886 +               ll_rw_block(WRITE, ncow_bh, cow_bh);
887 +
888 +       for(i = 0; i < ncow_bh ; i++){
889 +               wait_on_buffer(cow_bh[i]);
890 +               brelse(cow_bh[i]);
891 +       }
892 +
893 +       ll_rw_block(WRITE, 1, &bh);
894 +       brelse(bh);
895 +}
896 +
897 +static struct buffer_head *cow_new_bh(struct cow *dev, int sector)
898 +{
899 +       struct buffer_head *bh;
900 +
901 +       sector = (dev->bitmap_offset + sector / 8) / dev->sectorsize;
902 +       bh = getblk(dev->cow_dev, sector, dev->sectorsize);
903 +       memcpy(bh->b_data, dev->bitmap + sector / (8 * sizeof(dev->bitmap[0])),
904 +              dev->sectorsize);
905 +       return(bh);
906 +}
907 +
908 +/* Copied from loop.c, needed to avoid deadlocking in make_request. */
909 +
910 +static int cow_thread(void *data)
911 +{
912 +       struct cow *dev = data;
913 +       struct buffer_head *bh;
914 +
915 +       daemonize();
916 +       exit_files(current);
917 +
918 +       sprintf(current->comm, "cow%d", dev - cow_dev);
919 +
920 +       spin_lock_irq(&current->sigmask_lock);
921 +       sigfillset(&current->blocked);
922 +       flush_signals(current);
923 +       spin_unlock_irq(&current->sigmask_lock);
924 +
925 +       atomic_inc(&dev->working);
926 +
927 +       current->policy = SCHED_OTHER;
928 +       current->nice = -20;
929 +
930 +       current->flags |= PF_NOIO;
931 +
932 +       /*
933 +        * up sem, we are running
934 +        */
935 +       up(&dev->sem);
936 +
937 +       for(;;){
938 +               int start, len, nbh, i, update_bitmap = 0;
939 +               struct buffer_head *cow_bh[2];
940 +
941 +               down_interruptible(&dev->io_sem);
942 +               /*
943 +                * could be upped because of tear-down, not because of
944 +                * pending work
945 +                */
946 +               if(!atomic_read(&dev->working))
947 +                       break;
948 +
949 +               bh = cow_get_bh(dev);
950 +               if(bh == NULL){
951 +                       printk(KERN_ERR "cow: missing bh\n");
952 +                       continue;
953 +               }
954 +
955 +               start = bh->b_blocknr * bh->b_size / dev->sectorsize;
956 +               len = bh->b_size / dev->sectorsize;
957 +               for(i = 0; i < len ; i++){
958 +                       if(ubd_test_bit(start + i, 
959 +                                       (unsigned char *) dev->bitmap))
960 +                               continue;
961 +
962 +                       update_bitmap = 1;
963 +                       ubd_set_bit(start + i, (unsigned char *) dev->bitmap);
964 +               }
965 +
966 +               cow_bh[0] = NULL;
967 +               cow_bh[1] = NULL;
968 +               nbh = 0;
969 +               if(update_bitmap){
970 +                       cow_bh[0] = cow_new_bh(dev, start);
971 +                       nbh++;
972 +                       if(start / dev->sectorsize != 
973 +                          (start + len) / dev->sectorsize){
974 +                               cow_bh[1] = cow_new_bh(dev, start + len);
975 +                               nbh++;
976 +                       }
977 +               }
978 +               
979 +               bh->b_dev = dev->cow_dev;
980 +               bh->b_blocknr += dev->data_offset / dev->sectorsize;
981 +
982 +               cow_handle_bh(dev, bh, cow_bh, nbh);
983 +
984 +               /*
985 +                * upped both for pending work and tear-down, lo_pending
986 +                * will hit zero then
987 +                */
988 +               if(atomic_dec_and_test(&dev->working))
989 +                       break;
990 +       }
991 +
992 +       up(&dev->sem);
993 +       return(0);
994 +}
995 +
996 +static int cow_make_request(request_queue_t *q, int rw, struct buffer_head *bh)
997 +{
998 +       struct cow *dev;
999 +       int n, minor;
1000 +
1001 +       minor = MINOR(bh->b_rdev);
1002 +       n = minor >> COW_SHIFT;
1003 +       dev = &cow_dev[n];
1004 +
1005 +       dev->end_io = NULL;
1006 +       if(ubd_test_bit(bh->b_rsector, (unsigned char *) dev->bitmap)){
1007 +               bh->b_rdev = dev->cow_dev;
1008 +               bh->b_rsector += dev->data_offset / dev->sectorsize;
1009 +       }
1010 +       else if(rw == WRITE){
1011 +               bh->b_dev = dev->cow_dev;
1012 +               bh->b_blocknr += dev->data_offset / dev->sectorsize;
1013 +
1014 +               cow_add_bh(dev, bh);
1015 +               up(&dev->io_sem);
1016 +               return(0);
1017 +       }
1018 +       else {
1019 +               bh->b_rdev = dev->backing_dev;
1020 +       }
1021 +
1022 +       return(1);
1023 +}
1024 +
1025 +int cow_init(void)
1026 +{
1027 +       int i;
1028 +
1029 +       cow_dir_handle = devfs_mk_dir (NULL, "cow", NULL);
1030 +       if (devfs_register_blkdev(MAJOR_NR, "cow", &cow_blops)) {
1031 +               printk(KERN_ERR "cow: unable to get major %d\n", MAJOR_NR);
1032 +               return -1;
1033 +       }
1034 +       read_ahead[MAJOR_NR] = 8;               /* 8 sector (4kB) read-ahead */
1035 +       blksize_size[MAJOR_NR] = blk_sizes;
1036 +       blk_size[MAJOR_NR] = sizes;
1037 +       INIT_HARDSECT(hardsect_size, MAJOR_NR, hardsect_sizes);
1038 +
1039 +       cow_queue = BLK_DEFAULT_QUEUE(MAJOR_NR);
1040 +       blk_init_queue(cow_queue, NULL);
1041 +       INIT_ELV(cow_queue, &cow_queue->elevator);
1042 +       blk_queue_make_request(cow_queue, cow_make_request);
1043 +
1044 +       add_gendisk(&cow_gendisk);
1045 +
1046 +       for(i=0;i<MAX_DEV;i++) 
1047 +               cow_add(i);
1048 +
1049 +       return(0);
1050 +}
1051 +
1052 +__initcall(cow_init);
1053 +
1054 +static int reader(__u64 start, char *buf, int count, void *arg)
1055 +{
1056 +       dev_t dev = *((dev_t *) arg);
1057 +       struct buffer_head *bh;
1058 +       __u64 block;
1059 +       int cur, offset, left, n, blocksize = get_hardsect_size(dev);
1060 +
1061 +       if(blocksize == 0)
1062 +               panic("Zero blocksize");
1063 +
1064 +       block = start / blocksize;
1065 +       offset = start % blocksize;
1066 +       left = count;
1067 +       cur = 0;
1068 +       while(left > 0){
1069 +               n = (left > blocksize) ? blocksize : left;
1070 +
1071 +               bh = bread(dev, block, (n < 512) ? 512 : n);
1072 +               if(bh == NULL)
1073 +                       return(-EIO);
1074 +
1075 +               n -= offset;
1076 +               memcpy(&buf[cur], bh->b_data + offset, n);
1077 +               block++;
1078 +               left -= n;
1079 +               cur += n;
1080 +               offset = 0;
1081 +               brelse(bh);
1082 +       }
1083 +
1084 +       return(count);
1085 +}
1086 +
1087 +static int cow_open(struct inode *inode, struct file *filp)
1088 +{
1089 +       int (*dev_ioctl)(struct inode *, struct file *, unsigned int, 
1090 +                        unsigned long);
1091 +       mm_segment_t fs;
1092 +       struct cow *dev;
1093 +       __u64 size;
1094 +       __u32 version, align;
1095 +       time_t mtime;
1096 +       char *backing_file;
1097 +       int n, offset, err = 0;
1098 +
1099 +       n = DEVICE_NR(inode->i_rdev);
1100 +       if(n >= MAX_DEV)
1101 +               return(-ENODEV);
1102 +       dev = &cow_dev[n];
1103 +       offset = n << COW_SHIFT;
1104 +
1105 +       spin_lock(&cow_lock);
1106 +
1107 +       if(dev->count == 0){
1108 +               dev->cow_dev = name_to_kdev_t(dev->cow_path);
1109 +               if(dev->cow_dev == 0){
1110 +                       printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") "
1111 +                              "failed\n", dev->cow_path);
1112 +                       err = -ENODEV;
1113 +               }
1114 +
1115 +               dev->backing_dev = name_to_kdev_t(dev->backing_path);
1116 +               if(dev->backing_dev == 0){
1117 +                       printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") "
1118 +                              "failed\n", dev->backing_path);
1119 +                       err = -ENODEV;
1120 +               }
1121 +
1122 +               if(err) 
1123 +                       goto out;
1124 +
1125 +               dev->cow_bdev = bdget(dev->cow_dev);
1126 +               if(dev->cow_bdev == NULL){
1127 +                       printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", 
1128 +                              dev->cow_path);
1129 +                       err = -ENOMEM;
1130 +               }
1131 +               dev->backing_bdev = bdget(dev->backing_dev);
1132 +               if(dev->backing_bdev == NULL){
1133 +                       printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", 
1134 +                              dev->backing_path);
1135 +                       err = -ENOMEM;
1136 +               }
1137 +
1138 +               if(err) 
1139 +                       goto out;
1140 +
1141 +               err = blkdev_get(dev->cow_bdev, FMODE_READ|FMODE_WRITE, 0, 
1142 +                                BDEV_RAW);
1143 +               if(err){
1144 +                       printk("cow_open - blkdev_get of COW device failed, "
1145 +                              "error = %d\n", err);
1146 +                       goto out;
1147 +               }
1148 +               
1149 +               err = blkdev_get(dev->backing_bdev, FMODE_READ, 0, BDEV_RAW);
1150 +               if(err){
1151 +                       printk("cow_open - blkdev_get of backing device "
1152 +                              "failed, error = %d\n", err);
1153 +                       goto out;
1154 +               }
1155 +               
1156 +               err = read_cow_header(reader, &dev->cow_dev, &version, 
1157 +                                     &backing_file, &mtime, &size,
1158 +                                     &dev->sectorsize, &align, 
1159 +                                     &dev->bitmap_offset);
1160 +               if(err){
1161 +                       printk(KERN_ERR "cow_open - read_cow_header failed, "
1162 +                              "err = %d\n", err);
1163 +                       goto out;
1164 +               }
1165 +
1166 +               cow_sizes(version, size, dev->sectorsize, align, 
1167 +                         dev->bitmap_offset, &dev->bitmap_len, 
1168 +                         &dev->data_offset);
1169 +               dev->bitmap = (void *) vmalloc(dev->bitmap_len);
1170 +               if(dev->bitmap == NULL){
1171 +                       err = -ENOMEM;
1172 +                       printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
1173 +                       goto out;
1174 +               }
1175 +               flush_tlb_kernel_vm();
1176 +               
1177 +               err = reader(dev->bitmap_offset, (char *) dev->bitmap, 
1178 +                            dev->bitmap_len, &dev->cow_dev);
1179 +               if(err < 0){
1180 +                       printk(KERN_ERR "Failed to read COW bitmap\n");
1181 +                       vfree(dev->bitmap);
1182 +                       goto out;
1183 +               }
1184 +
1185 +               dev_ioctl = dev->backing_bdev->bd_op->ioctl;
1186 +               fs = get_fs();
1187 +               set_fs(KERNEL_DS);
1188 +               err = (*dev_ioctl)(inode, filp, BLKGETSIZE, 
1189 +                                  (unsigned long) &sizes[offset]);
1190 +               set_fs(fs);
1191 +               if(err){
1192 +                       printk(KERN_ERR "cow_open - BLKGETSIZE failed, "
1193 +                              "error = %d\n", err);
1194 +                       goto out;
1195 +               }
1196 +
1197 +               kernel_thread(cow_thread, dev, 
1198 +                             CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
1199 +               down(&dev->sem);
1200 +       }
1201 +       dev->count++;
1202 + out:
1203 +       spin_unlock(&cow_lock);
1204 +       return(err);
1205 +}
1206 +
1207 +static int cow_release(struct inode * inode, struct file * file)
1208 +{
1209 +       struct cow *dev;
1210 +       int n, err;
1211 +
1212 +       n = DEVICE_NR(inode->i_rdev);
1213 +       if(n >= MAX_DEV)
1214 +               return(-ENODEV);
1215 +       dev = &cow_dev[n];
1216 +
1217 +       spin_lock(&cow_lock);
1218 +
1219 +       if(--dev->count > 0)
1220 +               goto out;
1221 +
1222 +       err = blkdev_put(dev->cow_bdev, BDEV_RAW);
1223 +       if(err)
1224 +               printk("cow_release - blkdev_put of cow device failed, "
1225 +                      "error = %d\n", err);
1226 +       bdput(dev->cow_bdev);
1227 +       dev->cow_bdev = 0;
1228 +
1229 +       err = blkdev_put(dev->backing_bdev, BDEV_RAW);
1230 +       if(err)
1231 +               printk("cow_release - blkdev_put of backing device failed, "
1232 +                      "error = %d\n", err);
1233 +       bdput(dev->backing_bdev);
1234 +       dev->backing_bdev = 0;
1235 +
1236 + out:
1237 +       spin_unlock(&cow_lock);
1238 +       return(0);
1239 +}
1240 +
1241 +static int cow_ioctl(struct inode * inode, struct file * file,
1242 +                    unsigned int cmd, unsigned long arg)
1243 +{
1244 +       struct cow *dev;
1245 +       int (*dev_ioctl)(struct inode *, struct file *, unsigned int, 
1246 +                        unsigned long);
1247 +       int n;
1248 +
1249 +       n = DEVICE_NR(inode->i_rdev);
1250 +       if(n >= MAX_DEV)
1251 +               return(-ENODEV);
1252 +       dev = &cow_dev[n];
1253 +
1254 +       dev_ioctl = dev->backing_bdev->bd_op->ioctl;
1255 +       return((*dev_ioctl)(inode, file, cmd, arg));
1256 +}
1257 +
1258 +static int cow_revalidate(kdev_t rdev)
1259 +{
1260 +       printk(KERN_ERR "Need to implement cow_revalidate\n");
1261 +       return(0);
1262 +}
1263 +
1264 +static int parse_unit(char **ptr)
1265 +{
1266 +       char *str = *ptr, *end;
1267 +       int n = -1;
1268 +
1269 +       if(isdigit(*str)) {
1270 +               n = simple_strtoul(str, &end, 0);
1271 +               if(end == str)
1272 +                       return(-1);
1273 +               *ptr = end;
1274 +       }
1275 +       else if (('a' <= *str) && (*str <= 'h')) {
1276 +               n = *str - 'a';
1277 +               str++;
1278 +               *ptr = str;
1279 +       }
1280 +       return(n);
1281 +}
1282 +
1283 +static int cow_setup(char *str)
1284 +{
1285 +       struct cow *dev;
1286 +       char *cow_name, *backing_name;
1287 +       int unit;
1288 +
1289 +       unit = parse_unit(&str);
1290 +       if(unit < 0){
1291 +               printk(KERN_ERR "cow_setup - Couldn't parse unit number\n");
1292 +               return(1);
1293 +       }
1294 +
1295 +       if(*str != '='){
1296 +               printk(KERN_ERR "cow_setup - Missing '=' after unit "
1297 +                      "number\n");
1298 +               return(1);
1299 +       }
1300 +       str++;
1301 +
1302 +       cow_name = str;
1303 +       backing_name = strchr(str, ',');
1304 +       if(backing_name == NULL){
1305 +               printk(KERN_ERR "cow_setup - missing backing device name\n");
1306 +               return(0);
1307 +       }
1308 +       *backing_name = '\0';
1309 +       backing_name++;
1310 +
1311 +       spin_lock(&cow_lock);
1312 +
1313 +       dev = &cow_dev[unit];
1314 +       dev->cow_path = cow_name;
1315 +       dev->backing_path = backing_name;
1316 +       
1317 +       spin_unlock(&cow_lock);
1318 +       return(0);
1319 +}
1320 +
1321 +__setup("cow", cow_setup);
1322 +
1323 +/*
1324 + * Overrides for Emacs so that we follow Linus's tabbing style.
1325 + * Emacs will notice this stuff at the end of the file and automatically
1326 + * adjust the settings for this buffer only.  This must remain at the end
1327 + * of the file.
1328 + * ---------------------------------------------------------------------------
1329 + * Local variables:
1330 + * c-file-style: "linux"
1331 + * End:
1332 + */
1333 diff -Naur a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h
1334 --- a/arch/um/drivers/cow_sys.h 1969-12-31 19:00:00.000000000 -0500
1335 +++ b/arch/um/drivers/cow_sys.h 2004-02-11 12:27:42.000000000 -0500
1336 @@ -0,0 +1,48 @@
1337 +#ifndef __COW_SYS_H__
1338 +#define __COW_SYS_H__
1339 +
1340 +#include "kern_util.h"
1341 +#include "user_util.h"
1342 +#include "os.h"
1343 +#include "user.h"
1344 +
1345 +static inline void *cow_malloc(int size)
1346 +{
1347 +       return(um_kmalloc(size));
1348 +}
1349 +
1350 +static inline void cow_free(void *ptr)
1351 +{
1352 +       kfree(ptr);
1353 +}
1354 +
1355 +#define cow_printf printk
1356 +
1357 +static inline char *cow_strdup(char *str)
1358 +{
1359 +       return(uml_strdup(str));
1360 +}
1361 +
1362 +static inline int cow_seek_file(int fd, __u64 offset)
1363 +{
1364 +       return(os_seek_file(fd, offset));
1365 +}
1366 +
1367 +static inline int cow_file_size(char *file, __u64 *size_out)
1368 +{
1369 +       return(os_file_size(file, size_out));
1370 +}
1371 +
1372 +static inline int cow_write_file(int fd, char *buf, int size)
1373 +{
1374 +       return(os_write_file(fd, buf, size));
1375 +}
1376 +
1377 +#endif
1378 +
1379 +/*
1380 + * ---------------------------------------------------------------------------
1381 + * Local variables:
1382 + * c-file-style: "linux"
1383 + * End:
1384 + */
1385 diff -Naur a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c
1386 --- a/arch/um/drivers/cow_user.c        1969-12-31 19:00:00.000000000 -0500
1387 +++ b/arch/um/drivers/cow_user.c        2004-02-11 12:27:36.000000000 -0500
1388 @@ -0,0 +1,375 @@
1389 +#include <stddef.h>
1390 +#include <string.h>
1391 +#include <errno.h>
1392 +#include <unistd.h>
1393 +#include <byteswap.h>
1394 +#include <sys/time.h>
1395 +#include <sys/param.h>
1396 +#include <sys/user.h>
1397 +#include <netinet/in.h>
1398 +
1399 +#include "os.h"
1400 +
1401 +#include "cow.h"
1402 +#include "cow_sys.h"
1403 +
1404 +#define PATH_LEN_V1 256
1405 +
1406 +struct cow_header_v1 {
1407 +       int magic;
1408 +       int version;
1409 +       char backing_file[PATH_LEN_V1];
1410 +       time_t mtime;
1411 +       __u64 size;
1412 +       int sectorsize;
1413 +};
1414 +
1415 +#define PATH_LEN_V2 MAXPATHLEN
1416 +
1417 +struct cow_header_v2 {
1418 +       unsigned long magic;
1419 +       unsigned long version;
1420 +       char backing_file[PATH_LEN_V2];
1421 +       time_t mtime;
1422 +       __u64 size;
1423 +       int sectorsize;
1424 +};
1425 +
1426 +/* Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in 
1427 + * case other systems have different values for MAXPATHLEN
1428 + */
1429 +#define PATH_LEN_V3 4096
1430 +
1431 +/* Changes from V2 - 
1432 + *     PATH_LEN_V3 as described above
1433 + *     Explicitly specify field bit lengths for systems with different
1434 + *             lengths for the usual C types.  Not sure whether char or
1435 + *             time_t should be changed, this can be changed later without
1436 + *             breaking compatibility
1437 + *     Add alignment field so that different alignments can be used for the
1438 + *             bitmap and data
1439 + *     Add cow_format field to allow for the possibility of different ways
1440 + *             of specifying the COW blocks.  For now, the only value is 0,
1441 + *             for the traditional COW bitmap.
1442 + *     Move the backing_file field to the end of the header.  This allows
1443 + *             for the possibility of expanding it into the padding required
1444 + *             by the bitmap alignment.
1445 + *     The bitmap and data portions of the file will be aligned as specified
1446 + *             by the alignment field.  This is to allow COW files to be
1447 + *             put on devices with restrictions on access alignments, such as
1448 + *             /dev/raw, with a 512 byte alignment restriction.  This also
1449 + *             allows the data to be more aligned more strictly than on
1450 + *             sector boundaries.  This is needed for ubd-mmap, which needs
1451 + *             the data to be page aligned.
1452 + *     Fixed (finally!) the rounding bug
1453 + */
1454 +
1455 +struct cow_header_v3 {
1456 +       __u32 magic;
1457 +       __u32 version;
1458 +       time_t mtime;
1459 +       __u64 size;
1460 +       __u32 sectorsize;
1461 +       __u32 alignment;
1462 +       __u32 cow_format;
1463 +       char backing_file[PATH_LEN_V3];
1464 +};
1465 +
1466 +/* COW format definitions - for now, we have only the usual COW bitmap */
1467 +#define COW_BITMAP 0
1468 +
1469 +union cow_header {
1470 +       struct cow_header_v1 v1;
1471 +       struct cow_header_v2 v2;
1472 +       struct cow_header_v3 v3;
1473 +};
1474 +
1475 +#define COW_MAGIC 0x4f4f4f4d  /* MOOO */
1476 +#define COW_VERSION 3
1477 +
1478 +#define DIV_ROUND(x, len) (((x) + (len) - 1) / (len))
1479 +#define ROUND_UP(x, align) DIV_ROUND(x, align) * (align)
1480 +
1481 +void cow_sizes(int version, __u64 size, int sectorsize, int align, 
1482 +              int bitmap_offset, unsigned long *bitmap_len_out, 
1483 +              int *data_offset_out)
1484 +{
1485 +       if(version < 3){
1486 +               *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
1487 +
1488 +               *data_offset_out = bitmap_offset + *bitmap_len_out;
1489 +               *data_offset_out = (*data_offset_out + sectorsize - 1) / 
1490 +                       sectorsize;
1491 +               *data_offset_out *= sectorsize;
1492 +       }
1493 +       else {
1494 +               *bitmap_len_out = DIV_ROUND(size, sectorsize);
1495 +               *bitmap_len_out = DIV_ROUND(*bitmap_len_out, 8);
1496 +
1497 +               *data_offset_out = bitmap_offset + *bitmap_len_out;
1498 +               *data_offset_out = ROUND_UP(*data_offset_out, align);
1499 +       }
1500 +}
1501 +
1502 +static int absolutize(char *to, int size, char *from)
1503 +{
1504 +       char save_cwd[256], *slash;
1505 +       int remaining;
1506 +
1507 +       if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
1508 +               cow_printf("absolutize : unable to get cwd - errno = %d\n", 
1509 +                          errno);
1510 +               return(-1);
1511 +       }
1512 +       slash = strrchr(from, '/');
1513 +       if(slash != NULL){
1514 +               *slash = '\0';
1515 +               if(chdir(from)){
1516 +                       *slash = '/';
1517 +                       cow_printf("absolutize : Can't cd to '%s' - " 
1518 +                                  "errno = %d\n", from, errno);
1519 +                       return(-1);
1520 +               }
1521 +               *slash = '/';
1522 +               if(getcwd(to, size) == NULL){
1523 +                       cow_printf("absolutize : unable to get cwd of '%s' - "
1524 +                              "errno = %d\n", from, errno);
1525 +                       return(-1);
1526 +               }
1527 +               remaining = size - strlen(to);
1528 +               if(strlen(slash) + 1 > remaining){
1529 +                       cow_printf("absolutize : unable to fit '%s' into %d "
1530 +                              "chars\n", from, size);
1531 +                       return(-1);
1532 +               }
1533 +               strcat(to, slash);
1534 +       }
1535 +       else {
1536 +               if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
1537 +                       cow_printf("absolutize : unable to fit '%s' into %d "
1538 +                              "chars\n", from, size);
1539 +                       return(-1);
1540 +               }
1541 +               strcpy(to, save_cwd);
1542 +               strcat(to, "/");
1543 +               strcat(to, from);
1544 +       }
1545 +       chdir(save_cwd);
1546 +       return(0);
1547 +}
1548 +
1549 +int write_cow_header(char *cow_file, int fd, char *backing_file, 
1550 +                    int sectorsize, int alignment, long long *size)
1551 +{
1552 +       struct cow_header_v3 *header;
1553 +       unsigned long modtime;
1554 +       int err;
1555 +
1556 +       err = cow_seek_file(fd, 0);
1557 +       if(err < 0){
1558 +               cow_printf("write_cow_header - lseek failed, err = %d\n", -err);
1559 +               goto out;
1560 +       }
1561 +
1562 +       err = -ENOMEM;
1563 +       header = cow_malloc(sizeof(*header));
1564 +       if(header == NULL){
1565 +               cow_printf("Failed to allocate COW V3 header\n");
1566 +               goto out;
1567 +       }
1568 +       header->magic = htonl(COW_MAGIC);
1569 +       header->version = htonl(COW_VERSION);
1570 +
1571 +       err = -EINVAL;
1572 +       if(strlen(backing_file) > sizeof(header->backing_file) - 1){
1573 +               cow_printf("Backing file name \"%s\" is too long - names are "
1574 +                          "limited to %d characters\n", backing_file, 
1575 +                          sizeof(header->backing_file) - 1);
1576 +               goto out_free;
1577 +       }
1578 +
1579 +       if(absolutize(header->backing_file, sizeof(header->backing_file), 
1580 +                     backing_file))
1581 +               goto out_free;
1582 +
1583 +       err = os_file_modtime(header->backing_file, &modtime);
1584 +       if(err < 0){
1585 +               cow_printf("Backing file '%s' mtime request failed, "
1586 +                          "err = %d\n", header->backing_file, -err);
1587 +               goto out_free;
1588 +       }
1589 +
1590 +       err = cow_file_size(header->backing_file, size);
1591 +       if(err < 0){
1592 +               cow_printf("Couldn't get size of backing file '%s', "
1593 +                          "err = %d\n", header->backing_file, -err);
1594 +               goto out_free;
1595 +       }
1596 +
1597 +       header->mtime = htonl(modtime);
1598 +       header->size = htonll(*size);
1599 +       header->sectorsize = htonl(sectorsize);
1600 +       header->alignment = htonl(alignment);
1601 +       header->cow_format = COW_BITMAP;
1602 +
1603 +       err = os_write_file(fd, header, sizeof(*header));
1604 +       if(err != sizeof(*header)){
1605 +               cow_printf("Write of header to new COW file '%s' failed, "
1606 +                          "err = %d\n", cow_file, -err);
1607 +               goto out_free;
1608 +       }
1609 +       err = 0;
1610 + out_free:
1611 +       cow_free(header);
1612 + out:
1613 +       return(err);
1614 +}
1615 +
1616 +int file_reader(__u64 offset, char *buf, int len, void *arg)
1617 +{
1618 +       int fd = *((int *) arg);
1619 +
1620 +       return(pread(fd, buf, len, offset));
1621 +}
1622 +
1623 +/* XXX Need to sanity-check the values read from the header */
1624 +
1625 +int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, 
1626 +                   __u32 *version_out, char **backing_file_out, 
1627 +                   time_t *mtime_out, __u64 *size_out, 
1628 +                   int *sectorsize_out, __u32 *align_out, 
1629 +                   int *bitmap_offset_out)
1630 +{
1631 +       union cow_header *header;
1632 +       char *file;
1633 +       int err, n;
1634 +       unsigned long version, magic;
1635 +
1636 +       header = cow_malloc(sizeof(*header));
1637 +       if(header == NULL){
1638 +               cow_printf("read_cow_header - Failed to allocate header\n");
1639 +               return(-ENOMEM);
1640 +       }
1641 +       err = -EINVAL;
1642 +       n = (*reader)(0, (char *) header, sizeof(*header), arg);
1643 +       if(n < offsetof(typeof(header->v1), backing_file)){
1644 +               cow_printf("read_cow_header - short header\n");
1645 +               goto out;
1646 +       }
1647 +
1648 +       magic = header->v1.magic;
1649 +       if(magic == COW_MAGIC) {
1650 +               version = header->v1.version;
1651 +       }
1652 +       else if(magic == ntohl(COW_MAGIC)){
1653 +               version = ntohl(header->v1.version);
1654 +       }
1655 +       /* No error printed because the non-COW case comes through here */
1656 +       else goto out;
1657 +
1658 +       *version_out = version;
1659 +
1660 +       if(version == 1){
1661 +               if(n < sizeof(header->v1)){
1662 +                       cow_printf("read_cow_header - failed to read V1 "
1663 +                                  "header\n");
1664 +                       goto out;
1665 +               }
1666 +               *mtime_out = header->v1.mtime;
1667 +               *size_out = header->v1.size;
1668 +               *sectorsize_out = header->v1.sectorsize;
1669 +               *bitmap_offset_out = sizeof(header->v1);
1670 +               *align_out = *sectorsize_out;
1671 +               file = header->v1.backing_file;
1672 +       }
1673 +       else if(version == 2){
1674 +               if(n < sizeof(header->v2)){
1675 +                       cow_printf("read_cow_header - failed to read V2 "
1676 +                                  "header\n");
1677 +                       goto out;
1678 +               }
1679 +               *mtime_out = ntohl(header->v2.mtime);
1680 +               *size_out = ntohll(header->v2.size);
1681 +               *sectorsize_out = ntohl(header->v2.sectorsize);
1682 +               *bitmap_offset_out = sizeof(header->v2);
1683 +               *align_out = *sectorsize_out;
1684 +               file = header->v2.backing_file;
1685 +       }
1686 +       else if(version == 3){
1687 +               if(n < sizeof(header->v3)){
1688 +                       cow_printf("read_cow_header - failed to read V2 "
1689 +                                  "header\n");
1690 +                       goto out;
1691 +               }
1692 +               *mtime_out = ntohl(header->v3.mtime);
1693 +               *size_out = ntohll(header->v3.size);
1694 +               *sectorsize_out = ntohl(header->v3.sectorsize);
1695 +               *align_out = ntohl(header->v3.alignment);
1696 +               *bitmap_offset_out = ROUND_UP(sizeof(header->v3), *align_out);
1697 +               file = header->v3.backing_file;
1698 +       }
1699 +       else {
1700 +               cow_printf("read_cow_header - invalid COW version\n");
1701 +               goto out;               
1702 +       }
1703 +       err = -ENOMEM;
1704 +       *backing_file_out = cow_strdup(file);
1705 +       if(*backing_file_out == NULL){
1706 +               cow_printf("read_cow_header - failed to allocate backing "
1707 +                          "file\n");
1708 +               goto out;
1709 +       }
1710 +       err = 0;
1711 + out:
1712 +       cow_free(header);
1713 +       return(err);
1714 +}
1715 +
1716 +int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
1717 +                 int alignment, int *bitmap_offset_out, 
1718 +                 unsigned long *bitmap_len_out, int *data_offset_out)
1719 +{
1720 +       __u64 size, offset;
1721 +       char zero = 0;
1722 +       int err;
1723 +
1724 +       err = write_cow_header(cow_file, fd, backing_file, sectorsize, 
1725 +                              alignment, &size);
1726 +       if(err) 
1727 +               goto out;
1728 +       
1729 +       *bitmap_offset_out = ROUND_UP(sizeof(struct cow_header_v3), alignment);
1730 +       cow_sizes(COW_VERSION, size, sectorsize, alignment, *bitmap_offset_out,
1731 +                 bitmap_len_out, data_offset_out);
1732 +
1733 +       offset = *data_offset_out + size - sizeof(zero);
1734 +       err = cow_seek_file(fd, offset);
1735 +       if(err < 0){
1736 +               cow_printf("cow bitmap lseek failed : err = %d\n", -err);
1737 +               goto out;
1738 +       }
1739 +
1740 +       /* does not really matter how much we write it is just to set EOF 
1741 +        * this also sets the entire COW bitmap
1742 +        * to zero without having to allocate it 
1743 +        */
1744 +       err = cow_write_file(fd, &zero, sizeof(zero));
1745 +       if(err != sizeof(zero)){
1746 +               cow_printf("Write of bitmap to new COW file '%s' failed, "
1747 +                          "err = %d\n", cow_file, -err);
1748 +               err = -EINVAL;
1749 +               goto out;
1750 +       }
1751 +
1752 +       return(0);
1753 +
1754 + out:
1755 +       return(err);
1756 +}
1757 +
1758 +/*
1759 + * ---------------------------------------------------------------------------
1760 + * Local variables:
1761 + * c-file-style: "linux"
1762 + * End:
1763 + */
1764 diff -Naur a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
1765 --- a/arch/um/drivers/daemon_user.c     2004-02-11 12:15:11.000000000 -0500
1766 +++ b/arch/um/drivers/daemon_user.c     2004-02-11 12:26:57.000000000 -0500
1767 @@ -53,7 +53,8 @@
1768         struct request_v3 req;
1769         int fd, n, err;
1770  
1771 -       if((pri->control = socket(AF_UNIX, SOCK_STREAM, 0)) < 0){
1772 +       pri->control = socket(AF_UNIX, SOCK_STREAM, 0);
1773 +       if(pri->control < 0){
1774                 printk("daemon_open : control socket failed, errno = %d\n", 
1775                        errno);          
1776                 return(-errno);
1777 @@ -67,7 +68,8 @@
1778                 goto out;
1779         }
1780  
1781 -       if((fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0){
1782 +       fd = socket(AF_UNIX, SOCK_DGRAM, 0);
1783 +       if(fd < 0){
1784                 printk("daemon_open : data socket failed, errno = %d\n", 
1785                        errno);
1786                 err = -errno;
1787 @@ -91,18 +93,18 @@
1788         req.version = SWITCH_VERSION;
1789         req.type = REQ_NEW_CONTROL;
1790         req.sock = *local_addr;
1791 -       n = write(pri->control, &req, sizeof(req));
1792 +       n = os_write_file(pri->control, &req, sizeof(req));
1793         if(n != sizeof(req)){
1794 -               printk("daemon_open : control setup request returned %d, "
1795 -                      "errno = %d\n", n, errno);
1796 +               printk("daemon_open : control setup request failed, err = %d\n",
1797 +                      -n);
1798                 err = -ENOTCONN;
1799                 goto out;               
1800         }
1801  
1802 -       n = read(pri->control, sun, sizeof(*sun));
1803 +       n = os_read_file(pri->control, sun, sizeof(*sun));
1804         if(n != sizeof(*sun)){
1805 -               printk("daemon_open : read of data socket returned %d, "
1806 -                      "errno = %d\n", n, errno);
1807 +               printk("daemon_open : read of data socket failed, err = %d\n", 
1808 +                      -n);
1809                 err = -ENOTCONN;
1810                 goto out_close;         
1811         }
1812 @@ -111,9 +113,9 @@
1813         return(fd);
1814  
1815   out_close:
1816 -       close(fd);
1817 +       os_close_file(fd);
1818   out:
1819 -       close(pri->control);
1820 +       os_close_file(pri->control);
1821         return(err);
1822  }
1823  
1824 @@ -153,8 +155,8 @@
1825  {
1826         struct daemon_data *pri = data;
1827  
1828 -       close(pri->fd);
1829 -       close(pri->control);
1830 +       os_close_file(pri->fd);
1831 +       os_close_file(pri->control);
1832         if(pri->data_addr != NULL) kfree(pri->data_addr);
1833         if(pri->ctl_addr != NULL) kfree(pri->ctl_addr);
1834         if(pri->local_addr != NULL) kfree(pri->local_addr);
1835 diff -Naur a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c
1836 --- a/arch/um/drivers/fd.c      2004-02-11 12:16:47.000000000 -0500
1837 +++ b/arch/um/drivers/fd.c      2004-02-11 12:29:01.000000000 -0500
1838 @@ -35,7 +35,8 @@
1839                 printk("fd_init : couldn't parse file descriptor '%s'\n", str);
1840                 return(NULL);
1841         }
1842 -       if((data = um_kmalloc(sizeof(*data))) == NULL) return(NULL);
1843 +       data = um_kmalloc(sizeof(*data));
1844 +       if(data == NULL) return(NULL);
1845         *data = ((struct fd_chan) { .fd         = n,
1846                                     .raw        = opts->raw });
1847         return(data);
1848 diff -Naur a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c
1849 --- a/arch/um/drivers/harddog_user.c    2004-02-11 12:14:38.000000000 -0500
1850 +++ b/arch/um/drivers/harddog_user.c    2004-02-11 12:26:41.000000000 -0500
1851 @@ -27,10 +27,10 @@
1852         dup2(data->stdin, 0);
1853         dup2(data->stdout, 1);
1854         dup2(data->stdout, 2);
1855 -       close(data->stdin);
1856 -       close(data->stdout);
1857 -       close(data->close_me[0]);
1858 -       close(data->close_me[1]);
1859 +       os_close_file(data->stdin);
1860 +       os_close_file(data->stdout);
1861 +       os_close_file(data->close_me[0]);
1862 +       os_close_file(data->close_me[1]);
1863  }
1864  
1865  int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock)
1866 @@ -44,15 +44,15 @@
1867         char **args = NULL;
1868  
1869         err = os_pipe(in_fds, 1, 0);
1870 -       if(err){
1871 -               printk("harddog_open - os_pipe failed, errno = %d\n", -err);
1872 -               return(err);
1873 +       if(err < 0){
1874 +               printk("harddog_open - os_pipe failed, err = %d\n", -err);
1875 +               goto out;
1876         }
1877  
1878         err = os_pipe(out_fds, 1, 0);
1879 -       if(err){
1880 -               printk("harddog_open - os_pipe failed, errno = %d\n", -err);
1881 -               return(err);
1882 +       if(err < 0){
1883 +               printk("harddog_open - os_pipe failed, err = %d\n", -err);
1884 +               goto out_close_in;
1885         }
1886  
1887         data.stdin = out_fds[0];
1888 @@ -72,42 +72,47 @@
1889  
1890         pid = run_helper(pre_exec, &data, args, NULL);
1891  
1892 -       close(out_fds[0]);
1893 -       close(in_fds[1]);
1894 +       os_close_file(out_fds[0]);
1895 +       os_close_file(in_fds[1]);
1896  
1897         if(pid < 0){
1898                 err = -pid;
1899 -               printk("harddog_open - run_helper failed, errno = %d\n", err);
1900 -               goto out;
1901 +               printk("harddog_open - run_helper failed, errno = %d\n", -err);
1902 +               goto out_close_out;
1903         }
1904  
1905 -       n = read(in_fds[0], &c, sizeof(c));
1906 +       n = os_read_file(in_fds[0], &c, sizeof(c));
1907         if(n == 0){
1908                 printk("harddog_open - EOF on watchdog pipe\n");
1909                 helper_wait(pid);
1910                 err = -EIO;
1911 -               goto out;
1912 +               goto out_close_out;
1913         }
1914         else if(n < 0){
1915                 printk("harddog_open - read of watchdog pipe failed, "
1916 -                      "errno = %d\n", errno);
1917 +                      "err = %d\n", -n);
1918                 helper_wait(pid);
1919 -               err = -errno;
1920 -               goto out;
1921 +               err = n;
1922 +               goto out_close_out;
1923         }
1924         *in_fd_ret = in_fds[0];
1925         *out_fd_ret = out_fds[1];
1926         return(0);
1927 +
1928 + out_close_in:
1929 +       os_close_file(in_fds[0]);
1930 +       os_close_file(in_fds[1]);
1931 + out_close_out:
1932 +       os_close_file(out_fds[0]);
1933 +       os_close_file(out_fds[1]);
1934   out:
1935 -       close(out_fds[1]);
1936 -       close(in_fds[0]);
1937         return(err);
1938  }
1939  
1940  void stop_watchdog(int in_fd, int out_fd)
1941  {
1942 -       close(in_fd);
1943 -       close(out_fd);
1944 +       os_close_file(in_fd);
1945 +       os_close_file(out_fd);
1946  }
1947  
1948  int ping_watchdog(int fd)
1949 @@ -115,11 +120,12 @@
1950         int n;
1951         char c = '\n';
1952  
1953 -       n = write(fd, &c, sizeof(c));
1954 -       if(n < sizeof(c)){
1955 -               printk("ping_watchdog - write failed, errno = %d\n",
1956 -                      errno);
1957 -               return(-errno);
1958 +       n = os_write_file(fd, &c, sizeof(c));
1959 +       if(n != sizeof(c)){
1960 +               printk("ping_watchdog - write failed, err = %d\n", -n);
1961 +               if(n < 0) 
1962 +                       return(n);
1963 +               return(-EIO);
1964         }
1965         return 1;
1966  
1967 diff -Naur a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c
1968 --- a/arch/um/drivers/hostaudio_kern.c  2004-02-11 12:16:48.000000000 -0500
1969 +++ b/arch/um/drivers/hostaudio_kern.c  2004-02-11 12:29:03.000000000 -0500
1970 @@ -5,12 +5,12 @@
1971  
1972  #include "linux/config.h"
1973  #include "linux/module.h"
1974 -#include "linux/version.h"
1975  #include "linux/init.h"
1976  #include "linux/slab.h"
1977  #include "linux/fs.h"
1978  #include "linux/sound.h"
1979  #include "linux/soundcard.h"
1980 +#include "asm/uaccess.h"
1981  #include "kern_util.h"
1982  #include "init.h"
1983  #include "hostaudio.h"
1984 @@ -19,30 +19,39 @@
1985  char *dsp = HOSTAUDIO_DEV_DSP;
1986  char *mixer = HOSTAUDIO_DEV_MIXER;
1987  
1988 +#define DSP_HELP \
1989 +"    This is used to specify the host dsp device to the hostaudio driver.\n" \
1990 +"    The default is \"" HOSTAUDIO_DEV_DSP "\".\n\n"
1991 +
1992 +#define MIXER_HELP \
1993 +"    This is used to specify the host mixer device to the hostaudio driver.\n" \
1994 +"    The default is \"" HOSTAUDIO_DEV_MIXER "\".\n\n"
1995 +
1996  #ifndef MODULE
1997  static int set_dsp(char *name, int *add)
1998  {
1999 -       dsp = uml_strdup(name);
2000 +       dsp = name;
2001         return(0);
2002  }
2003  
2004 -__uml_setup("dsp=", set_dsp,
2005 -"dsp=<dsp device>\n"
2006 -"    This is used to specify the host dsp device to the hostaudio driver.\n"
2007 -"    The default is \"" HOSTAUDIO_DEV_DSP "\".\n\n"
2008 -);
2009 +__uml_setup("dsp=", set_dsp, "dsp=<dsp device>\n" DSP_HELP);
2010  
2011  static int set_mixer(char *name, int *add)
2012  {
2013 -       mixer = uml_strdup(name);
2014 +       mixer = name;
2015         return(0);
2016  }
2017  
2018 -__uml_setup("mixer=", set_mixer,
2019 -"mixer=<mixer device>\n"
2020 -"    This is used to specify the host mixer device to the hostaudio driver.\n"
2021 -"    The default is \"" HOSTAUDIO_DEV_MIXER "\".\n\n"
2022 -);
2023 +__uml_setup("mixer=", set_mixer, "mixer=<mixer device>\n" MIXER_HELP);
2024 +
2025 +#else /*MODULE*/
2026 +
2027 +MODULE_PARM(dsp, "s");
2028 +MODULE_PARM_DESC(dsp, DSP_HELP);
2029 +
2030 +MODULE_PARM(mixer, "s");
2031 +MODULE_PARM_DESC(mixer, MIXER_HELP);
2032 +
2033  #endif
2034  
2035  /* /dev/dsp file operations */
2036 @@ -51,23 +60,55 @@
2037                               loff_t *ppos)
2038  {
2039          struct hostaudio_state *state = file->private_data;
2040 +       void *kbuf;
2041 +       int err;
2042  
2043  #ifdef DEBUG
2044          printk("hostaudio: read called, count = %d\n", count);
2045  #endif
2046  
2047 -        return(hostaudio_read_user(state, buffer, count, ppos));
2048 +       kbuf = kmalloc(count, GFP_KERNEL);
2049 +       if(kbuf == NULL)
2050 +               return(-ENOMEM);
2051 +
2052 +        err = hostaudio_read_user(state, kbuf, count, ppos);
2053 +       if(err < 0)
2054 +               goto out;
2055 +
2056 +       if(copy_to_user(buffer, kbuf, err))
2057 +               err = -EFAULT;
2058 +
2059 + out:
2060 +       kfree(kbuf);
2061 +       return(err);
2062  }
2063  
2064  static ssize_t hostaudio_write(struct file *file, const char *buffer, 
2065                                size_t count, loff_t *ppos)
2066  {
2067          struct hostaudio_state *state = file->private_data;
2068 +       void *kbuf;
2069 +       int err;
2070  
2071  #ifdef DEBUG
2072          printk("hostaudio: write called, count = %d\n", count);
2073  #endif
2074 -        return(hostaudio_write_user(state, buffer, count, ppos));
2075 +
2076 +       kbuf = kmalloc(count, GFP_KERNEL);
2077 +       if(kbuf == NULL)
2078 +               return(-ENOMEM);
2079 +
2080 +       err = -EFAULT;
2081 +       if(copy_from_user(kbuf, buffer, count))
2082 +               goto out;
2083 +
2084 +        err = hostaudio_write_user(state, kbuf, count, ppos);
2085 +       if(err < 0)
2086 +               goto out;
2087 +
2088 + out:
2089 +       kfree(kbuf);
2090 +       return(err);
2091  }
2092  
2093  static unsigned int hostaudio_poll(struct file *file, 
2094 @@ -86,12 +127,43 @@
2095                            unsigned int cmd, unsigned long arg)
2096  {
2097          struct hostaudio_state *state = file->private_data;
2098 +       unsigned long data = 0;
2099 +       int err;
2100  
2101  #ifdef DEBUG
2102          printk("hostaudio: ioctl called, cmd = %u\n", cmd);
2103  #endif
2104 +       switch(cmd){
2105 +       case SNDCTL_DSP_SPEED:
2106 +       case SNDCTL_DSP_STEREO:
2107 +       case SNDCTL_DSP_GETBLKSIZE:
2108 +       case SNDCTL_DSP_CHANNELS:
2109 +       case SNDCTL_DSP_SUBDIVIDE:
2110 +       case SNDCTL_DSP_SETFRAGMENT:
2111 +               if(get_user(data, (int *) arg))
2112 +                       return(-EFAULT);
2113 +               break;
2114 +       default:
2115 +               break;
2116 +       }
2117 +
2118 +        err = hostaudio_ioctl_user(state, cmd, (unsigned long) &data);
2119 +
2120 +       switch(cmd){
2121 +       case SNDCTL_DSP_SPEED:
2122 +       case SNDCTL_DSP_STEREO:
2123 +       case SNDCTL_DSP_GETBLKSIZE:
2124 +       case SNDCTL_DSP_CHANNELS:
2125 +       case SNDCTL_DSP_SUBDIVIDE:
2126 +       case SNDCTL_DSP_SETFRAGMENT:
2127 +               if(put_user(data, (int *) arg))
2128 +                       return(-EFAULT);
2129 +               break;
2130 +       default:
2131 +               break;
2132 +       }
2133  
2134 -        return(hostaudio_ioctl_user(state, cmd, arg));
2135 +       return(err);
2136  }
2137  
2138  static int hostaudio_open(struct inode *inode, struct file *file)
2139 @@ -225,7 +297,8 @@
2140  
2141  static int __init hostaudio_init_module(void)
2142  {
2143 -        printk(KERN_INFO "UML Audio Relay\n");
2144 +        printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n",
2145 +              dsp, mixer);
2146  
2147         module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1);
2148          if(module_data.dev_audio < 0){
2149 diff -Naur a/arch/um/drivers/hostaudio_user.c b/arch/um/drivers/hostaudio_user.c
2150 --- a/arch/um/drivers/hostaudio_user.c  2004-02-11 12:16:08.000000000 -0500
2151 +++ b/arch/um/drivers/hostaudio_user.c  2004-02-11 12:28:04.000000000 -0500
2152 @@ -4,9 +4,6 @@
2153   */
2154  
2155  #include <sys/types.h>
2156 -#include <sys/stat.h>
2157 -#include <sys/ioctl.h>
2158 -#include <fcntl.h>
2159  #include <unistd.h>
2160  #include <errno.h>
2161  #include "hostaudio.h"
2162 @@ -20,45 +17,31 @@
2163  ssize_t hostaudio_read_user(struct hostaudio_state *state, char *buffer, 
2164                             size_t count, loff_t *ppos)
2165  {
2166 -       ssize_t ret;
2167 -
2168  #ifdef DEBUG
2169          printk("hostaudio: read_user called, count = %d\n", count);
2170  #endif
2171  
2172 -        ret = read(state->fd, buffer, count);
2173 -
2174 -        if(ret < 0) return(-errno);
2175 -        return(ret);
2176 +       return(os_read_file(state->fd, buffer, count));
2177  }
2178  
2179  ssize_t hostaudio_write_user(struct hostaudio_state *state, const char *buffer,
2180                              size_t count, loff_t *ppos)
2181  {
2182 -       ssize_t ret;
2183 -
2184  #ifdef DEBUG
2185          printk("hostaudio: write_user called, count = %d\n", count);
2186  #endif
2187  
2188 -        ret = write(state->fd, buffer, count);
2189 -
2190 -        if(ret < 0) return(-errno);
2191 -        return(ret);
2192 +       return(os_write_file(state->fd, buffer, count));
2193  }
2194  
2195  int hostaudio_ioctl_user(struct hostaudio_state *state, unsigned int cmd, 
2196                          unsigned long arg)
2197  {
2198 -       int ret;
2199  #ifdef DEBUG
2200          printk("hostaudio: ioctl_user called, cmd = %u\n", cmd);
2201  #endif
2202  
2203 -        ret = ioctl(state->fd, cmd, arg);
2204 -       
2205 -        if(ret < 0) return(-errno);
2206 -        return(ret);
2207 +       return(os_ioctl_generic(state->fd, cmd, arg));
2208  }
2209  
2210  int hostaudio_open_user(struct hostaudio_state *state, int r, int w, char *dsp)
2211 @@ -67,14 +50,15 @@
2212          printk("hostaudio: open_user called\n");
2213  #endif
2214  
2215 -        state->fd = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
2216 -
2217 -        if(state->fd >= 0) return(0);
2218 +       state->fd = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
2219  
2220 -        printk("hostaudio_open_user failed to open '%s', errno = %d\n",
2221 -              dsp, errno);
2222 +       if(state->fd < 0) {
2223 +               printk("hostaudio_open_user failed to open '%s', err = %d\n",
2224 +                      dsp, -state->fd);
2225 +               return(state->fd); 
2226 +       }
2227          
2228 -        return(-errno); 
2229 +       return(0);
2230  }
2231  
2232  int hostaudio_release_user(struct hostaudio_state *state)
2233 @@ -82,10 +66,10 @@
2234  #ifdef DEBUG
2235          printk("hostaudio: release called\n");
2236  #endif
2237 -        if(state->fd >= 0){
2238 -               close(state->fd);
2239 -               state->fd=-1;
2240 -        }
2241 +       if(state->fd >= 0){
2242 +               os_close_file(state->fd);
2243 +               state->fd = -1;
2244 +       }
2245  
2246          return(0);
2247  }
2248 @@ -95,15 +79,11 @@
2249  int hostmixer_ioctl_mixdev_user(struct hostmixer_state *state, 
2250                                 unsigned int cmd, unsigned long arg)
2251  {
2252 -       int ret;
2253  #ifdef DEBUG
2254          printk("hostmixer: ioctl_user called cmd = %u\n",cmd);
2255  #endif
2256  
2257 -        ret = ioctl(state->fd, cmd, arg);
2258 -       if(ret < 0) 
2259 -               return(-errno);
2260 -       return(ret);
2261 +       return(os_ioctl_generic(state->fd, cmd, arg));
2262  }
2263  
2264  int hostmixer_open_mixdev_user(struct hostmixer_state *state, int r, int w,
2265 @@ -115,12 +95,13 @@
2266  
2267          state->fd = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
2268  
2269 -        if(state->fd >= 0) return(0);
2270 -
2271 -        printk("hostaudio_open_mixdev_user failed to open '%s', errno = %d\n",
2272 -              mixer, errno);
2273 +       if(state->fd < 0) {
2274 +               printk("hostaudio_open_mixdev_user failed to open '%s', "
2275 +                      "err = %d\n", mixer, state->fd);
2276 +               return(state->fd); 
2277 +       }
2278          
2279 -        return(-errno); 
2280 +       return(0);
2281  }
2282  
2283  int hostmixer_release_mixdev_user(struct hostmixer_state *state)
2284 @@ -130,7 +111,7 @@
2285  #endif
2286  
2287          if(state->fd >= 0){
2288 -               close(state->fd);
2289 +               os_close_file(state->fd);
2290                 state->fd = -1;
2291          }
2292  
2293 diff -Naur a/arch/um/drivers/line.c b/arch/um/drivers/line.c
2294 --- a/arch/um/drivers/line.c    2004-02-11 12:16:38.000000000 -0500
2295 +++ b/arch/um/drivers/line.c    2004-02-11 12:28:38.000000000 -0500
2296 @@ -6,8 +6,8 @@
2297  #include "linux/sched.h"
2298  #include "linux/slab.h"
2299  #include "linux/list.h"
2300 +#include "linux/interrupt.h"
2301  #include "linux/devfs_fs_kernel.h"
2302 -#include "asm/irq.h"
2303  #include "asm/uaccess.h"
2304  #include "chan_kern.h"
2305  #include "irq_user.h"
2306 @@ -16,38 +16,55 @@
2307  #include "user_util.h"
2308  #include "kern_util.h"
2309  #include "os.h"
2310 +#include "irq_kern.h"
2311  
2312  #define LINE_BUFSIZE 4096
2313  
2314 -void line_interrupt(int irq, void *data, struct pt_regs *unused)
2315 +static irqreturn_t line_interrupt(int irq, void *data, struct pt_regs *unused)
2316  {
2317         struct line *dev = data;
2318  
2319         if(dev->count > 0) 
2320                 chan_interrupt(&dev->chan_list, &dev->task, dev->tty, irq, 
2321                                dev);
2322 +       return IRQ_HANDLED;
2323  }
2324  
2325 -void line_timer_cb(void *arg)
2326 +static void line_timer_cb(void *arg)
2327  {
2328         struct line *dev = arg;
2329  
2330         line_interrupt(dev->driver->read_irq, dev, NULL);
2331  }
2332  
2333 -static void buffer_data(struct line *line, const char *buf, int len)
2334 +static int write_room(struct line *dev)
2335  {
2336 -       int end;
2337 +       int n;
2338 +
2339 +       if(dev->buffer == NULL) return(LINE_BUFSIZE - 1);
2340 +
2341 +       n = dev->head - dev->tail;
2342 +       if(n <= 0) n = LINE_BUFSIZE + n;
2343 +       return(n - 1);
2344 +}
2345 +
2346 +static int buffer_data(struct line *line, const char *buf, int len)
2347 +{
2348 +       int end, room;
2349  
2350         if(line->buffer == NULL){
2351                 line->buffer = kmalloc(LINE_BUFSIZE, GFP_ATOMIC);
2352                 if(line->buffer == NULL){
2353                         printk("buffer_data - atomic allocation failed\n");
2354 -                       return;
2355 +                       return(0);
2356                 }
2357                 line->head = line->buffer;
2358                 line->tail = line->buffer;
2359         }
2360 +
2361 +       room = write_room(line);
2362 +       len = (len > room) ? room : len;
2363 +
2364         end = line->buffer + LINE_BUFSIZE - line->tail;
2365         if(len < end){
2366                 memcpy(line->tail, buf, len);
2367 @@ -60,6 +77,8 @@
2368                 memcpy(line->buffer, buf, len);
2369                 line->tail = line->buffer + len;
2370         }
2371 +
2372 +       return(len);
2373  }
2374  
2375  static int flush_buffer(struct line *line)
2376 @@ -95,7 +114,7 @@
2377         struct line *line;
2378         char *new;
2379         unsigned long flags;
2380 -       int n, err, i;
2381 +       int n, err, i, ret = 0;
2382  
2383         if(tty->stopped) return 0;
2384  
2385 @@ -104,9 +123,13 @@
2386                 if(new == NULL)
2387                         return(0);
2388                 n = copy_from_user(new, buf, len);
2389 -               if(n == len)
2390 -                       return(-EFAULT);
2391                 buf = new;
2392 +               if(n == len){
2393 +                       len = -EFAULT;
2394 +                       goto out_free;
2395 +               }
2396 +
2397 +               len -= n;
2398         }
2399  
2400         i = tty->index;
2401 @@ -115,41 +138,50 @@
2402         down(&line->sem);
2403         if(line->head != line->tail){
2404                 local_irq_save(flags);
2405 -               buffer_data(line, buf, len);
2406 +               ret += buffer_data(line, buf, len);
2407                 err = flush_buffer(line);
2408                 local_irq_restore(flags);
2409                 if(err <= 0)
2410 -                       goto out;
2411 +                       goto out_up;
2412         }
2413         else {
2414                 n = write_chan(&line->chan_list, buf, len, 
2415                                line->driver->write_irq);
2416                 if(n < 0){
2417 -                       len = n;
2418 -                       goto out;
2419 +                       ret = n;
2420 +                       goto out_up;
2421                 }
2422 -               if(n < len)
2423 -                       buffer_data(line, buf + n, len - n);
2424 +
2425 +               len -= n;
2426 +               ret += n;
2427 +               if(len > 0)
2428 +                       ret += buffer_data(line, buf + n, len);
2429         }
2430 - out:
2431 + out_up:
2432         up(&line->sem);
2433 -       return(len);
2434 + out_free:
2435 +       if(from_user)
2436 +               kfree(buf);
2437 +       return(ret);
2438  }
2439  
2440 -void line_write_interrupt(int irq, void *data, struct pt_regs *unused)
2441 +static irqreturn_t line_write_interrupt(int irq, void *data, 
2442 +                                       struct pt_regs *unused)
2443  {
2444         struct line *dev = data;
2445         struct tty_struct *tty = dev->tty;
2446         int err;
2447  
2448         err = flush_buffer(dev);
2449 -       if(err == 0) return;
2450 +       if(err == 0) 
2451 +               return(IRQ_NONE);
2452         else if(err < 0){
2453                 dev->head = dev->buffer;
2454                 dev->tail = dev->buffer;
2455         }
2456  
2457 -       if(tty == NULL) return;
2458 +       if(tty == NULL) 
2459 +               return(IRQ_NONE);
2460  
2461         if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
2462            (tty->ldisc.write_wakeup != NULL))
2463 @@ -161,21 +193,9 @@
2464          * writes.
2465          */
2466  
2467 -       if (waitqueue_active(&tty->write_wait))
2468 +       if(waitqueue_active(&tty->write_wait))
2469                 wake_up_interruptible(&tty->write_wait);
2470 -
2471 -}
2472 -
2473 -int line_write_room(struct tty_struct *tty)
2474 -{
2475 -       struct line *dev = tty->driver_data;
2476 -       int n;
2477 -
2478 -       if(dev->buffer == NULL) return(LINE_BUFSIZE - 1);
2479 -
2480 -       n = dev->head - dev->tail;
2481 -       if(n <= 0) n = LINE_BUFSIZE + n;
2482 -       return(n - 1);
2483 +       return(IRQ_HANDLED);
2484  }
2485  
2486  int line_setup_irq(int fd, int input, int output, void *data)
2487 @@ -305,7 +325,7 @@
2488                 if(*end != '='){
2489                         printk(KERN_ERR "line_setup failed to parse \"%s\"\n", 
2490                                init);
2491 -                       return(1);
2492 +                       return(0);
2493                 }
2494                 init = end;
2495         }
2496 @@ -313,12 +333,12 @@
2497         if((n >= 0) && (n >= num)){
2498                 printk("line_setup - %d out of range ((0 ... %d) allowed)\n",
2499                        n, num);
2500 -               return(1);
2501 +               return(0);
2502         }
2503         else if(n >= 0){
2504                 if(lines[n].count > 0){
2505                         printk("line_setup - device %d is open\n", n);
2506 -                       return(1);
2507 +                       return(0);
2508                 }
2509                 if(lines[n].init_pri <= INIT_ONE){
2510                         lines[n].init_pri = INIT_ONE;
2511 @@ -332,7 +352,7 @@
2512         else if(!all_allowed){
2513                 printk("line_setup - can't configure all devices from "
2514                        "mconsole\n");
2515 -               return(1);
2516 +               return(0);
2517         }
2518         else {
2519                 for(i = 0; i < num; i++){
2520 @@ -346,7 +366,7 @@
2521                         }
2522                 }
2523         }
2524 -       return(0);
2525 +       return(1);
2526  }
2527  
2528  int line_config(struct line *lines, int num, char *str)
2529 @@ -357,7 +377,7 @@
2530                 printk("line_config - uml_strdup failed\n");
2531                 return(-ENOMEM);
2532         }
2533 -       return(line_setup(lines, num, new, 0));
2534 +       return(!line_setup(lines, num, new, 0));
2535  }
2536  
2537  int line_get_config(char *name, struct line *lines, int num, char *str, 
2538 @@ -369,7 +389,7 @@
2539  
2540         dev = simple_strtoul(name, &end, 0);
2541         if((*end != '\0') || (end == name)){
2542 -               *error_out = "line_setup failed to parse device number";
2543 +               *error_out = "line_get_config failed to parse device number";
2544                 return(0);
2545         }
2546  
2547 @@ -379,15 +399,15 @@
2548         }
2549  
2550         line = &lines[dev];
2551 +
2552         down(&line->sem);
2553 -       
2554         if(!line->valid)
2555                 CONFIG_CHUNK(str, size, n, "none", 1);
2556         else if(line->count == 0)
2557                 CONFIG_CHUNK(str, size, n, line->init_str, 1);
2558         else n = chan_config_string(&line->chan_list, str, size, error_out);
2559 -
2560         up(&line->sem);
2561 +
2562         return(n);
2563  }
2564  
2565 @@ -396,7 +416,14 @@
2566         char config[sizeof("conxxxx=none\0")];
2567  
2568         sprintf(config, "%s=none", str);
2569 -       return(line_setup(lines, num, config, 0));
2570 +       return(!line_setup(lines, num, config, 0));
2571 +}
2572 +
2573 +int line_write_room(struct tty_struct *tty)
2574 +{
2575 +       struct line *dev = tty->driver_data;
2576 +
2577 +       return(write_room(dev));
2578  }
2579  
2580  struct tty_driver *line_register_devfs(struct lines *set,
2581 @@ -412,7 +439,8 @@
2582                 return NULL;
2583  
2584         driver->driver_name = line_driver->name;
2585 -       driver->name = line_driver->devfs_name;
2586 +       driver->name = line_driver->device_name;
2587 +       driver->devfs_name = line_driver->devfs_name;
2588         driver->major = line_driver->major;
2589         driver->minor_start = line_driver->minor_start;
2590         driver->type = line_driver->type;
2591 @@ -432,7 +460,7 @@
2592  
2593         for(i = 0; i < nlines; i++){
2594                 if(!lines[i].valid) 
2595 -                       tty_unregister_devfs(driver, i);
2596 +                       tty_unregister_device(driver, i);
2597         }
2598  
2599         mconsole_register_dev(&line_driver->mc);
2600 @@ -465,24 +493,25 @@
2601         struct line *line;
2602  };
2603  
2604 -void winch_interrupt(int irq, void *data, struct pt_regs *unused)
2605 +irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused)
2606  {
2607         struct winch *winch = data;
2608         struct tty_struct *tty;
2609         int err;
2610         char c;
2611  
2612 -       err = generic_read(winch->fd, &c, NULL);
2613 -       if(err < 0){
2614 -               if(err != -EAGAIN){
2615 -                       printk("winch_interrupt : read failed, errno = %d\n", 
2616 -                              -err);
2617 -                       printk("fd %d is losing SIGWINCH support\n", 
2618 -                              winch->tty_fd);
2619 -                       free_irq(irq, data);
2620 -                       return;
2621 +       if(winch->fd != -1){
2622 +               err = generic_read(winch->fd, &c, NULL);
2623 +               if(err < 0){
2624 +                       if(err != -EAGAIN){
2625 +                               printk("winch_interrupt : read failed, "
2626 +                                      "errno = %d\n", -err);
2627 +                               printk("fd %d is losing SIGWINCH support\n", 
2628 +                                      winch->tty_fd);
2629 +                               return(IRQ_HANDLED);
2630 +                       }
2631 +                       goto out;
2632                 }
2633 -               goto out;
2634         }
2635         tty = winch->line->tty;
2636         if(tty != NULL){
2637 @@ -492,7 +521,9 @@
2638                 kill_pg(tty->pgrp, SIGWINCH, 1);
2639         }
2640   out:
2641 -       reactivate_fd(winch->fd, WINCH_IRQ);
2642 +       if(winch->fd != -1)
2643 +               reactivate_fd(winch->fd, WINCH_IRQ);
2644 +       return(IRQ_HANDLED);
2645  }
2646  
2647  DECLARE_MUTEX(winch_handler_sem);
2648 @@ -529,7 +560,10 @@
2649  
2650         list_for_each(ele, &winch_handlers){
2651                 winch = list_entry(ele, struct winch, list);
2652 -               close(winch->fd);
2653 +               if(winch->fd != -1){
2654 +                       deactivate_fd(winch->fd, WINCH_IRQ);
2655 +                       os_close_file(winch->fd);
2656 +               }
2657                 if(winch->pid != -1) 
2658                         os_kill_process(winch->pid, 1);
2659         }
2660 diff -Naur a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
2661 --- a/arch/um/drivers/Makefile  2004-02-11 12:15:52.000000000 -0500
2662 +++ b/arch/um/drivers/Makefile  2004-02-11 12:27:45.000000000 -0500
2663 @@ -1,5 +1,5 @@
2664  # 
2665 -# Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
2666 +# Copyright (C) 2000, 2002, 2003 Jeff Dike (jdike@karaya.com)
2667  # Licensed under the GPL
2668  #
2669  
2670 @@ -39,6 +39,8 @@
2671  obj-$(CONFIG_TTY_CHAN) += tty.o 
2672  obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o
2673  obj-$(CONFIG_UML_WATCHDOG) += harddog.o
2674 +obj-$(CONFIG_BLK_DEV_COW) += cow_kern.o
2675 +obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
2676  
2677  obj-y += stdio_console.o $(CHAN_OBJS)
2678  
2679 @@ -46,18 +48,7 @@
2680  
2681  USER_OBJS := $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) fd.o \
2682         null.o pty.o tty.o xterm.o
2683 -USER_OBJS := $(foreach file,$(USER_OBJS),arch/um/drivers/$(file))
2684 +USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
2685  
2686  $(USER_OBJS) : %.o: %.c
2687         $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
2688 -
2689 -clean:
2690 -
2691 -modules:
2692 -
2693 -fastdep:
2694 -
2695 -dep:
2696 -
2697 -archmrproper: clean
2698 -
2699 diff -Naur a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c
2700 --- a/arch/um/drivers/mcast_user.c      2004-02-11 12:15:46.000000000 -0500
2701 +++ b/arch/um/drivers/mcast_user.c      2004-02-11 12:27:37.000000000 -0500
2702 @@ -23,6 +23,7 @@
2703  #include "kern_util.h"
2704  #include "user_util.h"
2705  #include "user.h"
2706 +#include "os.h"
2707  
2708  #define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
2709  
2710 @@ -62,7 +63,8 @@
2711                 goto out;
2712         }
2713  
2714 -       if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0){
2715 +       fd = socket(AF_INET, SOCK_DGRAM, 0);
2716 +       if (fd < 0){
2717                 printk("mcast_open : data socket failed, errno = %d\n", 
2718                        errno);
2719                 fd = -ENOMEM;
2720 @@ -72,7 +74,7 @@
2721         if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
2722                 printk("mcast_open: SO_REUSEADDR failed, errno = %d\n",
2723                         errno);
2724 -               close(fd);
2725 +               os_close_file(fd);
2726                 fd = -EINVAL;
2727                 goto out;
2728         }
2729 @@ -82,7 +84,7 @@
2730                        sizeof(pri->ttl)) < 0) {
2731                 printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n",
2732                         errno);
2733 -               close(fd);
2734 +               os_close_file(fd);
2735                 fd = -EINVAL;
2736                 goto out;
2737         }
2738 @@ -91,7 +93,7 @@
2739         if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
2740                 printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n",
2741                         errno);
2742 -               close(fd);
2743 +               os_close_file(fd);
2744                 fd = -EINVAL;
2745                 goto out;
2746         }
2747 @@ -99,7 +101,7 @@
2748         /* bind socket to mcast address */
2749         if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
2750                 printk("mcast_open : data bind failed, errno = %d\n", errno);
2751 -               close(fd);
2752 +               os_close_file(fd);
2753                 fd = -EINVAL;
2754                 goto out;
2755         }               
2756 @@ -115,7 +117,7 @@
2757                        "interface on the host.\n");
2758                 printk("eth0 should be configured in order to use the "
2759                        "multicast transport.\n");
2760 -               close(fd);
2761 +               os_close_file(fd);
2762                 fd = -EINVAL;
2763         }
2764  
2765 @@ -137,7 +139,7 @@
2766                         errno);
2767         }
2768  
2769 -       close(fd);
2770 +       os_close_file(fd);
2771  }
2772  
2773  int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri)
2774 diff -Naur a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
2775 --- a/arch/um/drivers/mconsole_kern.c   2004-02-11 12:14:15.000000000 -0500
2776 +++ b/arch/um/drivers/mconsole_kern.c   2004-02-11 12:25:42.000000000 -0500
2777 @@ -1,6 +1,6 @@
2778  /*
2779   * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
2780 - * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
2781 + * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
2782   * Licensed under the GPL
2783   */
2784  
2785 @@ -15,6 +15,9 @@
2786  #include "linux/sysrq.h"
2787  #include "linux/workqueue.h"
2788  #include "linux/module.h"
2789 +#include "linux/file.h"
2790 +#include "linux/fs.h"
2791 +#include "linux/namei.h"
2792  #include "linux/proc_fs.h"
2793  #include "asm/irq.h"
2794  #include "asm/uaccess.h"
2795 @@ -27,6 +30,7 @@
2796  #include "init.h"
2797  #include "os.h"
2798  #include "umid.h"
2799 +#include "irq_kern.h"
2800  
2801  static int do_unlink_socket(struct notifier_block *notifier, 
2802                             unsigned long what, void *data)
2803 @@ -67,7 +71,7 @@
2804  
2805  DECLARE_WORK(mconsole_work, mc_work_proc, NULL);
2806  
2807 -void mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2808 +irqreturn_t mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2809  {
2810         int fd;
2811         struct mconsole_entry *new;
2812 @@ -75,9 +79,10 @@
2813  
2814         fd = (int) dev_id;
2815         while (mconsole_get_request(fd, &req)){
2816 -               if(req.cmd->as_interrupt) (*req.cmd->handler)(&req);
2817 +               if(req.cmd->context == MCONSOLE_INTR) 
2818 +                       (*req.cmd->handler)(&req);
2819                 else {
2820 -                       new = kmalloc(sizeof(req), GFP_ATOMIC);
2821 +                       new = kmalloc(sizeof(*new), GFP_ATOMIC);
2822                         if(new == NULL)
2823                                 mconsole_reply(&req, "Out of memory", 1, 0);
2824                         else {
2825 @@ -88,6 +93,7 @@
2826         }
2827         if(!list_empty(&mc_requests)) schedule_work(&mconsole_work);
2828         reactivate_fd(fd, MCONSOLE_IRQ);
2829 +       return(IRQ_HANDLED);
2830  }
2831  
2832  void mconsole_version(struct mc_request *req)
2833 @@ -100,20 +106,110 @@
2834         mconsole_reply(req, version, 0, 0);
2835  }
2836  
2837 +void mconsole_log(struct mc_request *req)
2838 +{
2839 +       int len;
2840 +       char *ptr = req->request.data;
2841 +       
2842 +       ptr += strlen("log");
2843 +       while(isspace(*ptr)) ptr++;
2844 +
2845 +       len = req->len - (ptr - req->request.data);
2846 +       printk("%.*s", len, ptr);
2847 +       mconsole_reply(req, "", 0, 0);
2848 +}
2849 +
2850 +void mconsole_proc(struct mc_request *req)
2851 +{
2852 +       struct nameidata nd;
2853 +       struct file_system_type *proc;
2854 +       struct super_block *super;
2855 +       struct file *file;
2856 +       int n, err;
2857 +       char *ptr = req->request.data, *buf;
2858 +       
2859 +       ptr += strlen("proc");
2860 +       while(isspace(*ptr)) ptr++;
2861 +
2862 +       proc = get_fs_type("proc");
2863 +       if(proc == NULL){
2864 +               mconsole_reply(req, "procfs not registered", 1, 0);
2865 +               goto out;
2866 +       }
2867 +
2868 +       super = (*proc->get_sb)(proc, 0, NULL, NULL);
2869 +       put_filesystem(proc);
2870 +       if(super == NULL){
2871 +               mconsole_reply(req, "Failed to get procfs superblock", 1, 0);
2872 +               goto out;
2873 +       }
2874 +       up_write(&super->s_umount);
2875 +
2876 +       nd.dentry = super->s_root;
2877 +       nd.mnt = NULL;
2878 +       nd.flags = O_RDONLY + 1;
2879 +       nd.last_type = LAST_ROOT;
2880 +
2881 +       err = link_path_walk(ptr, &nd);
2882 +       if(err){
2883 +               mconsole_reply(req, "Failed to look up file", 1, 0);
2884 +               goto out_kill;
2885 +       }
2886 +
2887 +       file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
2888 +       if(IS_ERR(file)){
2889 +               mconsole_reply(req, "Failed to open file", 1, 0);
2890 +               goto out_kill;
2891 +       }
2892 +
2893 +       buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
2894 +       if(buf == NULL){
2895 +               mconsole_reply(req, "Failed to allocate buffer", 1, 0);
2896 +               goto out_fput;
2897 +       }
2898 +
2899 +       if((file->f_op != NULL) && (file->f_op->read != NULL)){
2900 +               do {
2901 +                       n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1, 
2902 +                                               &file->f_pos);
2903 +                       if(n >= 0){
2904 +                               buf[n] = '\0';
2905 +                               mconsole_reply(req, buf, 0, (n > 0));
2906 +                       }
2907 +                       else {
2908 +                               mconsole_reply(req, "Read of file failed", 
2909 +                                              1, 0);
2910 +                               goto out_free;
2911 +                       }
2912 +               } while(n > 0);
2913 +       }
2914 +       else mconsole_reply(req, "", 0, 0);
2915 +
2916 + out_free:
2917 +       kfree(buf);
2918 + out_fput:
2919 +       fput(file);
2920 + out_kill:
2921 +       deactivate_super(super);
2922 + out: ;
2923 +}
2924 +
2925  #define UML_MCONSOLE_HELPTEXT \
2926 -"Commands:
2927 -    version - Get kernel version
2928 -    help - Print this message
2929 -    halt - Halt UML
2930 -    reboot - Reboot UML
2931 -    config <dev>=<config> - Add a new device to UML; 
2932 -       same syntax as command line
2933 -    config <dev> - Query the configuration of a device
2934 -    remove <dev> - Remove a device from UML
2935 -    sysrq <letter> - Performs the SysRq action controlled by the letter
2936 -    cad - invoke the Ctl-Alt-Del handler
2937 -    stop - pause the UML; it will do nothing until it receives a 'go'
2938 -    go - continue the UML after a 'stop'
2939 +"Commands: \n\
2940 +    version - Get kernel version \n\
2941 +    help - Print this message \n\
2942 +    halt - Halt UML \n\
2943 +    reboot - Reboot UML \n\
2944 +    config <dev>=<config> - Add a new device to UML;  \n\
2945 +       same syntax as command line \n\
2946 +    config <dev> - Query the configuration of a device \n\
2947 +    remove <dev> - Remove a device from UML \n\
2948 +    sysrq <letter> - Performs the SysRq action controlled by the letter \n\
2949 +    cad - invoke the Ctl-Alt-Del handler \n\
2950 +    stop - pause the UML; it will do nothing until it receives a 'go' \n\
2951 +    go - continue the UML after a 'stop' \n\
2952 +    log <string> - make UML enter <string> into the kernel log\n\
2953 +    proc <file> - returns the contents of the UML's /proc/<file>\n\
2954  "
2955  
2956  void mconsole_help(struct mc_request *req)
2957 @@ -302,7 +398,7 @@
2958         if(umid_file_name("mconsole", file, sizeof(file))) return(-1);
2959         snprintf(mconsole_socket_name, sizeof(file), "%s", file);
2960  
2961 -       sock = create_unix_socket(file, sizeof(file));
2962 +       sock = os_create_unix_socket(file, sizeof(file), 1);
2963         if (sock < 0){
2964                 printk("Failed to initialize management console\n");
2965                 return(1);
2966 @@ -344,11 +440,16 @@
2967         if(buf == NULL) 
2968                 return(-ENOMEM);
2969  
2970 -       if(copy_from_user(buf, buffer, count))
2971 -               return(-EFAULT);
2972 +       if(copy_from_user(buf, buffer, count)){
2973 +               count = -EFAULT;
2974 +               goto out;
2975 +       }
2976 +
2977         buf[count] = '\0';
2978  
2979         mconsole_notify(notify_socket, MCONSOLE_USER_NOTIFY, buf, count);
2980 + out:
2981 +       kfree(buf);
2982         return(count);
2983  }
2984  
2985 diff -Naur a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
2986 --- a/arch/um/drivers/mconsole_user.c   2004-02-11 12:14:27.000000000 -0500
2987 +++ b/arch/um/drivers/mconsole_user.c   2004-02-11 12:26:08.000000000 -0500
2988 @@ -1,6 +1,6 @@
2989  /*
2990   * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
2991 - * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
2992 + * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
2993   * Licensed under the GPL
2994   */
2995  
2996 @@ -18,16 +18,18 @@
2997  #include "umid.h"
2998  
2999  static struct mconsole_command commands[] = {
3000 -       { "version", mconsole_version, 1 },
3001 -       { "halt", mconsole_halt, 0 },
3002 -       { "reboot", mconsole_reboot, 0 },
3003 -       { "config", mconsole_config, 0 },
3004 -       { "remove", mconsole_remove, 0 },
3005 -       { "sysrq", mconsole_sysrq, 1 },
3006 -       { "help", mconsole_help, 1 },
3007 -       { "cad", mconsole_cad, 1 },
3008 -       { "stop", mconsole_stop, 0 },
3009 -       { "go", mconsole_go, 1 },
3010 +       { "version", mconsole_version, MCONSOLE_INTR },
3011 +       { "halt", mconsole_halt, MCONSOLE_PROC },
3012 +       { "reboot", mconsole_reboot, MCONSOLE_PROC },
3013 +       { "config", mconsole_config, MCONSOLE_PROC },
3014 +       { "remove", mconsole_remove, MCONSOLE_PROC },
3015 +       { "sysrq", mconsole_sysrq, MCONSOLE_INTR },
3016 +       { "help", mconsole_help, MCONSOLE_INTR },
3017 +       { "cad", mconsole_cad, MCONSOLE_INTR },
3018 +       { "stop", mconsole_stop, MCONSOLE_PROC },
3019 +       { "go", mconsole_go, MCONSOLE_INTR },
3020 +       { "log", mconsole_log, MCONSOLE_INTR },
3021 +       { "proc", mconsole_proc, MCONSOLE_PROC },
3022  };
3023  
3024  /* Initialized in mconsole_init, which is an initcall */
3025 @@ -139,6 +141,7 @@
3026                 memcpy(reply.data, str, len);
3027                 reply.data[len] = '\0';
3028                 total -= len;
3029 +               str += len;
3030                 reply.len = len + 1;
3031  
3032                 len = sizeof(reply) + reply.len - sizeof(reply.data);
3033 diff -Naur a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
3034 --- a/arch/um/drivers/mmapper_kern.c    2004-02-11 12:14:23.000000000 -0500
3035 +++ b/arch/um/drivers/mmapper_kern.c    2004-02-11 12:26:07.000000000 -0500
3036 @@ -120,7 +120,10 @@
3037         printk(KERN_INFO "Mapper v0.1\n");
3038  
3039         v_buf = (char *) find_iomem("mmapper", &mmapper_size);
3040 -       if(mmapper_size == 0) return(0);
3041 +       if(mmapper_size == 0){
3042 +               printk(KERN_ERR "mmapper_init - find_iomem failed\n");
3043 +               return(0);
3044 +       }
3045  
3046         p_buf = __pa(v_buf);
3047  
3048 diff -Naur a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
3049 --- a/arch/um/drivers/net_kern.c        2004-02-11 12:15:23.000000000 -0500
3050 +++ b/arch/um/drivers/net_kern.c        2004-02-11 12:27:11.000000000 -0500
3051 @@ -26,6 +26,7 @@
3052  #include "mconsole_kern.h"
3053  #include "init.h"
3054  #include "irq_user.h"
3055 +#include "irq_kern.h"
3056  
3057  static spinlock_t opened_lock = SPIN_LOCK_UNLOCKED;
3058  LIST_HEAD(opened);
3059 @@ -37,7 +38,8 @@
3060         struct sk_buff *skb;
3061  
3062         /* If we can't allocate memory, try again next round. */
3063 -       if ((skb = dev_alloc_skb(dev->mtu)) == NULL) {
3064 +       skb = dev_alloc_skb(dev->mtu);
3065 +       if (skb == NULL) {
3066                 lp->stats.rx_dropped++;
3067                 return 0;
3068         }
3069 @@ -61,14 +63,14 @@
3070         return pkt_len;
3071  }
3072  
3073 -void uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
3074 +irqreturn_t uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
3075  {
3076         struct net_device *dev = dev_id;
3077         struct uml_net_private *lp = dev->priv;
3078         int err;
3079  
3080         if(!netif_running(dev))
3081 -               return;
3082 +               return(IRQ_NONE);
3083  
3084         spin_lock(&lp->lock);
3085         while((err = uml_net_rx(dev)) > 0) ;
3086 @@ -83,6 +85,7 @@
3087  
3088   out:
3089         spin_unlock(&lp->lock);
3090 +       return(IRQ_HANDLED);
3091  }
3092  
3093  static int uml_net_open(struct net_device *dev)
3094 @@ -252,37 +255,6 @@
3095  #endif
3096  }
3097  
3098 -/*
3099 - * default do nothing hard header packet routines for struct net_device init.
3100 - * real ethernet transports will overwrite with real routines.
3101 - */
3102 -static int uml_net_hard_header(struct sk_buff *skb, struct net_device *dev,
3103 -                 unsigned short type, void *daddr, void *saddr, unsigned len)
3104 -{
3105 -       return(0); /* no change */
3106 -}
3107 -
3108 -static int uml_net_rebuild_header(struct sk_buff *skb)
3109 -{
3110 -       return(0); /* ignore */ 
3111 -}
3112 -
3113 -static int uml_net_header_cache(struct neighbour *neigh, struct hh_cache *hh)
3114 -{
3115 -       return(-1); /* fail */
3116 -}
3117 -
3118 -static void uml_net_header_cache_update(struct hh_cache *hh,
3119 -                 struct net_device *dev, unsigned char * haddr)
3120 -{
3121 -       /* ignore */
3122 -}
3123 -
3124 -static int uml_net_header_parse(struct sk_buff *skb, unsigned char *haddr)
3125 -{
3126 -       return(0); /* nothing */
3127 -}
3128 -
3129  static spinlock_t devices_lock = SPIN_LOCK_UNLOCKED;
3130  static struct list_head devices = LIST_HEAD_INIT(devices);
3131  
3132 @@ -292,7 +264,7 @@
3133         struct uml_net *device;
3134         struct net_device *dev;
3135         struct uml_net_private *lp;
3136 -       int err, size;
3137 +       int save, err, size;
3138  
3139         size = transport->private_size + sizeof(struct uml_net_private) + 
3140                 sizeof(((struct uml_net_private *) 0)->user);
3141 @@ -334,12 +306,6 @@
3142         snprintf(dev->name, sizeof(dev->name), "eth%d", n);
3143         device->dev = dev;
3144  
3145 -        dev->hard_header = uml_net_hard_header;
3146 -        dev->rebuild_header = uml_net_rebuild_header;
3147 -        dev->hard_header_cache = uml_net_header_cache;
3148 -        dev->header_cache_update= uml_net_header_cache_update;
3149 -        dev->hard_header_parse = uml_net_header_parse;
3150 -
3151         (*transport->kern->init)(dev, init);
3152  
3153         dev->mtu = transport->user->max_packet;
3154 @@ -362,21 +328,29 @@
3155                 return 1;
3156         lp = dev->priv;
3157  
3158 -       INIT_LIST_HEAD(&lp->list);
3159 -       spin_lock_init(&lp->lock);
3160 -       lp->dev = dev;
3161 -       lp->fd = -1;
3162 -       lp->mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0 };
3163 -       lp->have_mac = device->have_mac;
3164 -       lp->protocol = transport->kern->protocol;
3165 -       lp->open = transport->user->open;
3166 -       lp->close = transport->user->close;
3167 -       lp->remove = transport->user->remove;
3168 -       lp->read = transport->kern->read;
3169 -       lp->write = transport->kern->write;
3170 -       lp->add_address = transport->user->add_address;
3171 -       lp->delete_address = transport->user->delete_address;
3172 -       lp->set_mtu = transport->user->set_mtu;
3173 +       /* lp.user is the first four bytes of the transport data, which
3174 +        * has already been initialized.  This structure assignment will
3175 +        * overwrite that, so we make sure that .user gets overwritten with
3176 +        * what it already has.
3177 +        */
3178 +       save = lp->user[0];
3179 +       *lp = ((struct uml_net_private) 
3180 +               { .list                 = LIST_HEAD_INIT(lp->list),
3181 +                 .lock                 = SPIN_LOCK_UNLOCKED,
3182 +                 .dev                  = dev,
3183 +                 .fd                   = -1,
3184 +                 .mac                  = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
3185 +                 .have_mac             = device->have_mac,
3186 +                 .protocol             = transport->kern->protocol,
3187 +                 .open                 = transport->user->open,
3188 +                 .close                = transport->user->close,
3189 +                 .remove               = transport->user->remove,
3190 +                 .read                 = transport->kern->read,
3191 +                 .write                = transport->kern->write,
3192 +                 .add_address          = transport->user->add_address,
3193 +                 .delete_address       = transport->user->delete_address,
3194 +                 .set_mtu              = transport->user->set_mtu,
3195 +                 .user                 = { save } });
3196  
3197         init_timer(&lp->tl);
3198         lp->tl.function = uml_net_user_timer_expire;
3199 @@ -609,7 +583,8 @@
3200         unregister_netdev(dev);
3201  
3202         list_del(&device->list);
3203 -       free_netdev(device);
3204 +       kfree(device);
3205 +       free_netdev(dev);
3206         return(0);
3207  }
3208  
3209 diff -Naur a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
3210 --- a/arch/um/drivers/net_user.c        2004-02-11 12:14:28.000000000 -0500
3211 +++ b/arch/um/drivers/net_user.c        2004-02-11 12:26:11.000000000 -0500
3212 @@ -26,8 +26,7 @@
3213         if(gate_addr == NULL) return(0);
3214         if(sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0], 
3215                   &tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4){
3216 -               printk("Invalid tap IP address - '%s'\n", 
3217 -                      gate_addr);
3218 +               printk("Invalid tap IP address - '%s'\n", gate_addr);
3219                 return(-EINVAL);
3220         }
3221         return(0);
3222 @@ -60,18 +59,18 @@
3223         }
3224                 
3225         *output = '\0';
3226 -       if(read(fd, &remain, sizeof(remain)) != sizeof(remain)){
3227 -               printk("read_output - read of length failed, errno = %d\n",
3228 -                      errno);
3229 +       n = os_read_file(fd, &remain, sizeof(remain));
3230 +       if(n != sizeof(remain)){
3231 +               printk("read_output - read of length failed, err = %d\n", -n);
3232                 return;
3233         }
3234  
3235         while(remain != 0){
3236                 n = (remain < len) ? remain : len;
3237 -               actual = read(fd, output, n);
3238 +               actual = os_read_file(fd, output, n);
3239                 if(actual != n){
3240                         printk("read_output - read of data failed, "
3241 -                              "errno = %d\n", errno);
3242 +                              "err = %d\n", -actual);
3243                         return;
3244                 }
3245                 remain -= actual;
3246 @@ -83,13 +82,12 @@
3247  {
3248         int n;
3249  
3250 -       while(((n = read(fd,  buf,  len)) < 0) && (errno == EINTR)) ;
3251 +       n = os_read_file(fd,  buf,  len);
3252  
3253 -       if(n < 0){
3254 -               if(errno == EAGAIN) return(0);
3255 -               return(-errno);
3256 -       }
3257 -       else if(n == 0) return(-ENOTCONN);
3258 +       if(n == -EAGAIN) 
3259 +               return(0);
3260 +       else if(n == 0) 
3261 +               return(-ENOTCONN);
3262         return(n);
3263  }
3264  
3265 @@ -112,13 +110,13 @@
3266  {
3267         int n;
3268  
3269 -       while(((n = write(fd, buf, len)) < 0) && (errno == EINTR)) ;
3270 -       if(n < 0){
3271 -               if(errno == EAGAIN) return(0);
3272 -               return(-errno);
3273 -       }
3274 -       else if(n == 0) return(-ENOTCONN);
3275 -       return(n);      
3276 +       n = os_write_file(fd, buf, len);
3277 +
3278 +       if(n == -EAGAIN) 
3279 +               return(0);
3280 +       else if(n == 0) 
3281 +               return(-ENOTCONN);
3282 +       return(n);
3283  }
3284  
3285  int net_send(int fd, void *buf, int len)
3286 @@ -157,7 +155,7 @@
3287  {
3288         struct change_pre_exec_data *data = arg;
3289  
3290 -       close(data->close_me);
3291 +       os_close_file(data->close_me);
3292         dup2(data->stdout, 1);
3293  }
3294  
3295 @@ -167,15 +165,15 @@
3296         struct change_pre_exec_data pe_data;
3297  
3298         err = os_pipe(fds, 1, 0);
3299 -       if(err){
3300 -               printk("change_tramp - pipe failed, errno = %d\n", -err);
3301 +       if(err < 0){
3302 +               printk("change_tramp - pipe failed, err = %d\n", -err);
3303                 return(err);
3304         }
3305         pe_data.close_me = fds[0];
3306         pe_data.stdout = fds[1];
3307         pid = run_helper(change_pre_exec, &pe_data, argv, NULL);
3308  
3309 -       close(fds[1]);
3310 +       os_close_file(fds[1]);
3311         read_output(fds[0], output, output_len);
3312         waitpid(pid, NULL, 0);  
3313         return(pid);
3314 diff -Naur a/arch/um/drivers/null.c b/arch/um/drivers/null.c
3315 --- a/arch/um/drivers/null.c    2004-02-11 12:14:21.000000000 -0500
3316 +++ b/arch/um/drivers/null.c    2004-02-11 12:26:02.000000000 -0500
3317 @@ -5,7 +5,6 @@
3318  
3319  #include <stdlib.h>
3320  #include <errno.h>
3321 -#include <fcntl.h>
3322  #include "chan_user.h"
3323  #include "os.h"
3324  
3325 diff -Naur a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c
3326 --- a/arch/um/drivers/port_kern.c       2004-02-11 12:14:18.000000000 -0500
3327 +++ b/arch/um/drivers/port_kern.c       2004-02-11 12:26:00.000000000 -0500
3328 @@ -6,6 +6,7 @@
3329  #include "linux/list.h"
3330  #include "linux/sched.h"
3331  #include "linux/slab.h"
3332 +#include "linux/interrupt.h"
3333  #include "linux/irq.h"
3334  #include "linux/spinlock.h"
3335  #include "linux/errno.h"
3336 @@ -14,6 +15,7 @@
3337  #include "kern_util.h"
3338  #include "kern.h"
3339  #include "irq_user.h"
3340 +#include "irq_kern.h"
3341  #include "port.h"
3342  #include "init.h"
3343  #include "os.h"
3344 @@ -38,21 +40,21 @@
3345  struct connection {
3346         struct list_head list;
3347         int fd;
3348 -       int helper_pid;
3349 +       int helper_pid;
3350         int socket[2];
3351         int telnetd_pid;
3352         struct port_list *port;
3353  };
3354  
3355 -static void pipe_interrupt(int irq, void *data, struct pt_regs *regs)
3356 +static irqreturn_t pipe_interrupt(int irq, void *data, struct pt_regs *regs)
3357  {
3358         struct connection *conn = data;
3359         int fd;
3360  
3361 -       fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
3362 +       fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
3363         if(fd < 0){
3364                 if(fd == -EAGAIN)
3365 -                       return;
3366 +                       return(IRQ_NONE);
3367  
3368                 printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n", 
3369                        -fd);
3370 @@ -65,6 +67,7 @@
3371         list_add(&conn->list, &conn->port->connections);
3372  
3373         up(&conn->port->sem);
3374 +       return(IRQ_HANDLED);
3375  }
3376  
3377  static int port_accept(struct port_list *port)
3378 @@ -102,8 +105,7 @@
3379         }
3380  
3381         list_add(&conn->list, &port->pending);
3382 -       ret = 1;
3383 -       goto out;
3384 +       return(1);
3385  
3386   out_free:
3387         kfree(conn);
3388 @@ -138,12 +140,13 @@
3389  
3390  DECLARE_WORK(port_work, port_work_proc, NULL);
3391  
3392 -static void port_interrupt(int irq, void *data, struct pt_regs *regs)
3393 +static irqreturn_t port_interrupt(int irq, void *data, struct pt_regs *regs)
3394  {
3395         struct port_list *port = data;
3396  
3397         port->has_connection = 1;
3398         schedule_work(&port_work);
3399 +       return(IRQ_HANDLED);
3400  } 
3401  
3402  void *port_data(int port_num)
3403 diff -Naur a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c
3404 --- a/arch/um/drivers/port_user.c       2004-02-11 12:15:59.000000000 -0500
3405 +++ b/arch/um/drivers/port_user.c       2004-02-11 12:27:52.000000000 -0500
3406 @@ -47,10 +47,12 @@
3407                 return(NULL);
3408         }
3409  
3410 -       if((kern_data = port_data(port)) == NULL) 
3411 +       kern_data = port_data(port);
3412 +       if(kern_data == NULL) 
3413                 return(NULL);
3414  
3415 -       if((data = um_kmalloc(sizeof(*data))) == NULL) 
3416 +       data = um_kmalloc(sizeof(*data));
3417 +       if(data == NULL) 
3418                 goto err;
3419  
3420         *data = ((struct port_chan) { .raw              = opts->raw,
3421 @@ -90,7 +92,7 @@
3422         struct port_chan *data = d;
3423  
3424         port_remove_dev(data->kernel_data);
3425 -       close(fd);
3426 +       os_close_file(fd);
3427  }
3428  
3429  int port_console_write(int fd, const char *buf, int n, void *d)
3430 @@ -130,11 +132,15 @@
3431                 goto out;
3432         }
3433    
3434 -       if((listen(fd, 1) < 0) || (os_set_fd_block(fd, 0))){
3435 +       if(listen(fd, 1) < 0){
3436                 err = -errno;
3437                 goto out;
3438         }
3439  
3440 +       err = os_set_fd_block(fd, 0);
3441 +       if(err < 0)
3442 +               goto out;
3443 +
3444         return(fd);
3445   out:
3446         os_close_file(fd);
3447 @@ -153,10 +159,10 @@
3448         dup2(data->sock_fd, 0);
3449         dup2(data->sock_fd, 1);
3450         dup2(data->sock_fd, 2);
3451 -       close(data->sock_fd);
3452 +       os_close_file(data->sock_fd);
3453         dup2(data->pipe_fd, 3);
3454         os_shutdown_socket(3, 1, 0);
3455 -       close(data->pipe_fd);
3456 +       os_close_file(data->pipe_fd);
3457  }
3458  
3459  int port_connection(int fd, int *socket, int *pid_out)
3460 @@ -166,11 +172,12 @@
3461                          "/usr/lib/uml/port-helper", NULL };
3462         struct port_pre_exec_data data;
3463  
3464 -       if((new = os_accept_connection(fd)) < 0)
3465 -               return(-errno);
3466 +       new = os_accept_connection(fd);
3467 +       if(new < 0)
3468 +               return(new);
3469  
3470         err = os_pipe(socket, 0, 0);
3471 -       if(err) 
3472 +       if(err < 0) 
3473                 goto out_close;
3474  
3475         data = ((struct port_pre_exec_data)
3476 @@ -186,11 +193,11 @@
3477  
3478   out_shutdown:
3479         os_shutdown_socket(socket[0], 1, 1);
3480 -       close(socket[0]);
3481 +       os_close_file(socket[0]);
3482         os_shutdown_socket(socket[1], 1, 1);    
3483 -       close(socket[1]);
3484 +       os_close_file(socket[1]);
3485   out_close:
3486 -       close(new);
3487 +       os_close_file(new);
3488         return(err);
3489  }
3490  
3491 diff -Naur a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c
3492 --- a/arch/um/drivers/pty.c     2004-02-11 12:16:37.000000000 -0500
3493 +++ b/arch/um/drivers/pty.c     2004-02-11 12:28:37.000000000 -0500
3494 @@ -7,12 +7,12 @@
3495  #include <unistd.h>
3496  #include <string.h>
3497  #include <errno.h>
3498 -#include <fcntl.h>
3499  #include <termios.h>
3500  #include "chan_user.h"
3501  #include "user.h"
3502  #include "user_util.h"
3503  #include "kern_util.h"
3504 +#include "os.h"
3505  
3506  struct pty_chan {
3507         void (*announce)(char *dev_name, int dev);
3508 @@ -26,7 +26,8 @@
3509  {
3510         struct pty_chan *data;
3511  
3512 -       if((data = um_kmalloc(sizeof(*data))) == NULL) return(NULL);
3513 +       data = um_kmalloc(sizeof(*data));
3514 +       if(data == NULL) return(NULL);
3515         *data = ((struct pty_chan) { .announce          = opts->announce, 
3516                                      .dev               = device,
3517                                      .raw               = opts->raw });
3518 @@ -39,7 +40,8 @@
3519         char *dev;
3520         int fd;
3521  
3522 -       if((fd = get_pty()) < 0){
3523 +       fd = get_pty();
3524 +       if(fd < 0){
3525                 printk("open_pts : Failed to open pts\n");
3526                 return(-errno);
3527         }
3528 @@ -57,29 +59,27 @@
3529  
3530  int getmaster(char *line)
3531  {
3532 -       struct stat stb;
3533         char *pty, *bank, *cp;
3534 -       int master;
3535 +       int master, err;
3536  
3537         pty = &line[strlen("/dev/ptyp")];
3538         for (bank = "pqrs"; *bank; bank++) {
3539                 line[strlen("/dev/pty")] = *bank;
3540                 *pty = '0';
3541 -               if (stat(line, &stb) < 0)
3542 +               if (os_stat_file(line, NULL) < 0)
3543                         break;
3544                 for (cp = "0123456789abcdef"; *cp; cp++) {
3545                         *pty = *cp;
3546 -                       master = open(line, O_RDWR);
3547 +                       master = os_open_file(line, of_rdwr(OPENFLAGS()), 0);
3548                         if (master >= 0) {
3549                                 char *tp = &line[strlen("/dev/")];
3550 -                               int ok;
3551  
3552                                 /* verify slave side is usable */
3553                                 *tp = 't';
3554 -                               ok = access(line, R_OK|W_OK) == 0;
3555 +                               err = os_access(line, OS_ACC_RW_OK);
3556                                 *tp = 'p';
3557 -                               if (ok) return(master);
3558 -                               (void) close(master);
3559 +                               if(err == 0) return(master);
3560 +                               (void) os_close_file(master);
3561                         }
3562                 }
3563         }
3564 diff -Naur a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c
3565 --- a/arch/um/drivers/slip_user.c       2004-02-11 12:16:37.000000000 -0500
3566 +++ b/arch/um/drivers/slip_user.c       2004-02-11 12:28:37.000000000 -0500
3567 @@ -4,11 +4,9 @@
3568  #include <stddef.h>
3569  #include <sched.h>
3570  #include <string.h>
3571 -#include <sys/fcntl.h>
3572  #include <sys/errno.h>
3573  #include <sys/termios.h>
3574  #include <sys/wait.h>
3575 -#include <sys/ioctl.h>
3576  #include <sys/signal.h>
3577  #include "user_util.h"
3578  #include "kern_util.h"
3579 @@ -65,9 +63,9 @@
3580  {
3581         struct slip_pre_exec_data *data = arg;
3582  
3583 -       if(data->stdin != -1) dup2(data->stdin, 0);
3584 +       if(data->stdin >= 0) dup2(data->stdin, 0);
3585         dup2(data->stdout, 1);
3586 -       if(data->close_me != -1) close(data->close_me);
3587 +       if(data->close_me >= 0) os_close_file(data->close_me);
3588  }
3589  
3590  static int slip_tramp(char **argv, int fd)
3591 @@ -77,8 +75,8 @@
3592         int status, pid, fds[2], err, output_len;
3593  
3594         err = os_pipe(fds, 1, 0);
3595 -       if(err){
3596 -               printk("slip_tramp : pipe failed, errno = %d\n", -err);
3597 +       if(err < 0){
3598 +               printk("slip_tramp : pipe failed, err = %d\n", -err);
3599                 return(err);
3600         }
3601  
3602 @@ -96,7 +94,7 @@
3603                         printk("slip_tramp : failed to allocate output "
3604                                "buffer\n");
3605  
3606 -               close(fds[1]);
3607 +               os_close_file(fds[1]);
3608                 read_output(fds[0], output, output_len);
3609                 if(output != NULL){
3610                         printk("%s", output);
3611 @@ -105,7 +103,7 @@
3612                 if(waitpid(pid, &status, 0) < 0) err = errno;
3613                 else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){
3614                         printk("'%s' didn't exit with status 0\n", argv[0]);
3615 -                       err = EINVAL;
3616 +                       err = -EINVAL;
3617                 }
3618         }
3619         return(err);
3620 @@ -118,15 +116,17 @@
3621         char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
3622         char *argv[] = { "uml_net", version_buf, "slip", "up", gate_buf, 
3623                          NULL };
3624 -       int sfd, mfd, disc, sencap, err;
3625 +       int sfd, mfd, err;
3626  
3627 -       if((mfd = get_pty()) < 0){
3628 -               printk("umn : Failed to open pty\n");
3629 -               return(-1);
3630 +       mfd = get_pty();
3631 +       if(mfd < 0){
3632 +               printk("umn : Failed to open pty, err = %d\n", -mfd);
3633 +               return(mfd);
3634         }
3635 -       if((sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0)) < 0){
3636 -               printk("Couldn't open tty for slip line\n");
3637 -               return(-1);
3638 +       sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0);
3639 +       if(sfd < 0){
3640 +               printk("Couldn't open tty for slip line, err = %d\n", -sfd);
3641 +               return(sfd);
3642         }
3643         if(set_up_tty(sfd)) return(-1);
3644         pri->slave = sfd;
3645 @@ -138,28 +138,23 @@
3646  
3647                 err = slip_tramp(argv, sfd);
3648  
3649 -               if(err != 0){
3650 -                       printk("slip_tramp failed - errno = %d\n", err);
3651 -                       return(-err);
3652 +               if(err < 0){
3653 +                       printk("slip_tramp failed - err = %d\n", -err);
3654 +                       return(err);
3655                 }
3656 -               if(ioctl(pri->slave, SIOCGIFNAME, pri->name) < 0){
3657 -                       printk("SIOCGIFNAME failed, errno = %d\n", errno);
3658 -                       return(-errno);
3659 +               err = os_get_ifname(pri->slave, pri->name);
3660 +               if(err < 0){
3661 +                       printk("get_ifname failed, err = %d\n", -err);
3662 +                       return(err);
3663                 }
3664                 iter_addresses(pri->dev, open_addr, pri->name);
3665         }
3666         else {
3667 -               disc = N_SLIP;
3668 -               if(ioctl(sfd, TIOCSETD, &disc) < 0){
3669 -                       printk("Failed to set slip line discipline - "
3670 -                              "errno = %d\n", errno);
3671 -                       return(-errno);
3672 -               }
3673 -               sencap = 0;
3674 -               if(ioctl(sfd, SIOCSIFENCAP, &sencap) < 0){
3675 -                       printk("Failed to set slip encapsulation - "
3676 -                              "errno = %d\n", errno);
3677 -                       return(-errno);
3678 +               err = os_set_slip(sfd);
3679 +               if(err < 0){
3680 +                       printk("Failed to set slip discipline encapsulation - "
3681 +                              "err = %d\n", -err);
3682 +                       return(err);
3683                 }
3684         }
3685         return(mfd);
3686 @@ -181,9 +176,9 @@
3687         err = slip_tramp(argv, -1);
3688  
3689         if(err != 0)
3690 -               printk("slip_tramp failed - errno = %d\n", err);
3691 -       close(fd);
3692 -       close(pri->slave);
3693 +               printk("slip_tramp failed - errno = %d\n", -err);
3694 +       os_close_file(fd);
3695 +       os_close_file(pri->slave);
3696         pri->slave = -1;
3697  }
3698  
3699 @@ -243,7 +238,7 @@
3700  {
3701         struct slip_data *pri = data;
3702  
3703 -       if(pri->slave == -1) return;
3704 +       if(pri->slave < 0) return;
3705         open_addr(addr, netmask, pri->name);
3706  }
3707  
3708 @@ -252,7 +247,7 @@
3709  {
3710         struct slip_data *pri = data;
3711  
3712 -       if(pri->slave == -1) return;
3713 +       if(pri->slave < 0) return;
3714         close_addr(addr, netmask, pri->name);
3715  }
3716  
3717 diff -Naur a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c
3718 --- a/arch/um/drivers/slirp_user.c      2004-02-11 12:16:03.000000000 -0500
3719 +++ b/arch/um/drivers/slirp_user.c      2004-02-11 12:27:58.000000000 -0500
3720 @@ -4,7 +4,6 @@
3721  #include <stddef.h>
3722  #include <sched.h>
3723  #include <string.h>
3724 -#include <sys/fcntl.h>
3725  #include <sys/errno.h>
3726  #include <sys/wait.h>
3727  #include <sys/signal.h>
3728 @@ -48,15 +47,15 @@
3729  
3730         return(pid);
3731  }
3732
3733 +
3734 +/* XXX This is just a trivial wrapper around os_pipe */ 
3735  static int slirp_datachan(int *mfd, int *sfd)
3736  {
3737         int fds[2], err;
3738  
3739         err = os_pipe(fds, 1, 1);
3740 -       if(err){
3741 -               printk("slirp_datachan: Failed to open pipe, errno = %d\n",
3742 -                      -err);
3743 +       if(err < 0){
3744 +               printk("slirp_datachan: Failed to open pipe, err = %d\n", -err);
3745                 return(err);
3746         }
3747  
3748 @@ -77,7 +76,7 @@
3749         pid = slirp_tramp(pri->argw.argv, sfd);
3750  
3751         if(pid < 0){
3752 -               printk("slirp_tramp failed - errno = %d\n", pid);
3753 +               printk("slirp_tramp failed - errno = %d\n", -pid);
3754                 os_close_file(sfd);     
3755                 os_close_file(mfd);     
3756                 return(pid);
3757 @@ -97,8 +96,8 @@
3758         struct slirp_data *pri = data;
3759         int status,err;
3760  
3761 -       close(fd);
3762 -       close(pri->slave);
3763 +       os_close_file(fd);
3764 +       os_close_file(pri->slave);
3765  
3766         pri->slave = -1;
3767  
3768 diff -Naur a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
3769 --- a/arch/um/drivers/ssl.c     2004-02-11 12:15:28.000000000 -0500
3770 +++ b/arch/um/drivers/ssl.c     2004-02-11 12:27:17.000000000 -0500
3771 @@ -10,6 +10,7 @@
3772  #include "linux/major.h"
3773  #include "linux/mm.h"
3774  #include "linux/init.h"
3775 +#include "linux/console.h"
3776  #include "asm/termbits.h"
3777  #include "asm/irq.h"
3778  #include "line.h"
3779 @@ -53,8 +54,9 @@
3780  
3781  static struct line_driver driver = {
3782         .name                   = "UML serial line",
3783 -       .devfs_name             = "tts/%d",
3784 -       .major                  = TTYAUX_MAJOR,
3785 +       .device_name            = "ttS",
3786 +       .devfs_name             = "tts/",
3787 +       .major                  = TTY_MAJOR,
3788         .minor_start            = 64,
3789         .type                   = TTY_DRIVER_TYPE_SERIAL,
3790         .subtype                = 0,
3791 @@ -149,6 +151,9 @@
3792         case TCSETSW:
3793         case TCGETA:
3794         case TIOCMGET:
3795 +       case TCSBRK:
3796 +       case TCSBRKP:
3797 +       case TIOCMSET:
3798                 ret = -ENOIOCTLCMD;
3799                 break;
3800         default:
3801 @@ -212,6 +217,37 @@
3802   */
3803  static int ssl_init_done = 0;
3804  
3805 +static void ssl_console_write(struct console *c, const char *string, 
3806 +                             unsigned len)
3807 +{
3808 +       struct line *line = &serial_lines[c->index];
3809 +       if(ssl_init_done)
3810 +               down(&line->sem);
3811 +       console_write_chan(&line->chan_list, string, len);
3812 +       if(ssl_init_done)
3813 +               up(&line->sem);
3814 +}
3815 +
3816 +static struct tty_driver *ssl_console_device(struct console *c, int *index)
3817 +{
3818 +       *index = c->index;
3819 +       return ssl_driver;
3820 +}
3821 +
3822 +static int ssl_console_setup(struct console *co, char *options)
3823 +{
3824 +       return(0);
3825 +}
3826 +
3827 +static struct console ssl_cons = {
3828 +       name:           "ttyS",
3829 +       write:          ssl_console_write,
3830 +       device:         ssl_console_device,
3831 +       setup:          ssl_console_setup,
3832 +       flags:          CON_PRINTBUFFER,
3833 +       index:          -1,
3834 +};
3835 +
3836  int ssl_init(void)
3837  {
3838         char *new_title;
3839 @@ -227,17 +263,18 @@
3840         new_title = add_xterm_umid(opts.xterm_title);
3841         if(new_title != NULL) opts.xterm_title = new_title;
3842  
3843 +       register_console(&ssl_cons);
3844         ssl_init_done = 1;
3845         return(0);
3846  }
3847  
3848 -__initcall(ssl_init);
3849 +late_initcall(ssl_init);
3850  
3851  static int ssl_chan_setup(char *str)
3852  {
3853 -       line_setup(serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0]),
3854 -                  str, 1);
3855 -       return(1);
3856 +       return(line_setup(serial_lines, 
3857 +                         sizeof(serial_lines)/sizeof(serial_lines[0]), 
3858 +                         str, 1));
3859  }
3860  
3861  __setup("ssl", ssl_chan_setup);
3862 diff -Naur a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
3863 --- a/arch/um/drivers/stdio_console.c   2004-02-11 12:14:32.000000000 -0500
3864 +++ b/arch/um/drivers/stdio_console.c   2004-02-11 12:26:14.000000000 -0500
3865 @@ -83,7 +83,8 @@
3866  
3867  static struct line_driver driver = {
3868         .name                   = "UML console",
3869 -       .devfs_name             = "vc/%d",
3870 +       .device_name            = "tty",
3871 +       .devfs_name             = "vc/",
3872         .major                  = TTY_MAJOR,
3873         .minor_start            = 0,
3874         .type                   = TTY_DRIVER_TYPE_CONSOLE,
3875 @@ -159,6 +160,15 @@
3876  
3877  static int con_init_done = 0;
3878  
3879 +static struct tty_operations console_ops = {
3880 +       .open                   = con_open,
3881 +       .close                  = con_close,
3882 +       .write                  = con_write,
3883 +       .chars_in_buffer        = chars_in_buffer,
3884 +       .set_termios            = set_termios,
3885 +       .write_room             = line_write_room,
3886 +};
3887 +
3888  int stdio_init(void)
3889  {
3890         char *new_title;
3891 @@ -166,7 +176,8 @@
3892         printk(KERN_INFO "Initializing stdio console driver\n");
3893  
3894         console_driver = line_register_devfs(&console_lines, &driver,
3895 -                               &console_ops, vts, sizeof(vts)/sizeof(vts[0]));
3896 +                                            &console_ops, vts,
3897 +                                            sizeof(vts)/sizeof(vts[0]));
3898  
3899         lines_init(vts, sizeof(vts)/sizeof(vts[0]));
3900  
3901 @@ -178,24 +189,19 @@
3902         return(0);
3903  }
3904  
3905 -__initcall(stdio_init);
3906 +late_initcall(stdio_init);
3907  
3908  static void console_write(struct console *console, const char *string, 
3909                           unsigned len)
3910  {
3911 -       if(con_init_done) down(&vts[console->index].sem);
3912 -       console_write_chan(&vts[console->index].chan_list, string, len);
3913 -       if(con_init_done) up(&vts[console->index].sem);
3914 -}
3915 +       struct line *line = &vts[console->index];
3916  
3917 -static struct tty_operations console_ops = {
3918 -       .open                   = con_open,
3919 -       .close                  = con_close,
3920 -       .write                  = con_write,
3921 -       .chars_in_buffer        = chars_in_buffer,
3922 -       .set_termios            = set_termios,
3923 -       .write_room             = line_write_room,
3924 -};
3925 +       if(con_init_done)
3926 +               down(&line->sem);
3927 +       console_write_chan(&line->chan_list, string, len);
3928 +       if(con_init_done)
3929 +               up(&line->sem);
3930 +}
3931  
3932  static struct tty_driver *console_device(struct console *c, int *index)
3933  {
3934 @@ -208,22 +214,28 @@
3935         return(0);
3936  }
3937  
3938 -static struct console stdiocons = INIT_CONSOLE("tty", console_write, 
3939 -                                              console_device, console_setup,
3940 -                                              CON_PRINTBUFFER);
3941 +static struct console stdiocons = {
3942 +       name:           "tty",
3943 +       write:          console_write,
3944 +       device:         console_device,
3945 +       setup:          console_setup,
3946 +       flags:          CON_PRINTBUFFER,
3947 +       index:          -1,
3948 +};
3949  
3950 -static void __init stdio_console_init(void)
3951 +static int __init stdio_console_init(void)
3952  {
3953         INIT_LIST_HEAD(&vts[0].chan_list);
3954         list_add(&init_console_chan.list, &vts[0].chan_list);
3955         register_console(&stdiocons);
3956 +       return(0);
3957  }
3958 +
3959  console_initcall(stdio_console_init);
3960  
3961  static int console_chan_setup(char *str)
3962  {
3963 -       line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1);
3964 -       return(1);
3965 +       return(line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1));
3966  }
3967  
3968  __setup("con", console_chan_setup);
3969 diff -Naur a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c
3970 --- a/arch/um/drivers/tty.c     2004-02-11 12:15:02.000000000 -0500
3971 +++ b/arch/um/drivers/tty.c     2004-02-11 12:26:51.000000000 -0500
3972 @@ -5,7 +5,6 @@
3973  
3974  #include <stdio.h>
3975  #include <termios.h>
3976 -#include <fcntl.h>
3977  #include <errno.h>
3978  #include <unistd.h>
3979  #include "chan_user.h"
3980 @@ -30,7 +29,8 @@
3981         }
3982         str++;
3983  
3984 -       if((data = um_kmalloc(sizeof(*data))) == NULL) 
3985 +       data = um_kmalloc(sizeof(*data)); 
3986 +       if(data == NULL) 
3987                 return(NULL);
3988         *data = ((struct tty_chan) { .dev       = str,
3989                                      .raw       = opts->raw });
3990 diff -Naur a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
3991 --- a/arch/um/drivers/ubd_kern.c        2004-02-11 12:15:25.000000000 -0500
3992 +++ b/arch/um/drivers/ubd_kern.c        2004-02-11 12:27:12.000000000 -0500
3993 @@ -8,6 +8,13 @@
3994   * old style ubd by setting UBD_SHIFT to 0
3995   * 2002-09-27...2002-10-18 massive tinkering for 2.5
3996   * partitions have changed in 2.5
3997 + * 2003-01-29 more tinkering for 2.5.59-1
3998 + * This should now address the sysfs problems and has
3999 + * the symlink for devfs to allow for booting with
4000 + * the common /dev/ubd/discX/... names rather than
4001 + * only /dev/ubdN/discN this version also has lots of
4002 + * clean ups preparing for ubd-many.
4003 + * James McMechan
4004   */
4005  
4006  #define MAJOR_NR UBD_MAJOR
4007 @@ -40,9 +47,12 @@
4008  #include "mconsole_kern.h"
4009  #include "init.h"
4010  #include "irq_user.h"
4011 +#include "irq_kern.h"
4012  #include "ubd_user.h"
4013  #include "2_5compat.h"
4014  #include "os.h"
4015 +#include "mem.h"
4016 +#include "mem_kern.h"
4017  
4018  static spinlock_t ubd_io_lock = SPIN_LOCK_UNLOCKED;
4019  static spinlock_t ubd_lock = SPIN_LOCK_UNLOCKED;
4020 @@ -56,6 +66,10 @@
4021  
4022  #define MAX_DEV (8)
4023  
4024 +/* Changed in early boot */
4025 +static int ubd_do_mmap = 0;
4026 +#define UBD_MMAP_BLOCK_SIZE PAGE_SIZE
4027 +
4028  static struct block_device_operations ubd_blops = {
4029          .owner         = THIS_MODULE,
4030          .open          = ubd_open,
4031 @@ -67,7 +81,7 @@
4032  static request_queue_t *ubd_queue;
4033  
4034  /* Protected by ubd_lock */
4035 -static int fake_major = 0;
4036 +static int fake_major = MAJOR_NR;
4037  
4038  static struct gendisk *ubd_gendisk[MAX_DEV];
4039  static struct gendisk *fake_gendisk[MAX_DEV];
4040 @@ -96,13 +110,19 @@
4041  
4042  struct ubd {
4043         char *file;
4044 -       int is_dir;
4045         int count;
4046         int fd;
4047         __u64 size;
4048         struct openflags boot_openflags;
4049         struct openflags openflags;
4050 +       int no_cow;
4051         struct cow cow;
4052 +
4053 +       int map_writes;
4054 +       int map_reads;
4055 +       int nomap_writes;
4056 +       int nomap_reads;
4057 +       int write_maps;
4058  };
4059  
4060  #define DEFAULT_COW { \
4061 @@ -115,21 +135,28 @@
4062  
4063  #define DEFAULT_UBD { \
4064         .file =                 NULL, \
4065 -       .is_dir =               0, \
4066         .count =                0, \
4067         .fd =                   -1, \
4068         .size =                 -1, \
4069         .boot_openflags =       OPEN_FLAGS, \
4070         .openflags =            OPEN_FLAGS, \
4071 +        .no_cow =               0, \
4072          .cow =                 DEFAULT_COW, \
4073 +       .map_writes             = 0, \
4074 +       .map_reads              = 0, \
4075 +       .nomap_writes           = 0, \
4076 +       .nomap_reads            = 0, \
4077 +       .write_maps             = 0, \
4078  }
4079  
4080  struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD };
4081  
4082  static int ubd0_init(void)
4083  {
4084 -       if(ubd_dev[0].file == NULL)
4085 -               ubd_dev[0].file = "root_fs";
4086 +       struct ubd *dev = &ubd_dev[0];
4087 +
4088 +       if(dev->file == NULL)
4089 +               dev->file = "root_fs";
4090         return(0);
4091  }
4092  
4093 @@ -196,19 +223,46 @@
4094  "    Create ide0 entries that map onto ubd devices.\n\n"
4095  );
4096  
4097 +static int parse_unit(char **ptr)
4098 +{
4099 +       char *str = *ptr, *end;
4100 +       int n = -1;
4101 +
4102 +       if(isdigit(*str)) {
4103 +               n = simple_strtoul(str, &end, 0);
4104 +               if(end == str)
4105 +                       return(-1);
4106 +               *ptr = end;
4107 +       }
4108 +       else if (('a' <= *str) && (*str <= 'h')) {
4109 +               n = *str - 'a';
4110 +               str++;
4111 +               *ptr = str;
4112 +       }
4113 +       return(n);
4114 +}
4115 +
4116  static int ubd_setup_common(char *str, int *index_out)
4117  {
4118 +       struct ubd *dev;
4119         struct openflags flags = global_openflags;
4120         char *backing_file;
4121         int n, err;
4122  
4123         if(index_out) *index_out = -1;
4124 -       n = *str++;
4125 +       n = *str;
4126         if(n == '='){
4127 -               static int fake_major_allowed = 1;
4128                 char *end;
4129                 int major;
4130  
4131 +               str++;
4132 +               if(!strcmp(str, "mmap")){
4133 +                       CHOOSE_MODE(printk("mmap not supported by the ubd "
4134 +                                          "driver in tt mode\n"),
4135 +                                   ubd_do_mmap = 1);
4136 +                       return(0);
4137 +               }
4138 +
4139                 if(!strcmp(str, "sync")){
4140                         global_openflags.s = 1;
4141                         return(0);
4142 @@ -220,20 +274,14 @@
4143                         return(1);
4144                 }
4145  
4146 -               if(!fake_major_allowed){
4147 -                       printk(KERN_ERR "Can't assign a fake major twice\n");
4148 -                       return(1);
4149 -               }
4150 -
4151                 err = 1;
4152                 spin_lock(&ubd_lock);
4153 -               if(!fake_major_allowed){
4154 +               if(fake_major != MAJOR_NR){
4155                         printk(KERN_ERR "Can't assign a fake major twice\n");
4156                         goto out1;
4157                 }
4158   
4159                 fake_major = major;
4160 -               fake_major_allowed = 0;
4161  
4162                 printk(KERN_INFO "Setting extra ubd major number to %d\n",
4163                        major);
4164 @@ -243,25 +291,23 @@
4165                 return(err);
4166         }
4167  
4168 -       if(n < '0'){
4169 -               printk(KERN_ERR "ubd_setup : index out of range\n"); }
4170 -
4171 -       if((n >= '0') && (n <= '9')) n -= '0';
4172 -       else if((n >= 'a') && (n <= 'z')) n -= 'a';
4173 -       else {
4174 -               printk(KERN_ERR "ubd_setup : device syntax invalid\n");
4175 +       n = parse_unit(&str);
4176 +       if(n < 0){
4177 +               printk(KERN_ERR "ubd_setup : couldn't parse unit number "
4178 +                      "'%s'\n", str);
4179                 return(1);
4180         }
4181         if(n >= MAX_DEV){
4182 -               printk(KERN_ERR "ubd_setup : index out of range "
4183 -                      "(%d devices)\n", MAX_DEV);      
4184 +               printk(KERN_ERR "ubd_setup : index %d out of range "
4185 +                      "(%d devices)\n", n, MAX_DEV);
4186                 return(1);
4187         }
4188  
4189         err = 1;
4190         spin_lock(&ubd_lock);
4191  
4192 -       if(ubd_dev[n].file != NULL){
4193 +       dev = &ubd_dev[n];
4194 +       if(dev->file != NULL){
4195                 printk(KERN_ERR "ubd_setup : device already configured\n");
4196                 goto out2;
4197         }
4198 @@ -276,6 +322,11 @@
4199                 flags.s = 1;
4200                 str++;
4201         }
4202 +       if (*str == 'd'){
4203 +               dev->no_cow = 1;
4204 +               str++;
4205 +       }
4206 +
4207         if(*str++ != '='){
4208                 printk(KERN_ERR "ubd_setup : Expected '='\n");
4209                 goto out2;
4210 @@ -284,14 +335,17 @@
4211         err = 0;
4212         backing_file = strchr(str, ',');
4213         if(backing_file){
4214 -               *backing_file = '\0';
4215 -               backing_file++;
4216 +               if(dev->no_cow)
4217 +                       printk(KERN_ERR "Can't specify both 'd' and a "
4218 +                              "cow file\n");
4219 +               else {
4220 +                       *backing_file = '\0';
4221 +                       backing_file++;
4222 +               }
4223         }
4224 -       ubd_dev[n].file = str;
4225 -       if(ubd_is_dir(ubd_dev[n].file))
4226 -               ubd_dev[n].is_dir = 1;
4227 -       ubd_dev[n].cow.file = backing_file;
4228 -       ubd_dev[n].boot_openflags = flags;
4229 +       dev->file = str;
4230 +       dev->cow.file = backing_file;
4231 +       dev->boot_openflags = flags;
4232   out2:
4233         spin_unlock(&ubd_lock);
4234         return(err);
4235 @@ -321,8 +375,7 @@
4236  static int fakehd_set = 0;
4237  static int fakehd(char *str)
4238  {
4239 -       printk(KERN_INFO 
4240 -              "fakehd : Changing ubd name to \"hd\".\n");
4241 +       printk(KERN_INFO "fakehd : Changing ubd name to \"hd\".\n");
4242         fakehd_set = 1;
4243         return 1;
4244  }
4245 @@ -368,32 +421,42 @@
4246  {
4247         struct io_thread_req req;
4248         struct request *rq = elv_next_request(ubd_queue);
4249 -       int n;
4250 +       int n, err;
4251  
4252         do_ubd = NULL;
4253         intr_count++;
4254         n = read_ubd_fs(thread_fd, &req, sizeof(req));
4255         if(n != sizeof(req)){
4256                 printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, "
4257 -                      "errno = %d\n", os_getpid(), -n);
4258 +                      "err = %d\n", os_getpid(), -n);
4259                 spin_lock(&ubd_io_lock);
4260                 end_request(rq, 0);
4261                 spin_unlock(&ubd_io_lock);
4262                 return;
4263         }
4264          
4265 -        if((req.offset != ((__u64) (rq->sector)) << 9) ||
4266 -          (req.length != (rq->current_nr_sectors) << 9))
4267 +       if((req.op != UBD_MMAP) && 
4268 +          ((req.offset != ((__u64) (rq->sector)) << 9) ||
4269 +           (req.length != (rq->current_nr_sectors) << 9)))
4270                 panic("I/O op mismatch");
4271         
4272 +       if(req.map_fd != -1){
4273 +               err = physmem_subst_mapping(req.buffer, req.map_fd, 
4274 +                                           req.map_offset, 1);
4275 +               if(err)
4276 +                       printk("ubd_handler - physmem_subst_mapping failed, "
4277 +                              "err = %d\n", -err);
4278 +       }
4279 +
4280         ubd_finish(rq, req.error);
4281         reactivate_fd(thread_fd, UBD_IRQ);      
4282         do_ubd_request(ubd_queue);
4283  }
4284  
4285 -static void ubd_intr(int irq, void *dev, struct pt_regs *unused)
4286 +static irqreturn_t ubd_intr(int irq, void *dev, struct pt_regs *unused)
4287  {
4288         ubd_handler();
4289 +       return(IRQ_HANDLED);
4290  }
4291  
4292  /* Only changed by ubd_init, which is an initcall. */
4293 @@ -417,10 +480,14 @@
4294  
4295  static void ubd_close(struct ubd *dev)
4296  {
4297 +       if(ubd_do_mmap)
4298 +               physmem_forget_descriptor(dev->fd);
4299         os_close_file(dev->fd);
4300         if(dev->cow.file == NULL)
4301                 return;
4302  
4303 +       if(ubd_do_mmap)
4304 +               physmem_forget_descriptor(dev->cow.fd);
4305         os_close_file(dev->cow.fd);
4306         vfree(dev->cow.bitmap);
4307         dev->cow.bitmap = NULL;
4308 @@ -429,18 +496,20 @@
4309  static int ubd_open_dev(struct ubd *dev)
4310  {
4311         struct openflags flags;
4312 -       int err, n, create_cow, *create_ptr;
4313 +       char **back_ptr;
4314 +       int err, create_cow, *create_ptr;
4315  
4316 +       dev->openflags = dev->boot_openflags;
4317         create_cow = 0;
4318         create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
4319 -       dev->fd = open_ubd_file(dev->file, &dev->openflags, &dev->cow.file,
4320 +       back_ptr = dev->no_cow ? NULL : &dev->cow.file;
4321 +       dev->fd = open_ubd_file(dev->file, &dev->openflags, back_ptr,
4322                                 &dev->cow.bitmap_offset, &dev->cow.bitmap_len, 
4323                                 &dev->cow.data_offset, create_ptr);
4324  
4325         if((dev->fd == -ENOENT) && create_cow){
4326 -               n = dev - ubd_dev;
4327                 dev->fd = create_cow_file(dev->file, dev->cow.file, 
4328 -                                         dev->openflags, 1 << 9,
4329 +                                         dev->openflags, 1 << 9, PAGE_SIZE,
4330                                           &dev->cow.bitmap_offset, 
4331                                           &dev->cow.bitmap_len,
4332                                           &dev->cow.data_offset);
4333 @@ -455,13 +524,17 @@
4334         if(dev->cow.file != NULL){
4335                 err = -ENOMEM;
4336                 dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len);
4337 -               if(dev->cow.bitmap == NULL) goto error;
4338 +               if(dev->cow.bitmap == NULL){
4339 +                       printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
4340 +                       goto error;
4341 +               }
4342                 flush_tlb_kernel_vm();
4343  
4344                 err = read_cow_bitmap(dev->fd, dev->cow.bitmap, 
4345                                       dev->cow.bitmap_offset, 
4346                                       dev->cow.bitmap_len);
4347 -               if(err) goto error;
4348 +               if(err < 0)
4349 +                       goto error;
4350  
4351                 flags = dev->openflags;
4352                 flags.w = 0;
4353 @@ -481,17 +554,31 @@
4354                         
4355  {
4356         struct gendisk *disk;
4357 +       char from[sizeof("ubd/nnnnn\0")], to[sizeof("discnnnnn/disc\0")];
4358 +       int err;
4359  
4360         disk = alloc_disk(1 << UBD_SHIFT);
4361 -       if (!disk)
4362 -               return -ENOMEM;
4363 +       if(disk == NULL)
4364 +               return(-ENOMEM);
4365  
4366         disk->major = major;
4367         disk->first_minor = unit << UBD_SHIFT;
4368         disk->fops = &ubd_blops;
4369         set_capacity(disk, size / 512);
4370 -       sprintf(disk->disk_name, "ubd");
4371 -       sprintf(disk->devfs_name, "ubd/disc%d", unit);
4372 +       if(major == MAJOR_NR){
4373 +               sprintf(disk->disk_name, "ubd%c", 'a' + unit);
4374 +               sprintf(disk->devfs_name, "ubd/disc%d", unit);
4375 +               sprintf(from, "ubd/%d", unit);
4376 +               sprintf(to, "disc%d/disc", unit);
4377 +               err = devfs_mk_symlink(from, to);
4378 +               if(err)
4379 +                       printk("ubd_new_disk failed to make link from %s to "
4380 +                              "%s, error = %d\n", from, to, err);
4381 +       }
4382 +       else {
4383 +               sprintf(disk->disk_name, "ubd_fake%d", unit);
4384 +               sprintf(disk->devfs_name, "ubd_fake/disc%d", unit);
4385 +       }
4386  
4387         disk->private_data = &ubd_dev[unit];
4388         disk->queue = ubd_queue;
4389 @@ -506,24 +593,21 @@
4390         struct ubd *dev = &ubd_dev[n];
4391         int err;
4392  
4393 -       if(dev->is_dir)
4394 -               return(-EISDIR);
4395 -
4396 -       if (!dev->file)
4397 +       if(dev->file == NULL)
4398                 return(-ENODEV);
4399  
4400         if (ubd_open_dev(dev))
4401                 return(-ENODEV);
4402  
4403         err = ubd_file_size(dev, &dev->size);
4404 -       if(err)
4405 +       if(err < 0)
4406                 return(err);
4407  
4408         err = ubd_new_disk(MAJOR_NR, dev->size, n, &ubd_gendisk[n]);
4409         if(err) 
4410                 return(err);
4411   
4412 -       if(fake_major)
4413 +       if(fake_major != MAJOR_NR)
4414                 ubd_new_disk(fake_major, dev->size, n, 
4415                              &fake_gendisk[n]);
4416  
4417 @@ -561,42 +645,42 @@
4418         return(err);
4419  }
4420  
4421 -static int ubd_get_config(char *dev, char *str, int size, char **error_out)
4422 +static int ubd_get_config(char *name, char *str, int size, char **error_out)
4423  {
4424 -       struct ubd *ubd;
4425 +       struct ubd *dev;
4426         char *end;
4427 -       int major, n = 0;
4428 +       int n, len = 0;
4429  
4430 -       major = simple_strtoul(dev, &end, 0);
4431 -       if((*end != '\0') || (end == dev)){
4432 -               *error_out = "ubd_get_config : didn't parse major number";
4433 +       n = simple_strtoul(name, &end, 0);
4434 +       if((*end != '\0') || (end == name)){
4435 +               *error_out = "ubd_get_config : didn't parse device number";
4436                 return(-1);
4437         }
4438  
4439 -       if((major >= MAX_DEV) || (major < 0)){
4440 -               *error_out = "ubd_get_config : major number out of range";
4441 +       if((n >= MAX_DEV) || (n < 0)){
4442 +               *error_out = "ubd_get_config : device number out of range";
4443                 return(-1);
4444         }
4445  
4446 -       ubd = &ubd_dev[major];
4447 +       dev = &ubd_dev[n];
4448         spin_lock(&ubd_lock);
4449  
4450 -       if(ubd->file == NULL){
4451 -               CONFIG_CHUNK(str, size, n, "", 1);
4452 +       if(dev->file == NULL){
4453 +               CONFIG_CHUNK(str, size, len, "", 1);
4454                 goto out;
4455         }
4456  
4457 -       CONFIG_CHUNK(str, size, n, ubd->file, 0);
4458 +       CONFIG_CHUNK(str, size, len, dev->file, 0);
4459  
4460 -       if(ubd->cow.file != NULL){
4461 -               CONFIG_CHUNK(str, size, n, ",", 0);
4462 -               CONFIG_CHUNK(str, size, n, ubd->cow.file, 1);
4463 +       if(dev->cow.file != NULL){
4464 +               CONFIG_CHUNK(str, size, len, ",", 0);
4465 +               CONFIG_CHUNK(str, size, len, dev->cow.file, 1);
4466         }
4467 -       else CONFIG_CHUNK(str, size, n, "", 1);
4468 +       else CONFIG_CHUNK(str, size, len, "", 1);
4469  
4470   out:
4471         spin_unlock(&ubd_lock);
4472 -       return(n);
4473 +       return(len);
4474  }
4475  
4476  static int ubd_remove(char *str)
4477 @@ -604,11 +688,9 @@
4478         struct ubd *dev;
4479         int n, err = -ENODEV;
4480  
4481 -       if(!isdigit(*str))
4482 -               return(err);    /* it should be a number 0-7/a-h */
4483 +       n = parse_unit(&str);
4484  
4485 -       n = *str - '0';
4486 -       if(n >= MAX_DEV) 
4487 +       if((n < 0) || (n >= MAX_DEV))
4488                 return(err);
4489  
4490         dev = &ubd_dev[n];
4491 @@ -669,7 +751,7 @@
4492                 
4493         elevator_init(ubd_queue, &elevator_noop);
4494  
4495 -       if (fake_major != 0) {
4496 +       if (fake_major != MAJOR_NR) {
4497                 char name[sizeof("ubd_nnn\0")];
4498  
4499                 snprintf(name, sizeof(name), "ubd_%d", fake_major);
4500 @@ -696,6 +778,7 @@
4501         io_pid = start_io_thread(stack + PAGE_SIZE - sizeof(void *), 
4502                                  &thread_fd);
4503         if(io_pid < 0){
4504 +               io_pid = -1;
4505                 printk(KERN_ERR 
4506                        "ubd : Failed to start I/O thread (errno = %d) - "
4507                        "falling back to synchronous I/O\n", -io_pid);
4508 @@ -703,8 +786,8 @@
4509         }
4510         err = um_request_irq(UBD_IRQ, thread_fd, IRQ_READ, ubd_intr, 
4511                              SA_INTERRUPT, "ubd", ubd_dev);
4512 -       if(err != 0) printk(KERN_ERR 
4513 -                           "um_request_irq failed - errno = %d\n", -err);
4514 +       if(err != 0) 
4515 +               printk(KERN_ERR "um_request_irq failed - errno = %d\n", -err);
4516         return(err);
4517  }
4518  
4519 @@ -714,15 +797,9 @@
4520  {
4521         struct gendisk *disk = inode->i_bdev->bd_disk;
4522         struct ubd *dev = disk->private_data;
4523 -       int err = -EISDIR;
4524 -
4525 -       if(dev->is_dir == 1)
4526 -               goto out;
4527 +       int err = 0;
4528  
4529 -       err = 0;
4530         if(dev->count == 0){
4531 -               dev->openflags = dev->boot_openflags;
4532 -
4533                 err = ubd_open_dev(dev);
4534                 if(err){
4535                         printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
4536 @@ -749,62 +826,156 @@
4537         return(0);
4538  }
4539  
4540 -void cowify_req(struct io_thread_req *req, struct ubd *dev)
4541 +static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask, 
4542 +                         __u64 *cow_offset, unsigned long *bitmap, 
4543 +                         __u64 bitmap_offset, unsigned long *bitmap_words,
4544 +                         __u64 bitmap_len)
4545 +{
4546 +       __u64 sector = io_offset >> 9;
4547 +       int i, update_bitmap = 0;
4548 +
4549 +       for(i = 0; i < length >> 9; i++){
4550 +               if(cow_mask != NULL)
4551 +                       ubd_set_bit(i, (unsigned char *) cow_mask);
4552 +               if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
4553 +                       continue;
4554 +
4555 +               update_bitmap = 1;
4556 +               ubd_set_bit(sector + i, (unsigned char *) bitmap);
4557 +       }
4558 +
4559 +       if(!update_bitmap)
4560 +               return;
4561 +
4562 +       *cow_offset = sector / (sizeof(unsigned long) * 8);
4563 +
4564 +       /* This takes care of the case where we're exactly at the end of the
4565 +        * device, and *cow_offset + 1 is off the end.  So, just back it up
4566 +        * by one word.  Thanks to Lynn Kerby for the fix and James McMechan
4567 +        * for the original diagnosis.
4568 +        */
4569 +       if(*cow_offset == ((bitmap_len + sizeof(unsigned long) - 1) / 
4570 +                          sizeof(unsigned long) - 1))
4571 +               (*cow_offset)--;
4572 +
4573 +       bitmap_words[0] = bitmap[*cow_offset];
4574 +       bitmap_words[1] = bitmap[*cow_offset + 1];
4575 +
4576 +       *cow_offset *= sizeof(unsigned long);
4577 +       *cow_offset += bitmap_offset;
4578 +}
4579 +
4580 +static void cowify_req(struct io_thread_req *req, unsigned long *bitmap, 
4581 +                      __u64 bitmap_offset, __u64 bitmap_len)
4582  {
4583 -        int i, update_bitmap, sector = req->offset >> 9;
4584 +       __u64 sector = req->offset >> 9;
4585 +       int i;
4586  
4587         if(req->length > (sizeof(req->sector_mask) * 8) << 9)
4588                 panic("Operation too long");
4589 +
4590         if(req->op == UBD_READ) {
4591                 for(i = 0; i < req->length >> 9; i++){
4592 -                       if(ubd_test_bit(sector + i, (unsigned char *) 
4593 -                                       dev->cow.bitmap)){
4594 +                       if(ubd_test_bit(sector + i, (unsigned char *) bitmap))
4595                                 ubd_set_bit(i, (unsigned char *) 
4596                                             &req->sector_mask);
4597 -                       }
4598                  }
4599 -        } 
4600 -        else {
4601 -               update_bitmap = 0;
4602 -               for(i = 0; i < req->length >> 9; i++){
4603 -                       ubd_set_bit(i, (unsigned char *) 
4604 -                                   &req->sector_mask);
4605 -                       if(!ubd_test_bit(sector + i, (unsigned char *) 
4606 -                                        dev->cow.bitmap))
4607 -                               update_bitmap = 1;
4608 -                       ubd_set_bit(sector + i, (unsigned char *) 
4609 -                                   dev->cow.bitmap);
4610 -               }
4611 -               if(update_bitmap){
4612 -                       req->cow_offset = sector / (sizeof(unsigned long) * 8);
4613 -                       req->bitmap_words[0] = 
4614 -                               dev->cow.bitmap[req->cow_offset];
4615 -                       req->bitmap_words[1] = 
4616 -                               dev->cow.bitmap[req->cow_offset + 1];
4617 -                       req->cow_offset *= sizeof(unsigned long);
4618 -                       req->cow_offset += dev->cow.bitmap_offset;
4619 +       }
4620 +       else cowify_bitmap(req->offset, req->length, &req->sector_mask,
4621 +                          &req->cow_offset, bitmap, bitmap_offset, 
4622 +                          req->bitmap_words, bitmap_len);
4623 +}
4624 +
4625 +static int mmap_fd(struct request *req, struct ubd *dev, __u64 offset)
4626 +{
4627 +       __u64 sector;
4628 +       unsigned char *bitmap;
4629 +       int bit, i;
4630 +
4631 +       /* mmap must have been requested on the command line */
4632 +       if(!ubd_do_mmap)
4633 +               return(-1);
4634 +
4635 +       /* The buffer must be page aligned */
4636 +       if(((unsigned long) req->buffer % UBD_MMAP_BLOCK_SIZE) != 0)
4637 +               return(-1);
4638 +
4639 +       /* The request must be a page long */
4640 +       if((req->current_nr_sectors << 9) != PAGE_SIZE)
4641 +               return(-1);
4642 +
4643 +       if(dev->cow.file == NULL)
4644 +               return(dev->fd);
4645 +
4646 +       sector = offset >> 9;
4647 +       bitmap = (unsigned char *) dev->cow.bitmap;
4648 +       bit = ubd_test_bit(sector, bitmap);
4649 +
4650 +       for(i = 1; i < req->current_nr_sectors; i++){
4651 +               if(ubd_test_bit(sector + i, bitmap) != bit)
4652 +                       return(-1);
4653 +       }
4654 +
4655 +       if(bit || (rq_data_dir(req) == WRITE))
4656 +               offset += dev->cow.data_offset;
4657 +
4658 +       /* The data on disk must be page aligned */
4659 +       if((offset % UBD_MMAP_BLOCK_SIZE) != 0)
4660 +               return(-1);
4661 +
4662 +       return(bit ? dev->fd : dev->cow.fd);
4663 +}
4664 +
4665 +static int prepare_mmap_request(struct ubd *dev, int fd, __u64 offset, 
4666 +                               struct request *req, 
4667 +                               struct io_thread_req *io_req)
4668 +{
4669 +       int err;
4670 +
4671 +       if(rq_data_dir(req) == WRITE){
4672 +               /* Writes are almost no-ops since the new data is already in the
4673 +                * host page cache
4674 +                */
4675 +               dev->map_writes++;
4676 +               if(dev->cow.file != NULL)
4677 +                       cowify_bitmap(io_req->offset, io_req->length, 
4678 +                                     &io_req->sector_mask, &io_req->cow_offset,
4679 +                                     dev->cow.bitmap, dev->cow.bitmap_offset,
4680 +                                     io_req->bitmap_words, 
4681 +                                     dev->cow.bitmap_len);
4682 +       }
4683 +       else {
4684 +               int w;
4685 +
4686 +               if((dev->cow.file != NULL) && (fd == dev->cow.fd))
4687 +                       w = 0;
4688 +               else w = dev->openflags.w;
4689 +
4690 +               if((dev->cow.file != NULL) && (fd == dev->fd))
4691 +                       offset += dev->cow.data_offset;
4692 +
4693 +               err = physmem_subst_mapping(req->buffer, fd, offset, w);
4694 +               if(err){
4695 +                       printk("physmem_subst_mapping failed, err = %d\n", 
4696 +                              -err);
4697 +                       return(1);
4698                 }
4699 +               dev->map_reads++;
4700         }
4701 +       io_req->op = UBD_MMAP;
4702 +       io_req->buffer = req->buffer;
4703 +       return(0);
4704  }
4705  
4706  static int prepare_request(struct request *req, struct io_thread_req *io_req)
4707  {
4708         struct gendisk *disk = req->rq_disk;
4709         struct ubd *dev = disk->private_data;
4710 -       __u64 block;
4711 -       int nsect;
4712 +       __u64 offset;
4713 +       int len, fd;
4714  
4715         if(req->rq_status == RQ_INACTIVE) return(1);
4716  
4717 -       if(dev->is_dir){
4718 -               strcpy(req->buffer, "HOSTFS:");
4719 -               strcat(req->buffer, dev->file);
4720 -               spin_lock(&ubd_io_lock);
4721 -               end_request(req, 1);
4722 -               spin_unlock(&ubd_io_lock);
4723 -               return(1);
4724 -       }
4725 -
4726         if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
4727                 printk("Write attempted on readonly ubd device %s\n", 
4728                        disk->disk_name);
4729 @@ -814,23 +985,49 @@
4730                 return(1);
4731         }
4732  
4733 -        block = req->sector;
4734 -        nsect = req->current_nr_sectors;
4735 +       offset = ((__u64) req->sector) << 9;
4736 +       len = req->current_nr_sectors << 9;
4737  
4738 -       io_req->op = rq_data_dir(req) == READ ? UBD_READ : UBD_WRITE;
4739         io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd;
4740         io_req->fds[1] = dev->fd;
4741 +       io_req->map_fd = -1;
4742 +       io_req->cow_offset = -1;
4743 +       io_req->offset = offset;
4744 +       io_req->length = len;
4745 +       io_req->error = 0;
4746 +       io_req->sector_mask = 0;
4747 +
4748 +       fd = mmap_fd(req, dev, io_req->offset);
4749 +       if(fd > 0){
4750 +               /* If mmapping is otherwise OK, but the first access to the 
4751 +                * page is a write, then it's not mapped in yet.  So we have 
4752 +                * to write the data to disk first, then we can map the disk
4753 +                * page in and continue normally from there.
4754 +                */
4755 +               if((rq_data_dir(req) == WRITE) && !is_remapped(req->buffer)){
4756 +                       io_req->map_fd = dev->fd;
4757 +                       io_req->map_offset = io_req->offset + 
4758 +                               dev->cow.data_offset;
4759 +                       dev->write_maps++;
4760 +               }
4761 +               else return(prepare_mmap_request(dev, fd, io_req->offset, req, 
4762 +                                                io_req));
4763 +       }
4764 +
4765 +       if(rq_data_dir(req) == READ)
4766 +               dev->nomap_reads++;
4767 +       else dev->nomap_writes++;
4768 +
4769 +       io_req->op = (rq_data_dir(req) == READ) ? UBD_READ : UBD_WRITE;
4770         io_req->offsets[0] = 0;
4771         io_req->offsets[1] = dev->cow.data_offset;
4772 -       io_req->offset = ((__u64) block) << 9;
4773 -       io_req->length = nsect << 9;
4774         io_req->buffer = req->buffer;
4775         io_req->sectorsize = 1 << 9;
4776 -       io_req->sector_mask = 0;
4777 -       io_req->cow_offset = -1;
4778 -       io_req->error = 0;
4779  
4780 -        if(dev->cow.file != NULL) cowify_req(io_req, dev);
4781 +       if(dev->cow.file != NULL) 
4782 +               cowify_req(io_req, dev->cow.bitmap, dev->cow.bitmap_offset,
4783 +                          dev->cow.bitmap_len);
4784 +
4785         return(0);
4786  }
4787  
4788 @@ -841,7 +1038,7 @@
4789         int err, n;
4790  
4791         if(thread_fd == -1){
4792 -               while(!list_empty(&q->queue_head)){
4793 +               while(!elv_queue_empty(q)){
4794                         req = elv_next_request(q);
4795                         err = prepare_request(req, &io_req);
4796                         if(!err){
4797 @@ -851,7 +1048,8 @@
4798                 }
4799         }
4800         else {
4801 -               if(do_ubd || list_empty(&q->queue_head)) return;
4802 +               if(do_ubd || elv_queue_empty(q))
4803 +                       return;
4804                 req = elv_next_request(q);
4805                 err = prepare_request(req, &io_req);
4806                 if(!err){
4807 @@ -885,7 +1083,7 @@
4808                 g.heads = 128;
4809                 g.sectors = 32;
4810                 g.cylinders = dev->size / (128 * 32 * 512);
4811 -               g.start = 2;
4812 +               g.start = get_start_sect(inode->i_bdev);
4813                 return(copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0);
4814  
4815         case HDIO_SET_UNMASKINTR:
4816 @@ -935,6 +1133,142 @@
4817         return(-EINVAL);
4818  }
4819  
4820 +static int ubd_check_remapped(int fd, unsigned long address, int is_write,
4821 +                             __u64 offset)
4822 +{
4823 +       __u64 bitmap_offset;
4824 +       unsigned long new_bitmap[2];
4825 +       int i, err, n;
4826 +
4827 +       /* If it's not a write access, we can't do anything about it */
4828 +       if(!is_write)
4829 +               return(0);
4830 +
4831 +       /* We have a write */
4832 +       for(i = 0; i < sizeof(ubd_dev) / sizeof(ubd_dev[0]); i++){
4833 +               struct ubd *dev = &ubd_dev[i];
4834 +
4835 +               if((dev->fd != fd) && (dev->cow.fd != fd))
4836 +                       continue;
4837 +
4838 +               /* It's a write to a ubd device */
4839 +
4840 +               if(!dev->openflags.w){
4841 +                       /* It's a write access on a read-only device - probably
4842 +                        * shouldn't happen.  If the kernel is trying to change
4843 +                        * something with no intention of writing it back out,
4844 +                        * then this message will clue us in that this needs
4845 +                        * fixing
4846 +                        */
4847 +                       printk("Write access to mapped page from readonly ubd "
4848 +                              "device %d\n", i);
4849 +                       return(0);
4850 +               }
4851 +
4852 +               /* It's a write to a writeable ubd device - it must be COWed
4853 +                * because, otherwise, the page would have been mapped in 
4854 +                * writeable
4855 +                */
4856 +
4857 +               if(!dev->cow.file)
4858 +                       panic("Write fault on writeable non-COW ubd device %d",
4859 +                             i);
4860 +
4861 +               /* It should also be an access to the backing file since the 
4862 +                * COW pages should be mapped in read-write
4863 +                */
4864 +
4865 +               if(fd == dev->fd)
4866 +                       panic("Write fault on a backing page of ubd "
4867 +                             "device %d\n", i);
4868 +
4869 +               /* So, we do the write, copying the backing data to the COW 
4870 +                * file... 
4871 +                */
4872 +
4873 +               err = os_seek_file(dev->fd, offset + dev->cow.data_offset);
4874 +               if(err < 0)
4875 +                       panic("Couldn't seek to %lld in COW file of ubd "
4876 +                             "device %d, err = %d", 
4877 +                             offset + dev->cow.data_offset, i, -err);
4878 +
4879 +               n = os_write_file(dev->fd, (void *) address, PAGE_SIZE);
4880 +               if(n != PAGE_SIZE)
4881 +                       panic("Couldn't copy data to COW file of ubd "
4882 +                             "device %d, err = %d", i, -n);
4883 +
4884 +               /* ... updating the COW bitmap... */
4885 +
4886 +               cowify_bitmap(offset, PAGE_SIZE, NULL, &bitmap_offset, 
4887 +                             dev->cow.bitmap, dev->cow.bitmap_offset, 
4888 +                             new_bitmap, dev->cow.bitmap_len);
4889 +
4890 +               err = os_seek_file(dev->fd, bitmap_offset);
4891 +               if(err < 0)
4892 +                       panic("Couldn't seek to %lld in COW file of ubd "
4893 +                             "device %d, err = %d", bitmap_offset, i, -err);
4894 +
4895 +               n = os_write_file(dev->fd, new_bitmap, sizeof(new_bitmap));
4896 +               if(n != sizeof(new_bitmap))
4897 +                       panic("Couldn't update bitmap  of ubd device %d, "
4898 +                             "err = %d", i, -n);
4899 +               
4900 +               /* Maybe we can map the COW page in, and maybe we can't.  If
4901 +                * it is a pre-V3 COW file, we can't, since the alignment will 
4902 +                * be wrong.  If it is a V3 or later COW file which has been 
4903 +                * moved to a system with a larger page size, then maybe we 
4904 +                * can't, depending on the exact location of the page.
4905 +                */
4906 +
4907 +               offset += dev->cow.data_offset;
4908 +
4909 +               /* Remove the remapping, putting the original anonymous page
4910 +                * back.  If the COW file can be mapped in, that is done.
4911 +                * Otherwise, the COW page is read in.
4912 +                */
4913 +
4914 +               if(!physmem_remove_mapping((void *) address))
4915 +                       panic("Address 0x%lx not remapped by ubd device %d", 
4916 +                             address, i);
4917 +               if((offset % UBD_MMAP_BLOCK_SIZE) == 0)
4918 +                       physmem_subst_mapping((void *) address, dev->fd, 
4919 +                                             offset, 1);
4920 +               else {
4921 +                       err = os_seek_file(dev->fd, offset);
4922 +                       if(err < 0)
4923 +                               panic("Couldn't seek to %lld in COW file of "
4924 +                                     "ubd device %d, err = %d", offset, i, 
4925 +                                     -err);
4926 +
4927 +                       n = os_read_file(dev->fd, (void *) address, PAGE_SIZE);
4928 +                       if(n != PAGE_SIZE)
4929 +                               panic("Failed to read page from offset %llx of "
4930 +                                     "COW file of ubd device %d, err = %d",
4931 +                                     offset, i, -n);
4932 +               }
4933 +
4934 +               return(1);
4935 +       }
4936 +
4937 +       /* It's not a write on a ubd device */
4938 +       return(0);
4939 +}
4940 +
4941 +static struct remapper ubd_remapper = {
4942 +       .list   = LIST_HEAD_INIT(ubd_remapper.list),
4943 +       .proc   = ubd_check_remapped,
4944 +};
4945 +
4946 +static int ubd_remapper_setup(void)
4947 +{
4948 +       if(ubd_do_mmap)
4949 +               register_remapper(&ubd_remapper);
4950 +
4951 +       return(0);
4952 +}
4953 +
4954 +__initcall(ubd_remapper_setup);
4955 +
4956  /*
4957   * Overrides for Emacs so that we follow Linus's tabbing style.
4958   * Emacs will notice this stuff at the end of the file and automatically
4959 diff -Naur a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c
4960 --- a/arch/um/drivers/ubd_user.c        2004-02-11 12:14:32.000000000 -0500
4961 +++ b/arch/um/drivers/ubd_user.c        2004-02-11 12:26:14.000000000 -0500
4962 @@ -11,11 +11,8 @@
4963  #include <signal.h>
4964  #include <string.h>
4965  #include <netinet/in.h>
4966 -#include <sys/stat.h>
4967  #include <sys/time.h>
4968 -#include <sys/fcntl.h>
4969  #include <sys/socket.h>
4970 -#include <string.h>
4971  #include <sys/mman.h>
4972  #include <sys/param.h>
4973  #include "asm/types.h"
4974 @@ -24,146 +21,30 @@
4975  #include "user.h"
4976  #include "ubd_user.h"
4977  #include "os.h"
4978 +#include "cow.h"
4979  
4980  #include <endian.h>
4981  #include <byteswap.h>
4982 -#if __BYTE_ORDER == __BIG_ENDIAN
4983 -# define ntohll(x) (x)
4984 -# define htonll(x) (x)
4985 -#elif __BYTE_ORDER == __LITTLE_ENDIAN
4986 -# define ntohll(x)  bswap_64(x)
4987 -# define htonll(x)  bswap_64(x)
4988 -#else
4989 -#error "__BYTE_ORDER not defined"
4990 -#endif
4991 -
4992 -#define PATH_LEN_V1 256
4993 -
4994 -struct cow_header_v1 {
4995 -       int magic;
4996 -       int version;
4997 -       char backing_file[PATH_LEN_V1];
4998 -       time_t mtime;
4999 -       __u64 size;
5000 -       int sectorsize;
5001 -};
5002 -
5003 -#define PATH_LEN_V2 MAXPATHLEN
5004 -
5005 -struct cow_header_v2 {
5006 -       unsigned long magic;
5007 -       unsigned long version;
5008 -       char backing_file[PATH_LEN_V2];
5009 -       time_t mtime;
5010 -       __u64 size;
5011 -       int sectorsize;
5012 -};
5013 -
5014 -union cow_header {
5015 -       struct cow_header_v1 v1;
5016 -       struct cow_header_v2 v2;
5017 -};
5018 -
5019 -#define COW_MAGIC 0x4f4f4f4d  /* MOOO */
5020 -#define COW_VERSION 2
5021 -
5022 -static void sizes(__u64 size, int sectorsize, int bitmap_offset, 
5023 -                 unsigned long *bitmap_len_out, int *data_offset_out)
5024 -{
5025 -       *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
5026 -
5027 -       *data_offset_out = bitmap_offset + *bitmap_len_out;
5028 -       *data_offset_out = (*data_offset_out + sectorsize - 1) / sectorsize;
5029 -       *data_offset_out *= sectorsize;
5030 -}
5031 -
5032 -static int read_cow_header(int fd, int *magic_out, char **backing_file_out, 
5033 -                          time_t *mtime_out, __u64 *size_out, 
5034 -                          int *sectorsize_out, int *bitmap_offset_out)
5035 -{
5036 -       union cow_header *header;
5037 -       char *file;
5038 -       int err, n;
5039 -       unsigned long version, magic;
5040 -
5041 -       header = um_kmalloc(sizeof(*header));
5042 -       if(header == NULL){
5043 -               printk("read_cow_header - Failed to allocate header\n");
5044 -               return(-ENOMEM);
5045 -       }
5046 -       err = -EINVAL;
5047 -       n = read(fd, header, sizeof(*header));
5048 -       if(n < offsetof(typeof(header->v1), backing_file)){
5049 -               printk("read_cow_header - short header\n");
5050 -               goto out;
5051 -       }
5052 -
5053 -       magic = header->v1.magic;
5054 -       if(magic == COW_MAGIC) {
5055 -               version = header->v1.version;
5056 -       }
5057 -       else if(magic == ntohl(COW_MAGIC)){
5058 -               version = ntohl(header->v1.version);
5059 -       }
5060 -       else goto out;
5061 -
5062 -       *magic_out = COW_MAGIC;
5063 -
5064 -       if(version == 1){
5065 -               if(n < sizeof(header->v1)){
5066 -                       printk("read_cow_header - failed to read V1 header\n");
5067 -                       goto out;
5068 -               }
5069 -               *mtime_out = header->v1.mtime;
5070 -               *size_out = header->v1.size;
5071 -               *sectorsize_out = header->v1.sectorsize;
5072 -               *bitmap_offset_out = sizeof(header->v1);
5073 -               file = header->v1.backing_file;
5074 -       }
5075 -       else if(version == 2){
5076 -               if(n < sizeof(header->v2)){
5077 -                       printk("read_cow_header - failed to read V2 header\n");
5078 -                       goto out;
5079 -               }
5080 -               *mtime_out = ntohl(header->v2.mtime);
5081 -               *size_out = ntohll(header->v2.size);
5082 -               *sectorsize_out = ntohl(header->v2.sectorsize);
5083 -               *bitmap_offset_out = sizeof(header->v2);
5084 -               file = header->v2.backing_file;
5085 -       }
5086 -       else {
5087 -               printk("read_cow_header - invalid COW version\n");
5088 -               goto out;
5089 -       }
5090 -       err = -ENOMEM;
5091 -       *backing_file_out = uml_strdup(file);
5092 -       if(*backing_file_out == NULL){
5093 -               printk("read_cow_header - failed to allocate backing file\n");
5094 -               goto out;
5095 -       }
5096 -       err = 0;
5097 - out:
5098 -       kfree(header);
5099 -       return(err);
5100 -}
5101  
5102  static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
5103  {
5104 -       struct stat buf1, buf2;
5105 +       struct uml_stat buf1, buf2;
5106 +       int err;
5107  
5108         if(from_cmdline == NULL) return(1);
5109         if(!strcmp(from_cmdline, from_cow)) return(1);
5110  
5111 -       if(stat(from_cmdline, &buf1) < 0){
5112 -               printk("Couldn't stat '%s', errno = %d\n", from_cmdline, 
5113 -                      errno);
5114 +       err = os_stat_file(from_cmdline, &buf1);
5115 +       if(err < 0){
5116 +               printk("Couldn't stat '%s', err = %d\n", from_cmdline, -err);
5117                 return(1);
5118         }
5119 -       if(stat(from_cow, &buf2) < 0){
5120 -               printk("Couldn't stat '%s', errno = %d\n", from_cow, errno);
5121 +       err = os_stat_file(from_cow, &buf2);
5122 +       if(err < 0){
5123 +               printk("Couldn't stat '%s', err = %d\n", from_cow, -err);
5124                 return(1);
5125         }
5126 -       if((buf1.st_dev == buf2.st_dev) && (buf1.st_ino == buf2.st_ino))
5127 +       if((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino))
5128                 return(1);
5129  
5130         printk("Backing file mismatch - \"%s\" requested,\n"
5131 @@ -174,20 +55,21 @@
5132  
5133  static int backing_file_mismatch(char *file, __u64 size, time_t mtime)
5134  {
5135 -       struct stat64 buf;
5136 +       unsigned long modtime;
5137         long long actual;
5138         int err;
5139  
5140 -       if(stat64(file, &buf) < 0){
5141 -               printk("Failed to stat backing file \"%s\", errno = %d\n",
5142 -                      file, errno);
5143 -               return(-errno);
5144 +       err = os_file_modtime(file, &modtime);
5145 +       if(err < 0){
5146 +               printk("Failed to get modification time of backing file "
5147 +                      "\"%s\", err = %d\n", file, -err);
5148 +               return(err);
5149         }
5150  
5151         err = os_file_size(file, &actual);
5152 -       if(err){
5153 +       if(err < 0){
5154                 printk("Failed to get size of backing file \"%s\", "
5155 -                      "errno = %d\n", file, -err);
5156 +                      "err = %d\n", file, -err);
5157                 return(err);
5158         }
5159  
5160 @@ -196,9 +78,9 @@
5161                        "file\n", size, actual);
5162                 return(-EINVAL);
5163         }
5164 -       if(buf.st_mtime != mtime){
5165 +       if(modtime != mtime){
5166                 printk("mtime mismatch (%ld vs %ld) of COW header vs backing "
5167 -                      "file\n", mtime, buf.st_mtime);
5168 +                      "file\n", mtime, modtime);
5169                 return(-EINVAL);
5170         }
5171         return(0);
5172 @@ -209,124 +91,16 @@
5173         int err;
5174  
5175         err = os_seek_file(fd, offset);
5176 -       if(err != 0) return(-errno);
5177 -       err = read(fd, buf, len);
5178 -       if(err < 0) return(-errno);
5179 -       return(0);
5180 -}
5181 +       if(err < 0) 
5182 +               return(err);
5183  
5184 -static int absolutize(char *to, int size, char *from)
5185 -{
5186 -       char save_cwd[256], *slash;
5187 -       int remaining;
5188 +       err = os_read_file(fd, buf, len);
5189 +       if(err < 0) 
5190 +               return(err);
5191  
5192 -       if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
5193 -               printk("absolutize : unable to get cwd - errno = %d\n", errno);
5194 -               return(-1);
5195 -       }
5196 -       slash = strrchr(from, '/');
5197 -       if(slash != NULL){
5198 -               *slash = '\0';
5199 -               if(chdir(from)){
5200 -                       *slash = '/';
5201 -                       printk("absolutize : Can't cd to '%s' - errno = %d\n",
5202 -                              from, errno);
5203 -                       return(-1);
5204 -               }
5205 -               *slash = '/';
5206 -               if(getcwd(to, size) == NULL){
5207 -                       printk("absolutize : unable to get cwd of '%s' - "
5208 -                              "errno = %d\n", from, errno);
5209 -                       return(-1);
5210 -               }
5211 -               remaining = size - strlen(to);
5212 -               if(strlen(slash) + 1 > remaining){
5213 -                       printk("absolutize : unable to fit '%s' into %d "
5214 -                              "chars\n", from, size);
5215 -                       return(-1);
5216 -               }
5217 -               strcat(to, slash);
5218 -       }
5219 -       else {
5220 -               if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
5221 -                       printk("absolutize : unable to fit '%s' into %d "
5222 -                              "chars\n", from, size);
5223 -                       return(-1);
5224 -               }
5225 -               strcpy(to, save_cwd);
5226 -               strcat(to, "/");
5227 -               strcat(to, from);
5228 -       }
5229 -       chdir(save_cwd);
5230         return(0);
5231  }
5232  
5233 -static int write_cow_header(char *cow_file, int fd, char *backing_file, 
5234 -                           int sectorsize, long long *size)
5235 -{
5236 -        struct cow_header_v2 *header;
5237 -       struct stat64 buf;
5238 -       int err;
5239 -
5240 -       err = os_seek_file(fd, 0);
5241 -       if(err != 0){
5242 -               printk("write_cow_header - lseek failed, errno = %d\n", errno);
5243 -               return(-errno);
5244 -       }
5245 -
5246 -       err = -ENOMEM;
5247 -       header = um_kmalloc(sizeof(*header));
5248 -       if(header == NULL){
5249 -               printk("Failed to allocate COW V2 header\n");
5250 -               goto out;
5251 -       }
5252 -       header->magic = htonl(COW_MAGIC);
5253 -       header->version = htonl(COW_VERSION);
5254 -
5255 -       err = -EINVAL;
5256 -       if(strlen(backing_file) > sizeof(header->backing_file) - 1){
5257 -               printk("Backing file name \"%s\" is too long - names are "
5258 -                      "limited to %d characters\n", backing_file, 
5259 -                      sizeof(header->backing_file) - 1);
5260 -               goto out_free;
5261 -       }
5262 -
5263 -       if(absolutize(header->backing_file, sizeof(header->backing_file), 
5264 -                     backing_file))
5265 -               goto out_free;
5266 -
5267 -       err = stat64(header->backing_file, &buf);
5268 -       if(err < 0){
5269 -               printk("Stat of backing file '%s' failed, errno = %d\n",
5270 -                      header->backing_file, errno);
5271 -               err = -errno;
5272 -               goto out_free;
5273 -       }
5274 -
5275 -       err = os_file_size(header->backing_file, size);
5276 -       if(err){
5277 -               printk("Couldn't get size of backing file '%s', errno = %d\n",
5278 -                      header->backing_file, -*size);
5279 -               goto out_free;
5280 -       }
5281 -
5282 -       header->mtime = htonl(buf.st_mtime);
5283 -       header->size = htonll(*size);
5284 -       header->sectorsize = htonl(sectorsize);
5285 -
5286 -       err = write(fd, header, sizeof(*header));
5287 -       if(err != sizeof(*header)){
5288 -               printk("Write of header to new COW file '%s' failed, "
5289 -                      "errno = %d\n", cow_file, errno);
5290 -               goto out_free;
5291 -       }
5292 -       err = 0;
5293 - out_free:
5294 -       kfree(header);
5295 - out:
5296 -       return(err);
5297 -}
5298 -
5299  int open_ubd_file(char *file, struct openflags *openflags, 
5300                   char **backing_file_out, int *bitmap_offset_out, 
5301                   unsigned long *bitmap_len_out, int *data_offset_out, 
5302 @@ -334,26 +108,36 @@
5303  {
5304         time_t mtime;
5305         __u64 size;
5306 +       __u32 version, align;
5307         char *backing_file;
5308 -        int fd, err, sectorsize, magic, same, mode = 0644;
5309 +       int fd, err, sectorsize, same, mode = 0644;
5310  
5311 -        if((fd = os_open_file(file, *openflags, mode)) < 0){
5312 +       fd = os_open_file(file, *openflags, mode);
5313 +       if(fd < 0){
5314                 if((fd == -ENOENT) && (create_cow_out != NULL))
5315                         *create_cow_out = 1;
5316                  if(!openflags->w ||
5317                     ((errno != EROFS) && (errno != EACCES))) return(-errno);
5318                 openflags->w = 0;
5319 -                if((fd = os_open_file(file, *openflags, mode)) < 0) 
5320 +               fd = os_open_file(file, *openflags, mode); 
5321 +               if(fd < 0) 
5322                         return(fd);
5323          }
5324 +
5325 +       err = os_lock_file(fd, openflags->w);
5326 +       if(err < 0){
5327 +               printk("Failed to lock '%s', err = %d\n", file, -err);
5328 +               goto out_close;
5329 +       }
5330 +       
5331         if(backing_file_out == NULL) return(fd);
5332  
5333 -       err = read_cow_header(fd, &magic, &backing_file, &mtime, &size, 
5334 -                             &sectorsize, bitmap_offset_out);
5335 +       err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime,
5336 +                             &size, &sectorsize, &align, bitmap_offset_out);
5337         if(err && (*backing_file_out != NULL)){
5338                 printk("Failed to read COW header from COW file \"%s\", "
5339 -                      "errno = %d\n", file, err);
5340 -               goto error;
5341 +                      "errno = %d\n", file, -err);
5342 +               goto out_close;
5343         }
5344         if(err) return(fd);
5345  
5346 @@ -363,36 +147,33 @@
5347  
5348         if(!same && !backing_file_mismatch(*backing_file_out, size, mtime)){
5349                 printk("Switching backing file to '%s'\n", *backing_file_out);
5350 -               err = write_cow_header(file, fd, *backing_file_out, 
5351 -                                      sectorsize, &size);
5352 +               err = write_cow_header(file, fd, *backing_file_out,
5353 +                                      sectorsize, align, &size);
5354                 if(err){
5355 -                       printk("Switch failed, errno = %d\n", err);
5356 +                       printk("Switch failed, errno = %d\n", -err);
5357                         return(err);
5358                 }
5359         }
5360         else {
5361                 *backing_file_out = backing_file;
5362                 err = backing_file_mismatch(*backing_file_out, size, mtime);
5363 -               if(err) goto error;
5364 +               if(err) goto out_close;
5365         }
5366  
5367 -       sizes(size, sectorsize, *bitmap_offset_out, bitmap_len_out, 
5368 -             data_offset_out);
5369 +       cow_sizes(version, size, sectorsize, align, *bitmap_offset_out, 
5370 +                 bitmap_len_out, data_offset_out);
5371  
5372          return(fd);
5373 - error:
5374 -       close(fd);
5375 + out_close:
5376 +       os_close_file(fd);
5377         return(err);
5378  }
5379  
5380  int create_cow_file(char *cow_file, char *backing_file, struct openflags flags,
5381 -                   int sectorsize, int *bitmap_offset_out, 
5382 +                   int sectorsize, int alignment, int *bitmap_offset_out, 
5383                     unsigned long *bitmap_len_out, int *data_offset_out)
5384  {
5385 -       __u64 blocks;
5386 -       long zero;
5387 -       int err, fd, i;
5388 -       long long size;
5389 +       int err, fd;
5390  
5391         flags.c = 1;
5392         fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
5393 @@ -403,57 +184,49 @@
5394                 goto out;
5395         }
5396  
5397 -       err = write_cow_header(cow_file, fd, backing_file, sectorsize, &size);
5398 -       if(err) goto out_close;
5399 -
5400 -       blocks = (size + sectorsize - 1) / sectorsize;
5401 -       blocks = (blocks + sizeof(long) * 8 - 1) / (sizeof(long) * 8);
5402 -       zero = 0;
5403 -       for(i = 0; i < blocks; i++){
5404 -               err = write(fd, &zero, sizeof(zero));
5405 -               if(err != sizeof(zero)){
5406 -                       printk("Write of bitmap to new COW file '%s' failed, "
5407 -                              "errno = %d\n", cow_file, errno);
5408 -                       goto out_close;
5409 -               }
5410 -       }
5411 -
5412 -       sizes(size, sectorsize, sizeof(struct cow_header_v2), 
5413 -             bitmap_len_out, data_offset_out);
5414 -       *bitmap_offset_out = sizeof(struct cow_header_v2);
5415 -
5416 -       return(fd);
5417 -
5418 - out_close:
5419 -       close(fd);
5420 +       err = init_cow_file(fd, cow_file, backing_file, sectorsize, alignment,
5421 +                           bitmap_offset_out, bitmap_len_out, 
5422 +                           data_offset_out);
5423 +       if(!err)
5424 +               return(fd);
5425 +       os_close_file(fd);
5426   out:
5427         return(err);
5428  }
5429  
5430 +/* XXX Just trivial wrappers around os_read_file and os_write_file */
5431  int read_ubd_fs(int fd, void *buffer, int len)
5432  {
5433 -       int n;
5434 -
5435 -       n = read(fd, buffer, len);
5436 -       if(n < 0) return(-errno);
5437 -       else return(n);
5438 +       return(os_read_file(fd, buffer, len));
5439  }
5440  
5441  int write_ubd_fs(int fd, char *buffer, int len)
5442  {
5443 -       int n;
5444 -
5445 -       n = write(fd, buffer, len);
5446 -       if(n < 0) return(-errno);
5447 -       else return(n);
5448 +       return(os_write_file(fd, buffer, len));
5449  }
5450  
5451 -int ubd_is_dir(char *file)
5452 +static int update_bitmap(struct io_thread_req *req)
5453  {
5454 -       struct stat64 buf;
5455 +       int n;
5456 +
5457 +       if(req->cow_offset == -1)
5458 +               return(0);
5459 +
5460 +       n = os_seek_file(req->fds[1], req->cow_offset);
5461 +       if(n < 0){
5462 +               printk("do_io - bitmap lseek failed : err = %d\n", -n);
5463 +               return(1);
5464 +       }
5465 +
5466 +       n = os_write_file(req->fds[1], &req->bitmap_words,
5467 +                         sizeof(req->bitmap_words));
5468 +       if(n != sizeof(req->bitmap_words)){
5469 +               printk("do_io - bitmap update failed, err = %d fd = %d\n", -n,
5470 +                      req->fds[1]);
5471 +               return(1);
5472 +       }
5473  
5474 -       if(stat64(file, &buf) < 0) return(0);
5475 -       return(S_ISDIR(buf.st_mode));
5476 +       return(0);
5477  }
5478  
5479  void do_io(struct io_thread_req *req)
5480 @@ -461,8 +234,18 @@
5481         char *buf;
5482         unsigned long len;
5483         int n, nsectors, start, end, bit;
5484 +       int err;
5485         __u64 off;
5486  
5487 +       if(req->op == UBD_MMAP){
5488 +               /* Touch the page to force the host to do any necessary IO to 
5489 +                * get it into memory 
5490 +                */
5491 +               n = *((volatile int *) req->buffer);
5492 +               req->error = update_bitmap(req);
5493 +               return;
5494 +       }
5495 +
5496         nsectors = req->length / req->sectorsize;
5497         start = 0;
5498         do {
5499 @@ -473,15 +256,14 @@
5500                                     &req->sector_mask) == bit))
5501                         end++;
5502  
5503 -               if(end != nsectors)
5504 -                       printk("end != nsectors\n");
5505                 off = req->offset + req->offsets[bit] + 
5506                         start * req->sectorsize;
5507                 len = (end - start) * req->sectorsize;
5508                 buf = &req->buffer[start * req->sectorsize];
5509  
5510 -               if(os_seek_file(req->fds[bit], off) != 0){
5511 -                       printk("do_io - lseek failed : errno = %d\n", errno);
5512 +               err = os_seek_file(req->fds[bit], off);
5513 +               if(err < 0){
5514 +                       printk("do_io - lseek failed : err = %d\n", -err);
5515                         req->error = 1;
5516                         return;
5517                 }
5518 @@ -490,11 +272,10 @@
5519                         do {
5520                                 buf = &buf[n];
5521                                 len -= n;
5522 -                               n = read(req->fds[bit], buf, len);
5523 +                               n = os_read_file(req->fds[bit], buf, len);
5524                                 if (n < 0) {
5525 -                                       printk("do_io - read returned %d : "
5526 -                                              "errno = %d fd = %d\n", n,
5527 -                                              errno, req->fds[bit]);
5528 +                                       printk("do_io - read failed, err = %d "
5529 +                                              "fd = %d\n", -n, req->fds[bit]);
5530                                         req->error = 1;
5531                                         return;
5532                                 }
5533 @@ -502,11 +283,10 @@
5534                         if (n < len) memset(&buf[n], 0, len - n);
5535                 }
5536                 else {
5537 -                       n = write(req->fds[bit], buf, len);
5538 +                       n = os_write_file(req->fds[bit], buf, len);
5539                         if(n != len){
5540 -                               printk("do_io - write returned %d : "
5541 -                                      "errno = %d fd = %d\n", n, 
5542 -                                      errno, req->fds[bit]);
5543 +                               printk("do_io - write failed err = %d "
5544 +                                      "fd = %d\n", -n, req->fds[bit]);
5545                                 req->error = 1;
5546                                 return;
5547                         }
5548 @@ -515,24 +295,7 @@
5549                 start = end;
5550         } while(start < nsectors);
5551  
5552 -       if(req->cow_offset != -1){
5553 -               if(os_seek_file(req->fds[1], req->cow_offset) != 0){
5554 -                       printk("do_io - bitmap lseek failed : errno = %d\n",
5555 -                              errno);
5556 -                       req->error = 1;
5557 -                       return;
5558 -               }
5559 -               n = write(req->fds[1], &req->bitmap_words, 
5560 -                         sizeof(req->bitmap_words));
5561 -               if(n != sizeof(req->bitmap_words)){
5562 -                       printk("do_io - bitmap update returned %d : "
5563 -                              "errno = %d fd = %d\n", n, errno, req->fds[1]);
5564 -                       req->error = 1;
5565 -                       return;
5566 -               }
5567 -       }
5568 -       req->error = 0;
5569 -       return;
5570 +       req->error = update_bitmap(req);
5571  }
5572  
5573  /* Changed in start_io_thread, which is serialized by being called only
5574 @@ -550,19 +313,23 @@
5575  
5576         signal(SIGWINCH, SIG_IGN);
5577         while(1){
5578 -               n = read(kernel_fd, &req, sizeof(req));
5579 -               if(n < 0) printk("io_thread - read returned %d, errno = %d\n",
5580 -                                n, errno);
5581 -               else if(n < sizeof(req)){
5582 -                       printk("io_thread - short read : length = %d\n", n);
5583 +               n = os_read_file(kernel_fd, &req, sizeof(req));
5584 +               if(n != sizeof(req)){
5585 +                       if(n < 0)
5586 +                               printk("io_thread - read failed, fd = %d, "
5587 +                                      "err = %d\n", kernel_fd, -n);
5588 +                       else {
5589 +                               printk("io_thread - short read, fd = %d, "
5590 +                                      "length = %d\n", kernel_fd, n);
5591 +                       }
5592                         continue;
5593                 }
5594                 io_count++;
5595                 do_io(&req);
5596 -               n = write(kernel_fd, &req, sizeof(req));
5597 +               n = os_write_file(kernel_fd, &req, sizeof(req));
5598                 if(n != sizeof(req))
5599 -                       printk("io_thread - write failed, errno = %d\n",
5600 -                              errno);
5601 +                       printk("io_thread - write failed, fd = %d, err = %d\n",
5602 +                              kernel_fd, -n);
5603         }
5604  }
5605  
5606 @@ -571,10 +338,11 @@
5607         int pid, fds[2], err;
5608  
5609         err = os_pipe(fds, 1, 1);
5610 -       if(err){
5611 -               printk("start_io_thread - os_pipe failed, errno = %d\n", -err);
5612 -               return(-1);
5613 +       if(err < 0){
5614 +               printk("start_io_thread - os_pipe failed, err = %d\n", -err);
5615 +               goto out;
5616         }
5617 +
5618         kernel_fd = fds[0];
5619         *fd_out = fds[1];
5620  
5621 @@ -582,32 +350,19 @@
5622                     NULL);
5623         if(pid < 0){
5624                 printk("start_io_thread - clone failed : errno = %d\n", errno);
5625 -               return(-errno);
5626 +               goto out_close;
5627         }
5628 -       return(pid);
5629 -}
5630 -
5631 -#ifdef notdef
5632 -int start_io_thread(unsigned long sp, int *fd_out)
5633 -{
5634 -       int pid;
5635  
5636 -       if((kernel_fd = get_pty()) < 0) return(-1);
5637 -       raw(kernel_fd, 0);
5638 -       if((*fd_out = open(ptsname(kernel_fd), O_RDWR)) < 0){
5639 -               printk("Couldn't open tty for IO\n");
5640 -               return(-1);
5641 -       }
5642 -
5643 -       pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD,
5644 -                   NULL);
5645 -       if(pid < 0){
5646 -               printk("start_io_thread - clone failed : errno = %d\n", errno);
5647 -               return(-errno);
5648 -       }
5649         return(pid);
5650 +
5651 + out_close:
5652 +       os_close_file(fds[0]);
5653 +       os_close_file(fds[1]);
5654 +       kernel_fd = -1;
5655 +       *fd_out = -1;
5656 + out:
5657 +       return(err);
5658  }
5659 -#endif
5660  
5661  /*
5662   * Overrides for Emacs so that we follow Linus's tabbing style.
5663 diff -Naur a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
5664 --- a/arch/um/drivers/xterm.c   2004-02-11 12:14:17.000000000 -0500
5665 +++ b/arch/um/drivers/xterm.c   2004-02-11 12:26:00.000000000 -0500
5666 @@ -8,7 +8,6 @@
5667  #include <unistd.h>
5668  #include <string.h>
5669  #include <errno.h>
5670 -#include <fcntl.h>
5671  #include <termios.h>
5672  #include <signal.h>
5673  #include <sched.h>
5674 @@ -36,7 +35,8 @@
5675  {
5676         struct xterm_chan *data;
5677  
5678 -       if((data = malloc(sizeof(*data))) == NULL) return(NULL);
5679 +       data = malloc(sizeof(*data));
5680 +       if(data == NULL) return(NULL);
5681         *data = ((struct xterm_chan) { .pid             = -1, 
5682                                        .helper_pid      = -1,
5683                                        .device          = device, 
5684 @@ -93,7 +93,7 @@
5685                          "/usr/lib/uml/port-helper", "-uml-socket",
5686                          file, NULL };
5687  
5688 -       if(access(argv[4], X_OK))
5689 +       if(os_access(argv[4], OS_ACC_X_OK) < 0)
5690                 argv[4] = "port-helper";
5691  
5692         fd = mkstemp(file);
5693 @@ -106,13 +106,13 @@
5694                 printk("xterm_open : unlink failed, errno = %d\n", errno);
5695                 return(-errno);
5696         }
5697 -       close(fd);
5698 +       os_close_file(fd);
5699  
5700 -       fd = create_unix_socket(file, sizeof(file));
5701 +       fd = os_create_unix_socket(file, sizeof(file), 1);
5702         if(fd < 0){
5703                 printk("xterm_open : create_unix_socket failed, errno = %d\n", 
5704                        -fd);
5705 -               return(-fd);
5706 +               return(fd);
5707         }
5708  
5709         sprintf(title, data->title, data->device);
5710 @@ -128,15 +128,16 @@
5711         if(data->direct_rcv)
5712                 new = os_rcv_fd(fd, &data->helper_pid);
5713         else {
5714 -               if((err = os_set_fd_block(fd, 0)) != 0){
5715 +               err = os_set_fd_block(fd, 0);
5716 +               if(err < 0){
5717                         printk("xterm_open : failed to set descriptor "
5718 -                              "non-blocking, errno = %d\n", err);
5719 +                              "non-blocking, err = %d\n", -err);
5720                         return(err);
5721                 }
5722                 new = xterm_fd(fd, &data->helper_pid);
5723         }
5724         if(new < 0){
5725 -               printk("xterm_open : os_rcv_fd failed, errno = %d\n", -new);
5726 +               printk("xterm_open : os_rcv_fd failed, err = %d\n", -new);
5727                 goto out;
5728         }
5729  
5730 @@ -160,7 +161,7 @@
5731         if(data->helper_pid != -1) 
5732                 os_kill_process(data->helper_pid, 0);
5733         data->helper_pid = -1;
5734 -       close(fd);
5735 +       os_close_file(fd);
5736  }
5737  
5738  void xterm_free(void *d)
5739 diff -Naur a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c
5740 --- a/arch/um/drivers/xterm_kern.c      2004-02-11 12:16:10.000000000 -0500
5741 +++ b/arch/um/drivers/xterm_kern.c      2004-02-11 12:28:20.000000000 -0500
5742 @@ -5,9 +5,12 @@
5743  
5744  #include "linux/errno.h"
5745  #include "linux/slab.h"
5746 +#include "linux/signal.h"
5747 +#include "linux/interrupt.h"
5748  #include "asm/semaphore.h"
5749  #include "asm/irq.h"
5750  #include "irq_user.h"
5751 +#include "irq_kern.h"
5752  #include "kern_util.h"
5753  #include "os.h"
5754  #include "xterm.h"
5755 @@ -19,17 +22,18 @@
5756         int new_fd;
5757  };
5758  
5759 -static void xterm_interrupt(int irq, void *data, struct pt_regs *regs)
5760 +static irqreturn_t xterm_interrupt(int irq, void *data, struct pt_regs *regs)
5761  {
5762         struct xterm_wait *xterm = data;
5763         int fd;
5764  
5765         fd = os_rcv_fd(xterm->fd, &xterm->pid);
5766         if(fd == -EAGAIN)
5767 -               return;
5768 +               return(IRQ_NONE);
5769  
5770         xterm->new_fd = fd;
5771         up(&xterm->sem);
5772 +       return(IRQ_HANDLED);
5773  }
5774  
5775  int xterm_fd(int socket, int *pid_out)
5776 @@ -54,7 +58,8 @@
5777         if(err){
5778                 printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, "
5779                        "err = %d\n",  err);
5780 -               return(err);
5781 +               ret = err;
5782 +               goto out;
5783         }
5784         down(&data->sem);
5785  
5786 @@ -62,6 +67,7 @@
5787  
5788         ret = data->new_fd;
5789         *pid_out = data->pid;
5790 + out:
5791         kfree(data);
5792  
5793         return(ret);
5794 diff -Naur a/arch/um/dyn.lds.S b/arch/um/dyn.lds.S
5795 --- a/arch/um/dyn.lds.S 2004-02-11 12:15:45.000000000 -0500
5796 +++ b/arch/um/dyn.lds.S 2004-02-11 12:27:35.000000000 -0500
5797 @@ -10,12 +10,15 @@
5798  {
5799    . = START + SIZEOF_HEADERS;
5800    .interp         : { *(.interp) }
5801 -  . = ALIGN(4096);
5802    __binary_start = .;
5803    . = ALIGN(4096);             /* Init code and data */
5804    _stext = .;
5805    __init_begin = .;
5806 -  .text.init : { *(.text.init) }
5807 +  .init.text : { 
5808 +       _sinittext = .;
5809 +       *(.init.text)
5810 +       _einittext = .;
5811 +  }
5812  
5813    . = ALIGN(4096);
5814  
5815 @@ -67,7 +70,7 @@
5816  
5817    #include "asm/common.lds.S"
5818  
5819 -  .data.init : { *(.data.init) }
5820 +  init.data : { *(.init.data) }
5821  
5822    /* Ensure the __preinit_array_start label is properly aligned.  We
5823       could instead move the label definition inside the section, but
5824 diff -Naur a/arch/um/include/2_5compat.h b/arch/um/include/2_5compat.h
5825 --- a/arch/um/include/2_5compat.h       2004-02-11 12:15:23.000000000 -0500
5826 +++ b/arch/um/include/2_5compat.h       2004-02-11 12:27:10.000000000 -0500
5827 @@ -6,20 +6,6 @@
5828  #ifndef __2_5_COMPAT_H__
5829  #define __2_5_COMPAT_H__
5830  
5831 -#include "linux/version.h"
5832 -
5833 -#define INIT_CONSOLE(dev_name, write_proc, device_proc, setup_proc, f) { \
5834 -       name :          dev_name, \
5835 -       write :         write_proc, \
5836 -       read :          NULL, \
5837 -       device :        device_proc, \
5838 -       setup :         setup_proc, \
5839 -       flags :         f, \
5840 -       index :         -1, \
5841 -       cflag :         0, \
5842 -       next :          NULL \
5843 -}
5844 -
5845  #define INIT_HARDSECT(arr, maj, sizes)
5846  
5847  #define SET_PRI(task) do ; while(0)
5848 diff -Naur a/arch/um/include/irq_kern.h b/arch/um/include/irq_kern.h
5849 --- a/arch/um/include/irq_kern.h        1969-12-31 19:00:00.000000000 -0500
5850 +++ b/arch/um/include/irq_kern.h        2004-02-11 12:27:15.000000000 -0500
5851 @@ -0,0 +1,28 @@
5852 +/* 
5853 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
5854 + * Licensed under the GPL
5855 + */
5856 +
5857 +#ifndef __IRQ_KERN_H__
5858 +#define __IRQ_KERN_H__
5859 +
5860 +#include "linux/interrupt.h"
5861 +
5862 +extern int um_request_irq(unsigned int irq, int fd, int type,
5863 +                         irqreturn_t (*handler)(int, void *, 
5864 +                                                struct pt_regs *),
5865 +                         unsigned long irqflags,  const char * devname,
5866 +                         void *dev_id);
5867 +
5868 +#endif
5869 +
5870 +/*
5871 + * Overrides for Emacs so that we follow Linus's tabbing style.
5872 + * Emacs will notice this stuff at the end of the file and automatically
5873 + * adjust the settings for this buffer only.  This must remain at the end
5874 + * of the file.
5875 + * ---------------------------------------------------------------------------
5876 + * Local variables:
5877 + * c-file-style: "linux"
5878 + * End:
5879 + */
5880 diff -Naur a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
5881 --- a/arch/um/include/kern_util.h       2004-02-11 12:15:00.000000000 -0500
5882 +++ b/arch/um/include/kern_util.h       2004-02-11 12:26:51.000000000 -0500
5883 @@ -63,10 +63,9 @@
5884  extern void *syscall_sp(void *t);
5885  extern void syscall_trace(void);
5886  extern int hz(void);
5887 -extern void idle_timer(void);
5888 +extern void uml_idle_timer(void);
5889  extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs);
5890  extern int external_pid(void *t);
5891 -extern int pid_to_processor_id(int pid);
5892  extern void boot_timer_handler(int sig);
5893  extern void interrupt_end(void);
5894  extern void initial_thread_cb(void (*proc)(void *), void *arg);
5895 @@ -90,9 +89,7 @@
5896  extern char *uml_strdup(char *string);
5897  extern void unprotect_kernel_mem(void);
5898  extern void protect_kernel_mem(void);
5899 -extern void set_kmem_end(unsigned long);
5900  extern void uml_cleanup(void);
5901 -extern int pid_to_processor_id(int pid);
5902  extern void set_current(void *t);
5903  extern void lock_signalled_task(void *t);
5904  extern void IPI_handler(int cpu);
5905 @@ -101,7 +98,9 @@
5906  extern int clear_user_proc(void *buf, int size);
5907  extern int copy_to_user_proc(void *to, void *from, int size);
5908  extern int copy_from_user_proc(void *to, void *from, int size);
5909 +extern int strlen_user_proc(char *str);
5910  extern void bus_handler(int sig, union uml_pt_regs *regs);
5911 +extern void winch(int sig, union uml_pt_regs *regs);
5912  extern long execute_syscall(void *r);
5913  extern int smp_sigio_handler(void);
5914  extern void *get_current(void);
5915 @@ -112,6 +111,8 @@
5916  extern void free_irq(unsigned int, void *);
5917  extern int um_in_interrupt(void);
5918  extern int cpu(void);
5919 +extern unsigned long long time_stamp(void);
5920 +
5921  #endif
5922  
5923  /*
5924 diff -Naur a/arch/um/include/line.h b/arch/um/include/line.h
5925 --- a/arch/um/include/line.h    2004-02-11 12:16:27.000000000 -0500
5926 +++ b/arch/um/include/line.h    2004-02-11 12:28:24.000000000 -0500
5927 @@ -9,12 +9,14 @@
5928  #include "linux/list.h"
5929  #include "linux/workqueue.h"
5930  #include "linux/tty.h"
5931 +#include "linux/interrupt.h"
5932  #include "asm/semaphore.h"
5933  #include "chan_user.h"
5934  #include "mconsole_kern.h"
5935  
5936  struct line_driver {
5937         char *name;
5938 +       char *device_name;
5939         char *devfs_name;
5940         short major;
5941         short minor_start;
5942 @@ -67,8 +69,6 @@
5943  
5944  #define LINES_INIT(n) {  num :         n }
5945  
5946 -extern void line_interrupt(int irq, void *data, struct pt_regs *unused);
5947 -extern void line_write_interrupt(int irq, void *data, struct pt_regs *unused);
5948  extern void line_close(struct line *lines, struct tty_struct *tty);
5949  extern int line_open(struct line *lines, struct tty_struct *tty, 
5950                      struct chan_opts *opts);
5951 diff -Naur a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h
5952 --- a/arch/um/include/mconsole.h        2004-02-11 12:15:15.000000000 -0500
5953 +++ b/arch/um/include/mconsole.h        2004-02-11 12:27:02.000000000 -0500
5954 @@ -41,11 +41,13 @@
5955  
5956  struct mc_request;
5957  
5958 +enum mc_context { MCONSOLE_INTR, MCONSOLE_PROC };
5959 +
5960  struct mconsole_command
5961  {
5962         char *command;
5963         void (*handler)(struct mc_request *req);
5964 -       int as_interrupt;
5965 +       enum mc_context context;
5966  };
5967  
5968  struct mc_request
5969 @@ -77,6 +79,8 @@
5970  extern void mconsole_cad(struct mc_request *req);
5971  extern void mconsole_stop(struct mc_request *req);
5972  extern void mconsole_go(struct mc_request *req);
5973 +extern void mconsole_log(struct mc_request *req);
5974 +extern void mconsole_proc(struct mc_request *req);
5975  
5976  extern int mconsole_get_request(int fd, struct mc_request *req);
5977  extern int mconsole_notify(char *sock_name, int type, const void *data, 
5978 diff -Naur a/arch/um/include/mem.h b/arch/um/include/mem.h
5979 --- a/arch/um/include/mem.h     2004-02-11 12:17:08.000000000 -0500
5980 +++ b/arch/um/include/mem.h     2004-02-11 12:29:12.000000000 -0500
5981 @@ -1,19 +1,18 @@
5982  /* 
5983 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
5984 + * Copyright (C) 2002, 2003 Jeff Dike (jdike@addtoit.com)
5985   * Licensed under the GPL
5986   */
5987  
5988  #ifndef __MEM_H__
5989  #define __MEM_H__
5990  
5991 -struct vm_reserved {
5992 -       struct list_head list;
5993 -       unsigned long start;
5994 -       unsigned long end;
5995 -};
5996 +#include "linux/types.h"
5997  
5998 -extern void set_usable_vm(unsigned long start, unsigned long end);
5999 -extern void set_kmem_end(unsigned long new);
6000 +extern int phys_mapping(unsigned long phys, __u64 *offset_out);
6001 +extern int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w);
6002 +extern int is_remapped(void *virt);
6003 +extern int physmem_remove_mapping(void *virt);
6004 +extern void physmem_forget_descriptor(int fd);
6005  
6006  #endif
6007  
6008 diff -Naur a/arch/um/include/mem_kern.h b/arch/um/include/mem_kern.h
6009 --- a/arch/um/include/mem_kern.h        1969-12-31 19:00:00.000000000 -0500
6010 +++ b/arch/um/include/mem_kern.h        2004-02-11 12:27:40.000000000 -0500
6011 @@ -0,0 +1,30 @@
6012 +/* 
6013 + * Copyright (C) 2003 Jeff Dike (jdike@addtoit.com)
6014 + * Licensed under the GPL
6015 + */
6016 +
6017 +#ifndef __MEM_KERN_H__
6018 +#define __MEM_KERN_H__
6019 +
6020 +#include "linux/list.h"
6021 +#include "linux/types.h"
6022 +
6023 +struct remapper {
6024 +       struct list_head list;
6025 +       int (*proc)(int, unsigned long, int, __u64);
6026 +};
6027 +
6028 +extern void register_remapper(struct remapper *info);
6029 +
6030 +#endif
6031 +
6032 +/*
6033 + * Overrides for Emacs so that we follow Linus's tabbing style.
6034 + * Emacs will notice this stuff at the end of the file and automatically
6035 + * adjust the settings for this buffer only.  This must remain at the end
6036 + * of the file.
6037 + * ---------------------------------------------------------------------------
6038 + * Local variables:
6039 + * c-file-style: "linux"
6040 + * End:
6041 + */
6042 diff -Naur a/arch/um/include/mem_user.h b/arch/um/include/mem_user.h
6043 --- a/arch/um/include/mem_user.h        2004-02-11 12:16:03.000000000 -0500
6044 +++ b/arch/um/include/mem_user.h        2004-02-11 12:27:57.000000000 -0500
6045 @@ -32,43 +32,38 @@
6046  #ifndef _MEM_USER_H
6047  #define _MEM_USER_H
6048  
6049 -struct mem_region {
6050 +struct iomem_region {
6051 +       struct iomem_region *next;
6052         char *driver;
6053 -       unsigned long start_pfn;
6054 -       unsigned long start;
6055 -       unsigned long len;
6056 -       void *mem_map;
6057         int fd;
6058 +       int size;
6059 +       unsigned long phys;
6060 +       unsigned long virt;
6061  };
6062  
6063 -extern struct mem_region *regions[];
6064 -extern struct mem_region physmem_region;
6065 +extern struct iomem_region *iomem_regions;
6066 +extern int iomem_size;
6067  
6068  #define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1))
6069  
6070  extern unsigned long host_task_size;
6071  extern unsigned long task_size;
6072  
6073 +extern void check_devanon(void);
6074  extern int init_mem_user(void);
6075  extern int create_mem_file(unsigned long len);
6076 -extern void setup_range(int fd, char *driver, unsigned long start,
6077 -                       unsigned long pfn, unsigned long total, int need_vm, 
6078 -                       struct mem_region *region, void *reserved);
6079  extern void setup_memory(void *entry);
6080  extern unsigned long find_iomem(char *driver, unsigned long *len_out);
6081 -extern int init_maps(struct mem_region *region);
6082 -extern int nregions(void);
6083 -extern int reserve_vm(unsigned long start, unsigned long end, void *e);
6084 +extern int init_maps(unsigned long physmem, unsigned long iomem, 
6085 +                    unsigned long highmem);
6086  extern unsigned long get_vm(unsigned long len);
6087  extern void setup_physmem(unsigned long start, unsigned long usable,
6088 -                         unsigned long len);
6089 -extern int setup_region(struct mem_region *region, void *entry);
6090 +                         unsigned long len, unsigned long highmem);
6091  extern void add_iomem(char *name, int fd, unsigned long size);
6092 -extern struct mem_region *phys_region(unsigned long phys);
6093  extern unsigned long phys_offset(unsigned long phys);
6094  extern void unmap_physmem(void);
6095 -extern int map_memory(unsigned long virt, unsigned long phys, 
6096 -                     unsigned long len, int r, int w, int x);
6097 +extern void map_memory(unsigned long virt, unsigned long phys, 
6098 +                      unsigned long len, int r, int w, int x);
6099  extern int protect_memory(unsigned long addr, unsigned long len, 
6100                           int r, int w, int x, int must_succeed);
6101  extern unsigned long get_kmem_end(void);
6102 diff -Naur a/arch/um/include/os.h b/arch/um/include/os.h
6103 --- a/arch/um/include/os.h      2004-02-11 12:14:31.000000000 -0500
6104 +++ b/arch/um/include/os.h      2004-02-11 12:26:12.000000000 -0500
6105 @@ -17,6 +17,32 @@
6106  #define OS_TYPE_FIFO 6
6107  #define OS_TYPE_SOCK 7
6108  
6109 +/* os_access() flags */
6110 +#define OS_ACC_F_OK    0       /* Test for existence.  */
6111 +#define OS_ACC_X_OK    1       /* Test for execute permission.  */
6112 +#define OS_ACC_W_OK    2       /* Test for write permission.  */
6113 +#define OS_ACC_R_OK    4       /* Test for read permission.  */
6114 +#define OS_ACC_RW_OK   (OS_ACC_W_OK | OS_ACC_R_OK) /* Test for RW permission */
6115 +
6116 +/*
6117 + * types taken from stat_file() in hostfs_user.c
6118 + * (if they are wrong here, they are wrong there...).
6119 + */
6120 +struct uml_stat {
6121 +       int                ust_dev;        /* device */
6122 +       unsigned long long ust_ino;        /* inode */
6123 +       int                ust_mode;       /* protection */
6124 +       int                ust_nlink;      /* number of hard links */
6125 +       int                ust_uid;        /* user ID of owner */
6126 +       int                ust_gid;        /* group ID of owner */
6127 +       unsigned long long ust_size;       /* total size, in bytes */
6128 +       int                ust_blksize;    /* blocksize for filesystem I/O */
6129 +       unsigned long long ust_blocks;     /* number of blocks allocated */
6130 +       unsigned long      ust_atime;      /* time of last access */
6131 +       unsigned long      ust_mtime;      /* time of last modification */
6132 +       unsigned long      ust_ctime;      /* time of last change */
6133 +};
6134 +
6135  struct openflags {
6136         unsigned int r : 1;
6137         unsigned int w : 1;
6138 @@ -84,29 +110,47 @@
6139         flags.e = 1; 
6140         return(flags); 
6141  }
6142
6143 +
6144  static inline struct openflags of_cloexec(struct openflags flags)
6145  { 
6146         flags.cl = 1; 
6147         return(flags); 
6148  }
6149    
6150 +extern int os_stat_file(const char *file_name, struct uml_stat *buf);
6151 +extern int os_stat_fd(const int fd, struct uml_stat *buf);
6152 +extern int os_access(const char *file, int mode);
6153 +extern void os_print_error(int error, const char* str);
6154 +extern int os_get_exec_close(int fd, int *close_on_exec);
6155 +extern int os_set_exec_close(int fd, int close_on_exec);
6156 +extern int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg);
6157 +extern int os_window_size(int fd, int *rows, int *cols);
6158 +extern int os_new_tty_pgrp(int fd, int pid);
6159 +extern int os_get_ifname(int fd, char *namebuf);
6160 +extern int os_set_slip(int fd);
6161 +extern int os_set_owner(int fd, int pid);
6162 +extern int os_sigio_async(int master, int slave);
6163 +extern int os_mode_fd(int fd, int mode);
6164 +
6165  extern int os_seek_file(int fd, __u64 offset);
6166  extern int os_open_file(char *file, struct openflags flags, int mode);
6167  extern int os_read_file(int fd, void *buf, int len);
6168 -extern int os_write_file(int fd, void *buf, int count);
6169 +extern int os_write_file(int fd, const void *buf, int count);
6170  extern int os_file_size(char *file, long long *size_out);
6171 +extern int os_file_modtime(char *file, unsigned long *modtime);
6172  extern int os_pipe(int *fd, int stream, int close_on_exec);
6173  extern int os_set_fd_async(int fd, int owner);
6174  extern int os_set_fd_block(int fd, int blocking);
6175  extern int os_accept_connection(int fd);
6176 +extern int os_create_unix_socket(char *file, int len, int close_on_exec);
6177  extern int os_shutdown_socket(int fd, int r, int w);
6178  extern void os_close_file(int fd);
6179  extern int os_rcv_fd(int fd, int *helper_pid_out);
6180 -extern int create_unix_socket(char *file, int len);
6181 +extern int create_unix_socket(char *file, int len, int close_on_exec);
6182  extern int os_connect_socket(char *name);
6183  extern int os_file_type(char *file);
6184  extern int os_file_mode(char *file, struct openflags *mode_out);
6185 +extern int os_lock_file(int fd, int excl);
6186  
6187  extern unsigned long os_process_pc(int pid);
6188  extern int os_process_parent(int pid);
6189 @@ -115,11 +159,12 @@
6190  extern void os_usr1_process(int pid);
6191  extern int os_getpid(void);
6192  
6193 -extern int os_map_memory(void *virt, int fd, unsigned long off, 
6194 +extern int os_map_memory(void *virt, int fd, unsigned long long off, 
6195                          unsigned long len, int r, int w, int x);
6196  extern int os_protect_memory(void *addr, unsigned long len, 
6197                              int r, int w, int x);
6198  extern int os_unmap_memory(void *addr, int len);
6199 +extern void os_flush_stdout(void);
6200  
6201  #endif
6202  
6203 diff -Naur a/arch/um/include/skas_ptrace.h b/arch/um/include/skas_ptrace.h
6204 --- a/arch/um/include/skas_ptrace.h     2004-02-11 12:16:37.000000000 -0500
6205 +++ b/arch/um/include/skas_ptrace.h     2004-02-11 12:28:37.000000000 -0500
6206 @@ -1,5 +1,5 @@
6207  /* 
6208 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
6209 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
6210   * Licensed under the GPL
6211   */
6212  
6213 diff -Naur a/arch/um/include/sysdep-i386/frame_user.h b/arch/um/include/sysdep-i386/frame_user.h
6214 --- a/arch/um/include/sysdep-i386/frame_user.h  2004-02-11 12:16:44.000000000 -0500
6215 +++ b/arch/um/include/sysdep-i386/frame_user.h  2004-02-11 12:29:00.000000000 -0500
6216 @@ -56,26 +56,26 @@
6217   * it would have to be __builtin_frame_address(1).
6218   */
6219  
6220 -static inline unsigned long frame_restorer(void)
6221 -{
6222 -       unsigned long *fp;
6223 -
6224 -       fp = __builtin_frame_address(0);
6225 -       return((unsigned long) (fp + 1));
6226 -}
6227 +#define frame_restorer() \
6228 +({ \
6229 +       unsigned long *fp; \
6230 +\
6231 +       fp = __builtin_frame_address(0); \
6232 +       ((unsigned long) (fp + 1)); \
6233 +})
6234  
6235  /* Similarly, this returns the value of sp when the handler was first
6236   * entered.  This is used to calculate the proper sp when delivering
6237   * signals.
6238   */
6239  
6240 -static inline unsigned long frame_sp(void)
6241 -{
6242 -       unsigned long *fp;
6243 -
6244 -       fp = __builtin_frame_address(0);
6245 -       return((unsigned long) (fp + 1));
6246 -}
6247 +#define frame_sp() \
6248 +({ \
6249 +       unsigned long *fp; \
6250 +\
6251 +       fp = __builtin_frame_address(0); \
6252 +       ((unsigned long) (fp + 1)); \
6253 +})
6254  
6255  #endif
6256  
6257 diff -Naur a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h
6258 --- a/arch/um/include/sysdep-i386/sigcontext.h  2004-02-11 12:16:08.000000000 -0500
6259 +++ b/arch/um/include/sysdep-i386/sigcontext.h  2004-02-11 12:28:19.000000000 -0500
6260 @@ -28,8 +28,8 @@
6261   */
6262  #define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
6263  
6264 -/* These are General Protection and Page Fault */
6265 -#define SEGV_IS_FIXABLE(trap) ((trap == 13) || (trap == 14))
6266 +/* This is Page Fault */
6267 +#define SEGV_IS_FIXABLE(trap) (trap == 14)
6268  
6269  #define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc)))
6270  
6271 diff -Naur a/arch/um/include/ubd_user.h b/arch/um/include/ubd_user.h
6272 --- a/arch/um/include/ubd_user.h        2004-02-11 12:15:48.000000000 -0500
6273 +++ b/arch/um/include/ubd_user.h        2004-02-11 12:27:41.000000000 -0500
6274 @@ -9,7 +9,7 @@
6275  
6276  #include "os.h"
6277  
6278 -enum ubd_req { UBD_READ, UBD_WRITE };
6279 +enum ubd_req { UBD_READ, UBD_WRITE, UBD_MMAP };
6280  
6281  struct io_thread_req {
6282         enum ubd_req op;
6283 @@ -20,8 +20,10 @@
6284         char *buffer;
6285         int sectorsize;
6286         unsigned long sector_mask;
6287 -       unsigned long cow_offset;
6288 +       unsigned long long cow_offset;
6289         unsigned long bitmap_words[2];
6290 +       int map_fd;
6291 +       unsigned long long map_offset;
6292         int error;
6293  };
6294  
6295 @@ -31,7 +33,7 @@
6296                          int *create_cow_out);
6297  extern int create_cow_file(char *cow_file, char *backing_file, 
6298                            struct openflags flags, int sectorsize, 
6299 -                          int *bitmap_offset_out, 
6300 +                          int alignment, int *bitmap_offset_out, 
6301                            unsigned long *bitmap_len_out,
6302                            int *data_offset_out);
6303  extern int read_cow_bitmap(int fd, void *buf, int offset, int len);
6304 @@ -39,7 +41,6 @@
6305  extern int write_ubd_fs(int fd, char *buffer, int len);
6306  extern int start_io_thread(unsigned long sp, int *fds_out);
6307  extern void do_io(struct io_thread_req *req);
6308 -extern int ubd_is_dir(char *file);
6309  
6310  static inline int ubd_test_bit(__u64 bit, unsigned char *data)
6311  {
6312 diff -Naur a/arch/um/include/um_uaccess.h b/arch/um/include/um_uaccess.h
6313 --- a/arch/um/include/um_uaccess.h      2004-02-11 12:16:07.000000000 -0500
6314 +++ b/arch/um/include/um_uaccess.h      2004-02-11 12:28:02.000000000 -0500
6315 @@ -38,22 +38,73 @@
6316                                 from, n));
6317  }
6318  
6319 +/*
6320 + * strncpy_from_user: - Copy a NUL terminated string from userspace.
6321 + * @dst:   Destination address, in kernel space.  This buffer must be at
6322 + *         least @count bytes long.
6323 + * @src:   Source address, in user space.
6324 + * @count: Maximum number of bytes to copy, including the trailing NUL.
6325 + * 
6326 + * Copies a NUL-terminated string from userspace to kernel space.
6327 + *
6328 + * On success, returns the length of the string (not including the trailing
6329 + * NUL).
6330 + *
6331 + * If access to userspace fails, returns -EFAULT (some data may have been
6332 + * copied).
6333 + *
6334 + * If @count is smaller than the length of the string, copies @count bytes
6335 + * and returns @count.
6336 + */
6337 +
6338  static inline int strncpy_from_user(char *dst, const char *src, int count)
6339  {
6340         return(CHOOSE_MODE_PROC(strncpy_from_user_tt, strncpy_from_user_skas,
6341                                 dst, src, count));
6342  }
6343  
6344 +/*
6345 + * __clear_user: - Zero a block of memory in user space, with less checking.
6346 + * @to:   Destination address, in user space.
6347 + * @n:    Number of bytes to zero.
6348 + *
6349 + * Zero a block of memory in user space.  Caller must check
6350 + * the specified block with access_ok() before calling this function.
6351 + *
6352 + * Returns number of bytes that could not be cleared.
6353 + * On success, this will be zero.
6354 + */
6355  static inline int __clear_user(void *mem, int len)
6356  {
6357         return(CHOOSE_MODE_PROC(__clear_user_tt, __clear_user_skas, mem, len));
6358  }
6359  
6360 +/*
6361 + * clear_user: - Zero a block of memory in user space.
6362 + * @to:   Destination address, in user space.
6363 + * @n:    Number of bytes to zero.
6364 + *
6365 + * Zero a block of memory in user space.
6366 + *
6367 + * Returns number of bytes that could not be cleared.
6368 + * On success, this will be zero.
6369 + */
6370  static inline int clear_user(void *mem, int len)
6371  {
6372         return(CHOOSE_MODE_PROC(clear_user_tt, clear_user_skas, mem, len));
6373  }
6374  
6375 +/*
6376 + * strlen_user: - Get the size of a string in user space.
6377 + * @str: The string to measure.
6378 + * @n:   The maximum valid length
6379 + *
6380 + * Get the size of a NUL-terminated string in user space.
6381 + *
6382 + * Returns the size of the string INCLUDING the terminating NUL.
6383 + * On exception, returns 0.
6384 + * If the string is too long, returns a value greater than @n.
6385 + */
6386  static inline int strnlen_user(const void *str, int len)
6387  {
6388         return(CHOOSE_MODE_PROC(strnlen_user_tt, strnlen_user_skas, str, len));
6389 diff -Naur a/arch/um/include/user.h b/arch/um/include/user.h
6390 --- a/arch/um/include/user.h    2004-02-11 12:14:17.000000000 -0500
6391 +++ b/arch/um/include/user.h    2004-02-11 12:26:00.000000000 -0500
6392 @@ -14,6 +14,7 @@
6393  extern void kfree(void *ptr);
6394  extern int in_aton(char *str);
6395  extern int open_gdb_chan(void);
6396 +extern int strlcpy(char *, const char *, int);
6397  
6398  #endif
6399  
6400 diff -Naur a/arch/um/include/user_util.h b/arch/um/include/user_util.h
6401 --- a/arch/um/include/user_util.h       2004-02-11 12:14:23.000000000 -0500
6402 +++ b/arch/um/include/user_util.h       2004-02-11 12:26:06.000000000 -0500
6403 @@ -14,8 +14,6 @@
6404  extern int unlockpt(int __fd);
6405  extern char *ptsname(int __fd);
6406  
6407 -enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
6408 -
6409  struct cpu_task {
6410         int pid;
6411         void *task;
6412 @@ -59,7 +57,6 @@
6413  extern void *add_signal_handler(int sig, void (*handler)(int));
6414  extern int start_fork_tramp(void *arg, unsigned long temp_stack, 
6415                             int clone_flags, int (*tramp)(void *));
6416 -extern int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags);
6417  extern int linux_main(int argc, char **argv);
6418  extern void set_cmdline(char *cmd);
6419  extern void input_cb(void (*proc)(void *), void *arg, int arg_len);
6420 @@ -86,11 +83,13 @@
6421  extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr);
6422  extern void write_sigio_workaround(void);
6423  extern void arch_check_bugs(void);
6424 +extern int cpu_feature(char *what, char *buf, int len);
6425  extern int arch_handle_signal(int sig, union uml_pt_regs *regs);
6426  extern int arch_fixup(unsigned long address, void *sc_ptr);
6427  extern void forward_pending_sigio(int target);
6428  extern int can_do_skas(void);
6429
6430 +extern void arch_init_thread(void);
6431 +
6432  #endif
6433  
6434  /*
6435 diff -Naur a/arch/um/Kconfig b/arch/um/Kconfig
6436 --- a/arch/um/Kconfig   2004-02-11 12:15:26.000000000 -0500
6437 +++ b/arch/um/Kconfig   2004-02-11 12:27:15.000000000 -0500
6438 @@ -61,6 +61,20 @@
6439  
6440  config NET
6441         bool "Networking support"
6442 +       help
6443 +       Unless you really know what you are doing, you should say Y here.
6444 +       The reason is that some programs need kernel networking support even
6445 +       when running on a stand-alone machine that isn't connected to any
6446 +       other computer. If you are upgrading from an older kernel, you
6447 +       should consider updating your networking tools too because changes
6448 +       in the kernel and the tools often go hand in hand. The tools are
6449 +       contained in the package net-tools, the location and version number
6450 +       of which are given in Documentation/Changes.
6451 +
6452 +       For a general introduction to Linux networking, it is highly
6453 +       recommended to read the NET-HOWTO, available from
6454 +       <http://www.tldp.org/docs.html#howto>.
6455 +
6456  
6457  source "fs/Kconfig.binfmt"
6458  
6459 @@ -85,6 +99,19 @@
6460          If you'd like to be able to work with files stored on the host, 
6461          say Y or M here; otherwise say N.
6462  
6463 +config HPPFS
6464 +       tristate "HoneyPot ProcFS"
6465 +       help
6466 +       hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc 
6467 +       entries to be overridden, removed, or fabricated from the host.
6468 +       Its purpose is to allow a UML to appear to be a physical machine
6469 +       by removing or changing anything in /proc which gives away the
6470 +       identity of a UML.
6471 +
6472 +       See http://user-mode-linux.sf.net/hppfs.html for more information.
6473 +
6474 +       You only need this if you are setting up a UML honeypot.  Otherwise,
6475 +       it is safe to say 'N' here.
6476  
6477  config MCONSOLE
6478         bool "Management console"
6479 @@ -105,6 +132,16 @@
6480  config MAGIC_SYSRQ
6481         bool "Magic SysRq key"
6482         depends on MCONSOLE
6483 +       help
6484 +       If you say Y here, you will have some control over the system even
6485 +       if the system crashes for example during kernel debugging (e.g., you
6486 +       will be able to flush the buffer cache to disk, reboot the system
6487 +       immediately or dump some status information). This is accomplished
6488 +       by pressing various keys while holding SysRq (Alt+PrintScreen). It
6489 +       also works on a serial console (on PC hardware at least), if you
6490 +       send a BREAK and then within 5 seconds a command keypress. The
6491 +       keys are documented in Documentation/sysrq.txt. Don't say Y
6492 +       unless you really know what this hack does.
6493  
6494  config HOST_2G_2G
6495         bool "2G/2G host address space split"
6496 @@ -160,6 +197,9 @@
6497  config HIGHMEM
6498         bool "Highmem support"
6499  
6500 +config PROC_MM
6501 +       bool "/proc/mm support"
6502 +
6503  config KERNEL_STACK_ORDER
6504         int "Kernel stack size order"
6505         default 2
6506 @@ -168,6 +208,17 @@
6507         be 1 << order pages.  The default is OK unless you're running Valgrind
6508         on UML, in which case, set this to 3.
6509  
6510 +config UML_REAL_TIME_CLOCK
6511 +       bool "Real-time Clock"
6512 +       default y
6513 +       help
6514 +       This option makes UML time deltas match wall clock deltas.  This should
6515 +       normally be enabled.  The exception would be if you are debugging with
6516 +       UML and spend long times with UML stopped at a breakpoint.  In this
6517 +       case, when UML is restarted, it will call the timer enough times to make
6518 +       up for the time spent at the breakpoint.  This could result in a 
6519 +       noticable lag.  If this is a problem, then disable this option.
6520 +
6521  endmenu
6522  
6523  source "init/Kconfig"
6524 @@ -240,6 +291,10 @@
6525  config PT_PROXY
6526         bool "Enable ptrace proxy"
6527         depends on XTERM_CHAN && DEBUG_INFO
6528 +       help
6529 +       This option enables a debugging interface which allows gdb to debug
6530 +       the kernel without needing to actually attach to kernel threads.
6531 +       If you want to do kernel debugging, say Y here; otherwise say N.
6532  
6533  config GPROF
6534         bool "Enable gprof support"
6535 diff -Naur a/arch/um/Kconfig_block b/arch/um/Kconfig_block
6536 --- a/arch/um/Kconfig_block     2004-02-11 12:16:04.000000000 -0500
6537 +++ b/arch/um/Kconfig_block     2004-02-11 12:28:00.000000000 -0500
6538 @@ -29,6 +29,20 @@
6539          wise choice too.  In all other cases (for example, if you're just
6540          playing around with User-Mode Linux) you can choose N.
6541  
6542 +# Turn this back on when the driver actually works
6543 +#
6544 +#config BLK_DEV_COW
6545 +#      tristate "COW block device"
6546 +#      help
6547 +#      This is a layered driver which sits above two other block devices.
6548 +#      One is read-only, and the other is a read-write layer which stores
6549 +#      all changes.  This provides the illusion that the read-only layer
6550 +#      can be mounted read-write and changed.
6551 +
6552 +config BLK_DEV_COW_COMMON
6553 +       bool
6554 +       default BLK_DEV_COW || BLK_DEV_UBD
6555 +
6556  config BLK_DEV_LOOP
6557         tristate "Loopback device support"
6558  
6559 diff -Naur a/arch/um/Kconfig_net b/arch/um/Kconfig_net
6560 --- a/arch/um/Kconfig_net       2004-02-11 12:15:54.000000000 -0500
6561 +++ b/arch/um/Kconfig_net       2004-02-11 12:27:47.000000000 -0500
6562 @@ -1,5 +1,5 @@
6563  
6564 -menu "Network Devices"
6565 +menu "UML Network Devices"
6566         depends on NET
6567  
6568  # UML virtual driver
6569 @@ -176,73 +176,5 @@
6570         
6571          Startup example: "eth0=slirp,FE:FD:01:02:03:04,/usr/local/bin/slirp"
6572  
6573 -
6574 -# Below are hardware-independent drivers mirrored from
6575 -# drivers/net/Config.in. It would be nice if Linux
6576 -# had HW independent drivers separated from the other
6577 -# but it does not. Until then each non-ISA/PCI arch
6578 -# needs to provide it's own menu of network drivers
6579 -config DUMMY
6580 -       tristate "Dummy net driver support"
6581 -
6582 -config BONDING
6583 -       tristate "Bonding driver support"
6584 -
6585 -config EQUALIZER
6586 -       tristate "EQL (serial line load balancing) support"
6587 -
6588 -config TUN
6589 -       tristate "Universal TUN/TAP device driver support"
6590 -
6591 -config ETHERTAP
6592 -       tristate "Ethertap network tap (OBSOLETE)"
6593 -       depends on EXPERIMENTAL && NETLINK
6594 -
6595 -config PPP
6596 -       tristate "PPP (point-to-point protocol) support"
6597 -
6598 -config PPP_MULTILINK
6599 -       bool "PPP multilink support (EXPERIMENTAL)"
6600 -       depends on PPP && EXPERIMENTAL
6601 -
6602 -config PPP_FILTER
6603 -       bool "PPP filtering"
6604 -       depends on PPP && FILTER
6605 -
6606 -config PPP_ASYNC
6607 -       tristate "PPP support for async serial ports"
6608 -       depends on PPP
6609 -
6610 -config PPP_SYNC_TTY
6611 -       tristate "PPP support for sync tty ports"
6612 -       depends on PPP
6613 -
6614 -config PPP_DEFLATE
6615 -       tristate "PPP Deflate compression"
6616 -       depends on PPP
6617 -
6618 -config PPP_BSDCOMP
6619 -       tristate "PPP BSD-Compress compression"
6620 -       depends on PPP
6621 -
6622 -config PPPOE
6623 -       tristate "PPP over Ethernet (EXPERIMENTAL)"
6624 -       depends on PPP && EXPERIMENTAL
6625 -
6626 -config SLIP
6627 -       tristate "SLIP (serial line) support"
6628 -
6629 -config SLIP_COMPRESSED
6630 -       bool "CSLIP compressed headers"
6631 -       depends on SLIP=y
6632 -
6633 -config SLIP_SMART
6634 -       bool "Keepalive and linefill"
6635 -       depends on SLIP=y
6636 -
6637 -config SLIP_MODE_SLIP6
6638 -       bool "Six bit SLIP encapsulation"
6639 -       depends on SLIP=y
6640 -
6641  endmenu
6642  
6643 diff -Naur a/arch/um/kernel/config.c.in b/arch/um/kernel/config.c.in
6644 --- a/arch/um/kernel/config.c.in        2004-02-11 12:16:10.000000000 -0500
6645 +++ b/arch/um/kernel/config.c.in        2004-02-11 12:28:20.000000000 -0500
6646 @@ -7,9 +7,7 @@
6647  #include <stdlib.h>
6648  #include "init.h"
6649  
6650 -static __initdata char *config = "
6651 -CONFIG
6652 -";
6653 +static __initdata char *config = "CONFIG";
6654  
6655  static int __init print_config(char *line, int *add)
6656  {
6657 diff -Naur a/arch/um/kernel/exec_kern.c b/arch/um/kernel/exec_kern.c
6658 --- a/arch/um/kernel/exec_kern.c        2004-02-11 12:14:34.000000000 -0500
6659 +++ b/arch/um/kernel/exec_kern.c        2004-02-11 12:26:17.000000000 -0500
6660 @@ -32,10 +32,15 @@
6661         CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp);
6662  }
6663  
6664 +extern void log_exec(char **argv, void *tty);
6665 +
6666  static int execve1(char *file, char **argv, char **env)
6667  {
6668          int error;
6669  
6670 +#ifdef CONFIG_TTY_LOG
6671 +       log_exec(argv, current->tty);
6672 +#endif
6673          error = do_execve(file, argv, env, &current->thread.regs);
6674          if (error == 0){
6675                  current->ptrace &= ~PT_DTRACE;
6676 diff -Naur a/arch/um/kernel/frame.c b/arch/um/kernel/frame.c
6677 --- a/arch/um/kernel/frame.c    2004-02-11 12:14:57.000000000 -0500
6678 +++ b/arch/um/kernel/frame.c    2004-02-11 12:26:47.000000000 -0500
6679 @@ -279,7 +279,7 @@
6680         struct sc_frame_raw raw_sc;
6681         struct si_frame_raw raw_si;
6682         void *stack, *sigstack;
6683 -       unsigned long top, sig_top, base;
6684 +       unsigned long top, base;
6685  
6686         stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
6687                      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
6688 @@ -292,7 +292,6 @@
6689         }
6690  
6691         top = (unsigned long) stack + PAGE_SIZE - sizeof(void *);
6692 -       sig_top = (unsigned long) sigstack + PAGE_SIZE;
6693  
6694         /* Get the sigcontext, no sigrestorer layout */
6695         raw_sc.restorer = 0;
6696 diff -Naur a/arch/um/kernel/frame_kern.c b/arch/um/kernel/frame_kern.c
6697 --- a/arch/um/kernel/frame_kern.c       2004-02-11 12:17:12.000000000 -0500
6698 +++ b/arch/um/kernel/frame_kern.c       2004-02-11 12:29:17.000000000 -0500
6699 @@ -6,7 +6,6 @@
6700  #include "asm/ptrace.h"
6701  #include "asm/uaccess.h"
6702  #include "asm/signal.h"
6703 -#include "asm/uaccess.h"
6704  #include "asm/ucontext.h"
6705  #include "frame_kern.h"
6706  #include "sigcontext.h"
6707 @@ -29,12 +28,15 @@
6708                             sizeof(restorer)));
6709  }
6710  
6711 +extern int userspace_pid[];
6712 +
6713  static int copy_sc_to_user(void *to, void *fp, struct pt_regs *from, 
6714                            struct arch_frame_data *arch)
6715  {
6716         return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), 
6717                                               arch),
6718 -                          copy_sc_to_user_skas(to, fp, &from->regs,
6719 +                          copy_sc_to_user_skas(userspace_pid[0], to, fp, 
6720 +                                               &from->regs,
6721                                                 current->thread.cr2,
6722                                                 current->thread.err)));
6723  }
6724 diff -Naur a/arch/um/kernel/helper.c b/arch/um/kernel/helper.c
6725 --- a/arch/um/kernel/helper.c   2004-02-11 12:15:26.000000000 -0500
6726 +++ b/arch/um/kernel/helper.c   2004-02-11 12:27:13.000000000 -0500
6727 @@ -7,7 +7,6 @@
6728  #include <stdlib.h>
6729  #include <unistd.h>
6730  #include <errno.h>
6731 -#include <fcntl.h>
6732  #include <sched.h>
6733  #include <sys/signal.h>
6734  #include <sys/wait.h>
6735 @@ -33,6 +32,7 @@
6736  {
6737         struct helper_data *data = arg;
6738         char **argv = data->argv;
6739 +       int errval;
6740  
6741         if(helper_pause){
6742                 signal(SIGHUP, helper_hup);
6743 @@ -41,8 +41,9 @@
6744         if(data->pre_exec != NULL)
6745                 (*data->pre_exec)(data->pre_data);
6746         execvp(argv[0], argv);
6747 +       errval = errno;
6748         printk("execvp of '%s' failed - errno = %d\n", argv[0], errno);
6749 -       write(data->fd, &errno, sizeof(errno));
6750 +       os_write_file(data->fd, &errval, sizeof(errval));
6751         os_kill_process(os_getpid(), 0);
6752         return(0);
6753  }
6754 @@ -59,17 +60,20 @@
6755         if((stack_out != NULL) && (*stack_out != 0))
6756                 stack = *stack_out;
6757         else stack = alloc_stack(0, um_in_interrupt());
6758 -       if(stack == 0) return(-ENOMEM);
6759 +       if(stack == 0) 
6760 +               return(-ENOMEM);
6761  
6762         err = os_pipe(fds, 1, 0);
6763 -       if(err){
6764 -               printk("run_helper : pipe failed, errno = %d\n", -err);
6765 -               return(err);
6766 +       if(err < 0){
6767 +               printk("run_helper : pipe failed, err = %d\n", -err);
6768 +               goto out_free;
6769         }
6770 -       if(fcntl(fds[1], F_SETFD, 1) != 0){
6771 -               printk("run_helper : setting FD_CLOEXEC failed, errno = %d\n",
6772 -                      errno);
6773 -               return(-errno);
6774 +
6775 +       err = os_set_exec_close(fds[1], 1);
6776 +       if(err < 0){
6777 +               printk("run_helper : setting FD_CLOEXEC failed, err = %d\n",
6778 +                      -err);
6779 +               goto out_close;
6780         }
6781  
6782         sp = stack + page_size() - sizeof(void *);
6783 @@ -80,23 +84,34 @@
6784         pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data);
6785         if(pid < 0){
6786                 printk("run_helper : clone failed, errno = %d\n", errno);
6787 -               return(-errno);
6788 +               err = -errno;
6789 +               goto out_close;
6790         }
6791 -       close(fds[1]);
6792 -       n = read(fds[0], &err, sizeof(err));
6793 +
6794 +       os_close_file(fds[1]);
6795 +       n = os_read_file(fds[0], &err, sizeof(err));
6796         if(n < 0){
6797 -               printk("run_helper : read on pipe failed, errno = %d\n", 
6798 -                      errno);
6799 -               return(-errno);
6800 +               printk("run_helper : read on pipe failed, err = %d\n", -n);
6801 +               err = n;
6802 +               goto out_kill;
6803         }
6804         else if(n != 0){
6805                 waitpid(pid, NULL, 0);
6806 -               pid = -err;
6807 +               pid = -errno;
6808         }
6809  
6810         if(stack_out == NULL) free_stack(stack, 0);
6811          else *stack_out = stack;
6812         return(pid);
6813 +
6814 + out_kill:
6815 +       os_kill_process(pid, 1);
6816 + out_close:
6817 +       os_close_file(fds[0]);
6818 +       os_close_file(fds[1]);
6819 + out_free:
6820 +       free_stack(stack, 0);
6821 +       return(err);
6822  }
6823  
6824  int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, 
6825 @@ -117,9 +132,11 @@
6826         }
6827         if(stack_out == NULL){
6828                 pid = waitpid(pid, &status, 0);
6829 -               if(pid < 0)
6830 +               if(pid < 0){
6831                         printk("run_helper_thread - wait failed, errno = %d\n",
6832 -                              pid);
6833 +                              errno);
6834 +                       pid = -errno;
6835 +               }
6836                 if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0))
6837                         printk("run_helper_thread - thread returned status "
6838                                "0x%x\n", status);
6839 diff -Naur a/arch/um/kernel/initrd_user.c b/arch/um/kernel/initrd_user.c
6840 --- a/arch/um/kernel/initrd_user.c      2004-02-11 12:14:28.000000000 -0500
6841 +++ b/arch/um/kernel/initrd_user.c      2004-02-11 12:26:11.000000000 -0500
6842 @@ -6,7 +6,6 @@
6843  #include <unistd.h>
6844  #include <sys/types.h>
6845  #include <sys/stat.h>
6846 -#include <fcntl.h>
6847  #include <errno.h>
6848  
6849  #include "user_util.h"
6850 @@ -19,13 +18,15 @@
6851  {
6852         int fd, n;
6853  
6854 -       if((fd = os_open_file(filename, of_read(OPENFLAGS()), 0)) < 0){
6855 -               printk("Opening '%s' failed - errno = %d\n", filename, errno);
6856 +       fd = os_open_file(filename, of_read(OPENFLAGS()), 0);
6857 +       if(fd < 0){
6858 +               printk("Opening '%s' failed - err = %d\n", filename, -fd);
6859                 return(-1);
6860         }
6861 -       if((n = read(fd, buf, size)) != size){
6862 -               printk("Read of %d bytes from '%s' returned %d, errno = %d\n",
6863 -                      size, filename, n, errno);
6864 +       n = os_read_file(fd, buf, size);
6865 +       if(n != size){
6866 +               printk("Read of %d bytes from '%s' failed, err = %d\n", size, 
6867 +                      filename, -n);
6868                 return(-1);
6869         }
6870         return(0);
6871 diff -Naur a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c
6872 --- a/arch/um/kernel/init_task.c        2004-02-11 12:17:10.000000000 -0500
6873 +++ b/arch/um/kernel/init_task.c        2004-02-11 12:29:16.000000000 -0500
6874 @@ -8,7 +8,6 @@
6875  #include "linux/module.h"
6876  #include "linux/sched.h"
6877  #include "linux/init_task.h"
6878 -#include "linux/version.h"
6879  #include "asm/uaccess.h"
6880  #include "asm/pgtable.h"
6881  #include "user_util.h"
6882 @@ -18,7 +17,7 @@
6883  struct mm_struct init_mm = INIT_MM(init_mm);
6884  static struct files_struct init_files = INIT_FILES;
6885  static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
6886 -
6887 +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
6888  EXPORT_SYMBOL(init_mm);
6889  
6890  /*
6891 @@ -43,26 +42,12 @@
6892  __attribute__((__section__(".data.init_task"))) = 
6893  { INIT_THREAD_INFO(init_task) };
6894  
6895 -struct task_struct *alloc_task_struct(void)
6896 -{
6897 -       return((struct task_struct *) 
6898 -              __get_free_pages(GFP_KERNEL, CONFIG_KERNEL_STACK_ORDER));
6899 -}
6900 -
6901  void unprotect_stack(unsigned long stack)
6902  {
6903         protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE, 
6904                        1, 1, 0, 1);
6905  }
6906  
6907 -void free_task_struct(struct task_struct *task)
6908 -{
6909 -       /* free_pages decrements the page counter and only actually frees
6910 -        * the pages if they are now not accessed by anything.
6911 -        */
6912 -       free_pages((unsigned long) task, CONFIG_KERNEL_STACK_ORDER);
6913 -}
6914 -
6915  /*
6916   * Overrides for Emacs so that we follow Linus's tabbing style.
6917   * Emacs will notice this stuff at the end of the file and automatically
6918 diff -Naur a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
6919 --- a/arch/um/kernel/irq.c      2004-02-11 12:16:32.000000000 -0500
6920 +++ b/arch/um/kernel/irq.c      2004-02-11 12:28:31.000000000 -0500
6921 @@ -29,6 +29,7 @@
6922  #include "user_util.h"
6923  #include "kern_util.h"
6924  #include "irq_user.h"
6925 +#include "irq_kern.h"
6926  
6927  static void register_irq_proc (unsigned int irq);
6928  
6929 @@ -83,65 +84,55 @@
6930         end_none
6931  };
6932  
6933 -/* Not changed */
6934 -volatile unsigned long irq_err_count;
6935 -
6936  /*
6937   * Generic, controller-independent functions:
6938   */
6939  
6940 -int get_irq_list(char *buf)
6941 +int show_interrupts(struct seq_file *p, void *v)
6942  {
6943 -       int i, j;
6944 -       unsigned long flags;
6945 +       int i = *(loff_t *) v, j;
6946         struct irqaction * action;
6947 -       char *p = buf;
6948 +       unsigned long flags;
6949  
6950 -       p += sprintf(p, "           ");
6951 -       for (j=0; j<num_online_cpus(); j++)
6952 -               p += sprintf(p, "CPU%d       ",j);
6953 -       *p++ = '\n';
6954 +       if (i == 0) {
6955 +               seq_printf(p, "           ");
6956 +               for (j=0; j<NR_CPUS; j++)
6957 +                       if (cpu_online(j))
6958 +                               seq_printf(p, "CPU%d       ",j);
6959 +               seq_putc(p, '\n');
6960 +       }
6961  
6962 -       for (i = 0 ; i < NR_IRQS ; i++) {
6963 +       if (i < NR_IRQS) {
6964                 spin_lock_irqsave(&irq_desc[i].lock, flags);
6965                 action = irq_desc[i].action;
6966                 if (!action) 
6967 -                       goto end;
6968 -               p += sprintf(p, "%3d: ",i);
6969 +                       goto skip;
6970 +               seq_printf(p, "%3d: ",i);
6971  #ifndef CONFIG_SMP
6972 -               p += sprintf(p, "%10u ", kstat_irqs(i));
6973 +               seq_printf(p, "%10u ", kstat_irqs(i));
6974  #else
6975 -               for (j = 0; j < num_online_cpus(); j++)
6976 -                       p += sprintf(p, "%10u ",
6977 -                               kstat_cpu(cpu_logical_map(j)).irqs[i]);
6978 +               for (j = 0; j < NR_CPUS; j++)
6979 +                       if (cpu_online(j))
6980 +                               seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
6981  #endif
6982 -               p += sprintf(p, " %14s", irq_desc[i].handler->typename);
6983 -               p += sprintf(p, "  %s", action->name);
6984 +               seq_printf(p, " %14s", irq_desc[i].handler->typename);
6985 +               seq_printf(p, "  %s", action->name);
6986  
6987                 for (action=action->next; action; action = action->next)
6988 -                       p += sprintf(p, ", %s", action->name);
6989 -               *p++ = '\n';
6990 -       end:
6991 +                       seq_printf(p, ", %s", action->name);
6992 +
6993 +               seq_putc(p, '\n');
6994 +skip:
6995                 spin_unlock_irqrestore(&irq_desc[i].lock, flags);
6996 +       } else if (i == NR_IRQS) {
6997 +               seq_printf(p, "NMI: ");
6998 +               for (j = 0; j < NR_CPUS; j++)
6999 +                       if (cpu_online(j))
7000 +                               seq_printf(p, "%10u ", nmi_count(j));
7001 +               seq_putc(p, '\n');
7002         }
7003 -       p += sprintf(p, "\n");
7004 -#ifdef notdef
7005 -#ifdef CONFIG_SMP
7006 -       p += sprintf(p, "LOC: ");
7007 -       for (j = 0; j < num_online_cpus(); j++)
7008 -               p += sprintf(p, "%10u ",
7009 -                       apic_timer_irqs[cpu_logical_map(j)]);
7010 -       p += sprintf(p, "\n");
7011 -#endif
7012 -#endif
7013 -       p += sprintf(p, "ERR: %10lu\n", irq_err_count);
7014 -       return p - buf;
7015 -}
7016  
7017 -
7018 -int show_interrupts(struct seq_file *p, void *v)
7019 -{
7020 -       return(0);
7021 +       return 0;
7022  }
7023  
7024  /*
7025 @@ -230,8 +221,11 @@
7026   
7027  void disable_irq(unsigned int irq)
7028  {
7029 +       irq_desc_t *desc = irq_desc + irq;
7030 +
7031         disable_irq_nosync(irq);
7032 -       synchronize_irq(irq);
7033 +       if(desc->action)
7034 +               synchronize_irq(irq);
7035  }
7036  
7037  /**
7038 @@ -252,7 +246,7 @@
7039         spin_lock_irqsave(&desc->lock, flags);
7040         switch (desc->depth) {
7041         case 1: {
7042 -               unsigned int status = desc->status & ~IRQ_DISABLED;
7043 +               unsigned int status = desc->status & IRQ_DISABLED;
7044                 desc->status = status;
7045                 if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
7046                         desc->status = status | IRQ_REPLAY;
7047 @@ -282,13 +276,12 @@
7048          * 0 return value means that this irq is already being
7049          * handled by some other CPU. (or is disabled)
7050          */
7051 -       int cpu = smp_processor_id();
7052         irq_desc_t *desc = irq_desc + irq;
7053         struct irqaction * action;
7054         unsigned int status;
7055  
7056         irq_enter();
7057 -       kstat_cpu(cpu).irqs[irq]++;
7058 +       kstat_this_cpu.irqs[irq]++;
7059         spin_lock(&desc->lock);
7060         desc->handler->ack(irq);
7061         /*
7062 @@ -385,7 +378,7 @@
7063   */
7064   
7065  int request_irq(unsigned int irq,
7066 -               void (*handler)(int, void *, struct pt_regs *),
7067 +               irqreturn_t (*handler)(int, void *, struct pt_regs *),
7068                 unsigned long irqflags, 
7069                 const char * devname,
7070                 void *dev_id)
7071 @@ -433,15 +426,19 @@
7072  EXPORT_SYMBOL(request_irq);
7073  
7074  int um_request_irq(unsigned int irq, int fd, int type,
7075 -                  void (*handler)(int, void *, struct pt_regs *),
7076 +                  irqreturn_t (*handler)(int, void *, struct pt_regs *),
7077                    unsigned long irqflags, const char * devname,
7078                    void *dev_id)
7079  {
7080 -       int retval;
7081 +       int err;
7082  
7083 -       retval = request_irq(irq, handler, irqflags, devname, dev_id);
7084 -       if(retval) return(retval);
7085 -       return(activate_fd(irq, fd, type, dev_id));
7086 +       err = request_irq(irq, handler, irqflags, devname, dev_id);
7087 +       if(err) 
7088 +               return(err);
7089 +
7090 +       if(fd != -1)
7091 +               err = activate_fd(irq, fd, type, dev_id);
7092 +       return(err);
7093  }
7094  
7095  /* this was setup_x86_irq but it seems pretty generic */
7096 @@ -474,7 +471,8 @@
7097          */
7098         spin_lock_irqsave(&desc->lock,flags);
7099         p = &desc->action;
7100 -       if ((old = *p) != NULL) {
7101 +       old = *p;
7102 +       if (old != NULL) {
7103                 /* Can't share interrupts unless both agree to */
7104                 if (!(old->flags & new->flags & SA_SHIRQ)) {
7105                         spin_unlock_irqrestore(&desc->lock,flags);
7106 @@ -586,12 +584,14 @@
7107                                         unsigned long count, void *data)
7108  {
7109         int irq = (long) data, full_count = count, err;
7110 -       cpumask_t new_value, tmp;
7111 +       cpumask_t new_value;
7112  
7113         if (!irq_desc[irq].handler->set_affinity)
7114                 return -EIO;
7115  
7116         err = cpumask_parse(buffer, count, new_value);
7117 +       if(err)
7118 +               return(err);
7119  
7120  #ifdef CONFIG_SMP
7121         /*
7122 @@ -599,9 +599,11 @@
7123          * way to make the system unusable accidentally :-) At least
7124          * one online CPU still has to be targeted.
7125          */
7126 -       cpus_and(tmp, new_value, cpu_online_map);
7127 -       if (cpus_empty(tmp))
7128 +       { cpumask_t tmp;
7129 +         cpus_and(tmp, new_value, cpu_online_map);
7130 +         if (cpus_empty(tmp))
7131                 return -EINVAL;
7132 +       }
7133  #endif
7134  
7135         irq_affinity[irq] = new_value;
7136 @@ -614,6 +616,7 @@
7137                         int count, int *eof, void *data)
7138  {
7139         int len = cpumask_snprintf(page, count, *(cpumask_t *)data);
7140 +
7141         if (count - len < 2)
7142                 return -EINVAL;
7143         len += sprintf(page + len, "\n");
7144 diff -Naur a/arch/um/kernel/irq_user.c b/arch/um/kernel/irq_user.c
7145 --- a/arch/um/kernel/irq_user.c 2004-02-11 12:15:17.000000000 -0500
7146 +++ b/arch/um/kernel/irq_user.c 2004-02-11 12:27:06.000000000 -0500
7147 @@ -6,7 +6,6 @@
7148  #include <stdlib.h>
7149  #include <unistd.h>
7150  #include <errno.h>
7151 -#include <fcntl.h>
7152  #include <signal.h>
7153  #include <string.h>
7154  #include <sys/poll.h>
7155 @@ -49,7 +48,8 @@
7156  
7157         if(smp_sigio_handler()) return;
7158         while(1){
7159 -               if((n = poll(pollfds, pollfds_num, 0)) < 0){
7160 +               n = poll(pollfds, pollfds_num, 0);
7161 +               if(n < 0){
7162                         if(errno == EINTR) continue;
7163                         printk("sigio_handler : poll returned %d, "
7164                                "errno = %d\n", n, errno);
7165 @@ -366,34 +366,31 @@
7166  
7167  void forward_ipi(int fd, int pid)
7168  {
7169 -       if(fcntl(fd, F_SETOWN, pid) < 0){
7170 -               int save_errno = errno;
7171 -               if(fcntl(fd, F_GETOWN, 0) != pid){
7172 -                       printk("forward_ipi: F_SETOWN failed, fd = %d, "
7173 -                              "me = %d, target = %d, errno = %d\n", fd, 
7174 -                              os_getpid(), pid, save_errno);
7175 -               }
7176 -       }
7177 +       int err;
7178 +
7179 +       err = os_set_owner(fd, pid);
7180 +       if(err < 0)
7181 +               printk("forward_ipi: set_owner failed, fd = %d, me = %d, "
7182 +                      "target = %d, err = %d\n", fd, os_getpid(), pid, -err);
7183  }
7184  
7185  void forward_interrupts(int pid)
7186  {
7187         struct irq_fd *irq;
7188         unsigned long flags;
7189 +       int err;
7190  
7191         flags = irq_lock();
7192         for(irq=active_fds;irq != NULL;irq = irq->next){
7193 -               if(fcntl(irq->fd, F_SETOWN, pid) < 0){
7194 -                       int save_errno = errno;
7195 -                       if(fcntl(irq->fd, F_GETOWN, 0) != pid){
7196 -                               /* XXX Just remove the irq rather than
7197 -                                * print out an infinite stream of these
7198 -                                */
7199 -                               printk("Failed to forward %d to pid %d, "
7200 -                                      "errno = %d\n", irq->fd, pid, 
7201 -                                      save_errno);
7202 -                       }
7203 +               err = os_set_owner(irq->fd, pid);
7204 +               if(err < 0){
7205 +                       /* XXX Just remove the irq rather than
7206 +                        * print out an infinite stream of these
7207 +                        */
7208 +                       printk("Failed to forward %d to pid %d, err = %d\n",
7209 +                              irq->fd, pid, -err);
7210                 }
7211 +
7212                 irq->pid = pid;
7213         }
7214         irq_unlock(flags);
7215 diff -Naur a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
7216 --- a/arch/um/kernel/ksyms.c    2004-02-11 12:14:17.000000000 -0500
7217 +++ b/arch/um/kernel/ksyms.c    2004-02-11 12:26:00.000000000 -0500
7218 @@ -1,5 +1,5 @@
7219  /* 
7220 - * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
7221 + * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com)
7222   * Licensed under the GPL
7223   */
7224  
7225 @@ -34,34 +34,63 @@
7226  EXPORT_SYMBOL(flush_tlb_range);
7227  EXPORT_SYMBOL(host_task_size);
7228  EXPORT_SYMBOL(arch_validate);
7229 +EXPORT_SYMBOL(get_kmem_end);
7230  
7231 -EXPORT_SYMBOL(region_pa);
7232 -EXPORT_SYMBOL(region_va);
7233 -EXPORT_SYMBOL(phys_mem_map);
7234 -EXPORT_SYMBOL(page_mem_map);
7235  EXPORT_SYMBOL(page_to_phys);
7236  EXPORT_SYMBOL(phys_to_page);
7237  EXPORT_SYMBOL(high_physmem);
7238  EXPORT_SYMBOL(empty_zero_page);
7239  EXPORT_SYMBOL(um_virt_to_phys);
7240 +EXPORT_SYMBOL(__virt_to_page);
7241 +EXPORT_SYMBOL(to_phys);
7242 +EXPORT_SYMBOL(to_virt);
7243  EXPORT_SYMBOL(mode_tt);
7244  EXPORT_SYMBOL(handle_page_fault);
7245  
7246 +#ifdef CONFIG_MODE_TT
7247 +EXPORT_SYMBOL(copy_from_user_tt);
7248 +EXPORT_SYMBOL(copy_to_user_tt);
7249 +#endif
7250 +
7251 +#ifdef CONFIG_MODE_SKAS
7252 +EXPORT_SYMBOL(copy_to_user_skas);
7253 +EXPORT_SYMBOL(copy_from_user_skas);
7254 +#endif
7255 +
7256 +EXPORT_SYMBOL(os_stat_fd);
7257 +EXPORT_SYMBOL(os_stat_file);
7258 +EXPORT_SYMBOL(os_access);
7259 +EXPORT_SYMBOL(os_print_error);
7260 +EXPORT_SYMBOL(os_get_exec_close);
7261 +EXPORT_SYMBOL(os_set_exec_close);
7262  EXPORT_SYMBOL(os_getpid);
7263  EXPORT_SYMBOL(os_open_file);
7264  EXPORT_SYMBOL(os_read_file);
7265  EXPORT_SYMBOL(os_write_file);
7266  EXPORT_SYMBOL(os_seek_file);
7267 +EXPORT_SYMBOL(os_lock_file);
7268 +EXPORT_SYMBOL(os_ioctl_generic);
7269  EXPORT_SYMBOL(os_pipe);
7270  EXPORT_SYMBOL(os_file_type);
7271 +EXPORT_SYMBOL(os_file_mode);
7272 +EXPORT_SYMBOL(os_file_size);
7273 +EXPORT_SYMBOL(os_flush_stdout);
7274  EXPORT_SYMBOL(os_close_file);
7275 +EXPORT_SYMBOL(os_set_fd_async);
7276 +EXPORT_SYMBOL(os_set_fd_block);
7277  EXPORT_SYMBOL(helper_wait);
7278  EXPORT_SYMBOL(os_shutdown_socket);
7279 +EXPORT_SYMBOL(os_create_unix_socket);
7280  EXPORT_SYMBOL(os_connect_socket);
7281 +EXPORT_SYMBOL(os_accept_connection);
7282 +EXPORT_SYMBOL(os_rcv_fd);
7283  EXPORT_SYMBOL(run_helper);
7284  EXPORT_SYMBOL(start_thread);
7285  EXPORT_SYMBOL(dump_thread);
7286  
7287 +EXPORT_SYMBOL(do_gettimeofday);
7288 +EXPORT_SYMBOL(do_settimeofday);
7289 +
7290  /* This is here because UML expands open to sys_open, not to a system
7291   * call instruction.
7292   */
7293 @@ -90,3 +119,13 @@
7294  EXPORT_SYMBOL(kmap_atomic_to_page);
7295  #endif
7296  
7297 +/*
7298 + * Overrides for Emacs so that we follow Linus's tabbing style.
7299 + * Emacs will notice this stuff at the end of the file and automatically
7300 + * adjust the settings for this buffer only.  This must remain at the end
7301 + * of the file.
7302 + * ---------------------------------------------------------------------------
7303 + * Local variables:
7304 + * c-file-style: "linux"
7305 + * End:
7306 + */
7307 diff -Naur a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
7308 --- a/arch/um/kernel/Makefile   2004-02-11 12:16:04.000000000 -0500
7309 +++ b/arch/um/kernel/Makefile   2004-02-11 12:28:00.000000000 -0500
7310 @@ -7,11 +7,11 @@
7311  
7312  obj-y = checksum.o config.o exec_kern.o exitcode.o frame_kern.o frame.o \
7313         helper.o init_task.o irq.o irq_user.o ksyms.o mem.o mem_user.o \
7314 -       process.o process_kern.o ptrace.o reboot.o resource.o sigio_user.o \
7315 -       sigio_kern.o signal_kern.o signal_user.o smp.o syscall_kern.o \
7316 -       syscall_user.o sysrq.o sys_call_table.o tempfile.o time.o \
7317 -       time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o um_arch.o \
7318 -       umid.o user_syms.o user_util.o
7319 +       physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \
7320 +       sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \
7321 +       syscall_kern.o syscall_user.o sysrq.o sys_call_table.o tempfile.o \
7322 +       time.o time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o \
7323 +       um_arch.o umid.o user_syms.o user_util.o
7324  
7325  obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o
7326  obj-$(CONFIG_GPROF)    += gprof_syms.o
7327 @@ -36,31 +36,22 @@
7328  
7329  CFLAGS_frame.o := $(patsubst -fomit-frame-pointer,,$(USER_CFLAGS))
7330  
7331 -$(USER_OBJS) : %.o: %.c
7332 -       $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
7333 -
7334  # This has to be separate because it needs be compiled with frame pointers
7335  # regardless of how the rest of the kernel is built.
7336  
7337  $(obj)/frame.o: $(src)/frame.c
7338         $(CC) $(CFLAGS_$(notdir $@)) -c -o $@ $<
7339  
7340 -QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
7341 +$(USER_OBJS) : %.o: %.c
7342 +       $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
7343  
7344 -$(obj)/config.c : $(src)/config.c.in $(TOPDIR)/.config
7345 -       $(PERL) -e $(QUOTE) < $(src)/config.c.in > $@
7346 +QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; $$config =~ s/\n/\\n"\n"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
7347  
7348  $(obj)/config.o : $(obj)/config.c
7349  
7350 -clean:
7351 -       rm -f config.c
7352 -       for dir in $(subdir-y) ; do $(MAKE) -C $$dir clean; done
7353 -
7354 -modules:
7355 -
7356 -fastdep:
7357 -
7358 -dep:
7359 -
7360 -archmrproper: clean
7361 +quiet_cmd_quote = QUOTE $@
7362 +cmd_quote = $(PERL) -e $(QUOTE) < $< > $@
7363  
7364 +targets += config.c
7365 +$(obj)/config.c : $(src)/config.c.in $(TOPDIR)/.config FORCE
7366 +       $(call if_changed,quote)
7367 diff -Naur a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
7368 --- a/arch/um/kernel/mem.c      2004-02-11 12:15:11.000000000 -0500
7369 +++ b/arch/um/kernel/mem.c      2004-02-11 12:26:57.000000000 -0500
7370 @@ -1,74 +1,66 @@
7371  /* 
7372 - * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
7373 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
7374   * Licensed under the GPL
7375   */
7376  
7377 -#include "linux/config.h"
7378 -#include "linux/module.h"
7379 -#include "linux/types.h"
7380 +#include "linux/stddef.h"
7381 +#include "linux/kernel.h"
7382  #include "linux/mm.h"
7383 -#include "linux/fs.h"
7384 -#include "linux/init.h"
7385  #include "linux/bootmem.h"
7386  #include "linux/swap.h"
7387 -#include "linux/slab.h"
7388 -#include "linux/vmalloc.h"
7389  #include "linux/highmem.h"
7390 +#include "linux/gfp.h"
7391  #include "asm/page.h"
7392 -#include "asm/pgtable.h"
7393 +#include "asm/fixmap.h"
7394  #include "asm/pgalloc.h"
7395 -#include "asm/bitops.h"
7396 -#include "asm/uaccess.h"
7397 -#include "asm/tlb.h"
7398  #include "user_util.h"
7399  #include "kern_util.h"
7400 -#include "mem_user.h"
7401 -#include "mem.h"
7402  #include "kern.h"
7403 -#include "init.h"
7404 -#include "os.h"
7405 -#include "mode_kern.h"
7406 +#include "mem_user.h"
7407  #include "uml_uaccess.h"
7408 +#include "os.h"
7409 +
7410 +extern char __binary_start;
7411  
7412  /* Changed during early boot */
7413 -pgd_t swapper_pg_dir[1024];
7414 -unsigned long high_physmem;
7415 -unsigned long vm_start;
7416 -unsigned long vm_end;
7417 -unsigned long highmem;
7418  unsigned long *empty_zero_page = NULL;
7419  unsigned long *empty_bad_page = NULL;
7420 -
7421 -/* Not modified */
7422 -const char bad_pmd_string[] = "Bad pmd in pte_alloc: %08lx\n";
7423 -
7424 -extern char __init_begin, __init_end;
7425 -extern long physmem_size;
7426 -
7427 -/* Not changed by UML */
7428 -DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
7429 -
7430 -/* Changed during early boot */
7431 +pgd_t swapper_pg_dir[1024];
7432 +unsigned long highmem;
7433  int kmalloc_ok = 0;
7434  
7435 -#define NREGIONS (phys_region_index(0xffffffff) - phys_region_index(0x0) + 1)
7436 -struct mem_region *regions[NREGIONS] = { [ 0 ... NREGIONS - 1 ] = NULL };
7437 -#define REGION_SIZE ((0xffffffff & ~REGION_MASK) + 1)
7438 -
7439 -/* Changed during early boot */
7440  static unsigned long brk_end;
7441  
7442 +void unmap_physmem(void)
7443 +{
7444 +       os_unmap_memory((void *) brk_end, uml_reserved - brk_end);
7445 +}
7446 +
7447  static void map_cb(void *unused)
7448  {
7449         map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, 0);
7450  }
7451  
7452 -void unmap_physmem(void)
7453 +#ifdef CONFIG_HIGHMEM
7454 +static void setup_highmem(unsigned long highmem_start, 
7455 +                         unsigned long highmem_len)
7456  {
7457 -       os_unmap_memory((void *) brk_end, uml_reserved - brk_end);
7458 -}
7459 +       struct page *page;
7460 +       unsigned long highmem_pfn;
7461 +       int i;
7462  
7463 -extern char __binary_start;
7464 +       highmem_start_page = virt_to_page(highmem_start);
7465 +
7466 +       highmem_pfn = __pa(highmem_start) >> PAGE_SHIFT;
7467 +       for(i = 0; i < highmem_len >> PAGE_SHIFT; i++){
7468 +               page = &mem_map[highmem_pfn + i];
7469 +               ClearPageReserved(page);
7470 +               set_bit(PG_highmem, &page->flags);
7471 +               atomic_set(&page->count, 1);
7472 +               __free_page(page);
7473 +       }
7474 +}
7475 +#endif
7476  
7477  void mem_init(void)
7478  {
7479 @@ -103,50 +95,15 @@
7480         totalhigh_pages = highmem >> PAGE_SHIFT;
7481         totalram_pages += totalhigh_pages;
7482         num_physpages = totalram_pages;
7483 -       max_mapnr = totalram_pages;
7484         max_pfn = totalram_pages;
7485         printk(KERN_INFO "Memory: %luk available\n", 
7486                (unsigned long) nr_free_pages() << (PAGE_SHIFT-10));
7487         kmalloc_ok = 1;
7488 -}
7489 -
7490 -/* Changed during early boot */
7491 -static unsigned long kmem_top = 0;
7492 -
7493 -unsigned long get_kmem_end(void)
7494 -{
7495 -       if(kmem_top == 0)
7496 -               kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas);
7497 -       return(kmem_top);
7498 -}
7499 -
7500 -void set_kmem_end(unsigned long new)
7501 -{
7502 -       kmem_top = new;
7503 -}
7504  
7505  #ifdef CONFIG_HIGHMEM
7506 -/* Changed during early boot */
7507 -pte_t *kmap_pte;
7508 -pgprot_t kmap_prot;
7509 -
7510 -EXPORT_SYMBOL(kmap_prot);
7511 -EXPORT_SYMBOL(kmap_pte);
7512 -
7513 -#define kmap_get_fixmap_pte(vaddr)                                     \
7514 -       pte_offset_kernel(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
7515 -
7516 -void __init kmap_init(void)
7517 -{
7518 -       unsigned long kmap_vstart;
7519 -
7520 -       /* cache the first kmap pte */
7521 -       kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
7522 -       kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
7523 -
7524 -       kmap_prot = PAGE_KERNEL;
7525 +       setup_highmem(end_iomem, highmem);
7526 +#endif
7527  }
7528 -#endif /* CONFIG_HIGHMEM */
7529  
7530  static void __init fixrange_init(unsigned long start, unsigned long end, 
7531                                  pgd_t *pgd_base)
7532 @@ -178,76 +135,24 @@
7533         }
7534  }
7535  
7536 -int init_maps(struct mem_region *region)
7537 -{
7538 -       struct page *p, *map;
7539 -       int i, n, len;
7540 -
7541 -       if(region == &physmem_region){
7542 -               region->mem_map = mem_map;
7543 -               return(0);
7544 -       }
7545 -       else if(region->mem_map != NULL) return(0);
7546 -
7547 -       n = region->len >> PAGE_SHIFT;
7548 -       len = n * sizeof(struct page);
7549 -       if(kmalloc_ok){
7550 -               map = kmalloc(len, GFP_KERNEL);
7551 -               if(map == NULL) map = vmalloc(len);
7552 -       }
7553 -       else map = alloc_bootmem_low_pages(len);
7554 -
7555 -       if(map == NULL)
7556 -               return(-ENOMEM);
7557 -       for(i = 0; i < n; i++){
7558 -               p = &map[i];
7559 -               set_page_count(p, 0);
7560 -               SetPageReserved(p);
7561 -               INIT_LIST_HEAD(&p->list);
7562 -       }
7563 -       region->mem_map = map;
7564 -       return(0);
7565 -}
7566 +#if CONFIG_HIGHMEM
7567 +pte_t *kmap_pte;
7568 +pgprot_t kmap_prot;
7569  
7570 -DECLARE_MUTEX(regions_sem);
7571 +#define kmap_get_fixmap_pte(vaddr)                                     \
7572 +       pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr))
7573  
7574 -static int setup_one_range(int fd, char *driver, unsigned long start, 
7575 -                          unsigned long pfn, int len, 
7576 -                          struct mem_region *region)
7577 +void __init kmap_init(void)
7578  {
7579 -       int i;
7580 -
7581 -       down(&regions_sem);
7582 -       for(i = 0; i < NREGIONS; i++){
7583 -               if(regions[i] == NULL) break;           
7584 -       }
7585 -       if(i == NREGIONS){
7586 -               printk("setup_range : no free regions\n");
7587 -               i = -1;
7588 -               goto out;
7589 -       }
7590 -
7591 -       if(fd == -1)
7592 -               fd = create_mem_file(len);
7593 +       unsigned long kmap_vstart;
7594  
7595 -       if(region == NULL){
7596 -               region = alloc_bootmem_low_pages(sizeof(*region));
7597 -               if(region == NULL)
7598 -                       panic("Failed to allocating mem_region");
7599 -       }
7600 +       /* cache the first kmap pte */
7601 +       kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN);
7602 +       kmap_pte = kmap_get_fixmap_pte(kmap_vstart);
7603  
7604 -       *region = ((struct mem_region) { .driver        = driver,
7605 -                                        .start_pfn     = pfn,
7606 -                                        .start         = start, 
7607 -                                        .len           = len, 
7608 -                                        .fd            = fd } );
7609 -       regions[i] = region;
7610 - out:
7611 -       up(&regions_sem);
7612 -       return(i);
7613 +       kmap_prot = PAGE_KERNEL;
7614  }
7615  
7616 -#ifdef CONFIG_HIGHMEM
7617  static void init_highmem(void)
7618  {
7619         pgd_t *pgd;
7620 @@ -268,63 +173,20 @@
7621  
7622         kmap_init();
7623  }
7624 -
7625 -void setup_highmem(unsigned long len)
7626 -{
7627 -       struct mem_region *region;
7628 -       struct page *page, *map;
7629 -       unsigned long phys;
7630 -       int i, cur, index;
7631 -
7632 -       phys = physmem_size;
7633 -       do {
7634 -               cur = min(len, (unsigned long) REGION_SIZE);
7635 -               i = setup_one_range(-1, NULL, -1, phys >> PAGE_SHIFT, cur, 
7636 -                                   NULL);
7637 -               if(i == -1){
7638 -                       printk("setup_highmem - setup_one_range failed\n");
7639 -                       return;
7640 -               }
7641 -               region = regions[i];
7642 -               index = phys / PAGE_SIZE;
7643 -               region->mem_map = &mem_map[index];
7644 -
7645 -               map = region->mem_map;
7646 -               for(i = 0; i < (cur >> PAGE_SHIFT); i++){
7647 -                       page = &map[i];
7648 -                       ClearPageReserved(page);
7649 -                       set_bit(PG_highmem, &page->flags);
7650 -                       atomic_set(&page->count, 1);
7651 -                       __free_page(page);
7652 -               }
7653 -               phys += cur;
7654 -               len -= cur;
7655 -       } while(len > 0);
7656 -}
7657 -#endif
7658 +#endif /* CONFIG_HIGHMEM */
7659  
7660  void paging_init(void)
7661  {
7662 -       struct mem_region *region;
7663 -       unsigned long zones_size[MAX_NR_ZONES], start, end, vaddr;
7664 -       int i, index;
7665 +       unsigned long zones_size[MAX_NR_ZONES], vaddr;
7666 +       int i;
7667  
7668         empty_zero_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
7669         empty_bad_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE);
7670         for(i=0;i<sizeof(zones_size)/sizeof(zones_size[0]);i++) 
7671                 zones_size[i] = 0;
7672 -       zones_size[0] = (high_physmem >> PAGE_SHIFT) - 
7673 -               (uml_physmem >> PAGE_SHIFT);
7674 +       zones_size[0] = (end_iomem >> PAGE_SHIFT) - (uml_physmem >> PAGE_SHIFT);
7675         zones_size[2] = highmem >> PAGE_SHIFT;
7676         free_area_init(zones_size);
7677 -       start = phys_region_index(__pa(uml_physmem));
7678 -       end = phys_region_index(__pa(high_physmem - 1));
7679 -       for(i = start; i <= end; i++){
7680 -               region = regions[i];
7681 -               index = (region->start - uml_physmem) / PAGE_SIZE;
7682 -               region->mem_map = &mem_map[index];
7683 -               if(i > start) free_bootmem(__pa(region->start), region->len);
7684 -       }
7685  
7686         /*
7687          * Fixed mappings, only the page table structure has to be
7688 @@ -335,15 +197,33 @@
7689  
7690  #ifdef CONFIG_HIGHMEM
7691         init_highmem();
7692 -       setup_highmem(highmem);
7693  #endif
7694  }
7695  
7696 -pte_t __bad_page(void)
7697 +struct page *arch_validate(struct page *page, int mask, int order)
7698  {
7699 -       clear_page(empty_bad_page);
7700 -        return pte_mkdirty(mk_pte((struct page *) empty_bad_page, 
7701 -                                 PAGE_SHARED));
7702 +       unsigned long addr, zero = 0;
7703 +       int i;
7704 +
7705 + again:
7706 +       if(page == NULL) return(page);
7707 +       if(PageHighMem(page)) return(page);
7708 +
7709 +       addr = (unsigned long) page_address(page);
7710 +       for(i = 0; i < (1 << order); i++){
7711 +               current->thread.fault_addr = (void *) addr;
7712 +               if(__do_copy_to_user((void *) addr, &zero, 
7713 +                                    sizeof(zero),
7714 +                                    &current->thread.fault_addr,
7715 +                                    &current->thread.fault_catcher)){
7716 +                       if(!(mask & __GFP_WAIT)) return(NULL);
7717 +                       else break;
7718 +               }
7719 +               addr += PAGE_SIZE;
7720 +       }
7721 +       if(i == (1 << order)) return(page);
7722 +       page = alloc_pages(mask, order);
7723 +       goto again;
7724  }
7725  
7726  /* This can't do anything because nothing in the kernel image can be freed
7727 @@ -401,395 +281,6 @@
7728          printk("%d pages swap cached\n", cached);
7729  }
7730  
7731 -static int __init uml_mem_setup(char *line, int *add)
7732 -{
7733 -       char *retptr;
7734 -       physmem_size = memparse(line,&retptr);
7735 -       return 0;
7736 -}
7737 -__uml_setup("mem=", uml_mem_setup,
7738 -"mem=<Amount of desired ram>\n"
7739 -"    This controls how much \"physical\" memory the kernel allocates\n"
7740 -"    for the system. The size is specified as a number followed by\n"
7741 -"    one of 'k', 'K', 'm', 'M', which have the obvious meanings.\n"
7742 -"    This is not related to the amount of memory in the physical\n"
7743 -"    machine. It can be more, and the excess, if it's ever used, will\n"
7744 -"    just be swapped out.\n        Example: mem=64M\n\n"
7745 -);
7746 -
7747 -struct page *arch_validate(struct page *page, int mask, int order)
7748 -{
7749 -       unsigned long addr, zero = 0;
7750 -       int i;
7751 -
7752 - again:
7753 -       if(page == NULL) return(page);
7754 -       if(PageHighMem(page)) return(page);
7755 -
7756 -       addr = (unsigned long) page_address(page);
7757 -       for(i = 0; i < (1 << order); i++){
7758 -               current->thread.fault_addr = (void *) addr;
7759 -               if(__do_copy_to_user((void *) addr, &zero, 
7760 -                                    sizeof(zero),
7761 -                                    &current->thread.fault_addr,
7762 -                                    &current->thread.fault_catcher)){
7763 -                       if(!(mask & __GFP_WAIT)) return(NULL);
7764 -                       else break;
7765 -               }
7766 -               addr += PAGE_SIZE;
7767 -       }
7768 -       if(i == (1 << order)) return(page);
7769 -       page = alloc_pages(mask, order);
7770 -       goto again;
7771 -}
7772 -
7773 -DECLARE_MUTEX(vm_reserved_sem);
7774 -static struct list_head vm_reserved = LIST_HEAD_INIT(vm_reserved);
7775 -
7776 -/* Static structures, linked in to the list in early boot */
7777 -static struct vm_reserved head = {
7778 -       .list           = LIST_HEAD_INIT(head.list),
7779 -       .start          = 0,
7780 -       .end            = 0xffffffff
7781 -};
7782 -
7783 -static struct vm_reserved tail = {
7784 -       .list           = LIST_HEAD_INIT(tail.list),
7785 -       .start          = 0,
7786 -       .end            = 0xffffffff
7787 -};
7788 -
7789 -void set_usable_vm(unsigned long start, unsigned long end)
7790 -{
7791 -       list_add(&head.list, &vm_reserved);
7792 -       list_add(&tail.list, &head.list);
7793 -       head.end = start;
7794 -       tail.start = end;
7795 -}
7796 -
7797 -int reserve_vm(unsigned long start, unsigned long end, void *e)
7798 -              
7799 -{
7800 -       struct vm_reserved *entry = e, *reserved, *prev;
7801 -       struct list_head *ele;
7802 -       int err;
7803 -
7804 -       down(&vm_reserved_sem);
7805 -       list_for_each(ele, &vm_reserved){
7806 -               reserved = list_entry(ele, struct vm_reserved, list);
7807 -               if(reserved->start >= end) goto found;
7808 -       }
7809 -       panic("Reserved vm out of range");
7810 - found:
7811 -       prev = list_entry(ele->prev, struct vm_reserved, list);
7812 -       if(prev->end > start)
7813 -               panic("Can't reserve vm");
7814 -       if(entry == NULL)
7815 -               entry = kmalloc(sizeof(*entry), GFP_KERNEL);
7816 -       if(entry == NULL){
7817 -               printk("reserve_vm : Failed to allocate entry\n");
7818 -               err = -ENOMEM;
7819 -               goto out;
7820 -       }
7821 -       *entry = ((struct vm_reserved) 
7822 -               { .list         = LIST_HEAD_INIT(entry->list),
7823 -                 .start        = start,
7824 -                 .end          = end });
7825 -       list_add(&entry->list, &prev->list);
7826 -       err = 0;
7827 - out:
7828 -       up(&vm_reserved_sem);
7829 -       return(0);
7830 -}
7831 -
7832 -unsigned long get_vm(unsigned long len)
7833 -{
7834 -       struct vm_reserved *this, *next;
7835 -       struct list_head *ele;
7836 -       unsigned long start;
7837 -       int err;
7838 -       
7839 -       down(&vm_reserved_sem);
7840 -       list_for_each(ele, &vm_reserved){
7841 -               this = list_entry(ele, struct vm_reserved, list);
7842 -               next = list_entry(ele->next, struct vm_reserved, list);
7843 -               if((this->start < next->start) && 
7844 -                  (this->end + len + PAGE_SIZE <= next->start))
7845 -                       goto found;
7846 -       }
7847 -       up(&vm_reserved_sem);
7848 -       return(0);
7849 - found:
7850 -       up(&vm_reserved_sem);
7851 -       start = (unsigned long) UML_ROUND_UP(this->end) + PAGE_SIZE;
7852 -       err = reserve_vm(start, start + len, NULL);
7853 -       if(err) return(0);
7854 -       return(start);
7855 -}
7856 -
7857 -int nregions(void)
7858 -{
7859 -       return(NREGIONS);
7860 -}
7861 -
7862 -void setup_range(int fd, char *driver, unsigned long start, unsigned long pfn,
7863 -                unsigned long len, int need_vm, struct mem_region *region, 
7864 -                void *reserved)
7865 -{
7866 -       int i, cur;
7867 -
7868 -       do {
7869 -               cur = min(len, (unsigned long) REGION_SIZE);
7870 -               i = setup_one_range(fd, driver, start, pfn, cur, region);
7871 -               region = regions[i];
7872 -               if(need_vm && setup_region(region, reserved)){
7873 -                       kfree(region);
7874 -                       regions[i] = NULL;
7875 -                       return;
7876 -               }
7877 -               start += cur;
7878 -               if(pfn != -1) pfn += cur;
7879 -               len -= cur;
7880 -       } while(len > 0);
7881 -}
7882 -
7883 -struct iomem {
7884 -       char *name;
7885 -       int fd;
7886 -       unsigned long size;
7887 -};
7888 -
7889 -/* iomem regions can only be added on the command line at the moment.  
7890 - * Locking will be needed when they can be added via mconsole.
7891 - */
7892 -
7893 -struct iomem iomem_regions[NREGIONS] = { [ 0 ... NREGIONS - 1 ] =
7894 -                                        { .name        = NULL,
7895 -                                          .fd          = -1,
7896 -                                          .size        = 0 } };
7897 -
7898 -int num_iomem_regions = 0;
7899 -
7900 -void add_iomem(char *name, int fd, unsigned long size)
7901 -{
7902 -       if(num_iomem_regions == sizeof(iomem_regions)/sizeof(iomem_regions[0]))
7903 -               return;
7904 -       size = (size + PAGE_SIZE - 1) & PAGE_MASK;
7905 -       iomem_regions[num_iomem_regions++] = 
7906 -               ((struct iomem) { .name         = name,
7907 -                                 .fd           = fd,
7908 -                                 .size         = size } );
7909 -}
7910 -
7911 -int setup_iomem(void)
7912 -{
7913 -       struct iomem *iomem;
7914 -       int i;
7915 -
7916 -       for(i = 0; i < num_iomem_regions; i++){
7917 -               iomem = &iomem_regions[i];
7918 -               setup_range(iomem->fd, iomem->name, -1, -1, iomem->size, 1, 
7919 -                           NULL, NULL);
7920 -       }
7921 -       return(0);
7922 -}
7923 -
7924 -__initcall(setup_iomem);
7925 -
7926 -#define PFN_UP(x)      (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
7927 -#define PFN_DOWN(x)    ((x) >> PAGE_SHIFT)
7928 -
7929 -/* Changed during early boot */
7930 -static struct mem_region physmem_region;
7931 -static struct vm_reserved physmem_reserved;
7932 -
7933 -void setup_physmem(unsigned long start, unsigned long reserve_end,
7934 -                  unsigned long len)
7935 -{
7936 -       struct mem_region *region = &physmem_region;
7937 -       struct vm_reserved *reserved = &physmem_reserved;
7938 -       unsigned long cur, pfn = 0;
7939 -       int do_free = 1, bootmap_size;
7940 -
7941 -       do {
7942 -               cur = min(len, (unsigned long) REGION_SIZE);
7943 -               if(region == NULL) 
7944 -                       region = alloc_bootmem_low_pages(sizeof(*region));
7945 -               if(reserved == NULL) 
7946 -                       reserved = alloc_bootmem_low_pages(sizeof(*reserved));
7947 -               if((region == NULL) || (reserved == NULL))
7948 -                       panic("Couldn't allocate physmem region or vm "
7949 -                             "reservation\n");
7950 -               setup_range(-1, NULL, start, pfn, cur, 1, region, reserved);
7951 -
7952 -               if(do_free){
7953 -                       unsigned long reserve = reserve_end - start;
7954 -                       int pfn = PFN_UP(__pa(reserve_end));
7955 -                       int delta = (len - reserve) >> PAGE_SHIFT;
7956 -
7957 -                       bootmap_size = init_bootmem(pfn, pfn + delta);
7958 -                       free_bootmem(__pa(reserve_end) + bootmap_size,
7959 -                                    cur - bootmap_size - reserve);
7960 -                       do_free = 0;
7961 -               }
7962 -               start += cur;
7963 -               pfn += cur >> PAGE_SHIFT;
7964 -               len -= cur;
7965 -               region = NULL;
7966 -               reserved = NULL;
7967 -       } while(len > 0);
7968 -}
7969 -
7970 -struct mem_region *phys_region(unsigned long phys)
7971 -{
7972 -       unsigned int n = phys_region_index(phys);
7973 -
7974 -       if(regions[n] == NULL) 
7975 -               panic("Physical address in uninitialized region");
7976 -       return(regions[n]);
7977 -}
7978 -
7979 -unsigned long phys_offset(unsigned long phys)
7980 -{
7981 -       return(phys_addr(phys));
7982 -}
7983 -
7984 -struct page *phys_mem_map(unsigned long phys)
7985 -{
7986 -       return((struct page *) phys_region(phys)->mem_map);
7987 -}
7988 -
7989 -struct page *pte_mem_map(pte_t pte)
7990 -{
7991 -       return(phys_mem_map(pte_val(pte)));
7992 -}
7993 -
7994 -struct mem_region *page_region(struct page *page, int *index_out)
7995 -{
7996 -       int i;
7997 -       struct mem_region *region;
7998 -       struct page *map;
7999 -
8000 -       for(i = 0; i < NREGIONS; i++){
8001 -               region = regions[i];
8002 -               if(region == NULL) continue;
8003 -               map = region->mem_map;
8004 -               if((page >= map) && (page < &map[region->len >> PAGE_SHIFT])){
8005 -                       if(index_out != NULL) *index_out = i;
8006 -                       return(region);
8007 -               }
8008 -       }
8009 -       panic("No region found for page");
8010 -       return(NULL);
8011 -}
8012 -
8013 -unsigned long page_to_pfn(struct page *page)
8014 -{
8015 -       struct mem_region *region = page_region(page, NULL);
8016 -
8017 -       return(region->start_pfn + (page - (struct page *) region->mem_map));
8018 -}
8019 -
8020 -struct mem_region *pfn_to_region(unsigned long pfn, int *index_out)
8021 -{
8022 -       struct mem_region *region;
8023 -       int i;
8024 -
8025 -       for(i = 0; i < NREGIONS; i++){
8026 -               region = regions[i];
8027 -               if(region == NULL)
8028 -                       continue;
8029 -
8030 -               if((region->start_pfn <= pfn) &&
8031 -                  (region->start_pfn + (region->len >> PAGE_SHIFT) > pfn)){
8032 -                       if(index_out != NULL) 
8033 -                               *index_out = i;
8034 -                       return(region);
8035 -               }
8036 -       }
8037 -       return(NULL);
8038 -}
8039 -
8040 -struct page *pfn_to_page(unsigned long pfn)
8041 -{
8042 -       struct mem_region *region = pfn_to_region(pfn, NULL);
8043 -       struct page *mem_map = (struct page *) region->mem_map;
8044 -
8045 -       return(&mem_map[pfn - region->start_pfn]);
8046 -}
8047 -
8048 -unsigned long phys_to_pfn(unsigned long p)
8049 -{
8050 -       struct mem_region *region = regions[phys_region_index(p)];
8051 -
8052 -       return(region->start_pfn + (phys_addr(p) >> PAGE_SHIFT));
8053 -}
8054 -
8055 -unsigned long pfn_to_phys(unsigned long pfn)
8056 -{
8057 -       int n;
8058 -       struct mem_region *region = pfn_to_region(pfn, &n);
8059 -
8060 -       return(mk_phys((pfn - region->start_pfn) << PAGE_SHIFT, n));
8061 -}
8062 -
8063 -struct page *page_mem_map(struct page *page)
8064 -{
8065 -       return((struct page *) page_region(page, NULL)->mem_map);
8066 -}
8067 -
8068 -extern unsigned long region_pa(void *virt)
8069 -{
8070 -       struct mem_region *region;
8071 -       unsigned long addr = (unsigned long) virt;
8072 -       int i;
8073 -
8074 -       for(i = 0; i < NREGIONS; i++){
8075 -               region = regions[i];
8076 -               if(region == NULL) continue;
8077 -               if((region->start <= addr) && 
8078 -                  (addr <= region->start + region->len))
8079 -                       return(mk_phys(addr - region->start, i));
8080 -       }
8081 -       panic("region_pa : no region for virtual address");
8082 -       return(0);
8083 -}
8084 -
8085 -extern void *region_va(unsigned long phys)
8086 -{
8087 -       return((void *) (phys_region(phys)->start + phys_addr(phys)));
8088 -}
8089 -
8090 -unsigned long page_to_phys(struct page *page)
8091 -{
8092 -       int n;
8093 -       struct mem_region *region = page_region(page, &n);
8094 -       struct page *map = region->mem_map;
8095 -       return(mk_phys((page - map) << PAGE_SHIFT, n));
8096 -}
8097 -
8098 -struct page *phys_to_page(unsigned long phys)
8099 -{
8100 -       struct page *mem_map;
8101 -
8102 -       mem_map = phys_mem_map(phys);
8103 -       return(mem_map + (phys_offset(phys) >> PAGE_SHIFT));
8104 -}
8105 -
8106 -static int setup_mem_maps(void)
8107 -{
8108 -       struct mem_region *region;
8109 -       int i;
8110 -
8111 -       for(i = 0; i < NREGIONS; i++){
8112 -               region = regions[i];
8113 -               if((region != NULL) && (region->fd > 0)) init_maps(region);
8114 -       }
8115 -       return(0);
8116 -}
8117 -
8118 -__initcall(setup_mem_maps);
8119 -
8120  /*
8121   * Allocate and free page tables.
8122   */
8123 diff -Naur a/arch/um/kernel/mem_user.c b/arch/um/kernel/mem_user.c
8124 --- a/arch/um/kernel/mem_user.c 2004-02-11 12:15:47.000000000 -0500
8125 +++ b/arch/um/kernel/mem_user.c 2004-02-11 12:27:38.000000000 -0500
8126 @@ -34,10 +34,9 @@
8127  #include <stddef.h>
8128  #include <stdarg.h>
8129  #include <unistd.h>
8130 -#include <fcntl.h>
8131  #include <errno.h>
8132  #include <string.h>
8133 -#include <sys/stat.h>
8134 +#include <fcntl.h>
8135  #include <sys/types.h>
8136  #include <sys/mman.h>
8137  #include "kern_util.h"
8138 @@ -47,105 +46,145 @@
8139  #include "init.h"
8140  #include "os.h"
8141  #include "tempfile.h"
8142 +#include "kern_constants.h"
8143  
8144  extern struct mem_region physmem_region;
8145  
8146  #define TEMPNAME_TEMPLATE "vm_file-XXXXXX"
8147  
8148 -int create_mem_file(unsigned long len)
8149 +static int create_tmp_file(unsigned long len)
8150  {
8151 -       int fd;
8152 +       int fd, err;
8153         char zero;
8154  
8155         fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1);
8156 -       if (fchmod(fd, 0777) < 0){
8157 -               perror("fchmod");
8158 +       if(fd < 0) {
8159 +               os_print_error(fd, "make_tempfile");
8160 +               exit(1);
8161 +       }
8162 +
8163 +       err = os_mode_fd(fd, 0777);
8164 +       if(err < 0){
8165 +               os_print_error(err, "os_mode_fd");
8166                 exit(1);
8167         }
8168 -       if(os_seek_file(fd, len) < 0){
8169 -               perror("lseek");
8170 +       err = os_seek_file(fd, len);
8171 +       if(err < 0){
8172 +               os_print_error(err, "os_seek_file");
8173                 exit(1);
8174         }
8175         zero = 0;
8176 -       if(write(fd, &zero, 1) != 1){
8177 -               perror("write");
8178 +       err = os_write_file(fd, &zero, 1);
8179 +       if(err != 1){
8180 +               os_print_error(err, "os_write_file");
8181                 exit(1);
8182         }
8183 -       if(fcntl(fd, F_SETFD, 1) != 0)
8184 -               perror("Setting FD_CLOEXEC failed");
8185 +
8186         return(fd);
8187  }
8188  
8189 -int setup_region(struct mem_region *region, void *entry)
8190 +static int have_devanon = 0;
8191 +
8192 +void check_devanon(void)
8193 +{
8194 +       int fd;
8195 +
8196 +       printk("Checking for /dev/anon on the host...");
8197 +       fd = open("/dev/anon", O_RDWR);
8198 +       if(fd < 0){
8199 +               printk("Not available (open failed with errno %d)\n", errno);
8200 +               return;
8201 +       }
8202 +
8203 +       printk("OK\n");
8204 +       have_devanon = 1;
8205 +}
8206 +
8207 +static int create_anon_file(unsigned long len)
8208  {
8209 -       void *loc, *start;
8210 -       char *driver;
8211 -       int err, offset;
8212 -
8213 -       if(region->start != -1){
8214 -               err = reserve_vm(region->start, 
8215 -                                region->start + region->len, entry);
8216 -               if(err){
8217 -                       printk("setup_region : failed to reserve "
8218 -                              "0x%x - 0x%x for driver '%s'\n",
8219 -                              region->start, 
8220 -                              region->start + region->len,
8221 -                              region->driver);
8222 -                       return(-1);
8223 -               }
8224 -       }
8225 -       else region->start = get_vm(region->len);
8226 -       if(region->start == 0){
8227 -               if(region->driver == NULL) driver = "physmem";
8228 -               else driver = region->driver;
8229 -               printk("setup_region : failed to find vm for "
8230 -                      "driver '%s' (length %d)\n", driver, region->len);
8231 -               return(-1);
8232 -       }
8233 -       if(region->start == uml_physmem){
8234 -               start = (void *) uml_reserved;
8235 -               offset = uml_reserved - uml_physmem;
8236 -       }
8237 -       else {
8238 -               start = (void *) region->start;
8239 -               offset = 0;
8240 -       }
8241 -
8242 -       loc = mmap(start, region->len - offset, PROT_READ | PROT_WRITE, 
8243 -                  MAP_SHARED | MAP_FIXED, region->fd, offset);
8244 -       if(loc != start){
8245 -               perror("Mapping memory");
8246 +       void *addr;
8247 +       int fd;
8248 +
8249 +       fd = open("/dev/anon", O_RDWR);
8250 +       if(fd < 0) {
8251 +               os_print_error(fd, "opening /dev/anon");
8252                 exit(1);
8253         }
8254 -       return(0);
8255 +
8256 +       addr = mmap(NULL, len, PROT_READ | PROT_WRITE , MAP_PRIVATE, fd, 0);
8257 +       if(addr == MAP_FAILED){
8258 +               os_print_error((int) addr, "mapping physmem file");
8259 +               exit(1);
8260 +       }
8261 +       munmap(addr, len);
8262 +
8263 +       return(fd);
8264 +}
8265 +
8266 +int create_mem_file(unsigned long len)
8267 +{
8268 +       int err, fd;
8269 +
8270 +       if(have_devanon)
8271 +               fd = create_anon_file(len);
8272 +       else fd = create_tmp_file(len);
8273 +
8274 +       err = os_set_exec_close(fd, 1);
8275 +       if(err < 0)
8276 +               os_print_error(err, "exec_close");
8277 +       return(fd);
8278  }
8279  
8280 +struct iomem_region *iomem_regions = NULL;
8281 +int iomem_size = 0;
8282 +
8283  static int __init parse_iomem(char *str, int *add)
8284  {
8285 -       struct stat buf;
8286 +       struct iomem_region *new;
8287 +       struct uml_stat buf;
8288         char *file, *driver;
8289 -       int fd;
8290 +       int fd, err;
8291  
8292         driver = str;
8293         file = strchr(str,',');
8294         if(file == NULL){
8295 -               printk("parse_iomem : failed to parse iomem\n");
8296 -               return(1);
8297 +               printf("parse_iomem : failed to parse iomem\n");
8298 +               goto out;
8299         }
8300         *file = '\0';
8301         file++;
8302         fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0);
8303         if(fd < 0){
8304 -               printk("parse_iomem - Couldn't open io file, errno = %d\n", 
8305 -                      errno);
8306 -               return(1);
8307 -       }
8308 -       if(fstat(fd, &buf) < 0) {
8309 -               printk("parse_iomem - cannot fstat file, errno = %d\n", errno);
8310 -               return(1);
8311 +               os_print_error(fd, "parse_iomem - Couldn't open io file");
8312 +               goto out;
8313         }
8314 -       add_iomem(driver, fd, buf.st_size);
8315 +
8316 +       err = os_stat_fd(fd, &buf);
8317 +       if(err < 0){
8318 +               os_print_error(err, "parse_iomem - cannot stat_fd file");
8319 +               goto out_close;
8320 +       }
8321 +
8322 +       new = malloc(sizeof(*new));
8323 +       if(new == NULL){
8324 +               perror("Couldn't allocate iomem_region struct");
8325 +               goto out_close;
8326 +       }
8327 +
8328 +       *new = ((struct iomem_region) { .next           = iomem_regions,
8329 +                                       .driver         = driver,
8330 +                                       .fd             = fd,
8331 +                                       .size           = buf.ust_size,
8332 +                                       .phys           = 0,
8333 +                                       .virt           = 0 });
8334 +       iomem_regions = new;
8335 +       iomem_size += new->size + UM_KERN_PAGE_SIZE;
8336 +
8337         return(0);
8338 + out_close:
8339 +       os_close_file(fd);
8340 + out:
8341 +       return(1);
8342  }
8343  
8344  __uml_setup("iomem=", parse_iomem,
8345 @@ -153,73 +192,20 @@
8346  "    Configure <file> as an IO memory region named <name>.\n\n"
8347  );
8348  
8349 -#ifdef notdef
8350 -int logging = 0;
8351 -int logging_fd = -1;
8352 -
8353 -int logging_line = 0;
8354 -char logging_buf[256];
8355 -
8356 -void log(char *fmt, ...)
8357 -{
8358 -       va_list ap;
8359 -       struct timeval tv;
8360 -       struct openflags flags;
8361 -
8362 -       if(logging == 0) return;
8363 -       if(logging_fd < 0){
8364 -               flags = of_create(of_trunc(of_rdrw(OPENFLAGS())));
8365 -               logging_fd = os_open_file("log", flags, 0644);
8366 -       }
8367 -       gettimeofday(&tv, NULL);
8368 -       sprintf(logging_buf, "%d\t %u.%u  ", logging_line++, tv.tv_sec, 
8369 -               tv.tv_usec);
8370 -       va_start(ap, fmt);
8371 -       vsprintf(&logging_buf[strlen(logging_buf)], fmt, ap);
8372 -       va_end(ap);
8373 -       write(logging_fd, logging_buf, strlen(logging_buf));
8374 -}
8375 -#endif
8376 -
8377 -int map_memory(unsigned long virt, unsigned long phys, unsigned long len, 
8378 -              int r, int w, int x)
8379 -{
8380 -       struct mem_region *region = phys_region(phys);
8381 -
8382 -       return(os_map_memory((void *) virt, region->fd, phys_offset(phys), len,
8383 -                            r, w, x));
8384 -}
8385 -
8386  int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x,
8387                    int must_succeed)
8388  {
8389 -       if(os_protect_memory((void *) addr, len, r, w, x) < 0){
8390 +       int err;
8391 +
8392 +       err = os_protect_memory((void *) addr, len, r, w, x);
8393 +       if(err < 0){
8394                  if(must_succeed)
8395 -                        panic("protect failed, errno = %d", errno);
8396 -                else return(-errno);
8397 +                       panic("protect failed, err = %d", -err);
8398 +               else return(err);
8399         }
8400         return(0);
8401  }
8402  
8403 -unsigned long find_iomem(char *driver, unsigned long *len_out)
8404 -{
8405 -       struct mem_region *region;
8406 -       int i, n;
8407 -
8408 -       n = nregions();
8409 -       for(i = 0; i < n; i++){
8410 -               region = regions[i];
8411 -               if(region == NULL) continue;
8412 -               if((region->driver != NULL) &&
8413 -                  !strcmp(region->driver, driver)){
8414 -                       *len_out = region->len;
8415 -                       return(region->start);
8416 -               }
8417 -       }
8418 -       *len_out = 0;
8419 -       return 0;
8420 -}
8421 -
8422  /*
8423   * Overrides for Emacs so that we follow Linus's tabbing style.
8424   * Emacs will notice this stuff at the end of the file and automatically
8425 diff -Naur a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
8426 --- a/arch/um/kernel/physmem.c  1969-12-31 19:00:00.000000000 -0500
8427 +++ b/arch/um/kernel/physmem.c  2004-02-11 12:26:07.000000000 -0500
8428 @@ -0,0 +1,468 @@
8429 +/* 
8430 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
8431 + * Licensed under the GPL
8432 + */
8433 +
8434 +#include "linux/mm.h"
8435 +#include "linux/ghash.h"
8436 +#include "linux/slab.h"
8437 +#include "linux/vmalloc.h"
8438 +#include "linux/bootmem.h"
8439 +#include "asm/types.h"
8440 +#include "asm/pgtable.h"
8441 +#include "kern_util.h"
8442 +#include "user_util.h"
8443 +#include "mode_kern.h"
8444 +#include "mem.h"
8445 +#include "mem_user.h"
8446 +#include "os.h"
8447 +#include "kern.h"
8448 +#include "init.h"
8449 +
8450 +#if 0
8451 +static pgd_t physmem_pgd[PTRS_PER_PGD];
8452 +
8453 +static struct phys_desc *lookup_mapping(void *addr)
8454 +{
8455 +       pgd = &physmem_pgd[pgd_index(addr)];
8456 +       if(pgd_none(pgd))
8457 +               return(NULL);
8458 +
8459 +       pmd = pmd_offset(pgd, addr);
8460 +       if(pmd_none(pmd))
8461 +               return(NULL);
8462 +
8463 +       pte = pte_offset_kernel(pmd, addr);
8464 +       return((struct phys_desc *) pte_val(pte));
8465 +}
8466 +
8467 +static struct add_mapping(void *addr, struct phys_desc *new)
8468 +{
8469 +}
8470 +#endif
8471 +
8472 +#define PHYS_HASHSIZE (8192)
8473 +
8474 +struct phys_desc;
8475 +
8476 +DEF_HASH_STRUCTS(virtmem, PHYS_HASHSIZE, struct phys_desc);
8477 +
8478 +struct phys_desc {
8479 +       struct virtmem_ptrs virt_ptrs;
8480 +       int fd;
8481 +       __u64 offset;
8482 +       void *virt;
8483 +       unsigned long phys;
8484 +       struct list_head list;
8485 +};
8486 +
8487 +struct virtmem_table virtmem_hash;
8488 +
8489 +static int virt_cmp(void *virt1, void *virt2)
8490 +{
8491 +       return(virt1 != virt2);
8492 +}
8493 +
8494 +static int virt_hash(void *virt)
8495 +{
8496 +       unsigned long addr = ((unsigned long) virt) >> PAGE_SHIFT;
8497 +       return(addr % PHYS_HASHSIZE);
8498 +}
8499 +
8500 +DEF_HASH(static, virtmem, struct phys_desc, virt_ptrs, void *, virt, virt_cmp, 
8501 +        virt_hash);
8502 +
8503 +LIST_HEAD(descriptor_mappings);
8504 +
8505 +struct desc_mapping {
8506 +       int fd;
8507 +       struct list_head list;
8508 +       struct list_head pages;
8509 +};
8510 +
8511 +static struct desc_mapping *find_mapping(int fd)
8512 +{
8513 +       struct desc_mapping *desc;
8514 +       struct list_head *ele;
8515 +
8516 +       list_for_each(ele, &descriptor_mappings){
8517 +               desc = list_entry(ele, struct desc_mapping, list);
8518 +               if(desc->fd == fd)
8519 +                       return(desc);
8520 +       }
8521 +
8522 +       return(NULL);
8523 +}
8524 +
8525 +static struct desc_mapping *descriptor_mapping(int fd)
8526 +{
8527 +       struct desc_mapping *desc;
8528 +
8529 +       desc = find_mapping(fd);
8530 +       if(desc != NULL)
8531 +               return(desc);
8532 +
8533 +       desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
8534 +       if(desc == NULL)
8535 +               return(NULL);
8536 +
8537 +       *desc = ((struct desc_mapping) 
8538 +               { .fd =         fd,
8539 +                 .list =       LIST_HEAD_INIT(desc->list),
8540 +                 .pages =      LIST_HEAD_INIT(desc->pages) });
8541 +       list_add(&desc->list, &descriptor_mappings);
8542 +
8543 +       return(desc);
8544 +}
8545 +
8546 +int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w)
8547 +{
8548 +       struct desc_mapping *fd_maps;
8549 +       struct phys_desc *desc;
8550 +       unsigned long phys;
8551 +       int err;
8552 +
8553 +       fd_maps = descriptor_mapping(fd);
8554 +       if(fd_maps == NULL)
8555 +               return(-ENOMEM);
8556 +
8557 +       phys = __pa(virt);
8558 +       if(find_virtmem_hash(&virtmem_hash, virt) != NULL)
8559 +               panic("Address 0x%p is already substituted\n", virt);
8560 +
8561 +       err = -ENOMEM;
8562 +       desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
8563 +       if(desc == NULL)
8564 +               goto out;
8565 +
8566 +       *desc = ((struct phys_desc) 
8567 +               { .virt_ptrs =  { NULL, NULL },
8568 +                 .fd =         fd,
8569 +                 .offset =             offset,
8570 +                 .virt =               virt,
8571 +                 .phys =               __pa(virt),
8572 +                 .list =               LIST_HEAD_INIT(desc->list) });
8573 +       insert_virtmem_hash(&virtmem_hash, desc);
8574 +
8575 +       list_add(&desc->list, &fd_maps->pages);
8576 +
8577 +       virt = (void *) ((unsigned long) virt & PAGE_MASK);
8578 +       err = os_map_memory(virt, fd, offset, PAGE_SIZE, 1, w, 0);
8579 +       if(!err)
8580 +               goto out;
8581 +
8582 +       remove_virtmem_hash(&virtmem_hash, desc);
8583 +       kfree(desc);
8584 + out:
8585 +       return(err);
8586 +}
8587 +
8588 +static int physmem_fd = -1;
8589 +
8590 +static void remove_mapping(struct phys_desc *desc)
8591 +{
8592 +       void *virt = desc->virt;
8593 +       int err;
8594 +
8595 +       remove_virtmem_hash(&virtmem_hash, desc);
8596 +       list_del(&desc->list);
8597 +       kfree(desc);
8598 +
8599 +       err = os_map_memory(virt, physmem_fd, __pa(virt), PAGE_SIZE, 1, 1, 0);
8600 +       if(err)
8601 +               panic("Failed to unmap block device page from physical memory, "
8602 +                     "errno = %d", -err);
8603 +}
8604 +
8605 +int physmem_remove_mapping(void *virt)
8606 +{
8607 +       struct phys_desc *desc;
8608 +
8609 +       virt = (void *) ((unsigned long) virt & PAGE_MASK);
8610 +       desc = find_virtmem_hash(&virtmem_hash, virt);
8611 +       if(desc == NULL)
8612 +               return(0);
8613 +
8614 +       remove_mapping(desc);
8615 +       return(1);
8616 +}
8617 +
8618 +void physmem_forget_descriptor(int fd)
8619 +{
8620 +       struct desc_mapping *desc;
8621 +       struct phys_desc *page;
8622 +       struct list_head *ele, *next;
8623 +       __u64 offset;
8624 +       void *addr;
8625 +       int err;
8626 +
8627 +       desc = find_mapping(fd);
8628 +       if(desc == NULL)
8629 +               return;
8630 +
8631 +       list_for_each_safe(ele, next, &desc->pages){
8632 +               page = list_entry(ele, struct phys_desc, list);
8633 +               offset = page->offset;
8634 +               addr = page->virt;
8635 +               remove_mapping(page);
8636 +               err = os_seek_file(fd, offset);
8637 +               if(err)
8638 +                       panic("physmem_forget_descriptor - failed to seek "
8639 +                             "to %lld in fd %d, error = %d\n",
8640 +                             offset, fd, -err);
8641 +               err = os_read_file(fd, addr, PAGE_SIZE);
8642 +               if(err < 0)
8643 +                       panic("physmem_forget_descriptor - failed to read "
8644 +                             "from fd %d to 0x%p, error = %d\n",
8645 +                             fd, addr, -err);
8646 +       }
8647 +
8648 +       list_del(&desc->list);
8649 +       kfree(desc);
8650 +}
8651 +
8652 +void arch_free_page(struct page *page, int order)
8653 +{
8654 +       void *virt;
8655 +       int i;
8656 +
8657 +       for(i = 0; i < (1 << order); i++){
8658 +               virt = __va(page_to_phys(page + i));
8659 +               physmem_remove_mapping(virt);
8660 +       }
8661 +}
8662 +
8663 +int is_remapped(void *virt)
8664 +{
8665 +       return(find_virtmem_hash(&virtmem_hash, virt) != NULL);
8666 +}
8667 +
8668 +/* Changed during early boot */
8669 +unsigned long high_physmem;
8670 +
8671 +extern unsigned long physmem_size;
8672 +
8673 +void *to_virt(unsigned long phys)
8674 +{
8675 +       return((void *) uml_physmem + phys);
8676 +}
8677 +
8678 +unsigned long to_phys(void *virt)
8679 +{
8680 +       return(((unsigned long) virt) - uml_physmem);
8681 +}
8682 +
8683 +int init_maps(unsigned long physmem, unsigned long iomem, unsigned long highmem)
8684 +{
8685 +       struct page *p, *map;
8686 +       unsigned long phys_len, phys_pages, highmem_len, highmem_pages;
8687 +       unsigned long iomem_len, iomem_pages, total_len, total_pages;
8688 +       int i;
8689 +
8690 +       phys_pages = physmem >> PAGE_SHIFT;
8691 +       phys_len = phys_pages * sizeof(struct page);
8692 +
8693 +       iomem_pages = iomem >> PAGE_SHIFT;
8694 +       iomem_len = iomem_pages * sizeof(struct page);
8695 +
8696 +       highmem_pages = highmem >> PAGE_SHIFT;
8697 +       highmem_len = highmem_pages * sizeof(struct page);
8698 +
8699 +       total_pages = phys_pages + iomem_pages + highmem_pages;
8700 +       total_len = phys_len + iomem_pages + highmem_len;
8701 +
8702 +       if(kmalloc_ok){
8703 +               map = kmalloc(total_len, GFP_KERNEL);
8704 +               if(map == NULL) 
8705 +                       map = vmalloc(total_len);
8706 +       }
8707 +       else map = alloc_bootmem_low_pages(total_len);
8708 +
8709 +       if(map == NULL)
8710 +               return(-ENOMEM);
8711 +
8712 +       for(i = 0; i < total_pages; i++){
8713 +               p = &map[i];
8714 +               set_page_count(p, 0);
8715 +               SetPageReserved(p);
8716 +               INIT_LIST_HEAD(&p->list);
8717 +       }
8718 +
8719 +       mem_map = map;
8720 +       max_mapnr = total_pages;
8721 +       return(0);
8722 +}
8723 +
8724 +struct page *phys_to_page(const unsigned long phys)
8725 +{
8726 +       return(&mem_map[phys >> PAGE_SHIFT]);
8727 +}
8728 +
8729 +struct page *__virt_to_page(const unsigned long virt)
8730 +{
8731 +       return(&mem_map[__pa(virt) >> PAGE_SHIFT]);
8732 +}
8733 +
8734 +unsigned long page_to_phys(struct page *page)
8735 +{
8736 +       return((page - mem_map) << PAGE_SHIFT);
8737 +}
8738 +
8739 +pte_t mk_pte(struct page *page, pgprot_t pgprot)
8740 +{
8741 +       pte_t pte;
8742 +
8743 +       pte_val(pte) = page_to_phys(page) + pgprot_val(pgprot);
8744 +       if(pte_present(pte)) pte_mknewprot(pte_mknewpage(pte));
8745 +       return(pte);
8746 +}
8747 +
8748 +/* Changed during early boot */
8749 +static unsigned long kmem_top = 0;
8750 +
8751 +unsigned long get_kmem_end(void)
8752 +{
8753 +       if(kmem_top == 0) 
8754 +               kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas);
8755 +       return(kmem_top);
8756 +}
8757 +
8758 +void map_memory(unsigned long virt, unsigned long phys, unsigned long len, 
8759 +               int r, int w, int x)
8760 +{
8761 +       __u64 offset;
8762 +       int fd, err;
8763 +
8764 +       fd = phys_mapping(phys, &offset);
8765 +       err = os_map_memory((void *) virt, fd, offset, len, r, w, x);
8766 +       if(err)
8767 +               panic("map_memory(0x%lx, %d, 0x%llx, %ld, %d, %d, %d) failed, "
8768 +                     "err = %d\n", virt, fd, offset, len, r, w, x, err);
8769 +}
8770 +
8771 +#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
8772 +
8773 +void setup_physmem(unsigned long start, unsigned long reserve_end,
8774 +                  unsigned long len, unsigned long highmem)
8775 +{
8776 +       unsigned long reserve = reserve_end - start;
8777 +       int pfn = PFN_UP(__pa(reserve_end));
8778 +       int delta = (len - reserve) >> PAGE_SHIFT;
8779 +       int err, offset, bootmap_size;
8780 +
8781 +       physmem_fd = create_mem_file(len + highmem);
8782 +
8783 +       offset = uml_reserved - uml_physmem;
8784 +       err = os_map_memory((void *) uml_reserved, physmem_fd, offset, 
8785 +                           len - offset, 1, 1, 0);
8786 +       if(err < 0){
8787 +               os_print_error(err, "Mapping memory");
8788 +               exit(1);
8789 +       }
8790 +
8791 +       bootmap_size = init_bootmem(pfn, pfn + delta);
8792 +       free_bootmem(__pa(reserve_end) + bootmap_size,
8793 +                    len - bootmap_size - reserve);
8794 +}
8795 +
8796 +int phys_mapping(unsigned long phys, __u64 *offset_out)
8797 +{
8798 +       struct phys_desc *desc = find_virtmem_hash(&virtmem_hash, 
8799 +                                                  __va(phys & PAGE_MASK));
8800 +       int fd = -1;
8801 +
8802 +       if(desc != NULL){
8803 +               fd = desc->fd;
8804 +               *offset_out = desc->offset;
8805 +       }
8806 +       else if(phys < physmem_size){
8807 +               fd = physmem_fd;
8808 +               *offset_out = phys;
8809 +       }
8810 +       else if(phys < __pa(end_iomem)){
8811 +               struct iomem_region *region = iomem_regions;
8812 +       
8813 +               while(region != NULL){
8814 +                       if((phys >= region->phys) && 
8815 +                          (phys < region->phys + region->size)){
8816 +                               fd = region->fd;
8817 +                               *offset_out = phys - region->phys;
8818 +                               break;
8819 +                       }
8820 +                       region = region->next;
8821 +               }
8822 +       }
8823 +       else if(phys < __pa(end_iomem) + highmem){
8824 +               fd = physmem_fd;
8825 +               *offset_out = phys - iomem_size;
8826 +       }
8827 +
8828 +       return(fd);
8829 +}
8830 +
8831 +static int __init uml_mem_setup(char *line, int *add)
8832 +{
8833 +       char *retptr;
8834 +       physmem_size = memparse(line,&retptr);
8835 +       return 0;
8836 +}
8837 +__uml_setup("mem=", uml_mem_setup,
8838 +"mem=<Amount of desired ram>\n"
8839 +"    This controls how much \"physical\" memory the kernel allocates\n"
8840 +"    for the system. The size is specified as a number followed by\n"
8841 +"    one of 'k', 'K', 'm', 'M', which have the obvious meanings.\n"
8842 +"    This is not related to the amount of memory in the host.  It can\n"
8843 +"    be more, and the excess, if it's ever used, will just be swapped out.\n"
8844 +"      Example: mem=64M\n\n"
8845 +);
8846 +
8847 +unsigned long find_iomem(char *driver, unsigned long *len_out)
8848 +{
8849 +       struct iomem_region *region = iomem_regions;
8850 +       
8851 +       while(region != NULL){
8852 +               if(!strcmp(region->driver, driver)){
8853 +                       *len_out = region->size;
8854 +                       return(region->virt);
8855 +               }
8856 +       }
8857 +
8858 +       return(0);
8859 +}
8860 +
8861 +int setup_iomem(void)
8862 +{
8863 +       struct iomem_region *region = iomem_regions;
8864 +       unsigned long iomem_start = high_physmem + PAGE_SIZE;
8865 +       int err;
8866 +
8867 +       while(region != NULL){
8868 +               err = os_map_memory((void *) iomem_start, region->fd, 0, 
8869 +                                   region->size, 1, 1, 0);
8870 +               if(err)
8871 +                       printk("Mapping iomem region for driver '%s' failed, "
8872 +                              "errno = %d\n", region->driver, -err);
8873 +               else {
8874 +                       region->virt = iomem_start;
8875 +                       region->phys = __pa(region->virt);
8876 +               }
8877 +
8878 +               iomem_start += region->size + PAGE_SIZE;
8879 +               region = region->next;
8880 +       }
8881 +
8882 +       return(0);
8883 +}
8884 +
8885 +__initcall(setup_iomem);
8886 +
8887 +/*
8888 + * Overrides for Emacs so that we follow Linus's tabbing style.
8889 + * Emacs will notice this stuff at the end of the file and automatically
8890 + * adjust the settings for this buffer only.  This must remain at the end
8891 + * of the file.
8892 + * ---------------------------------------------------------------------------
8893 + * Local variables:
8894 + * c-file-style: "linux"
8895 + * End:
8896 + */
8897 diff -Naur a/arch/um/kernel/process.c b/arch/um/kernel/process.c
8898 --- a/arch/um/kernel/process.c  2004-02-11 12:16:36.000000000 -0500
8899 +++ b/arch/um/kernel/process.c  2004-02-11 12:28:35.000000000 -0500
8900 @@ -9,12 +9,10 @@
8901  #include <sched.h>
8902  #include <errno.h>
8903  #include <stdarg.h>
8904 -#include <fcntl.h>
8905  #include <stdlib.h>
8906  #include <setjmp.h>
8907  #include <sys/time.h>
8908  #include <sys/ptrace.h>
8909 -#include <sys/ioctl.h>
8910  #include <sys/wait.h>
8911  #include <sys/mman.h>
8912  #include <asm/ptrace.h>
8913 @@ -58,7 +56,11 @@
8914  {
8915         int flags = altstack ? SA_ONSTACK : 0;
8916  
8917 -       set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags,
8918 +       /* NODEFER is set here because SEGV isn't turned back on when the 
8919 +        * handler is ready to receive signals.  This causes any segfault
8920 +        * during a copy_user to kill the process because the fault is blocked.
8921 +        */
8922 +       set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags | SA_NODEFER,
8923                     SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
8924         set_handler(SIGTRAP, (__sighandler_t) sig_handler, flags, 
8925                     SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
8926 @@ -72,7 +74,6 @@
8927                     SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
8928         set_handler(SIGUSR2, (__sighandler_t) sig_handler, 
8929                     SA_NOMASK | flags, -1);
8930 -       (void) CHOOSE_MODE(signal(SIGCHLD, SIG_IGN), (void *) 0);
8931         signal(SIGHUP, SIG_IGN);
8932  
8933         init_irq_signals(altstack);
8934 @@ -123,11 +124,12 @@
8935         /* Start the process and wait for it to kill itself */
8936         new_pid = clone(outer_tramp, (void *) sp, clone_flags, &arg);
8937         if(new_pid < 0) return(-errno);
8938 -       while((err = waitpid(new_pid, &status, 0) < 0) && (errno == EINTR)) ;
8939 +       while(((err = waitpid(new_pid, &status, 0)) < 0) && (errno == EINTR)) ;
8940         if(err < 0) panic("Waiting for outer trampoline failed - errno = %d", 
8941                           errno);
8942         if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL))
8943 -               panic("outer trampoline didn't exit with SIGKILL");
8944 +               panic("outer trampoline didn't exit with SIGKILL, "
8945 +                     "status = %d", status);
8946  
8947         return(arg.pid);
8948  }
8949 @@ -138,7 +140,7 @@
8950  
8951         os_stop_process(os_getpid());
8952  
8953 -       if(read(fd, &c, sizeof(c)) != sizeof(c))
8954 +       if(os_read_file(fd, &c, sizeof(c)) != sizeof(c))
8955                 panic("read failed in suspend_new_thread");
8956  }
8957  
8958 @@ -233,7 +235,7 @@
8959         int n;
8960  
8961         *jmp_ptr = &buf;
8962 -       n = setjmp(buf);
8963 +       n = sigsetjmp(buf, 1);
8964         if(n != 0)
8965                 return(n);
8966         (*fn)(arg);
8967 @@ -273,7 +275,7 @@
8968         stop_ptraced_child(pid, stack, 1);
8969  
8970         printf("Checking for /proc/mm...");
8971 -       if(access("/proc/mm", W_OK)){
8972 +       if(os_access("/proc/mm", OS_ACC_W_OK) < 0){
8973                 printf("not found\n");
8974                 ret = 0;
8975         }
8976 diff -Naur a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
8977 --- a/arch/um/kernel/process_kern.c     2004-02-11 12:15:46.000000000 -0500
8978 +++ b/arch/um/kernel/process_kern.c     2004-02-11 12:27:37.000000000 -0500
8979 @@ -16,6 +16,7 @@
8980  #include "linux/module.h"
8981  #include "linux/init.h"
8982  #include "linux/capability.h"
8983 +#include "linux/spinlock.h"
8984  #include "asm/unistd.h"
8985  #include "asm/mman.h"
8986  #include "asm/segment.h"
8987 @@ -23,7 +24,6 @@
8988  #include "asm/pgtable.h"
8989  #include "asm/processor.h"
8990  #include "asm/tlbflush.h"
8991 -#include "asm/spinlock.h"
8992  #include "asm/uaccess.h"
8993  #include "asm/user.h"
8994  #include "user_util.h"
8995 @@ -52,17 +52,12 @@
8996  
8997  struct task_struct *get_task(int pid, int require)
8998  {
8999 -        struct task_struct *task, *ret;
9000 +        struct task_struct *ret;
9001  
9002 -        ret = NULL;
9003          read_lock(&tasklist_lock);
9004 -        for_each_process(task){
9005 -                if(task->pid == pid){
9006 -                        ret = task;
9007 -                        break;
9008 -                }
9009 -        }
9010 +       ret = find_task_by_pid(pid);
9011          read_unlock(&tasklist_lock);
9012 +
9013          if(require && (ret == NULL)) panic("get_task couldn't find a task\n");
9014          return(ret);
9015  }
9016 @@ -95,7 +90,8 @@
9017         int flags = GFP_KERNEL;
9018  
9019         if(atomic) flags |= GFP_ATOMIC;
9020 -       if((page = __get_free_pages(flags, order)) == 0)
9021 +       page = __get_free_pages(flags, order);
9022 +       if(page == 0)
9023                 return(0);
9024         stack_protections(page);
9025         return(page);
9026 @@ -103,13 +99,15 @@
9027  
9028  int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
9029  {
9030 -       struct task_struct *p;
9031 +       int pid;
9032  
9033         current->thread.request.u.thread.proc = fn;
9034         current->thread.request.u.thread.arg = arg;
9035 -       p = do_fork(CLONE_VM | flags, 0, NULL, 0, NULL, NULL);
9036 -       if(IS_ERR(p)) panic("do_fork failed in kernel_thread");
9037 -       return(p->pid);
9038 +       pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0, NULL, 0, NULL, 
9039 +                     NULL);
9040 +       if(pid < 0)
9041 +               panic("do_fork failed in kernel_thread, errno = %d", pid);
9042 +       return(pid);
9043  }
9044  
9045  void switch_mm(struct mm_struct *prev, struct mm_struct *next, 
9046 @@ -129,7 +127,7 @@
9047                 { external_pid(task), task });
9048  }
9049  
9050 -void *switch_to(void *prev, void *next, void *last)
9051 +void *_switch_to(void *prev, void *next, void *last)
9052  {
9053         return(CHOOSE_MODE(switch_to_tt(prev, next), 
9054                            switch_to_skas(prev, next)));
9055 @@ -149,7 +147,7 @@
9056  void exit_thread(void)
9057  {
9058         CHOOSE_MODE(exit_thread_tt(), exit_thread_skas());
9059 -       unprotect_stack((unsigned long) current->thread_info);
9060 +       unprotect_stack((unsigned long) current_thread);
9061  }
9062   
9063  void *get_current(void)
9064 @@ -157,6 +155,10 @@
9065         return(current);
9066  }
9067  
9068 +void prepare_to_copy(struct task_struct *tsk)
9069 +{
9070 +}
9071 +
9072  int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
9073                 unsigned long stack_top, struct task_struct * p, 
9074                 struct pt_regs *regs)
9075 @@ -190,7 +192,7 @@
9076  
9077  void default_idle(void)
9078  {
9079 -       idle_timer();
9080 +       uml_idle_timer();
9081  
9082         atomic_inc(&init_mm.mm_count);
9083         current->mm = &init_mm;
9084 @@ -367,10 +369,15 @@
9085         return(clear_user(buf, size));
9086  }
9087  
9088 +int strlen_user_proc(char *str)
9089 +{
9090 +       return(strlen_user(str));
9091 +}
9092 +
9093  int smp_sigio_handler(void)
9094  {
9095  #ifdef CONFIG_SMP
9096 -       int cpu = current->thread_info->cpu;
9097 +       int cpu = current_thread->cpu;
9098         IPI_handler(cpu);
9099         if(cpu != 0)
9100                 return(1);
9101 @@ -385,7 +392,7 @@
9102  
9103  int cpu(void)
9104  {
9105 -       return(current->thread_info->cpu);
9106 +       return(current_thread->cpu);
9107  }
9108  
9109  /*
9110 diff -Naur a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
9111 --- a/arch/um/kernel/ptrace.c   2004-02-11 12:14:24.000000000 -0500
9112 +++ b/arch/um/kernel/ptrace.c   2004-02-11 12:26:07.000000000 -0500
9113 @@ -311,11 +311,8 @@
9114  
9115         /* the 0x80 provides a way for the tracing parent to distinguish
9116            between a syscall stop and SIGTRAP delivery */
9117 -       current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
9118 -                                       ? 0x80 : 0);
9119 -       current->state = TASK_STOPPED;
9120 -       notify_parent(current, SIGCHLD);
9121 -       schedule();
9122 +       ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
9123 +                                ? 0x80 : 0));
9124  
9125         /*
9126          * this isn't the same as continuing with a signal, but it will do
9127 diff -Naur a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
9128 --- a/arch/um/kernel/reboot.c   2004-02-11 12:15:45.000000000 -0500
9129 +++ b/arch/um/kernel/reboot.c   2004-02-11 12:27:36.000000000 -0500
9130 @@ -15,6 +15,7 @@
9131  #ifdef CONFIG_SMP
9132  static void kill_idlers(int me)
9133  {
9134 +#ifdef CONFIG_MODE_TT
9135         struct task_struct *p;
9136         int i;
9137  
9138 @@ -23,6 +24,7 @@
9139                 if((p != NULL) && (p->thread.mode.tt.extern_pid != me))
9140                         os_kill_process(p->thread.mode.tt.extern_pid, 0);
9141         }
9142 +#endif
9143  }
9144  #endif
9145  
9146 diff -Naur a/arch/um/kernel/sigio_kern.c b/arch/um/kernel/sigio_kern.c
9147 --- a/arch/um/kernel/sigio_kern.c       2004-02-11 12:14:33.000000000 -0500
9148 +++ b/arch/um/kernel/sigio_kern.c       2004-02-11 12:26:17.000000000 -0500
9149 @@ -6,18 +6,21 @@
9150  #include "linux/kernel.h"
9151  #include "linux/list.h"
9152  #include "linux/slab.h"
9153 -#include "asm/irq.h"
9154 +#include "linux/signal.h"
9155 +#include "linux/interrupt.h"
9156  #include "init.h"
9157  #include "sigio.h"
9158  #include "irq_user.h"
9159 +#include "irq_kern.h"
9160  
9161  /* Protected by sigio_lock() called from write_sigio_workaround */
9162  static int sigio_irq_fd = -1;
9163  
9164 -void sigio_interrupt(int irq, void *data, struct pt_regs *unused)
9165 +irqreturn_t sigio_interrupt(int irq, void *data, struct pt_regs *unused)
9166  {
9167         read_sigio_fd(sigio_irq_fd);
9168         reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ);
9169 +       return(IRQ_HANDLED);
9170  }
9171  
9172  int write_sigio_irq(int fd)
9173 diff -Naur a/arch/um/kernel/sigio_user.c b/arch/um/kernel/sigio_user.c
9174 --- a/arch/um/kernel/sigio_user.c       2004-02-11 12:16:48.000000000 -0500
9175 +++ b/arch/um/kernel/sigio_user.c       2004-02-11 12:29:02.000000000 -0500
9176 @@ -7,7 +7,6 @@
9177  #include <stdlib.h>
9178  #include <termios.h>
9179  #include <pty.h>
9180 -#include <fcntl.h>
9181  #include <signal.h>
9182  #include <errno.h>
9183  #include <string.h>
9184 @@ -26,7 +25,7 @@
9185  int pty_close_sigio = 0;
9186  
9187  /* Used as a flag during SIGIO testing early in boot */
9188 -static int got_sigio = 0;
9189 +static volatile int got_sigio = 0;
9190  
9191  void __init handler(int sig)
9192  {
9193 @@ -45,7 +44,7 @@
9194  
9195         info->err = 0;
9196         if(openpty(&info->master, &info->slave, NULL, NULL, NULL))
9197 -               info->err = errno;
9198 +               info->err = -errno;
9199  }
9200  
9201  void __init check_one_sigio(void (*proc)(int, int))
9202 @@ -53,11 +52,11 @@
9203         struct sigaction old, new;
9204         struct termios tt;
9205         struct openpty_arg pty = { .master = -1, .slave = -1 };
9206 -       int master, slave, flags;
9207 +       int master, slave, err;
9208  
9209         initial_thread_cb(openpty_cb, &pty);
9210         if(pty.err){
9211 -               printk("openpty failed, errno = %d\n", pty.err);
9212 +               printk("openpty failed, errno = %d\n", -pty.err);
9213                 return;
9214         }
9215  
9216 @@ -69,23 +68,16 @@
9217                 return;
9218         }
9219  
9220 +       /* XXX These can fail with EINTR */
9221         if(tcgetattr(master, &tt) < 0)
9222                 panic("check_sigio : tcgetattr failed, errno = %d\n", errno);
9223         cfmakeraw(&tt);
9224         if(tcsetattr(master, TCSADRAIN, &tt) < 0)
9225                 panic("check_sigio : tcsetattr failed, errno = %d\n", errno);
9226  
9227 -       if((flags = fcntl(master, F_GETFL)) < 0)
9228 -               panic("tty_fds : fcntl F_GETFL failed, errno = %d\n", errno);
9229 -
9230 -       if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
9231 -          (fcntl(master, F_SETOWN, os_getpid()) < 0))
9232 -               panic("check_sigio : fcntl F_SETFL or F_SETOWN failed, "
9233 -                     "errno = %d\n", errno);
9234 -
9235 -       if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0))
9236 -               panic("check_sigio : fcntl F_SETFL failed, errno = %d\n", 
9237 -                     errno);
9238 +       err = os_sigio_async(master, slave);
9239 +       if(err < 0)
9240 +               panic("tty_fds : sigio_async failed, err = %d\n", -err);
9241  
9242         if(sigaction(SIGIO, NULL, &old) < 0)
9243                 panic("check_sigio : sigaction 1 failed, errno = %d\n", errno);
9244 @@ -97,8 +89,8 @@
9245         got_sigio = 0;
9246         (*proc)(master, slave);
9247                 
9248 -       close(master);
9249 -       close(slave);
9250 +       os_close_file(master);
9251 +       os_close_file(slave);
9252  
9253         if(sigaction(SIGIO, &old, NULL) < 0)
9254                 panic("check_sigio : sigaction 3 failed, errno = %d\n", errno);
9255 @@ -112,25 +104,25 @@
9256         printk("Checking that host ptys support output SIGIO...");
9257  
9258         memset(buf, 0, sizeof(buf));
9259 -       while(write(master, buf, sizeof(buf)) > 0) ;
9260 +
9261 +       while(os_write_file(master, buf, sizeof(buf)) > 0) ;
9262         if(errno != EAGAIN)
9263                 panic("check_sigio : write failed, errno = %d\n", errno);
9264 -
9265 -       while(((n = read(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
9266 +       while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ;
9267  
9268         if(got_sigio){
9269                 printk("Yes\n");
9270                 pty_output_sigio = 1;
9271         }
9272 -       else if(errno == EAGAIN) printk("No, enabling workaround\n");
9273 -       else panic("check_sigio : read failed, errno = %d\n", errno);
9274 +       else if(n == -EAGAIN) printk("No, enabling workaround\n");
9275 +       else panic("check_sigio : read failed, err = %d\n", n);
9276  }
9277  
9278  static void tty_close(int master, int slave)
9279  {
9280         printk("Checking that host ptys support SIGIO on close...");
9281  
9282 -       close(slave);
9283 +       os_close_file(slave);
9284         if(got_sigio){
9285                 printk("Yes\n");
9286                 pty_close_sigio = 1;
9287 @@ -140,7 +132,8 @@
9288  
9289  void __init check_sigio(void)
9290  {
9291 -       if(access("/dev/ptmx", R_OK) && access("/dev/ptyp0", R_OK)){
9292 +       if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) &&
9293 +          (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){
9294                 printk("No pseudo-terminals available - skipping pty SIGIO "
9295                        "check\n");
9296                 return;
9297 @@ -201,11 +194,10 @@
9298                         p = &fds->poll[i];
9299                         if(p->revents == 0) continue;
9300                         if(p->fd == sigio_private[1]){
9301 -                               n = read(sigio_private[1], &c, sizeof(c));
9302 +                               n = os_read_file(sigio_private[1], &c, sizeof(c));
9303                                 if(n != sizeof(c))
9304                                         printk("write_sigio_thread : "
9305 -                                              "read failed, errno = %d\n",
9306 -                                              errno);
9307 +                                              "read failed, err = %d\n", -n);
9308                                 tmp = current_poll;
9309                                 current_poll = next_poll;
9310                                 next_poll = tmp;
9311 @@ -218,10 +210,10 @@
9312                                         (fds->used - i) * sizeof(*fds->poll));
9313                         }
9314  
9315 -                       n = write(respond_fd, &c, sizeof(c));
9316 +                       n = os_write_file(respond_fd, &c, sizeof(c));
9317                         if(n != sizeof(c))
9318                                 printk("write_sigio_thread : write failed, "
9319 -                                      "errno = %d\n", errno);
9320 +                                      "err = %d\n", -n);
9321                 }
9322         }
9323  }
9324 @@ -252,15 +244,15 @@
9325         char c;
9326  
9327         flags = set_signals(0);
9328 -       n = write(sigio_private[0], &c, sizeof(c));
9329 +       n = os_write_file(sigio_private[0], &c, sizeof(c));
9330         if(n != sizeof(c)){
9331 -               printk("update_thread : write failed, errno = %d\n", errno);
9332 +               printk("update_thread : write failed, err = %d\n", -n);
9333                 goto fail;
9334         }
9335  
9336 -       n = read(sigio_private[0], &c, sizeof(c));
9337 +       n = os_read_file(sigio_private[0], &c, sizeof(c));
9338         if(n != sizeof(c)){
9339 -               printk("update_thread : read failed, errno = %d\n", errno);
9340 +               printk("update_thread : read failed, err = %d\n", -n);
9341                 goto fail;
9342         }
9343  
9344 @@ -271,10 +263,10 @@
9345         if(write_sigio_pid != -1) 
9346                 os_kill_process(write_sigio_pid, 1);
9347         write_sigio_pid = -1;
9348 -       close(sigio_private[0]);
9349 -       close(sigio_private[1]);        
9350 -       close(write_sigio_fds[0]);
9351 -       close(write_sigio_fds[1]);
9352 +       os_close_file(sigio_private[0]);
9353 +       os_close_file(sigio_private[1]);        
9354 +       os_close_file(write_sigio_fds[0]);
9355 +       os_close_file(write_sigio_fds[1]);
9356         sigio_unlock();
9357         set_signals(flags);
9358  }
9359 @@ -369,15 +361,15 @@
9360                 goto out;
9361  
9362         err = os_pipe(write_sigio_fds, 1, 1);
9363 -       if(err){
9364 +       if(err < 0){
9365                 printk("write_sigio_workaround - os_pipe 1 failed, "
9366 -                      "errno = %d\n", -err);
9367 +                      "err = %d\n", -err);
9368                 goto out;
9369         }
9370         err = os_pipe(sigio_private, 1, 1);
9371 -       if(err){
9372 +       if(err < 0){
9373                 printk("write_sigio_workaround - os_pipe 2 failed, "
9374 -                      "errno = %d\n", -err);
9375 +                      "err = %d\n", -err);
9376                 goto out_close1;
9377         }
9378         if(setup_initial_poll(sigio_private[1]))
9379 @@ -399,11 +391,11 @@
9380         os_kill_process(write_sigio_pid, 1);
9381         write_sigio_pid = -1;
9382   out_close2:
9383 -       close(sigio_private[0]);
9384 -       close(sigio_private[1]);        
9385 +       os_close_file(sigio_private[0]);
9386 +       os_close_file(sigio_private[1]);        
9387   out_close1:
9388 -       close(write_sigio_fds[0]);
9389 -       close(write_sigio_fds[1]);
9390 +       os_close_file(write_sigio_fds[0]);
9391 +       os_close_file(write_sigio_fds[1]);
9392         sigio_unlock();
9393  }
9394  
9395 @@ -412,10 +404,16 @@
9396         int n;
9397         char c;
9398  
9399 -       n = read(fd, &c, sizeof(c));
9400 +       n = os_read_file(fd, &c, sizeof(c));
9401         if(n != sizeof(c)){
9402 -               printk("read_sigio_fd - read failed, errno = %d\n", errno);
9403 -               return(-errno);
9404 +               if(n < 0) {
9405 +                       printk("read_sigio_fd - read failed, err = %d\n", -n);
9406 +                       return(n);
9407 +               } 
9408 +               else { 
9409 +                       printk("read_sigio_fd - short read, bytes = %d\n", n);
9410 +                       return(-EIO);
9411 +               }
9412         }
9413         return(n);
9414  }
9415 diff -Naur a/arch/um/kernel/signal_kern.c b/arch/um/kernel/signal_kern.c
9416 --- a/arch/um/kernel/signal_kern.c      2004-02-11 12:15:52.000000000 -0500
9417 +++ b/arch/um/kernel/signal_kern.c      2004-02-11 12:27:44.000000000 -0500
9418 @@ -36,7 +36,7 @@
9419         if(sig == SIGSEGV){
9420                 struct k_sigaction *ka;
9421  
9422 -               ka = &current->sig->action[SIGSEGV - 1];
9423 +               ka = &current->sighand->action[SIGSEGV - 1];
9424                 ka->sa.sa_handler = SIG_DFL;
9425         }
9426         force_sig(SIGSEGV, current);
9427 @@ -60,10 +60,10 @@
9428         int err, ret;
9429  
9430         ret = 0;
9431 +       /* Always make any pending restarted system calls return -EINTR */
9432 +       current_thread_info()->restart_block.fn = do_no_restart_syscall;
9433         switch(error){
9434         case -ERESTART_RESTARTBLOCK:
9435 -               current_thread_info()->restart_block.fn = 
9436 -                       do_no_restart_syscall;
9437         case -ERESTARTNOHAND:
9438                 ret = -EINTR;
9439                 break;
9440 @@ -142,7 +142,7 @@
9441                 return(0);
9442  
9443         /* Whee!  Actually deliver the signal.  */
9444 -       ka = &current->sig->action[sig -1 ];
9445 +       ka = &current->sighand->action[sig -1 ];
9446         err = handle_signal(regs, sig, ka, &info, oldset, error);
9447         if(!err) return(1);
9448  
9449 @@ -201,7 +201,7 @@
9450         }
9451  }
9452  
9453 -int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
9454 +int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
9455  {
9456         sigset_t saveset, newset;
9457  
9458 @@ -227,20 +227,59 @@
9459         }
9460  }
9461  
9462 +int sys_sigaction(int sig, const struct old_sigaction __user *act,
9463 +                        struct old_sigaction __user *oact)
9464 +{
9465 +       struct k_sigaction new_ka, old_ka;
9466 +       int ret;
9467 +
9468 +       if (act) {
9469 +               old_sigset_t mask;
9470 +               if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
9471 +                   __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
9472 +                   __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
9473 +                       return -EFAULT;
9474 +               __get_user(new_ka.sa.sa_flags, &act->sa_flags);
9475 +               __get_user(mask, &act->sa_mask);
9476 +               siginitset(&new_ka.sa.sa_mask, mask);
9477 +       }
9478 +
9479 +       ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
9480 +
9481 +       if (!ret && oact) {
9482 +               if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
9483 +                   __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
9484 +                   __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
9485 +                       return -EFAULT;
9486 +               __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
9487 +               __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
9488 +       }
9489 +
9490 +       return ret;
9491 +}
9492 +
9493 +int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
9494 +{
9495 +       return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
9496 +}
9497 +
9498 +extern int userspace_pid[];
9499 +
9500  static int copy_sc_from_user(struct pt_regs *to, void *from, 
9501                              struct arch_frame_data *arch)
9502  {
9503         int ret;
9504  
9505         ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from, arch),
9506 -                         copy_sc_from_user_skas(&to->regs, from));
9507 +                         copy_sc_from_user_skas(userspace_pid[0], 
9508 +                                                &to->regs, from));
9509         return(ret);
9510  }
9511  
9512  int sys_sigreturn(struct pt_regs regs)
9513  {
9514 -       void *sc = sp_to_sc(PT_REGS_SP(&current->thread.regs));
9515 -       void *mask = sp_to_mask(PT_REGS_SP(&current->thread.regs));
9516 +       void __user *sc = sp_to_sc(PT_REGS_SP(&current->thread.regs));
9517 +       void __user *mask = sp_to_mask(PT_REGS_SP(&current->thread.regs));
9518         int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
9519  
9520         spin_lock_irq(&current->sighand->siglock);
9521 @@ -257,8 +296,8 @@
9522  
9523  int sys_rt_sigreturn(struct pt_regs regs)
9524  {
9525 -       struct ucontext *uc = sp_to_uc(PT_REGS_SP(&current->thread.regs));
9526 -       void *fp;
9527 +       unsigned long sp = PT_REGS_SP(&current->thread.regs);
9528 +       struct ucontext __user *uc = sp_to_uc(sp);
9529         int sig_size = _NSIG_WORDS * sizeof(unsigned long);
9530  
9531         spin_lock_irq(&current->sighand->siglock);
9532 @@ -266,7 +305,6 @@
9533         sigdelsetmask(&current->blocked, ~_BLOCKABLE);
9534         recalc_sigpending();
9535         spin_unlock_irq(&current->sighand->siglock);
9536 -       fp = (void *) (((unsigned long) uc) + sizeof(struct ucontext));
9537         copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext,
9538                           &signal_frame_si.common.arch);
9539         return(PT_REGS_SYSCALL_RET(&current->thread.regs));
9540 diff -Naur a/arch/um/kernel/skas/include/mode.h b/arch/um/kernel/skas/include/mode.h
9541 --- a/arch/um/kernel/skas/include/mode.h        2004-02-11 12:15:48.000000000 -0500
9542 +++ b/arch/um/kernel/skas/include/mode.h        2004-02-11 12:27:41.000000000 -0500
9543 @@ -12,14 +12,16 @@
9544  extern int have_fpx_regs;
9545  
9546  extern void user_time_init_skas(void);
9547 -extern int copy_sc_from_user_skas(union uml_pt_regs *regs, void *from_ptr);
9548 -extern int copy_sc_to_user_skas(void *to_ptr, void *fp, 
9549 +extern int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs, 
9550 +                                 void *from_ptr);
9551 +extern int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp, 
9552                                 union uml_pt_regs *regs, 
9553                                 unsigned long fault_addr, int fault_type);
9554  extern void sig_handler_common_skas(int sig, void *sc_ptr);
9555  extern void halt_skas(void);
9556  extern void reboot_skas(void);
9557  extern void kill_off_processes_skas(void);
9558 +extern int is_skas_winch(int pid, int fd, void *data);
9559  
9560  #endif
9561  
9562 diff -Naur a/arch/um/kernel/skas/include/skas.h b/arch/um/kernel/skas/include/skas.h
9563 --- a/arch/um/kernel/skas/include/skas.h        2004-02-11 12:14:37.000000000 -0500
9564 +++ b/arch/um/kernel/skas/include/skas.h        2004-02-11 12:26:22.000000000 -0500
9565 @@ -8,7 +8,7 @@
9566  
9567  #include "sysdep/ptrace.h"
9568  
9569 -extern int userspace_pid;
9570 +extern int userspace_pid[];
9571  
9572  extern void switch_threads(void *me, void *next);
9573  extern void thread_wait(void *sw, void *fb);
9574 @@ -32,7 +32,7 @@
9575  extern int new_mm(int from);
9576  extern void save_registers(union uml_pt_regs *regs);
9577  extern void restore_registers(union uml_pt_regs *regs);
9578 -extern void start_userspace(void);
9579 +extern void start_userspace(int cpu);
9580  extern void init_registers(int pid);
9581  
9582  #endif
9583 diff -Naur a/arch/um/kernel/skas/include/uaccess.h b/arch/um/kernel/skas/include/uaccess.h
9584 --- a/arch/um/kernel/skas/include/uaccess.h     2004-02-11 12:15:17.000000000 -0500
9585 +++ b/arch/um/kernel/skas/include/uaccess.h     2004-02-11 12:27:05.000000000 -0500
9586 @@ -6,20 +6,12 @@
9587  #ifndef __SKAS_UACCESS_H
9588  #define __SKAS_UACCESS_H
9589  
9590 -#include "linux/string.h"
9591 -#include "linux/sched.h"
9592 -#include "linux/err.h"
9593 -#include "asm/processor.h"
9594 -#include "asm/pgtable.h"
9595  #include "asm/errno.h"
9596 -#include "asm/current.h"
9597 -#include "asm/a.out.h"
9598 -#include "kern_util.h"
9599  
9600  #define access_ok_skas(type, addr, size) \
9601         ((segment_eq(get_fs(), KERNEL_DS)) || \
9602          (((unsigned long) (addr) < TASK_SIZE) && \
9603 -         ((unsigned long) (addr) + (size) < TASK_SIZE)))
9604 +         ((unsigned long) (addr) + (size) <= TASK_SIZE)))
9605  
9606  static inline int verify_area_skas(int type, const void * addr, 
9607                                    unsigned long size)
9608 @@ -27,197 +19,12 @@
9609         return(access_ok_skas(type, addr, size) ? 0 : -EFAULT);
9610  }
9611  
9612 -static inline unsigned long maybe_map(unsigned long virt, int is_write)
9613 -{
9614 -       pte_t pte;
9615 -
9616 -       void *phys = um_virt_to_phys(current, virt, &pte);
9617 -       int dummy_code;
9618 -
9619 -       if(IS_ERR(phys) || (is_write && !pte_write(pte))){
9620 -               if(handle_page_fault(virt, 0, is_write, 0, &dummy_code))
9621 -                       return(0);
9622 -               phys = um_virt_to_phys(current, virt, NULL);
9623 -       }
9624 -       return((unsigned long) __va((unsigned long) phys));
9625 -}
9626 -
9627 -static inline int buffer_op(unsigned long addr, int len, 
9628 -                           int (*op)(unsigned long addr, int len, void *arg),
9629 -                           void *arg)
9630 -{
9631 -       int size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
9632 -       int remain = len, n;
9633 -
9634 -       n = (*op)(addr, size, arg);
9635 -       if(n != 0)
9636 -               return(n < 0 ? remain : 0);
9637 -
9638 -       addr += size;
9639 -       remain -= size;
9640 -       if(remain == 0) 
9641 -               return(0);
9642 -
9643 -       while(addr < ((addr + remain) & PAGE_MASK)){
9644 -               n = (*op)(addr, PAGE_SIZE, arg);
9645 -               if(n != 0)
9646 -                       return(n < 0 ? remain : 0);
9647 -
9648 -               addr += PAGE_SIZE;
9649 -               remain -= PAGE_SIZE;
9650 -       }
9651 -       if(remain == 0)
9652 -               return(0);
9653 -
9654 -       n = (*op)(addr, remain, arg);
9655 -       if(n != 0)
9656 -               return(n < 0 ? remain : 0);
9657 -       return(0);
9658 -}
9659 -
9660 -static inline int copy_chunk_from_user(unsigned long from, int len, void *arg)
9661 -{
9662 -       unsigned long *to_ptr = arg, to = *to_ptr;
9663 -
9664 -       from = maybe_map(from, 0);
9665 -       if(from == 0)
9666 -               return(-1);
9667 -
9668 -       memcpy((void *) to, (void *) from, len);
9669 -       *to_ptr += len;
9670 -       return(0);
9671 -}
9672 -
9673 -static inline int copy_from_user_skas(void *to, const void *from, int n)
9674 -{
9675 -       if(segment_eq(get_fs(), KERNEL_DS)){
9676 -               memcpy(to, from, n);
9677 -               return(0);
9678 -       }
9679 -
9680 -       return(access_ok_skas(VERIFY_READ, from, n) ?
9681 -              buffer_op((unsigned long) from, n, copy_chunk_from_user, &to) :
9682 -              n);
9683 -}
9684 -
9685 -static inline int copy_chunk_to_user(unsigned long to, int len, void *arg)
9686 -{
9687 -       unsigned long *from_ptr = arg, from = *from_ptr;
9688 -
9689 -       to = maybe_map(to, 1);
9690 -       if(to == 0)
9691 -               return(-1);
9692 -
9693 -       memcpy((void *) to, (void *) from, len);
9694 -       *from_ptr += len;
9695 -       return(0);
9696 -}
9697 -
9698 -static inline int copy_to_user_skas(void *to, const void *from, int n)
9699 -{
9700 -       if(segment_eq(get_fs(), KERNEL_DS)){
9701 -               memcpy(to, from, n);
9702 -               return(0);
9703 -       }
9704 -
9705 -       return(access_ok_skas(VERIFY_WRITE, to, n) ?
9706 -              buffer_op((unsigned long) to, n, copy_chunk_to_user, &from) :
9707 -              n);
9708 -}
9709 -
9710 -static inline int strncpy_chunk_from_user(unsigned long from, int len, 
9711 -                                         void *arg)
9712 -{
9713 -        char **to_ptr = arg, *to = *to_ptr;
9714 -       int n;
9715 -
9716 -       from = maybe_map(from, 0);
9717 -       if(from == 0)
9718 -               return(-1);
9719 -
9720 -       strncpy(to, (void *) from, len);
9721 -       n = strnlen(to, len);
9722 -       *to_ptr += n;
9723 -
9724 -       if(n < len) 
9725 -               return(1);
9726 -       return(0);
9727 -}
9728 -
9729 -static inline int strncpy_from_user_skas(char *dst, const char *src, int count)
9730 -{
9731 -       int n;
9732 -       char *ptr = dst;
9733 -
9734 -       if(segment_eq(get_fs(), KERNEL_DS)){
9735 -               strncpy(dst, src, count);
9736 -               return(strnlen(dst, count));
9737 -       }
9738 -
9739 -       if(!access_ok_skas(VERIFY_READ, src, 1))
9740 -               return(-EFAULT);
9741 -
9742 -       n = buffer_op((unsigned long) src, count, strncpy_chunk_from_user, 
9743 -                     &ptr);
9744 -       if(n != 0)
9745 -               return(-EFAULT);
9746 -       return(strnlen(dst, count));
9747 -}
9748 -
9749 -static inline int clear_chunk(unsigned long addr, int len, void *unused)
9750 -{
9751 -       addr = maybe_map(addr, 1);
9752 -       if(addr == 0) 
9753 -               return(-1);
9754 -
9755 -       memset((void *) addr, 0, len);
9756 -       return(0);
9757 -}
9758 -
9759 -static inline int __clear_user_skas(void *mem, int len)
9760 -{
9761 -       return(buffer_op((unsigned long) mem, len, clear_chunk, NULL));
9762 -}
9763 -
9764 -static inline int clear_user_skas(void *mem, int len)
9765 -{
9766 -       if(segment_eq(get_fs(), KERNEL_DS)){
9767 -               memset(mem, 0, len);
9768 -               return(0);
9769 -       }
9770 -
9771 -       return(access_ok_skas(VERIFY_WRITE, mem, len) ? 
9772 -              buffer_op((unsigned long) mem, len, clear_chunk, NULL) : len);
9773 -}
9774 -
9775 -static inline int strnlen_chunk(unsigned long str, int len, void *arg)
9776 -{
9777 -       int *len_ptr = arg, n;
9778 -
9779 -       str = maybe_map(str, 0);
9780 -       if(str == 0) 
9781 -               return(-1);
9782 -
9783 -       n = strnlen((void *) str, len);
9784 -       *len_ptr += n;
9785 -
9786 -       if(n < len)
9787 -               return(1);
9788 -       return(0);
9789 -}
9790 -
9791 -static inline int strnlen_user_skas(const void *str, int len)
9792 -{
9793 -       int count = 0, n;
9794 -
9795 -       if(segment_eq(get_fs(), KERNEL_DS))
9796 -               return(strnlen(str, len) + 1);
9797 -
9798 -       n = buffer_op((unsigned long) str, len, strnlen_chunk, &count);
9799 -       if(n == 0)
9800 -               return(count + 1);
9801 -       return(-EFAULT);
9802 -}
9803 +extern int copy_from_user_skas(void *to, const void *from, int n);
9804 +extern int copy_to_user_skas(void *to, const void *from, int n);
9805 +extern int strncpy_from_user_skas(char *dst, const char *src, int count);
9806 +extern int __clear_user_skas(void *mem, int len);
9807 +extern int clear_user_skas(void *mem, int len);
9808 +extern int strnlen_user_skas(const void *str, int len);
9809  
9810  #endif
9811  
9812 diff -Naur a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile
9813 --- a/arch/um/kernel/skas/Makefile      2004-02-11 12:14:38.000000000 -0500
9814 +++ b/arch/um/kernel/skas/Makefile      2004-02-11 12:26:41.000000000 -0500
9815 @@ -5,20 +5,24 @@
9816  
9817  obj-y = exec_kern.o exec_user.o mem.o mem_user.o mmu.o process.o \
9818         process_kern.o syscall_kern.o syscall_user.o time.o tlb.o trap_user.o \
9819 -       sys-$(SUBARCH)/
9820 +       uaccess.o sys-$(SUBARCH)/
9821 +
9822 +host-progs     := util/mk_ptregs
9823 +clean-files    := include/skas_ptregs.h
9824  
9825  USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o
9826  USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
9827  
9828 -include/skas_ptregs.h : util/mk_ptregs
9829 -       util/mk_ptregs > $@
9830 -
9831 -util/mk_ptregs :
9832 -       $(MAKE) -C util
9833 +$(TOPDIR)/arch/um/include/skas_ptregs.h : $(src)/util/mk_ptregs
9834 +       @echo -n '  Generating $@'
9835 +       @$< > $@.tmp
9836 +       @if [ -r $@ ] && cmp -s $@ $@.tmp; then \
9837 +               echo ' (unchanged)'; \
9838 +               rm -f $@.tmp; \
9839 +       else \
9840 +               echo ' (updated)'; \
9841 +               mv -f $@.tmp $@; \
9842 +       fi
9843  
9844  $(USER_OBJS) : %.o: %.c
9845         $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
9846 -
9847 -clean :
9848 -       $(MAKE) -C util clean
9849 -       $(RM) -f include/skas_ptregs.h
9850 diff -Naur a/arch/um/kernel/skas/mem_user.c b/arch/um/kernel/skas/mem_user.c
9851 --- a/arch/um/kernel/skas/mem_user.c    2004-02-11 12:14:58.000000000 -0500
9852 +++ b/arch/um/kernel/skas/mem_user.c    2004-02-11 12:26:50.000000000 -0500
9853 @@ -7,6 +7,7 @@
9854  #include <sys/mman.h>
9855  #include <sys/ptrace.h>
9856  #include "mem_user.h"
9857 +#include "mem.h"
9858  #include "user.h"
9859  #include "os.h"
9860  #include "proc_mm.h"
9861 @@ -15,12 +16,12 @@
9862          int r, int w, int x)
9863  {
9864         struct proc_mm_op map;
9865 -       struct mem_region *region;
9866 -       int prot, n;
9867 +       __u64 offset;
9868 +       int prot, n, phys_fd;
9869  
9870         prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 
9871                 (x ? PROT_EXEC : 0);
9872 -       region = phys_region(phys);
9873 +       phys_fd = phys_mapping(phys, &offset);
9874  
9875         map = ((struct proc_mm_op) { .op        = MM_MMAP,
9876                                      .u         = 
9877 @@ -30,12 +31,12 @@
9878                                          .prot          = prot,
9879                                          .flags         = MAP_SHARED | 
9880                                                           MAP_FIXED,
9881 -                                        .fd            = region->fd,
9882 -                                        .offset        = phys_offset(phys)
9883 +                                        .fd            = phys_fd,
9884 +                                        .offset        = offset
9885                                        } } } );
9886         n = os_write_file(fd, &map, sizeof(map));
9887         if(n != sizeof(map)) 
9888 -               printk("map : /proc/mm map failed, errno = %d\n", errno);
9889 +               printk("map : /proc/mm map failed, err = %d\n", -n);
9890  }
9891  
9892  int unmap(int fd, void *addr, int len)
9893 @@ -49,8 +50,13 @@
9894                                          { .addr        = (unsigned long) addr,
9895                                            .len         = len } } } );
9896         n = os_write_file(fd, &unmap, sizeof(unmap));
9897 -       if((n != 0) && (n != sizeof(unmap)))
9898 -               return(-errno);
9899 +       if(n != sizeof(unmap)) {
9900 +               if(n < 0) 
9901 +                       return(n);
9902 +               else if(n > 0) 
9903 +                       return(-EIO);
9904 +       }
9905 +
9906         return(0);
9907  }
9908  
9909 @@ -71,11 +77,15 @@
9910                                            .prot        = prot } } } );
9911  
9912         n = os_write_file(fd, &protect, sizeof(protect));
9913 -       if((n != 0) && (n != sizeof(protect))){
9914 +       if(n != sizeof(protect)) {
9915 +               if(n == 0) return(0);
9916 +
9917                 if(must_succeed)
9918 -                       panic("protect failed, errno = %d", errno);
9919 -               return(-errno);
9920 +                       panic("protect failed, err = %d", -n);
9921 +
9922 +               return(-EIO);
9923         }
9924 +
9925         return(0);
9926  }
9927  
9928 diff -Naur a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
9929 --- a/arch/um/kernel/skas/mmu.c 2004-02-11 12:17:12.000000000 -0500
9930 +++ b/arch/um/kernel/skas/mmu.c 2004-02-11 12:29:17.000000000 -0500
9931 @@ -22,9 +22,11 @@
9932         else from = -1;
9933  
9934         mm->context.skas.mm_fd = new_mm(from);
9935 -       if(mm->context.skas.mm_fd < 0)
9936 -               panic("init_new_context_skas - new_mm failed, errno = %d\n",
9937 -                     mm->context.skas.mm_fd);
9938 +       if(mm->context.skas.mm_fd < 0){
9939 +               printk("init_new_context_skas - new_mm failed, errno = %d\n",
9940 +                      mm->context.skas.mm_fd);
9941 +               return(mm->context.skas.mm_fd);
9942 +       }
9943  
9944         return(0);
9945  }
9946 diff -Naur a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
9947 --- a/arch/um/kernel/skas/process.c     2004-02-11 12:16:47.000000000 -0500
9948 +++ b/arch/um/kernel/skas/process.c     2004-02-11 12:29:02.000000000 -0500
9949 @@ -4,6 +4,7 @@
9950   */
9951  
9952  #include <stdlib.h>
9953 +#include <unistd.h>
9954  #include <errno.h>
9955  #include <signal.h>
9956  #include <setjmp.h>
9957 @@ -24,6 +25,18 @@
9958  #include "os.h"
9959  #include "proc_mm.h"
9960  #include "skas_ptrace.h"
9961 +#include "chan_user.h"
9962 +
9963 +int is_skas_winch(int pid, int fd, void *data)
9964 +{
9965 +       if(pid != getpid())
9966 +               return(0);
9967 +
9968 +       register_winch_irq(-1, fd, -1, data);
9969 +       return(1);
9970 +}
9971 +
9972 +/* These are set once at boot time and not changed thereafter */
9973  
9974  unsigned long exec_regs[FRAME_SIZE];
9975  unsigned long exec_fp_regs[HOST_FP_SIZE];
9976 @@ -48,11 +61,11 @@
9977         int err, syscall_nr, status;
9978  
9979         syscall_nr = PT_SYSCALL_NR(regs->skas.regs);
9980 +       UPT_SYSCALL_NR(regs) = syscall_nr;
9981         if(syscall_nr < 1){
9982                 relay_signal(SIGTRAP, regs);
9983                 return;
9984         }
9985 -       UPT_SYSCALL_NR(regs) = syscall_nr;
9986  
9987         err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);
9988         if(err < 0)
9989 @@ -72,8 +85,6 @@
9990         handle_syscall(regs);
9991  }
9992  
9993 -int userspace_pid;
9994 -
9995  static int userspace_tramp(void *arg)
9996  {
9997         init_new_thread_signals(0);
9998 @@ -83,7 +94,11 @@
9999         return(0);
10000  }
10001  
10002 -void start_userspace(void)
10003 +/* Each element set once, and only accessed by a single processor anyway */
10004 +#define NR_CPUS 1
10005 +int userspace_pid[NR_CPUS];
10006 +
10007 +void start_userspace(int cpu)
10008  {
10009         void *stack;
10010         unsigned long sp;
10011 @@ -114,21 +129,21 @@
10012         if(munmap(stack, PAGE_SIZE) < 0)
10013                 panic("start_userspace : munmap failed, errno = %d\n", errno);
10014  
10015 -       userspace_pid = pid;
10016 +       userspace_pid[cpu] = pid;
10017  }
10018  
10019  void userspace(union uml_pt_regs *regs)
10020  {
10021 -       int err, status, op;
10022 +       int err, status, op, pid = userspace_pid[0];
10023  
10024         restore_registers(regs);
10025                 
10026 -       err = ptrace(PTRACE_SYSCALL, userspace_pid, 0, 0);
10027 +       err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
10028         if(err)
10029                 panic("userspace - PTRACE_SYSCALL failed, errno = %d\n", 
10030                        errno);
10031         while(1){
10032 -               err = waitpid(userspace_pid, &status, WUNTRACED);
10033 +               err = waitpid(pid, &status, WUNTRACED);
10034                 if(err < 0)
10035                         panic("userspace - waitpid failed, errno = %d\n", 
10036                               errno);
10037 @@ -139,16 +154,17 @@
10038                 if(WIFSTOPPED(status)){
10039                         switch(WSTOPSIG(status)){
10040                         case SIGSEGV:
10041 -                               handle_segv(userspace_pid);
10042 +                               handle_segv(pid);
10043                                 break;
10044                         case SIGTRAP:
10045 -                               handle_trap(userspace_pid, regs);
10046 +                               handle_trap(pid, regs);
10047                                 break;
10048                         case SIGIO:
10049                         case SIGVTALRM:
10050                         case SIGILL:
10051                         case SIGBUS:
10052                         case SIGFPE:
10053 +                       case SIGWINCH:
10054                                 user_signal(WSTOPSIG(status), regs);
10055                                 break;
10056                         default:
10057 @@ -162,7 +178,7 @@
10058  
10059                 op = singlestepping_skas() ? PTRACE_SINGLESTEP : 
10060                         PTRACE_SYSCALL;
10061 -               err = ptrace(op, userspace_pid, 0, 0);
10062 +               err = ptrace(op, pid, 0, 0);
10063                 if(err)
10064                         panic("userspace - PTRACE_SYSCALL failed, "
10065                               "errno = %d\n", errno);
10066 @@ -177,7 +193,7 @@
10067         *switch_buf_ptr = &switch_buf;
10068         *fork_buf_ptr = &fork_buf;
10069  
10070 -       if(setjmp(fork_buf) == 0)
10071 +       if(sigsetjmp(fork_buf, 1) == 0)
10072                 new_thread_proc(stack, handler);
10073  
10074         remove_sigstack();
10075 @@ -189,16 +205,16 @@
10076  
10077         *switch_buf = &buf;
10078         fork_buf = fb;
10079 -       if(setjmp(buf) == 0)
10080 -               longjmp(*fork_buf, 1);
10081 +       if(sigsetjmp(buf, 1) == 0)
10082 +               siglongjmp(*fork_buf, 1);
10083  }
10084  
10085 -static int move_registers(int int_op, int fp_op, union uml_pt_regs *regs,
10086 -                         unsigned long *fp_regs)
10087 +static int move_registers(int pid, int int_op, int fp_op, 
10088 +                         union uml_pt_regs *regs, unsigned long *fp_regs)
10089  {
10090 -       if(ptrace(int_op, userspace_pid, 0, regs->skas.regs) < 0)
10091 +       if(ptrace(int_op, pid, 0, regs->skas.regs) < 0)
10092                 return(-errno);
10093 -       if(ptrace(fp_op, userspace_pid, 0, fp_regs) < 0)
10094 +       if(ptrace(fp_op, pid, 0, fp_regs) < 0)
10095                 return(-errno);
10096         return(0);
10097  }
10098 @@ -217,10 +233,11 @@
10099                 fp_regs = regs->skas.fp;
10100         }
10101  
10102 -       err = move_registers(PTRACE_GETREGS, fp_op, regs, fp_regs);
10103 +       err = move_registers(userspace_pid[0], PTRACE_GETREGS, fp_op, regs, 
10104 +                            fp_regs);
10105         if(err)
10106                 panic("save_registers - saving registers failed, errno = %d\n",
10107 -                     err);
10108 +                     -err);
10109  }
10110  
10111  void restore_registers(union uml_pt_regs *regs)
10112 @@ -237,10 +254,11 @@
10113                 fp_regs = regs->skas.fp;
10114         }
10115  
10116 -       err = move_registers(PTRACE_SETREGS, fp_op, regs, fp_regs);
10117 +       err = move_registers(userspace_pid[0], PTRACE_SETREGS, fp_op, regs, 
10118 +                            fp_regs);
10119         if(err)
10120                 panic("restore_registers - saving registers failed, "
10121 -                     "errno = %d\n", err);
10122 +                     "errno = %d\n", -err);
10123  }
10124  
10125  void switch_threads(void *me, void *next)
10126 @@ -248,8 +266,8 @@
10127         jmp_buf my_buf, **me_ptr = me, *next_buf = next;
10128         
10129         *me_ptr = &my_buf;
10130 -       if(setjmp(my_buf) == 0)
10131 -               longjmp(*next_buf, 1);
10132 +       if(sigsetjmp(my_buf, 1) == 0)
10133 +               siglongjmp(*next_buf, 1);
10134  }
10135  
10136  static jmp_buf initial_jmpbuf;
10137 @@ -265,14 +283,14 @@
10138         int n;
10139  
10140         *fork_buf_ptr = &initial_jmpbuf;
10141 -       n = setjmp(initial_jmpbuf);
10142 +       n = sigsetjmp(initial_jmpbuf, 1);
10143         if(n == 0)
10144                 new_thread_proc((void *) stack, new_thread_handler);
10145         else if(n == 1)
10146                 remove_sigstack();
10147         else if(n == 2){
10148                 (*cb_proc)(cb_arg);
10149 -               longjmp(*cb_back, 1);
10150 +               siglongjmp(*cb_back, 1);
10151         }
10152         else if(n == 3){
10153                 kmalloc_ok = 0;
10154 @@ -282,7 +300,7 @@
10155                 kmalloc_ok = 0;
10156                 return(1);
10157         }
10158 -       longjmp(**switch_buf, 1);
10159 +       siglongjmp(**switch_buf, 1);
10160  }
10161  
10162  void remove_sigstack(void)
10163 @@ -304,8 +322,8 @@
10164         cb_back = &here;
10165  
10166         block_signals();
10167 -       if(setjmp(here) == 0)
10168 -               longjmp(initial_jmpbuf, 2);
10169 +       if(sigsetjmp(here, 1) == 0)
10170 +               siglongjmp(initial_jmpbuf, 2);
10171         unblock_signals();
10172  
10173         cb_proc = NULL;
10174 @@ -316,22 +334,23 @@
10175  void halt_skas(void)
10176  {
10177         block_signals();
10178 -       longjmp(initial_jmpbuf, 3);
10179 +       siglongjmp(initial_jmpbuf, 3);
10180  }
10181  
10182  void reboot_skas(void)
10183  {
10184         block_signals();
10185 -       longjmp(initial_jmpbuf, 4);
10186 +       siglongjmp(initial_jmpbuf, 4);
10187  }
10188  
10189  int new_mm(int from)
10190  {
10191         struct proc_mm_op copy;
10192 -       int n, fd = os_open_file("/proc/mm", of_write(OPENFLAGS()), 0);
10193 +       int n, fd = os_open_file("/proc/mm", 
10194 +                                of_cloexec(of_write(OPENFLAGS())), 0);
10195  
10196         if(fd < 0)
10197 -               return(-errno);
10198 +               return(fd);
10199  
10200         if(from != -1){
10201                 copy = ((struct proc_mm_op) { .op       = MM_COPY_SEGMENTS,
10202 @@ -340,8 +359,9 @@
10203                 n = os_write_file(fd, &copy, sizeof(copy));
10204                 if(n != sizeof(copy)) 
10205                         printk("new_mm : /proc/mm copy_segments failed, "
10206 -                              "errno = %d\n", errno);
10207 +                              "err = %d\n", -n);
10208         }
10209 +
10210         return(fd);
10211  }
10212  
10213 @@ -349,7 +369,8 @@
10214  {
10215         int err;
10216  
10217 -       err = ptrace(PTRACE_SWITCH_MM, userspace_pid, 0, mm_fd);
10218 +#warning need cpu pid in switch_mm_skas
10219 +       err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, mm_fd);
10220         if(err)
10221                 panic("switch_mm_skas - PTRACE_SWITCH_MM failed, errno = %d\n",
10222                       errno);
10223 @@ -357,7 +378,8 @@
10224  
10225  void kill_off_processes_skas(void)
10226  {
10227 -       os_kill_process(userspace_pid, 1);
10228 +#warning need to loop over userspace_pids in kill_off_processes_skas
10229 +       os_kill_process(userspace_pid[0], 1);
10230  }
10231  
10232  void init_registers(int pid)
10233 diff -Naur a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
10234 --- a/arch/um/kernel/skas/process_kern.c        2004-02-11 12:14:33.000000000 -0500
10235 +++ b/arch/um/kernel/skas/process_kern.c        2004-02-11 12:26:15.000000000 -0500
10236 @@ -61,11 +61,13 @@
10237         thread_wait(&current->thread.mode.skas.switch_buf, 
10238                     current->thread.mode.skas.fork_buf);
10239  
10240 -#ifdef CONFIG_SMP
10241 -       schedule_tail(NULL);
10242 -#endif
10243 +       if(current->thread.prev_sched != NULL)
10244 +               schedule_tail(current->thread.prev_sched);
10245         current->thread.prev_sched = NULL;
10246  
10247 +       /* The return value is 1 if the kernel thread execs a process,
10248 +        * 0 if it just exits
10249 +        */
10250         n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
10251         if(n == 1)
10252                 userspace(&current->thread.regs.regs);
10253 @@ -93,9 +95,8 @@
10254                     current->thread.mode.skas.fork_buf);
10255         
10256         force_flush_all();
10257 -#ifdef CONFIG_SMP
10258 -       schedule_tail(current->thread.prev_sched);
10259 -#endif
10260 +       if(current->thread.prev_sched != NULL)
10261 +               schedule_tail(current->thread.prev_sched);
10262         current->thread.prev_sched = NULL;
10263         unblock_signals();
10264  
10265 @@ -136,7 +137,7 @@
10266  
10267  void init_idle_skas(void)
10268  {
10269 -       cpu_tasks[current->thread_info->cpu].pid = os_getpid();
10270 +       cpu_tasks[current_thread->cpu].pid = os_getpid();
10271         default_idle();
10272  }
10273  
10274 @@ -160,11 +161,11 @@
10275  
10276  int start_uml_skas(void)
10277  {
10278 -       start_userspace();
10279 +       start_userspace(0);
10280         capture_signal_stack();
10281 +       uml_idle_timer();
10282  
10283         init_new_thread_signals(1);
10284 -       idle_timer();
10285  
10286         init_task.thread.request.u.thread.proc = start_kernel_proc;
10287         init_task.thread.request.u.thread.arg = NULL;
10288 @@ -175,12 +176,14 @@
10289  
10290  int external_pid_skas(struct task_struct *task)
10291  {
10292 -       return(userspace_pid);
10293 +#warning Need to look up userspace_pid by cpu  
10294 +       return(userspace_pid[0]);
10295  }
10296  
10297  int thread_pid_skas(struct task_struct *task)
10298  {
10299 -       return(userspace_pid);
10300 +#warning Need to look up userspace_pid by cpu  
10301 +       return(userspace_pid[0]);
10302  }
10303  
10304  /*
10305 diff -Naur a/arch/um/kernel/skas/syscall_kern.c b/arch/um/kernel/skas/syscall_kern.c
10306 --- a/arch/um/kernel/skas/syscall_kern.c        2004-02-11 12:15:58.000000000 -0500
10307 +++ b/arch/um/kernel/skas/syscall_kern.c        2004-02-11 12:27:51.000000000 -0500
10308 @@ -1,5 +1,5 @@
10309  /* 
10310 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
10311 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
10312   * Licensed under the GPL
10313   */
10314  
10315 diff -Naur a/arch/um/kernel/skas/sys-i386/Makefile b/arch/um/kernel/skas/sys-i386/Makefile
10316 --- a/arch/um/kernel/skas/sys-i386/Makefile     2004-02-11 12:16:38.000000000 -0500
10317 +++ b/arch/um/kernel/skas/sys-i386/Makefile     2004-02-11 12:28:37.000000000 -0500
10318 @@ -10,5 +10,3 @@
10319  
10320  $(USER_OBJS) : %.o: %.c
10321         $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
10322 -
10323 -clean :
10324 diff -Naur a/arch/um/kernel/skas/sys-i386/sigcontext.c b/arch/um/kernel/skas/sys-i386/sigcontext.c
10325 --- a/arch/um/kernel/skas/sys-i386/sigcontext.c 2004-02-11 12:14:18.000000000 -0500
10326 +++ b/arch/um/kernel/skas/sys-i386/sigcontext.c 2004-02-11 12:26:01.000000000 -0500
10327 @@ -12,10 +12,9 @@
10328  #include "kern_util.h"
10329  #include "user.h"
10330  #include "sigcontext.h"
10331 +#include "mode.h"
10332  
10333 -extern int userspace_pid;
10334 -
10335 -int copy_sc_from_user_skas(union uml_pt_regs *regs, void *from_ptr)
10336 +int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs, void *from_ptr)
10337  {
10338         struct sigcontext sc, *from = from_ptr;
10339         unsigned long fpregs[FP_FRAME_SIZE];
10340 @@ -41,13 +40,12 @@
10341         regs->skas.regs[EIP] = sc.eip;
10342         regs->skas.regs[CS] = sc.cs;
10343         regs->skas.regs[EFL] = sc.eflags;
10344 -       regs->skas.regs[UESP] = sc.esp_at_signal;
10345         regs->skas.regs[SS] = sc.ss;
10346         regs->skas.fault_addr = sc.cr2;
10347         regs->skas.fault_type = FAULT_WRITE(sc.err);
10348         regs->skas.trap_type = sc.trapno;
10349  
10350 -       err = ptrace(PTRACE_SETFPREGS, userspace_pid, 0, fpregs);
10351 +       err = ptrace(PTRACE_SETFPREGS, pid, 0, fpregs);
10352         if(err < 0){
10353                 printk("copy_sc_to_user - PTRACE_SETFPREGS failed, "
10354                        "errno = %d\n", errno);
10355 @@ -57,8 +55,9 @@
10356         return(0);
10357  }
10358  
10359 -int copy_sc_to_user_skas(void *to_ptr, void *fp, union uml_pt_regs *regs, 
10360 -                        unsigned long fault_addr, int fault_type)
10361 +int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp, 
10362 +                        union uml_pt_regs *regs, unsigned long fault_addr, 
10363 +                        int fault_type)
10364  {
10365         struct sigcontext sc, *to = to_ptr;
10366         struct _fpstate *to_fp;
10367 @@ -86,7 +85,7 @@
10368         sc.err = TO_SC_ERR(fault_type);
10369         sc.trapno = regs->skas.trap_type;
10370  
10371 -       err = ptrace(PTRACE_GETFPREGS, userspace_pid, 0, fpregs);
10372 +       err = ptrace(PTRACE_GETFPREGS, pid, 0, fpregs);
10373         if(err < 0){
10374                 printk("copy_sc_to_user - PTRACE_GETFPREGS failed, "
10375                        "errno = %d\n", errno);
10376 diff -Naur a/arch/um/kernel/skas/trap_user.c b/arch/um/kernel/skas/trap_user.c
10377 --- a/arch/um/kernel/skas/trap_user.c   2004-02-11 12:15:17.000000000 -0500
10378 +++ b/arch/um/kernel/skas/trap_user.c   2004-02-11 12:27:06.000000000 -0500
10379 @@ -1,5 +1,5 @@
10380  /* 
10381 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
10382 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
10383   * Licensed under the GPL
10384   */
10385  
10386 @@ -41,8 +41,6 @@
10387  {
10388         struct signal_info *info;
10389  
10390 -       if(sig == SIGVTALRM)
10391 -               missed_ticks[cpu()]++;
10392         regs->skas.is_user = 1;
10393         regs->skas.fault_addr = 0;
10394         regs->skas.fault_type = 0;
10395 diff -Naur a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
10396 --- a/arch/um/kernel/skas/uaccess.c     1969-12-31 19:00:00.000000000 -0500
10397 +++ b/arch/um/kernel/skas/uaccess.c     2004-02-11 12:28:20.000000000 -0500
10398 @@ -0,0 +1,219 @@
10399 +/* 
10400 + * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
10401 + * Licensed under the GPL
10402 + */
10403 +
10404 +#include "linux/stddef.h"
10405 +#include "linux/kernel.h"
10406 +#include "linux/string.h"
10407 +#include "linux/fs.h"
10408 +#include "linux/highmem.h"
10409 +#include "asm/page.h"
10410 +#include "asm/pgtable.h"
10411 +#include "asm/uaccess.h"
10412 +#include "kern_util.h"
10413 +
10414 +extern void *um_virt_to_phys(struct task_struct *task, unsigned long addr, 
10415 +                            pte_t *pte_out);
10416 +
10417 +static unsigned long maybe_map(unsigned long virt, int is_write)
10418 +{
10419 +       pte_t pte;
10420 +       int err;
10421 +
10422 +       void *phys = um_virt_to_phys(current, virt, &pte);
10423 +       int dummy_code;
10424 +
10425 +       if(IS_ERR(phys) || (is_write && !pte_write(pte))){
10426 +               err = handle_page_fault(virt, 0, is_write, 0, &dummy_code);
10427 +               if(err)
10428 +                       return(0);
10429 +               phys = um_virt_to_phys(current, virt, NULL);
10430 +       }
10431 +       return((unsigned long) phys);
10432 +}
10433 +
10434 +static int do_op(unsigned long addr, int len, int is_write, 
10435 +                int (*op)(unsigned long addr, int len, void *arg), void *arg)
10436 +{
10437 +       struct page *page;
10438 +       int n;
10439 +
10440 +       addr = maybe_map(addr, is_write);
10441 +       if(addr == -1)
10442 +               return(-1);
10443 +
10444 +       page = phys_to_page(addr);
10445 +       addr = (unsigned long) kmap(page) + (addr & ~PAGE_MASK);
10446 +       n = (*op)(addr, len, arg);
10447 +       kunmap(page);
10448 +
10449 +       return(n);
10450 +}
10451 +
10452 +static int buffer_op(unsigned long addr, int len, int is_write,
10453 +                    int (*op)(unsigned long addr, int len, void *arg),
10454 +                    void *arg)
10455 +{
10456 +       int size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len);
10457 +       int remain = len, n;
10458 +
10459 +       n = do_op(addr, size, is_write, op, arg);
10460 +       if(n != 0)
10461 +               return(n < 0 ? remain : 0);
10462 +
10463 +       addr += size;
10464 +       remain -= size;
10465 +       if(remain == 0) 
10466 +               return(0);
10467 +
10468 +       while(addr < ((addr + remain) & PAGE_MASK)){
10469 +               n = do_op(addr, PAGE_SIZE, is_write, op, arg);
10470 +               if(n != 0)
10471 +                       return(n < 0 ? remain : 0);
10472 +
10473 +               addr += PAGE_SIZE;
10474 +               remain -= PAGE_SIZE;
10475 +       }
10476 +       if(remain == 0)
10477 +               return(0);
10478 +
10479 +       n = do_op(addr, remain, is_write, op, arg);
10480 +       if(n != 0)
10481 +               return(n < 0 ? remain : 0);
10482 +       return(0);
10483 +}
10484 +
10485 +static int copy_chunk_from_user(unsigned long from, int len, void *arg)
10486 +{
10487 +       unsigned long *to_ptr = arg, to = *to_ptr;
10488 +
10489 +       memcpy((void *) to, (void *) from, len);
10490 +       *to_ptr += len;
10491 +       return(0);
10492 +}
10493 +
10494 +int copy_from_user_skas(void *to, const void *from, int n)
10495 +{
10496 +       if(segment_eq(get_fs(), KERNEL_DS)){
10497 +               memcpy(to, from, n);
10498 +               return(0);
10499 +       }
10500 +
10501 +       return(access_ok_skas(VERIFY_READ, from, n) ?
10502 +              buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to):
10503 +              n);
10504 +}
10505 +
10506 +static int copy_chunk_to_user(unsigned long to, int len, void *arg)
10507 +{
10508 +       unsigned long *from_ptr = arg, from = *from_ptr;
10509 +
10510 +       memcpy((void *) to, (void *) from, len);
10511 +       *from_ptr += len;
10512 +       return(0);
10513 +}
10514 +
10515 +int copy_to_user_skas(void *to, const void *from, int n)
10516 +{
10517 +       if(segment_eq(get_fs(), KERNEL_DS)){
10518 +               memcpy(to, from, n);
10519 +               return(0);
10520 +       }
10521 +
10522 +       return(access_ok_skas(VERIFY_WRITE, to, n) ?
10523 +              buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) :
10524 +              n);
10525 +}
10526 +
10527 +static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
10528 +{
10529 +       char **to_ptr = arg, *to = *to_ptr;
10530 +       int n;
10531 +
10532 +       strncpy(to, (void *) from, len);
10533 +       n = strnlen(to, len);
10534 +       *to_ptr += n;
10535 +
10536 +       if(n < len) 
10537 +               return(1);
10538 +       return(0);
10539 +}
10540 +
10541 +int strncpy_from_user_skas(char *dst, const char *src, int count)
10542 +{
10543 +       int n;
10544 +       char *ptr = dst;
10545 +
10546 +       if(segment_eq(get_fs(), KERNEL_DS)){
10547 +               strncpy(dst, src, count);
10548 +               return(strnlen(dst, count));
10549 +       }
10550 +
10551 +       if(!access_ok_skas(VERIFY_READ, src, 1))
10552 +               return(-EFAULT);
10553 +
10554 +       n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user, 
10555 +                     &ptr);
10556 +       if(n != 0)
10557 +               return(-EFAULT);
10558 +       return(strnlen(dst, count));
10559 +}
10560 +
10561 +static int clear_chunk(unsigned long addr, int len, void *unused)
10562 +{
10563 +       memset((void *) addr, 0, len);
10564 +       return(0);
10565 +}
10566 +
10567 +int __clear_user_skas(void *mem, int len)
10568 +{
10569 +       return(buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL));
10570 +}
10571 +
10572 +int clear_user_skas(void *mem, int len)
10573 +{
10574 +       if(segment_eq(get_fs(), KERNEL_DS)){
10575 +               memset(mem, 0, len);
10576 +               return(0);
10577 +       }
10578 +
10579 +       return(access_ok_skas(VERIFY_WRITE, mem, len) ? 
10580 +              buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len);
10581 +}
10582 +
10583 +static int strnlen_chunk(unsigned long str, int len, void *arg)
10584 +{
10585 +       int *len_ptr = arg, n;
10586 +
10587 +       n = strnlen((void *) str, len);
10588 +       *len_ptr += n;
10589 +
10590 +       if(n < len)
10591 +               return(1);
10592 +       return(0);
10593 +}
10594 +
10595 +int strnlen_user_skas(const void *str, int len)
10596 +{
10597 +       int count = 0, n;
10598 +
10599 +       if(segment_eq(get_fs(), KERNEL_DS))
10600 +               return(strnlen(str, len) + 1);
10601 +
10602 +       n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count);
10603 +       if(n == 0)
10604 +               return(count + 1);
10605 +       return(-EFAULT);
10606 +}
10607 +
10608 +/*
10609 + * Overrides for Emacs so that we follow Linus's tabbing style.
10610 + * Emacs will notice this stuff at the end of the file and automatically
10611 + * adjust the settings for this buffer only.  This must remain at the end
10612 + * of the file.
10613 + * ---------------------------------------------------------------------------
10614 + * Local variables:
10615 + * c-file-style: "linux"
10616 + * End:
10617 + */
10618 diff -Naur a/arch/um/kernel/skas/util/Makefile b/arch/um/kernel/skas/util/Makefile
10619 --- a/arch/um/kernel/skas/util/Makefile 2004-02-11 12:16:34.000000000 -0500
10620 +++ b/arch/um/kernel/skas/util/Makefile 2004-02-11 12:28:33.000000000 -0500
10621 @@ -1,10 +1,9 @@
10622  all: mk_ptregs
10623  
10624  mk_ptregs : mk_ptregs.o
10625 -       $(CC) -o mk_ptregs mk_ptregs.o
10626 +       $(HOSTCC) -o mk_ptregs mk_ptregs.o
10627  
10628  mk_ptregs.o : mk_ptregs.c
10629 -       $(CC) -c $< 
10630 +       $(HOSTCC) -c $< 
10631  
10632 -clean : 
10633 -       $(RM) -f mk_ptregs *.o *~
10634 +clean-files := mk_ptregs *.o *~
10635 diff -Naur a/arch/um/kernel/skas/util/mk_ptregs.c b/arch/um/kernel/skas/util/mk_ptregs.c
10636 --- a/arch/um/kernel/skas/util/mk_ptregs.c      2004-02-11 12:15:12.000000000 -0500
10637 +++ b/arch/um/kernel/skas/util/mk_ptregs.c      2004-02-11 12:27:00.000000000 -0500
10638 @@ -1,3 +1,4 @@
10639 +#include <stdio.h>
10640  #include <asm/ptrace.h>
10641  #include <asm/user.h>
10642  
10643 diff -Naur a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c
10644 --- a/arch/um/kernel/smp.c      2004-02-11 12:14:32.000000000 -0500
10645 +++ b/arch/um/kernel/smp.c      2004-02-11 12:26:13.000000000 -0500
10646 @@ -1,9 +1,15 @@
10647  /* 
10648 - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
10649 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
10650   * Licensed under the GPL
10651   */
10652  
10653  #include "linux/config.h"
10654 +#include "linux/percpu.h"
10655 +#include "asm/pgalloc.h"
10656 +#include "asm/tlb.h"
10657 +
10658 +/* For some reason, mmu_gathers are referenced when CONFIG_SMP is off. */
10659 +DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
10660  
10661  #ifdef CONFIG_SMP
10662  
10663 @@ -23,7 +29,7 @@
10664  #include "os.h"
10665  
10666  /* CPU online map, set by smp_boot_cpus */
10667 -unsigned long cpu_online_map = cpumask_of_cpu(0);
10668 +unsigned long cpu_online_map = CPU_MASK_NONE;
10669  
10670  EXPORT_SYMBOL(cpu_online_map);
10671  
10672 @@ -55,7 +61,7 @@
10673  
10674  void smp_send_reschedule(int cpu)
10675  {
10676 -       write(cpu_data[cpu].ipi_pipe[1], "R", 1);
10677 +       os_write_file(cpu_data[cpu].ipi_pipe[1], "R", 1);
10678         num_reschedules_sent++;
10679  }
10680  
10681 @@ -100,35 +106,34 @@
10682  
10683         printk(KERN_INFO "Stopping all CPUs...");
10684         for(i = 0; i < num_online_cpus(); i++){
10685 -               if(i == current->thread_info->cpu)
10686 +               if(i == current_thread->cpu)
10687                         continue;
10688 -               write(cpu_data[i].ipi_pipe[1], "S", 1);
10689 +               os_write_file(cpu_data[i].ipi_pipe[1], "S", 1);
10690         }
10691         printk("done\n");
10692  }
10693  
10694 -static cpumask_t smp_commenced_mask;
10695 -static cpumask_t smp_callin_map = CPU_MASK_NONE;
10696 +static cpumask_t smp_commenced_mask = CPU_MASK_NONE;
10697 +static cpumask_t cpu_callin_map = CPU_MASK_NONE;
10698  
10699  static int idle_proc(void *cpup)
10700  {
10701         int cpu = (int) cpup, err;
10702  
10703         err = os_pipe(cpu_data[cpu].ipi_pipe, 1, 1);
10704 -       if(err)
10705 -               panic("CPU#%d failed to create IPI pipe, errno = %d", cpu, 
10706 -                     -err);
10707 +       if(err < 0)
10708 +               panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err);
10709  
10710         activate_ipi(cpu_data[cpu].ipi_pipe[0], 
10711                      current->thread.mode.tt.extern_pid);
10712   
10713         wmb();
10714 -       if (cpu_test_and_set(cpu, &smp_callin_map)) {
10715 +       if (cpu_test_and_set(cpu, cpu_callin_map)) {
10716                 printk("huh, CPU#%d already present??\n", cpu);
10717                 BUG();
10718         }
10719  
10720 -       while (!cpu_isset(cpu, &smp_commenced_mask))
10721 +       while (!cpu_isset(cpu, smp_commenced_mask))
10722                 cpu_relax();
10723  
10724         cpu_set(cpu, cpu_online_map);
10725 @@ -143,16 +148,20 @@
10726  
10727          current->thread.request.u.thread.proc = idle_proc;
10728          current->thread.request.u.thread.arg = (void *) cpu;
10729 -       new_task = do_fork(CLONE_VM | CLONE_IDLETASK, 0, NULL, 0, NULL, NULL);
10730 -       if(IS_ERR(new_task)) panic("do_fork failed in idle_thread");
10731 +       new_task = copy_process(CLONE_VM | CLONE_IDLETASK, 0, NULL, 0, NULL, 
10732 +                               NULL);
10733 +       if(IS_ERR(new_task)) 
10734 +               panic("copy_process failed in idle_thread, error = %ld",
10735 +                     PTR_ERR(new_task));
10736  
10737         cpu_tasks[cpu] = ((struct cpu_task) 
10738                           { .pid =      new_task->thread.mode.tt.extern_pid,
10739                             .task =     new_task } );
10740         idle_threads[cpu] = new_task;
10741 -       CHOOSE_MODE(write(new_task->thread.mode.tt.switch_pipe[1], &c, 
10742 +       CHOOSE_MODE(os_write_file(new_task->thread.mode.tt.switch_pipe[1], &c, 
10743                           sizeof(c)),
10744                     ({ panic("skas mode doesn't support SMP"); }));
10745 +       wake_up_forked_process(new_task);
10746         return(new_task);
10747  }
10748  
10749 @@ -160,15 +169,17 @@
10750  {
10751         struct task_struct *idle;
10752         unsigned long waittime;
10753 -       int err, cpu;
10754 +       int err, cpu, me = smp_processor_id();
10755  
10756 -       cpu_set(0, cpu_online_map);
10757 -       cpu_set(0, smp_callin_map);
10758 +       cpu_clear(me, cpu_online_map);
10759 +       cpu_set(me, cpu_online_map);
10760 +       cpu_set(me, cpu_callin_map);
10761  
10762 -       err = os_pipe(cpu_data[0].ipi_pipe, 1, 1);
10763 -       if(err) panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
10764 +       err = os_pipe(cpu_data[me].ipi_pipe, 1, 1);
10765 +       if(err < 0)
10766 +               panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
10767  
10768 -       activate_ipi(cpu_data[0].ipi_pipe[0], 
10769 +       activate_ipi(cpu_data[me].ipi_pipe[0], 
10770                      current->thread.mode.tt.extern_pid);
10771  
10772         for(cpu = 1; cpu < ncpus; cpu++){
10773 @@ -180,10 +191,10 @@
10774                 unhash_process(idle);
10775  
10776                 waittime = 200000000;
10777 -               while (waittime-- && !cpu_isset(cpu, smp_callin_map))
10778 +               while (waittime-- && !cpu_isset(cpu, cpu_callin_map))
10779                         cpu_relax();
10780  
10781 -               if (cpu_isset(cpu, smp_callin_map))
10782 +               if (cpu_isset(cpu, cpu_callin_map))
10783                         printk("done\n");
10784                 else printk("failed\n");
10785         }
10786 @@ -216,7 +227,7 @@
10787         int fd;
10788  
10789         fd = cpu_data[cpu].ipi_pipe[0];
10790 -       while (read(fd, &c, 1) == 1) {
10791 +       while (os_read_file(fd, &c, 1) == 1) {
10792                 switch (c) {
10793                 case 'C':
10794                         smp_call_function_slave(cpu);
10795 @@ -273,9 +284,9 @@
10796         info = _info;
10797  
10798         for (i=0;i<NR_CPUS;i++)
10799 -               if((i != current->thread_info->cpu) && 
10800 +               if((i != current_thread->cpu) && 
10801                    cpu_isset(i, cpu_online_map))
10802 -                       write(cpu_data[i].ipi_pipe[1], "C", 1);
10803 +                       os_write_file(cpu_data[i].ipi_pipe[1], "C", 1);
10804  
10805         while (atomic_read(&scf_started) != cpus)
10806                 barrier();
10807 diff -Naur a/arch/um/kernel/syscall_kern.c b/arch/um/kernel/syscall_kern.c
10808 --- a/arch/um/kernel/syscall_kern.c     2004-02-11 12:16:08.000000000 -0500
10809 +++ b/arch/um/kernel/syscall_kern.c     2004-02-11 12:28:04.000000000 -0500
10810 @@ -1,5 +1,5 @@
10811  /* 
10812 - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
10813 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
10814   * Licensed under the GPL
10815   */
10816  
10817 @@ -35,39 +35,40 @@
10818  
10819  long sys_fork(void)
10820  {
10821 -       struct task_struct *p;
10822 +       long ret;
10823  
10824         current->thread.forking = 1;
10825 -        p = do_fork(SIGCHLD, 0, NULL, 0, NULL, NULL);
10826 +        ret = do_fork(SIGCHLD, 0, NULL, 0, NULL, NULL);
10827         current->thread.forking = 0;
10828 -       return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
10829 +       return(ret);
10830  }
10831  
10832 -long sys_clone(unsigned long clone_flags, unsigned long newsp)
10833 +long sys_clone(unsigned long clone_flags, unsigned long newsp, 
10834 +              int *parent_tid, int *child_tid)
10835  {
10836 -       struct task_struct *p;
10837 +       long ret;
10838  
10839         current->thread.forking = 1;
10840 -       p = do_fork(clone_flags, newsp, NULL, 0, NULL, NULL);
10841 +       ret = do_fork(clone_flags, newsp, NULL, 0, parent_tid, child_tid);
10842         current->thread.forking = 0;
10843 -       return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
10844 +       return(ret);
10845  }
10846  
10847  long sys_vfork(void)
10848  {
10849 -       struct task_struct *p;
10850 +       long ret;
10851  
10852         current->thread.forking = 1;
10853 -       p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0, NULL, NULL);
10854 +       ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0, NULL, 
10855 +                     NULL);
10856         current->thread.forking = 0;
10857 -       return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
10858 +       return(ret);
10859  }
10860  
10861  /* common code for old and new mmaps */
10862 -static inline long do_mmap2(
10863 -       unsigned long addr, unsigned long len,
10864 -       unsigned long prot, unsigned long flags,
10865 -       unsigned long fd, unsigned long pgoff)
10866 +long do_mmap2(struct mm_struct *mm, unsigned long addr, unsigned long len,
10867 +             unsigned long prot, unsigned long flags, unsigned long fd,
10868 +             unsigned long pgoff)
10869  {
10870         int error = -EBADF;
10871         struct file * file = NULL;
10872 @@ -79,9 +80,9 @@
10873                         goto out;
10874         }
10875  
10876 -       down_write(&current->mm->mmap_sem);
10877 -       error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
10878 -       up_write(&current->mm->mmap_sem);
10879 +       down_write(&mm->mmap_sem);
10880 +       error = do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
10881 +       up_write(&mm->mmap_sem);
10882  
10883         if (file)
10884                 fput(file);
10885 @@ -93,7 +94,7 @@
10886                unsigned long prot, unsigned long flags,
10887                unsigned long fd, unsigned long pgoff)
10888  {
10889 -       return do_mmap2(addr, len, prot, flags, fd, pgoff);
10890 +       return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
10891  }
10892  
10893  /*
10894 @@ -120,7 +121,8 @@
10895         if (offset & ~PAGE_MASK)
10896                 goto out;
10897  
10898 -       err = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
10899 +       err = do_mmap2(current->mm, addr, len, prot, flags, fd, 
10900 +                      offset >> PAGE_SHIFT);
10901   out:
10902         return err;
10903  }
10904 @@ -135,43 +137,12 @@
10905  
10906          error = do_pipe(fd);
10907          if (!error) {
10908 -                if (copy_to_user(fildes, fd, 2*sizeof(int)))
10909 +               if (copy_to_user(fildes, fd, sizeof(fd)))
10910                          error = -EFAULT;
10911          }
10912          return error;
10913  }
10914  
10915 -int sys_sigaction(int sig, const struct old_sigaction *act,
10916 -                        struct old_sigaction *oact)
10917 -{
10918 -       struct k_sigaction new_ka, old_ka;
10919 -       int ret;
10920 -
10921 -       if (act) {
10922 -               old_sigset_t mask;
10923 -               if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
10924 -                   __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
10925 -                   __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
10926 -                       return -EFAULT;
10927 -               __get_user(new_ka.sa.sa_flags, &act->sa_flags);
10928 -               __get_user(mask, &act->sa_mask);
10929 -               siginitset(&new_ka.sa.sa_mask, mask);
10930 -       }
10931 -
10932 -       ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
10933 -
10934 -       if (!ret && oact) {
10935 -               if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
10936 -                   __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
10937 -                   __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
10938 -                       return -EFAULT;
10939 -               __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
10940 -               __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
10941 -       }
10942 -
10943 -       return ret;
10944 -}
10945 -
10946  /*
10947   * sys_ipc() is the de-multiplexer for the SysV IPC calls..
10948   *
10949 @@ -253,7 +224,7 @@
10950                 return sys_shmctl (first, second,
10951                                    (struct shmid_ds *) ptr);
10952         default:
10953 -               return -EINVAL;
10954 +               return -ENOSYS;
10955         }
10956  }
10957  
10958 @@ -302,11 +273,6 @@
10959         return error;
10960  }
10961  
10962 -int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
10963 -{
10964 -       return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
10965 -}
10966 -
10967  long execute_syscall(void *r)
10968  {
10969         return(CHOOSE_MODE_PROC(execute_syscall_tt, execute_syscall_skas, r));
10970 diff -Naur a/arch/um/kernel/sys_call_table.c b/arch/um/kernel/sys_call_table.c
10971 --- a/arch/um/kernel/sys_call_table.c   2004-02-11 12:16:34.000000000 -0500
10972 +++ b/arch/um/kernel/sys_call_table.c   2004-02-11 12:28:33.000000000 -0500
10973 @@ -5,7 +5,6 @@
10974  
10975  #include "linux/config.h"
10976  #include "linux/unistd.h"
10977 -#include "linux/version.h"
10978  #include "linux/sys.h"
10979  #include "linux/swap.h"
10980  #include "linux/sysctl.h"
10981 @@ -219,15 +218,30 @@
10982  extern syscall_handler_t sys_gettid;
10983  extern syscall_handler_t sys_readahead;
10984  extern syscall_handler_t sys_tkill;
10985 +extern syscall_handler_t sys_setxattr;
10986 +extern syscall_handler_t sys_lsetxattr;
10987 +extern syscall_handler_t sys_fsetxattr;
10988 +extern syscall_handler_t sys_getxattr;
10989 +extern syscall_handler_t sys_lgetxattr;
10990 +extern syscall_handler_t sys_fgetxattr;
10991 +extern syscall_handler_t sys_listxattr;
10992 +extern syscall_handler_t sys_llistxattr;
10993 +extern syscall_handler_t sys_flistxattr;
10994 +extern syscall_handler_t sys_removexattr;
10995 +extern syscall_handler_t sys_lremovexattr;
10996 +extern syscall_handler_t sys_fremovexattr;
10997  extern syscall_handler_t sys_sendfile64;
10998  extern syscall_handler_t sys_futex;
10999  extern syscall_handler_t sys_sched_setaffinity;
11000  extern syscall_handler_t sys_sched_getaffinity;
11001 +extern syscall_handler_t sys_set_thread_area;
11002 +extern syscall_handler_t sys_get_thread_area;
11003  extern syscall_handler_t sys_io_setup;
11004  extern syscall_handler_t sys_io_destroy;
11005  extern syscall_handler_t sys_io_getevents;
11006  extern syscall_handler_t sys_io_submit;
11007  extern syscall_handler_t sys_io_cancel;
11008 +extern syscall_handler_t sys_fadvise64;
11009  extern syscall_handler_t sys_exit_group;
11010  extern syscall_handler_t sys_lookup_dcookie;
11011  extern syscall_handler_t sys_epoll_create;
11012 @@ -235,6 +249,20 @@
11013  extern syscall_handler_t sys_epoll_wait;
11014  extern syscall_handler_t sys_remap_file_pages;
11015  extern syscall_handler_t sys_set_tid_address;
11016 +extern syscall_handler_t sys_timer_create;
11017 +extern syscall_handler_t sys_timer_settime;
11018 +extern syscall_handler_t sys_timer_gettime;
11019 +extern syscall_handler_t sys_timer_getoverrun;
11020 +extern syscall_handler_t sys_timer_delete;
11021 +extern syscall_handler_t sys_clock_settime;
11022 +extern syscall_handler_t sys_clock_gettime;
11023 +extern syscall_handler_t sys_clock_getres;
11024 +extern syscall_handler_t sys_clock_nanosleep;
11025 +extern syscall_handler_t sys_statfs64;
11026 +extern syscall_handler_t sys_fstatfs64;
11027 +extern syscall_handler_t sys_tgkill;
11028 +extern syscall_handler_t sys_utimes;
11029 +extern syscall_handler_t sys_fadvise64_64;
11030  
11031  #ifdef CONFIG_NFSD
11032  #define NFSSERVCTL sys_nfsservctl
11033 @@ -246,7 +274,7 @@
11034  extern syscall_handler_t um_time;
11035  extern syscall_handler_t um_stime;
11036  
11037 -#define LAST_GENERIC_SYSCALL __NR_set_tid_address
11038 +#define LAST_GENERIC_SYSCALL __NR_vserver
11039  
11040  #if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL
11041  #define LAST_SYSCALL LAST_GENERIC_SYSCALL
11042 @@ -455,32 +483,37 @@
11043         [ __NR_stat64 ] = sys_stat64,
11044         [ __NR_lstat64 ] = sys_lstat64,
11045         [ __NR_fstat64 ] = sys_fstat64,
11046 -       [ __NR_fcntl64 ] = sys_fcntl64,
11047         [ __NR_getdents64 ] = sys_getdents64,
11048 +       [ __NR_fcntl64 ] = sys_fcntl64,
11049 +       [ 223 ] = sys_ni_syscall,
11050         [ __NR_gettid ] = sys_gettid,
11051         [ __NR_readahead ] = sys_readahead,
11052 -       [ __NR_setxattr ] = sys_ni_syscall,
11053 -       [ __NR_lsetxattr ] = sys_ni_syscall,
11054 -       [ __NR_fsetxattr ] = sys_ni_syscall,
11055 -       [ __NR_getxattr ] = sys_ni_syscall,
11056 -       [ __NR_lgetxattr ] = sys_ni_syscall,
11057 -       [ __NR_fgetxattr ] = sys_ni_syscall,
11058 -       [ __NR_listxattr ] = sys_ni_syscall,
11059 -       [ __NR_llistxattr ] = sys_ni_syscall,
11060 -       [ __NR_flistxattr ] = sys_ni_syscall,
11061 -       [ __NR_removexattr ] = sys_ni_syscall,
11062 -       [ __NR_lremovexattr ] = sys_ni_syscall,
11063 -       [ __NR_fremovexattr ] = sys_ni_syscall,
11064 +       [ __NR_setxattr ] = sys_setxattr,
11065 +       [ __NR_lsetxattr ] = sys_lsetxattr,
11066 +       [ __NR_fsetxattr ] = sys_fsetxattr,
11067 +       [ __NR_getxattr ] = sys_getxattr,
11068 +       [ __NR_lgetxattr ] = sys_lgetxattr,
11069 +       [ __NR_fgetxattr ] = sys_fgetxattr,
11070 +       [ __NR_listxattr ] = sys_listxattr,
11071 +       [ __NR_llistxattr ] = sys_llistxattr,
11072 +       [ __NR_flistxattr ] = sys_flistxattr,
11073 +       [ __NR_removexattr ] = sys_removexattr,
11074 +       [ __NR_lremovexattr ] = sys_lremovexattr,
11075 +       [ __NR_fremovexattr ] = sys_fremovexattr,
11076         [ __NR_tkill ] = sys_tkill,
11077         [ __NR_sendfile64 ] = sys_sendfile64,
11078         [ __NR_futex ] = sys_futex,
11079         [ __NR_sched_setaffinity ] = sys_sched_setaffinity,
11080         [ __NR_sched_getaffinity ] = sys_sched_getaffinity,
11081 +       [ __NR_set_thread_area ] = sys_ni_syscall,
11082 +       [ __NR_get_thread_area ] = sys_ni_syscall,
11083         [ __NR_io_setup ] = sys_io_setup,
11084         [ __NR_io_destroy ] = sys_io_destroy,
11085         [ __NR_io_getevents ] = sys_io_getevents,
11086         [ __NR_io_submit ] = sys_io_submit,
11087         [ __NR_io_cancel ] = sys_io_cancel,
11088 +       [ __NR_fadvise64 ] = sys_fadvise64,
11089 +       [ 251 ] = sys_ni_syscall,
11090         [ __NR_exit_group ] = sys_exit_group,
11091         [ __NR_lookup_dcookie ] = sys_lookup_dcookie,
11092         [ __NR_epoll_create ] = sys_epoll_create,
11093 @@ -488,6 +521,21 @@
11094         [ __NR_epoll_wait ] = sys_epoll_wait,
11095          [ __NR_remap_file_pages ] = sys_remap_file_pages,
11096          [ __NR_set_tid_address ] = sys_set_tid_address,
11097 +       [ __NR_timer_create ] = sys_timer_create,
11098 +       [ __NR_timer_settime ] = sys_timer_settime,
11099 +       [ __NR_timer_gettime ] = sys_timer_gettime,
11100 +       [ __NR_timer_getoverrun ] = sys_timer_getoverrun,
11101 +       [ __NR_timer_delete ] = sys_timer_delete,
11102 +       [ __NR_clock_settime ] = sys_clock_settime,
11103 +       [ __NR_clock_gettime ] = sys_clock_gettime,
11104 +       [ __NR_clock_getres ] = sys_clock_getres,
11105 +       [ __NR_clock_nanosleep ] = sys_clock_nanosleep,
11106 +       [ __NR_statfs64 ] = sys_statfs64,
11107 +       [ __NR_fstatfs64 ] = sys_fstatfs64,
11108 +       [ __NR_tgkill ] = sys_tgkill,
11109 +       [ __NR_utimes ] = sys_utimes,
11110 +       [ __NR_fadvise64_64 ] = sys_fadvise64_64,
11111 +       [ __NR_vserver ] = sys_ni_syscall,
11112  
11113         ARCH_SYSCALLS
11114         [ LAST_SYSCALL + 1 ... NR_syscalls ] = 
11115 diff -Naur a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c
11116 --- a/arch/um/kernel/sysrq.c    2004-02-11 12:14:56.000000000 -0500
11117 +++ b/arch/um/kernel/sysrq.c    2004-02-11 12:26:47.000000000 -0500
11118 @@ -55,6 +55,14 @@
11119         show_trace((unsigned long *)esp);
11120  }
11121  
11122 +void show_stack(struct task_struct *task, unsigned long *sp)
11123 +{
11124 +       if(task)
11125 +               show_trace_task(task);
11126 +       else
11127 +               show_trace(sp);
11128 +}
11129 +
11130  /*
11131   * Overrides for Emacs so that we follow Linus's tabbing style.
11132   * Emacs will notice this stuff at the end of the file and automatically
11133 diff -Naur a/arch/um/kernel/tempfile.c b/arch/um/kernel/tempfile.c
11134 --- a/arch/um/kernel/tempfile.c 2004-02-11 12:15:48.000000000 -0500
11135 +++ b/arch/um/kernel/tempfile.c 2004-02-11 12:27:41.000000000 -0500
11136 @@ -28,6 +28,7 @@
11137         }
11138         if((dir == NULL) || (*dir == '\0')) 
11139                 dir = "/tmp";
11140 +
11141         tempdir = malloc(strlen(dir) + 2);
11142         if(tempdir == NULL){
11143                 fprintf(stderr, "Failed to malloc tempdir, "
11144 @@ -49,7 +50,8 @@
11145         else
11146                 *tempname = 0;
11147         strcat(tempname, template);
11148 -       if((fd = mkstemp(tempname)) < 0){
11149 +       fd = mkstemp(tempname);
11150 +       if(fd < 0){
11151                 fprintf(stderr, "open - cannot create %s: %s\n", tempname, 
11152                         strerror(errno));
11153                 return -1;
11154 @@ -59,7 +61,8 @@
11155                 return -1;
11156         }
11157         if(out_tempname){
11158 -               if((*out_tempname = strdup(tempname)) == NULL){
11159 +               *out_tempname = strdup(tempname);
11160 +               if(*out_tempname == NULL){
11161                         perror("strdup");
11162                         return -1;
11163                 }
11164 diff -Naur a/arch/um/kernel/time.c b/arch/um/kernel/time.c
11165 --- a/arch/um/kernel/time.c     2004-02-11 12:14:28.000000000 -0500
11166 +++ b/arch/um/kernel/time.c     2004-02-11 12:26:11.000000000 -0500
11167 @@ -4,24 +4,33 @@
11168   */
11169  
11170  #include <stdio.h>
11171 +#include <stdlib.h>
11172  #include <unistd.h>
11173  #include <time.h>
11174  #include <sys/time.h>
11175  #include <signal.h>
11176  #include <errno.h>
11177 -#include "linux/module.h"
11178  #include "user_util.h"
11179  #include "kern_util.h"
11180  #include "user.h"
11181  #include "process.h"
11182  #include "signal_user.h"
11183  #include "time_user.h"
11184 +#include "kern_constants.h"
11185 +
11186 +/* XXX This really needs to be declared and initialized in a kernel file since 
11187 + * it's in <linux/time.h>
11188 + */
11189 +extern struct timespec wall_to_monotonic;
11190  
11191  extern struct timeval xtime;
11192  
11193 +struct timeval local_offset = { 0, 0 };
11194 +
11195  void timer(void)
11196  {
11197         gettimeofday(&xtime, NULL);
11198 +       timeradd(&xtime, &local_offset, &xtime);
11199  }
11200  
11201  void set_interval(int timer_type)
11202 @@ -66,7 +75,7 @@
11203                        errno);
11204  }
11205  
11206 -void idle_timer(void)
11207 +void uml_idle_timer(void)
11208  {
11209         if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
11210                 panic("Couldn't unset SIGVTALRM handler");
11211 @@ -76,14 +85,56 @@
11212         set_interval(ITIMER_REAL);
11213  }
11214  
11215 +static unsigned long long get_host_hz(void)
11216 +{
11217 +       char mhzline[16], *end;
11218 +       int ret, mult, mhz, rest, len;
11219 +
11220 +       ret = cpu_feature("cpu MHz", mhzline, 
11221 +                         sizeof(mhzline) / sizeof(mhzline[0]));
11222 +       if(!ret)
11223 +               panic ("Could not get host MHZ");
11224 +
11225 +       mhz = strtoul(mhzline, &end, 10);
11226 +
11227 +       /* This business is to parse a floating point number without using
11228 +        * floating types.
11229 +        */
11230 +
11231 +       rest = 0;
11232 +       mult = 0;
11233 +       if(*end == '.'){
11234 +               end++;
11235 +               len = strlen(end);
11236 +               if(len < 6)
11237 +                       mult = 6 - len;
11238 +               else if(len > 6)
11239 +                       end[6] = '\0';
11240 +               rest = strtoul(end, NULL, 10);
11241 +               while(mult-- > 0)
11242 +                       rest *= 10;
11243 +       }
11244 +
11245 +       return(1000000 * mhz + rest);
11246 +}
11247 +
11248 +unsigned long long host_hz = 0;
11249 +
11250 +extern int do_posix_clock_monotonic_gettime(struct timespec *tp);
11251 +
11252  void time_init(void)
11253  {
11254 +       struct timespec now;
11255
11256 +       host_hz = get_host_hz();
11257         if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR)
11258                 panic("Couldn't set SIGVTALRM handler");
11259         set_interval(ITIMER_VIRTUAL);
11260 -}
11261  
11262 -struct timeval local_offset = { 0, 0 };
11263 +       do_posix_clock_monotonic_gettime(&now);
11264 +       wall_to_monotonic.tv_sec = -now.tv_sec;
11265 +       wall_to_monotonic.tv_nsec = -now.tv_nsec;
11266 +}
11267  
11268  void do_gettimeofday(struct timeval *tv)
11269  {
11270 @@ -95,15 +146,13 @@
11271         time_unlock(flags);
11272  }
11273  
11274 -EXPORT_SYMBOL(do_gettimeofday);
11275 -
11276  int do_settimeofday(struct timespec *tv)
11277  {
11278         struct timeval now;
11279         unsigned long flags;
11280         struct timeval tv_in;
11281  
11282 -       if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
11283 +       if ((unsigned long) tv->tv_nsec >= UM_NSEC_PER_SEC)
11284                 return -EINVAL;
11285  
11286         tv_in.tv_sec = tv->tv_sec;
11287 @@ -113,9 +162,9 @@
11288         gettimeofday(&now, NULL);
11289         timersub(&tv_in, &now, &local_offset);
11290         time_unlock(flags);
11291 -}
11292  
11293 -EXPORT_SYMBOL(do_settimeofday);
11294 +       return(0);
11295 +}
11296  
11297  void idle_sleep(int secs)
11298  {
11299 diff -Naur a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c
11300 --- a/arch/um/kernel/time_kern.c        2004-02-11 12:15:59.000000000 -0500
11301 +++ b/arch/um/kernel/time_kern.c        2004-02-11 12:27:52.000000000 -0500
11302 @@ -30,6 +30,14 @@
11303         return(HZ);
11304  }
11305  
11306 +/*
11307 + * Scheduler clock - returns current time in nanosec units.
11308 + */
11309 +unsigned long long sched_clock(void)
11310 +{
11311 +       return (unsigned long long)jiffies_64 * (1000000000 / HZ);
11312 +}
11313 +
11314  /* Changed at early boot */
11315  int timer_irq_inited = 0;
11316  
11317 @@ -39,13 +47,47 @@
11318   */
11319  int __attribute__ ((__section__ (".unprotected"))) missed_ticks[NR_CPUS];
11320  
11321 +static int first_tick;
11322 +static unsigned long long prev_tsc;
11323 +static long long delta;                /* Deviation per interval */
11324 +
11325 +extern unsigned long long host_hz;
11326 +
11327  void timer_irq(union uml_pt_regs *regs)
11328  {
11329 -       int cpu = current->thread_info->cpu, ticks = missed_ticks[cpu];
11330 +       unsigned long long ticks = 0;
11331 +
11332 +       if(!timer_irq_inited){
11333 +               /* This is to ensure that ticks don't pile up when
11334 +                * the timer handler is suspended */
11335 +               first_tick = 0;
11336 +               return;
11337 +       }
11338 +
11339 +       if(first_tick){
11340 +#if defined(CONFIG_UML_REAL_TIME_CLOCK)
11341 +               unsigned long long tsc;
11342 +               /* We've had 1 tick */
11343 +               tsc = time_stamp();
11344 +
11345 +               delta += tsc - prev_tsc;
11346 +               prev_tsc = tsc;
11347 +
11348 +               ticks += (delta * HZ) / host_hz;
11349 +               delta -= (ticks * host_hz) / HZ;
11350 +#else
11351 +               ticks = 1;
11352 +#endif
11353 +       }
11354 +       else {
11355 +               prev_tsc = time_stamp();
11356 +               first_tick = 1;
11357 +       }
11358  
11359 -        if(!timer_irq_inited) return;
11360 -       missed_ticks[cpu] = 0;
11361 -       while(ticks--) do_IRQ(TIMER_IRQ, regs);
11362 +       while(ticks > 0){
11363 +               do_IRQ(TIMER_IRQ, regs);
11364 +               ticks--;
11365 +       }
11366  }
11367  
11368  void boot_timer_handler(int sig)
11369 @@ -58,12 +100,13 @@
11370         do_timer(&regs);
11371  }
11372  
11373 -void um_timer(int irq, void *dev, struct pt_regs *regs)
11374 +irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs)
11375  {
11376         do_timer(regs);
11377 -       write_seqlock(&xtime_lock);
11378 +       write_seqlock_irq(&xtime_lock);
11379         timer();
11380 -       write_sequnlock(&xtime_lock);
11381 +       write_sequnlock_irq(&xtime_lock);
11382 +       return(IRQ_HANDLED);
11383  }
11384  
11385  long um_time(int * tloc)
11386 @@ -81,12 +124,12 @@
11387  long um_stime(int * tptr)
11388  {
11389         int value;
11390 -       struct timeval new;
11391 +       struct timespec new;
11392  
11393         if (get_user(value, tptr))
11394                  return -EFAULT;
11395         new.tv_sec = value;
11396 -       new.tv_usec = 0;
11397 +       new.tv_nsec = 0;
11398         do_settimeofday(&new);
11399         return 0;
11400  }
11401 @@ -125,9 +168,11 @@
11402  void timer_handler(int sig, union uml_pt_regs *regs)
11403  {
11404  #ifdef CONFIG_SMP
11405 +       local_irq_disable();
11406         update_process_times(user_context(UPT_SP(regs)));
11407 +       local_irq_enable();
11408  #endif
11409 -       if(current->thread_info->cpu == 0)
11410 +       if(current_thread->cpu == 0)
11411                 timer_irq(regs);
11412  }
11413  
11414 @@ -136,6 +181,7 @@
11415  unsigned long time_lock(void)
11416  {
11417         unsigned long flags;
11418 +
11419         spin_lock_irqsave(&timer_spinlock, flags);
11420         return(flags);
11421  }
11422 @@ -150,8 +196,8 @@
11423         int err;
11424  
11425         CHOOSE_MODE(user_time_init_tt(), user_time_init_skas());
11426 -       if((err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", 
11427 -                             NULL)) != 0)
11428 +       err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", NULL);
11429 +       if(err != 0)
11430                 printk(KERN_ERR "timer_init : request_irq failed - "
11431                        "errno = %d\n", -err);
11432         timer_irq_inited = 1;
11433 @@ -160,7 +206,6 @@
11434  
11435  __initcall(timer_init);
11436  
11437 -
11438  /*
11439   * Overrides for Emacs so that we follow Linus's tabbing style.
11440   * Emacs will notice this stuff at the end of the file and automatically
11441 diff -Naur a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c
11442 --- a/arch/um/kernel/trap_kern.c        2004-02-11 12:14:18.000000000 -0500
11443 +++ b/arch/um/kernel/trap_kern.c        2004-02-11 12:26:00.000000000 -0500
11444 @@ -16,12 +16,15 @@
11445  #include "asm/tlbflush.h"
11446  #include "asm/a.out.h"
11447  #include "asm/current.h"
11448 +#include "asm/irq.h"
11449  #include "user_util.h"
11450  #include "kern_util.h"
11451  #include "kern.h"
11452  #include "chan_kern.h"
11453  #include "mconsole_kern.h"
11454  #include "2_5compat.h"
11455 +#include "mem.h"
11456 +#include "mem_kern.h"
11457  
11458  int handle_page_fault(unsigned long address, unsigned long ip, 
11459                       int is_write, int is_user, int *code_out)
11460 @@ -51,12 +54,12 @@
11461         if(is_write && !(vma->vm_flags & VM_WRITE)) 
11462                 goto out;
11463         page = address & PAGE_MASK;
11464 -       if(page == (unsigned long) current->thread_info + PAGE_SIZE)
11465 +       if(page == (unsigned long) current_thread + PAGE_SIZE)
11466                 panic("Kernel stack overflow");
11467         pgd = pgd_offset(mm, page);
11468         pmd = pmd_offset(pgd, page);
11469 - survive:
11470         do {
11471 + survive:
11472                 switch (handle_mm_fault(mm, vma, address, is_write)){
11473                 case VM_FAULT_MINOR:
11474                         current->min_flt++;
11475 @@ -71,14 +74,20 @@
11476                         err = -ENOMEM;
11477                         goto out_of_memory;
11478                 default:
11479 -                       BUG();
11480 +                       if (current->pid == 1) {
11481 +                               up_read(&mm->mmap_sem);
11482 +                               yield();
11483 +                               down_read(&mm->mmap_sem);
11484 +                               goto survive;
11485 +                       }
11486 +                       goto out;
11487                 }
11488                 pte = pte_offset_kernel(pmd, page);
11489         } while(!pte_present(*pte));
11490 +       err = 0;
11491         *pte = pte_mkyoung(*pte);
11492         if(pte_write(*pte)) *pte = pte_mkdirty(*pte);
11493         flush_tlb_page(vma, page);
11494 -       err = 0;
11495   out:
11496         up_read(&mm->mmap_sem);
11497         return(err);
11498 @@ -98,6 +107,33 @@
11499         goto out;
11500  }
11501  
11502 +LIST_HEAD(physmem_remappers);
11503 +
11504 +void register_remapper(struct remapper *info)
11505 +{
11506 +       list_add(&info->list, &physmem_remappers);
11507 +}
11508 +
11509 +static int check_remapped_addr(unsigned long address, int is_write)
11510 +{
11511 +       struct remapper *remapper;
11512 +       struct list_head *ele;
11513 +       __u64 offset;
11514 +       int fd;
11515 +
11516 +       fd = phys_mapping(__pa(address), &offset);
11517 +       if(fd == -1)
11518 +               return(0);
11519 +
11520 +       list_for_each(ele, &physmem_remappers){
11521 +               remapper = list_entry(ele, struct remapper, list);
11522 +               if((*remapper->proc)(fd, address, is_write, offset))
11523 +                       return(1);
11524 +       }
11525 +
11526 +       return(0);
11527 +}
11528 +
11529  unsigned long segv(unsigned long address, unsigned long ip, int is_write, 
11530                    int is_user, void *sc)
11531  {
11532 @@ -109,7 +145,9 @@
11533                  flush_tlb_kernel_vm();
11534                  return(0);
11535          }
11536 -        if(current->mm == NULL)
11537 +       else if(check_remapped_addr(address & PAGE_MASK, is_write))
11538 +               return(0);
11539 +       else if(current->mm == NULL)
11540                 panic("Segfault with no mm");
11541         err = handle_page_fault(address, ip, is_write, is_user, &si.si_code);
11542  
11543 @@ -120,9 +158,8 @@
11544                 current->thread.fault_addr = (void *) address;
11545                 do_longjmp(catcher, 1);
11546         } 
11547 -       else if(current->thread.fault_addr != NULL){
11548 +       else if(current->thread.fault_addr != NULL)
11549                 panic("fault_addr set but no fault catcher");
11550 -       }
11551         else if(arch_fixup(ip, sc))
11552                 return(0);
11553  
11554 @@ -155,8 +192,6 @@
11555  {
11556         struct siginfo si;
11557  
11558 -       printk(KERN_ERR "Unfixable SEGV in '%s' (pid %d) at 0x%lx "
11559 -              "(ip 0x%lx)\n", current->comm, current->pid, address, ip);
11560         si.si_signo = SIGSEGV;
11561         si.si_code = SEGV_ACCERR;
11562         si.si_addr = (void *) address;
11563 @@ -180,6 +215,11 @@
11564         else relay_signal(sig, regs);
11565  }
11566  
11567 +void winch(int sig, union uml_pt_regs *regs)
11568 +{
11569 +       do_IRQ(WINCH_IRQ, regs);
11570 +}
11571 +
11572  void trap_init(void)
11573  {
11574  }
11575 diff -Naur a/arch/um/kernel/trap_user.c b/arch/um/kernel/trap_user.c
11576 --- a/arch/um/kernel/trap_user.c        2004-02-11 12:15:23.000000000 -0500
11577 +++ b/arch/um/kernel/trap_user.c        2004-02-11 12:27:10.000000000 -0500
11578 @@ -5,11 +5,9 @@
11579  
11580  #include <stdlib.h>
11581  #include <errno.h>
11582 -#include <fcntl.h>
11583  #include <setjmp.h>
11584  #include <signal.h>
11585  #include <sys/time.h>
11586 -#include <sys/ioctl.h>
11587  #include <sys/ptrace.h>
11588  #include <sys/wait.h>
11589  #include <asm/page.h>
11590 @@ -82,6 +80,8 @@
11591                      .is_irq            = 0 },
11592         [ SIGILL ] { .handler           = relay_signal,
11593                      .is_irq            = 0 },
11594 +       [ SIGWINCH ] { .handler         = winch,
11595 +                      .is_irq          = 1 },
11596         [ SIGBUS ] { .handler           = bus_handler,
11597                      .is_irq            = 0 },
11598         [ SIGSEGV] { .handler           = segv_handler,
11599 @@ -123,7 +123,7 @@
11600  {
11601         jmp_buf *buf = b;
11602  
11603 -       longjmp(*buf, val);
11604 +       siglongjmp(*buf, val);
11605  }
11606  
11607  /*
11608 diff -Naur a/arch/um/kernel/tt/exec_kern.c b/arch/um/kernel/tt/exec_kern.c
11609 --- a/arch/um/kernel/tt/exec_kern.c     2004-02-11 12:14:28.000000000 -0500
11610 +++ b/arch/um/kernel/tt/exec_kern.c     2004-02-11 12:26:11.000000000 -0500
11611 @@ -17,6 +17,7 @@
11612  #include "mem_user.h"
11613  #include "os.h"
11614  #include "tlb.h"
11615 +#include "mode.h"
11616  
11617  static int exec_tramp(void *sig_stack)
11618  {
11619 @@ -47,17 +48,17 @@
11620                 do_exit(SIGKILL);
11621         }
11622  
11623 -       if(current->thread_info->cpu == 0)
11624 +       if(current_thread->cpu == 0)
11625                 forward_interrupts(new_pid);
11626         current->thread.request.op = OP_EXEC;
11627         current->thread.request.u.exec.pid = new_pid;
11628 -       unprotect_stack((unsigned long) current->thread_info);
11629 +       unprotect_stack((unsigned long) current_thread);
11630         os_usr1_process(os_getpid());
11631  
11632         enable_timer();
11633         free_page(stack);
11634         protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1);
11635 -       task_protections((unsigned long) current->thread_info);
11636 +       task_protections((unsigned long) current_thread);
11637         force_flush_all();
11638         unblock_signals();
11639  }
11640 diff -Naur a/arch/um/kernel/tt/include/mode.h b/arch/um/kernel/tt/include/mode.h
11641 --- a/arch/um/kernel/tt/include/mode.h  2004-02-11 12:16:01.000000000 -0500
11642 +++ b/arch/um/kernel/tt/include/mode.h  2004-02-11 12:27:56.000000000 -0500
11643 @@ -8,6 +8,8 @@
11644  
11645  #include "sysdep/ptrace.h"
11646  
11647 +enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
11648 +
11649  extern int tracing_pid;
11650  
11651  extern int tracer(int (*init_proc)(void *), void *sp);
11652 diff -Naur a/arch/um/kernel/tt/include/uaccess.h b/arch/um/kernel/tt/include/uaccess.h
11653 --- a/arch/um/kernel/tt/include/uaccess.h       2004-02-11 12:16:02.000000000 -0500
11654 +++ b/arch/um/kernel/tt/include/uaccess.h       2004-02-11 12:27:56.000000000 -0500
11655 @@ -1,5 +1,5 @@
11656  /* 
11657 - * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
11658 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
11659   * Licensed under the GPL
11660   */
11661  
11662 @@ -43,65 +43,19 @@
11663  
11664  extern int __do_copy_from_user(void *to, const void *from, int n,
11665                                void **fault_addr, void **fault_catcher);
11666 -
11667 -static inline int copy_from_user_tt(void *to, const void *from, int n)
11668 -{
11669 -       return(access_ok_tt(VERIFY_READ, from, n) ?
11670 -              __do_copy_from_user(to, from, n, 
11671 -                                  &current->thread.fault_addr,
11672 -                                  &current->thread.fault_catcher) : n);
11673 -}
11674 -
11675 -static inline int copy_to_user_tt(void *to, const void *from, int n)
11676 -{
11677 -       return(access_ok_tt(VERIFY_WRITE, to, n) ?
11678 -              __do_copy_to_user(to, from, n, 
11679 -                                  &current->thread.fault_addr,
11680 -                                  &current->thread.fault_catcher) : n);
11681 -}
11682 -
11683  extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
11684                                   void **fault_addr, void **fault_catcher);
11685 -
11686 -static inline int strncpy_from_user_tt(char *dst, const char *src, int count)
11687 -{
11688 -       int n;
11689 -
11690 -       if(!access_ok_tt(VERIFY_READ, src, 1)) return(-EFAULT);
11691 -       n = __do_strncpy_from_user(dst, src, count, 
11692 -                                  &current->thread.fault_addr,
11693 -                                  &current->thread.fault_catcher);
11694 -       if(n < 0) return(-EFAULT);
11695 -       return(n);
11696 -}
11697 -
11698  extern int __do_clear_user(void *mem, size_t len, void **fault_addr,
11699                            void **fault_catcher);
11700 -
11701 -static inline int __clear_user_tt(void *mem, int len)
11702 -{
11703 -       return(__do_clear_user(mem, len,
11704 -                              &current->thread.fault_addr,
11705 -                              &current->thread.fault_catcher));
11706 -}
11707 -
11708 -static inline int clear_user_tt(void *mem, int len)
11709 -{
11710 -       return(access_ok_tt(VERIFY_WRITE, mem, len) ? 
11711 -              __do_clear_user(mem, len, 
11712 -                              &current->thread.fault_addr,
11713 -                              &current->thread.fault_catcher) : len);
11714 -}
11715 -
11716  extern int __do_strnlen_user(const char *str, unsigned long n,
11717                              void **fault_addr, void **fault_catcher);
11718  
11719 -static inline int strnlen_user_tt(const void *str, int len)
11720 -{
11721 -       return(__do_strnlen_user(str, len,
11722 -                                &current->thread.fault_addr,
11723 -                                &current->thread.fault_catcher));
11724 -}
11725 +extern int copy_from_user_tt(void *to, const void *from, int n);
11726 +extern int copy_to_user_tt(void *to, const void *from, int n);
11727 +extern int strncpy_from_user_tt(char *dst, const char *src, int count);
11728 +extern int __clear_user_tt(void *mem, int len);
11729 +extern int clear_user_tt(void *mem, int len);
11730 +extern int strnlen_user_tt(const void *str, int len);
11731  
11732  #endif
11733  
11734 diff -Naur a/arch/um/kernel/tt/Makefile b/arch/um/kernel/tt/Makefile
11735 --- a/arch/um/kernel/tt/Makefile        2004-02-11 12:15:45.000000000 -0500
11736 +++ b/arch/um/kernel/tt/Makefile        2004-02-11 12:27:36.000000000 -0500
11737 @@ -1,5 +1,5 @@
11738  # 
11739 -# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
11740 +# Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
11741  # Licensed under the GPL
11742  #
11743  
11744 @@ -7,7 +7,7 @@
11745  
11746  obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \
11747         syscall_kern.o syscall_user.o time.o tlb.o tracer.o trap_user.o \
11748 -       uaccess_user.o sys-$(SUBARCH)/
11749 +       uaccess.o uaccess_user.o sys-$(SUBARCH)/
11750  
11751  obj-$(CONFIG_PT_PROXY) += gdb_kern.o ptproxy/
11752  
11753 @@ -27,5 +27,3 @@
11754  
11755  $(obj)/unmap_fin.o : $(src)/unmap.o
11756         ld -r -o $@ $< -lc -L/usr/lib
11757 -
11758 -clean :
11759 diff -Naur a/arch/um/kernel/tt/mem_user.c b/arch/um/kernel/tt/mem_user.c
11760 --- a/arch/um/kernel/tt/mem_user.c      2004-02-11 12:14:34.000000000 -0500
11761 +++ b/arch/um/kernel/tt/mem_user.c      2004-02-11 12:26:17.000000000 -0500
11762 @@ -25,14 +25,13 @@
11763         size = (unsigned long) segment_end - 
11764                 (unsigned long) segment_start;
11765         data = create_mem_file(size);
11766 -       if((addr = mmap(NULL, size, PROT_WRITE | PROT_READ, 
11767 -                       MAP_SHARED, data, 0)) == MAP_FAILED){
11768 +       addr = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, data, 0);
11769 +       if(addr == MAP_FAILED){
11770                 perror("mapping new data segment");
11771                 exit(1);
11772         }
11773         memcpy(addr, segment_start, size);
11774 -       if(switcheroo(data, prot, addr, segment_start, 
11775 -                     size) < 0){
11776 +       if(switcheroo(data, prot, addr, segment_start, size) < 0){
11777                 printf("switcheroo failed\n");
11778                 exit(1);
11779         }
11780 diff -Naur a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
11781 --- a/arch/um/kernel/tt/process_kern.c  2004-02-11 12:16:33.000000000 -0500
11782 +++ b/arch/um/kernel/tt/process_kern.c  2004-02-11 12:28:32.000000000 -0500
11783 @@ -62,7 +62,7 @@
11784         reading = 0;
11785         err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c));
11786         if(err != sizeof(c))
11787 -               panic("write of switch_pipe failed, errno = %d", -err);
11788 +               panic("write of switch_pipe failed, err = %d", -err);
11789  
11790         reading = 1;
11791         if((from->state == TASK_ZOMBIE) || (from->state == TASK_DEAD))
11792 @@ -104,48 +104,72 @@
11793  
11794  void release_thread_tt(struct task_struct *task)
11795  {
11796 -       os_kill_process(task->thread.mode.tt.extern_pid, 0);
11797 +       int pid = task->thread.mode.tt.extern_pid;
11798 +
11799 +       if(os_getpid() != pid)
11800 +               os_kill_process(pid, 0);
11801  }
11802  
11803  void exit_thread_tt(void)
11804  {
11805 -       close(current->thread.mode.tt.switch_pipe[0]);
11806 -       close(current->thread.mode.tt.switch_pipe[1]);
11807 +       os_close_file(current->thread.mode.tt.switch_pipe[0]);
11808 +       os_close_file(current->thread.mode.tt.switch_pipe[1]);
11809  }
11810  
11811  void schedule_tail(task_t *prev);
11812  
11813  static void new_thread_handler(int sig)
11814  {
11815 +       unsigned long disable;
11816         int (*fn)(void *);
11817         void *arg;
11818  
11819         fn = current->thread.request.u.thread.proc;
11820         arg = current->thread.request.u.thread.arg;
11821 +
11822         UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
11823 +       disable = (1 << (SIGVTALRM - 1)) | (1 << (SIGALRM - 1)) |
11824 +               (1 << (SIGIO - 1)) | (1 << (SIGPROF - 1));
11825 +       SC_SIGMASK(UPT_SC(&current->thread.regs.regs)) &= ~disable;
11826 +
11827         suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
11828  
11829 -       block_signals();
11830 +       force_flush_all();
11831 +       if(current->thread.prev_sched != NULL)
11832 +               schedule_tail(current->thread.prev_sched);
11833 +       current->thread.prev_sched = NULL;
11834 +
11835         init_new_thread_signals(1);
11836 -#ifdef CONFIG_SMP
11837 -       schedule_tail(current->thread.prev_sched);
11838 -#endif
11839         enable_timer();
11840         free_page(current->thread.temp_stack);
11841         set_cmdline("(kernel thread)");
11842 -       force_flush_all();
11843  
11844 -       current->thread.prev_sched = NULL;
11845         change_sig(SIGUSR1, 1);
11846         change_sig(SIGVTALRM, 1);
11847         change_sig(SIGPROF, 1);
11848 -       unblock_signals();
11849 +       local_irq_enable();
11850         if(!run_kernel_thread(fn, arg, &current->thread.exec_buf))
11851                 do_exit(0);
11852  }
11853  
11854  static int new_thread_proc(void *stack)
11855  {
11856 +       /* local_irq_disable is needed to block out signals until this thread is
11857 +        * properly scheduled.  Otherwise, the tracing thread will get mighty 
11858 +        * upset about any signals that arrive before that.  
11859 +        * This has the complication that it sets the saved signal mask in
11860 +        * the sigcontext to block signals.  This gets restored when this
11861 +        * thread (or a descendant, since they get a copy of this sigcontext)
11862 +        * returns to userspace.
11863 +        * So, this is compensated for elsewhere.
11864 +        * XXX There is still a small window until local_irq_disable() actually 
11865 +        * finishes where signals are possible - shouldn't be a problem in 
11866 +        * practice since SIGIO hasn't been forwarded here yet, and the 
11867 +        * local_irq_disable should finish before a SIGVTALRM has time to be 
11868 +        * delivered.
11869 +        */
11870 +
11871 +       local_irq_disable();
11872         init_new_thread_stack(stack, new_thread_handler);
11873         os_usr1_process(os_getpid());
11874         return(0);
11875 @@ -156,7 +180,7 @@
11876   * itself with a SIGUSR1.  set_user_mode has to be run with SIGUSR1 off,
11877   * so it is blocked before it's called.  They are re-enabled on sigreturn
11878   * despite the fact that they were blocked when the SIGUSR1 was issued because
11879 - * copy_thread copies the parent's signcontext, including the signal mask
11880 + * copy_thread copies the parent's sigcontext, including the signal mask
11881   * onto the signal frame.
11882   */
11883  
11884 @@ -165,35 +189,32 @@
11885         UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
11886         suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
11887  
11888 -#ifdef CONFIG_SMP      
11889 -       schedule_tail(NULL);
11890 -#endif
11891 +       force_flush_all();
11892 +       if(current->thread.prev_sched != NULL)
11893 +               schedule_tail(current->thread.prev_sched);
11894 +       current->thread.prev_sched = NULL;
11895 +
11896         enable_timer();
11897         change_sig(SIGVTALRM, 1);
11898         local_irq_enable();
11899 -       force_flush_all();
11900         if(current->mm != current->parent->mm)
11901                 protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 
11902                                1, 0, 1);
11903 -       task_protections((unsigned long) current->thread_info);
11904 -
11905 -       current->thread.prev_sched = NULL;
11906 +       task_protections((unsigned long) current_thread);
11907  
11908         free_page(current->thread.temp_stack);
11909 +       local_irq_disable();
11910         change_sig(SIGUSR1, 0);
11911         set_user_mode(current);
11912  }
11913  
11914 -static int sigusr1 = SIGUSR1;
11915 -
11916  int fork_tramp(void *stack)
11917  {
11918 -       int sig = sigusr1;
11919 -
11920         local_irq_disable();
11921 +       arch_init_thread();
11922         init_new_thread_stack(stack, finish_fork_handler);
11923  
11924 -       kill(os_getpid(), sig);
11925 +       os_usr1_process(os_getpid());
11926         return(0);
11927  }
11928  
11929 @@ -213,8 +234,8 @@
11930         }
11931  
11932         err = os_pipe(p->thread.mode.tt.switch_pipe, 1, 1);
11933 -       if(err){
11934 -               printk("copy_thread : pipe failed, errno = %d\n", -err);
11935 +       if(err < 0){
11936 +               printk("copy_thread : pipe failed, err = %d\n", -err);
11937                 return(err);
11938         }
11939  
11940 @@ -377,8 +398,8 @@
11941  
11942         pages = (1 << CONFIG_KERNEL_STACK_ORDER);
11943  
11944 -       start = (unsigned long) current->thread_info + PAGE_SIZE;
11945 -       end = (unsigned long) current + PAGE_SIZE * pages;
11946 +       start = (unsigned long) current_thread + PAGE_SIZE;
11947 +       end = (unsigned long) current_thread + PAGE_SIZE * pages;
11948         protect_memory(uml_reserved, start - uml_reserved, 1, w, 1, 1);
11949         protect_memory(end, high_physmem - end, 1, w, 1, 1);
11950  
11951 @@ -454,8 +475,9 @@
11952  
11953         init_task.thread.mode.tt.extern_pid = pid;
11954         err = os_pipe(init_task.thread.mode.tt.switch_pipe, 1, 1);
11955 -       if(err) panic("Can't create switch pipe for init_task, errno = %d", 
11956 -                     err);
11957 +       if(err) 
11958 +               panic("Can't create switch pipe for init_task, errno = %d", 
11959 +                     -err);
11960  }
11961  
11962  int singlestepping_tt(void *t)
11963 diff -Naur a/arch/um/kernel/tt/ptproxy/Makefile b/arch/um/kernel/tt/ptproxy/Makefile
11964 --- a/arch/um/kernel/tt/ptproxy/Makefile        2004-02-11 12:15:11.000000000 -0500
11965 +++ b/arch/um/kernel/tt/ptproxy/Makefile        2004-02-11 12:26:57.000000000 -0500
11966 @@ -9,5 +9,3 @@
11967  
11968  $(USER_OBJS) : %.o: %.c
11969         $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
11970 -
11971 -clean:
11972 diff -Naur a/arch/um/kernel/tt/ptproxy/proxy.c b/arch/um/kernel/tt/ptproxy/proxy.c
11973 --- a/arch/um/kernel/tt/ptproxy/proxy.c 2004-02-11 12:15:57.000000000 -0500
11974 +++ b/arch/um/kernel/tt/ptproxy/proxy.c 2004-02-11 12:27:50.000000000 -0500
11975 @@ -15,7 +15,6 @@
11976  #include <unistd.h>
11977  #include <signal.h>
11978  #include <string.h>
11979 -#include <fcntl.h>
11980  #include <termios.h>
11981  #include <sys/wait.h>
11982  #include <sys/types.h>
11983 @@ -293,10 +292,10 @@
11984  }
11985  
11986  char gdb_init_string[] = 
11987 -"att 1
11988 -b panic
11989 -b stop
11990 -handle SIGWINCH nostop noprint pass
11991 +"att 1 \n\
11992 +b panic \n\
11993 +b stop \n\
11994 +handle SIGWINCH nostop noprint pass \n\
11995  ";
11996  
11997  int start_debugger(char *prog, int startup, int stop, int *fd_out)
11998 @@ -304,7 +303,8 @@
11999         int slave, child;
12000  
12001         slave = open_gdb_chan();
12002 -       if((child = fork()) == 0){
12003 +       child = fork();
12004 +       if(child == 0){
12005                 char *tempname = NULL;
12006                 int fd;
12007  
12008 @@ -327,18 +327,19 @@
12009                         exit(1);
12010  #endif
12011                 }
12012 -               if((fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0)) < 0){
12013 -                       printk("start_debugger : make_tempfile failed, errno = %d\n",
12014 -                              errno);
12015 +               fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0);
12016 +               if(fd < 0){
12017 +                       printk("start_debugger : make_tempfile failed,"
12018 +                              "err = %d\n", -fd);
12019                         exit(1);
12020                 }
12021 -               write(fd, gdb_init_string, sizeof(gdb_init_string) - 1);
12022 +               os_write_file(fd, gdb_init_string, sizeof(gdb_init_string) - 1);
12023                 if(startup){
12024                         if(stop){
12025 -                               write(fd, "b start_kernel\n",
12026 +                               os_write_file(fd, "b start_kernel\n",
12027                                       strlen("b start_kernel\n"));
12028                         }
12029 -                       write(fd, "c\n", strlen("c\n"));
12030 +                       os_write_file(fd, "c\n", strlen("c\n"));
12031                 }
12032                 if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
12033                         printk("start_debugger :  PTRACE_TRACEME failed, "
12034 diff -Naur a/arch/um/kernel/tt/ptproxy/sysdep.c b/arch/um/kernel/tt/ptproxy/sysdep.c
12035 --- a/arch/um/kernel/tt/ptproxy/sysdep.c        2004-02-11 12:16:27.000000000 -0500
12036 +++ b/arch/um/kernel/tt/ptproxy/sysdep.c        2004-02-11 12:28:24.000000000 -0500
12037 @@ -9,6 +9,7 @@
12038  #include <string.h>
12039  #include <stdlib.h>
12040  #include <signal.h>
12041 +#include <errno.h>
12042  #include <sys/types.h>
12043  #include <sys/ptrace.h>
12044  #include <asm/ptrace.h>
12045 diff -Naur a/arch/um/kernel/tt/ptproxy/wait.c b/arch/um/kernel/tt/ptproxy/wait.c
12046 --- a/arch/um/kernel/tt/ptproxy/wait.c  2004-02-11 12:16:37.000000000 -0500
12047 +++ b/arch/um/kernel/tt/ptproxy/wait.c  2004-02-11 12:28:37.000000000 -0500
12048 @@ -56,21 +56,23 @@
12049  int real_wait_return(struct debugger *debugger)
12050  {
12051         unsigned long ip;
12052 -       int err, pid;
12053 +       int pid;
12054  
12055         pid = debugger->pid;
12056 +
12057         ip = ptrace(PTRACE_PEEKUSER, pid, PT_IP_OFFSET, 0);
12058 -       ip = IP_RESTART_SYSCALL(ip);
12059 -       err = ptrace(PTRACE_POKEUSER, pid, PT_IP_OFFSET, ip);
12060 +       IP_RESTART_SYSCALL(ip);
12061 +
12062         if(ptrace(PTRACE_POKEUSER, pid, PT_IP_OFFSET, ip) < 0)
12063                 tracer_panic("real_wait_return : Failed to restart system "
12064 -                            "call, errno = %d\n");
12065 +                            "call, errno = %d\n", errno);
12066 +
12067         if((ptrace(PTRACE_SYSCALL, debugger->pid, 0, SIGCHLD) < 0) ||
12068            (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
12069            (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
12070            debugger_normal_return(debugger, -1))
12071                 tracer_panic("real_wait_return : gdb failed to wait, "
12072 -                            "errno = %d\n");
12073 +                            "errno = %d\n", errno);
12074         return(0);
12075  }
12076  
12077 diff -Naur a/arch/um/kernel/tt/syscall_kern.c b/arch/um/kernel/tt/syscall_kern.c
12078 --- a/arch/um/kernel/tt/syscall_kern.c  2004-02-11 12:14:00.000000000 -0500
12079 +++ b/arch/um/kernel/tt/syscall_kern.c  2004-02-11 12:25:40.000000000 -0500
12080 @@ -1,5 +1,5 @@
12081  /* 
12082 - * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
12083 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
12084   * Licensed under the GPL
12085   */
12086  
12087 diff -Naur a/arch/um/kernel/tt/sys-i386/Makefile b/arch/um/kernel/tt/sys-i386/Makefile
12088 --- a/arch/um/kernel/tt/sys-i386/Makefile       2004-02-11 12:15:17.000000000 -0500
12089 +++ b/arch/um/kernel/tt/sys-i386/Makefile       2004-02-11 12:27:05.000000000 -0500
12090 @@ -10,5 +10,3 @@
12091  
12092  $(USER_OBJS) : %.o: %.c
12093         $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
12094 -
12095 -clean :
12096 diff -Naur a/arch/um/kernel/tt/tlb.c b/arch/um/kernel/tt/tlb.c
12097 --- a/arch/um/kernel/tt/tlb.c   2004-02-11 12:14:18.000000000 -0500
12098 +++ b/arch/um/kernel/tt/tlb.c   2004-02-11 12:26:01.000000000 -0500
12099 @@ -10,6 +10,7 @@
12100  #include "asm/page.h"
12101  #include "asm/pgtable.h"
12102  #include "asm/uaccess.h"
12103 +#include "asm/tlbflush.h"
12104  #include "user_util.h"
12105  #include "mem_user.h"
12106  #include "os.h"
12107 diff -Naur a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c
12108 --- a/arch/um/kernel/tt/tracer.c        2004-02-11 12:14:16.000000000 -0500
12109 +++ b/arch/um/kernel/tt/tracer.c        2004-02-11 12:25:59.000000000 -0500
12110 @@ -39,16 +39,17 @@
12111                 return(0);
12112  
12113         register_winch_irq(tracer_winch[0], fd, -1, data);
12114 -       return(0);
12115 +       return(1);
12116  }
12117  
12118  static void tracer_winch_handler(int sig)
12119  {
12120 +       int n;
12121         char c = 1;
12122  
12123 -       if(write(tracer_winch[1], &c, sizeof(c)) != sizeof(c))
12124 -               printk("tracer_winch_handler - write failed, errno = %d\n",
12125 -                      errno);
12126 +       n = os_write_file(tracer_winch[1], &c, sizeof(c));
12127 +       if(n != sizeof(c))
12128 +               printk("tracer_winch_handler - write failed, err = %d\n", -n);
12129  }
12130  
12131  /* Called only by the tracing thread during initialization */
12132 @@ -58,9 +59,8 @@
12133         int err;
12134  
12135         err = os_pipe(tracer_winch, 1, 1);
12136 -       if(err){
12137 -               printk("setup_tracer_winch : os_pipe failed, errno = %d\n", 
12138 -                      -err);
12139 +       if(err < 0){
12140 +               printk("setup_tracer_winch : os_pipe failed, err = %d\n", -err);
12141                 return;
12142         }
12143         signal(SIGWINCH, tracer_winch_handler);
12144 @@ -130,8 +130,8 @@
12145         case SIGTSTP:
12146                 if(ptrace(PTRACE_CONT, pid, 0, sig) < 0)
12147                         tracer_panic("sleeping_process_signal : Failed to "
12148 -                                    "continue pid %d, errno = %d\n", pid,
12149 -                                    sig);
12150 +                                    "continue pid %d, signal = %d, "
12151 +                                    "errno = %d\n", pid, sig, errno);
12152                 break;
12153  
12154         /* This happens when the debugger (e.g. strace) is doing system call 
12155 @@ -145,7 +145,7 @@
12156                 if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
12157                         tracer_panic("sleeping_process_signal : Failed to "
12158                                      "PTRACE_SYSCALL pid %d, errno = %d\n",
12159 -                                    pid, sig);
12160 +                                    pid, errno);
12161                 break;
12162         case SIGSTOP:
12163                 break;
12164 @@ -218,7 +218,7 @@
12165                         err = attach(debugger_parent);
12166                         if(err){
12167                                 printf("Failed to attach debugger parent %d, "
12168 -                                      "errno = %d\n", debugger_parent, err);
12169 +                                      "errno = %d\n", debugger_parent, -err);
12170                                 debugger_parent = -1;
12171                         }
12172                         else {
12173 @@ -233,7 +233,8 @@
12174         }
12175         set_cmdline("(tracing thread)");
12176         while(1){
12177 -               if((pid = waitpid(-1, &status, WUNTRACED)) <= 0){
12178 +               pid = waitpid(-1, &status, WUNTRACED);
12179 +               if(pid <= 0){
12180                         if(errno != ECHILD){
12181                                 printf("wait failed - errno = %d\n", errno);
12182                         }
12183 @@ -401,7 +402,7 @@
12184                 
12185                 if(!strcmp(line, "go")) debug_stop = 0;
12186                 else if(!strcmp(line, "parent")) debug_parent = 1;
12187 -               else printk("Unknown debug option : '%s'\n", line);
12188 +               else printf("Unknown debug option : '%s'\n", line);
12189  
12190                 line = next;
12191         }
12192 diff -Naur a/arch/um/kernel/tt/uaccess.c b/arch/um/kernel/tt/uaccess.c
12193 --- a/arch/um/kernel/tt/uaccess.c       1969-12-31 19:00:00.000000000 -0500
12194 +++ b/arch/um/kernel/tt/uaccess.c       2004-02-11 12:25:43.000000000 -0500
12195 @@ -0,0 +1,73 @@
12196 +/* 
12197 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
12198 + * Licensed under the GPL
12199 + */
12200 +
12201 +#include "linux/sched.h"
12202 +#include "asm/uaccess.h"
12203 +
12204 +int copy_from_user_tt(void *to, const void *from, int n)
12205 +{
12206 +       if(!access_ok_tt(VERIFY_READ, from, n)) 
12207 +               return(n);
12208 +
12209 +       return(__do_copy_from_user(to, from, n, &current->thread.fault_addr,
12210 +                                  &current->thread.fault_catcher));
12211 +}
12212 +
12213 +int copy_to_user_tt(void *to, const void *from, int n)
12214 +{
12215 +       if(!access_ok_tt(VERIFY_WRITE, to, n))
12216 +               return(n);
12217 +               
12218 +       return(__do_copy_to_user(to, from, n, &current->thread.fault_addr,
12219 +                                &current->thread.fault_catcher));
12220 +}
12221 +
12222 +int strncpy_from_user_tt(char *dst, const char *src, int count)
12223 +{
12224 +       int n;
12225 +
12226 +       if(!access_ok_tt(VERIFY_READ, src, 1)) 
12227 +               return(-EFAULT);
12228 +
12229 +       n = __do_strncpy_from_user(dst, src, count, 
12230 +                                  &current->thread.fault_addr,
12231 +                                  &current->thread.fault_catcher);
12232 +       if(n < 0) return(-EFAULT);
12233 +       return(n);
12234 +}
12235 +
12236 +int __clear_user_tt(void *mem, int len)
12237 +{
12238 +       return(__do_clear_user(mem, len,
12239 +                              &current->thread.fault_addr,
12240 +                              &current->thread.fault_catcher));
12241 +}
12242 +
12243 +int clear_user_tt(void *mem, int len)
12244 +{
12245 +       if(!access_ok_tt(VERIFY_WRITE, mem, len))
12246 +               return(len);
12247 +
12248 +       return(__do_clear_user(mem, len, &current->thread.fault_addr,
12249 +                              &current->thread.fault_catcher));
12250 +}
12251 +
12252 +int strnlen_user_tt(const void *str, int len)
12253 +{
12254 +       return(__do_strnlen_user(str, len,
12255 +                                &current->thread.fault_addr,
12256 +                                &current->thread.fault_catcher));
12257 +}
12258 +
12259 +/*
12260 + * Overrides for Emacs so that we follow Linus's tabbing style.
12261 + * Emacs will notice this stuff at the end of the file and automatically
12262 + * adjust the settings for this buffer only.  This must remain at the end
12263 + * of the file.
12264 + * ---------------------------------------------------------------------------
12265 + * Local variables:
12266 + * c-file-style: "linux"
12267 + * End:
12268 + */
12269 diff -Naur a/arch/um/kernel/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c
12270 --- a/arch/um/kernel/tt/uaccess_user.c  2004-02-11 12:14:38.000000000 -0500
12271 +++ b/arch/um/kernel/tt/uaccess_user.c  2004-02-11 12:26:42.000000000 -0500
12272 @@ -8,15 +8,20 @@
12273  #include <string.h>
12274  #include "user_util.h"
12275  #include "uml_uaccess.h"
12276 +#include "task.h"
12277 +#include "kern_util.h"
12278  
12279  int __do_copy_from_user(void *to, const void *from, int n,
12280                         void **fault_addr, void **fault_catcher)
12281  {
12282 +       struct tt_regs save = TASK_REGS(get_current())->tt;
12283         unsigned long fault;
12284         int faulted;
12285  
12286         fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
12287                                __do_copy, &faulted);
12288 +       TASK_REGS(get_current())->tt = save;
12289 +
12290         if(!faulted) return(0);
12291         else return(n - (fault - (unsigned long) from));
12292  }
12293 @@ -29,11 +34,14 @@
12294  int __do_strncpy_from_user(char *dst, const char *src, unsigned long count,
12295                            void **fault_addr, void **fault_catcher)
12296  {
12297 +       struct tt_regs save = TASK_REGS(get_current())->tt;
12298         unsigned long fault;
12299         int faulted;
12300  
12301         fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher,
12302                                __do_strncpy, &faulted);
12303 +       TASK_REGS(get_current())->tt = save;
12304 +
12305         if(!faulted) return(strlen(dst));
12306         else return(-1);
12307  }
12308 @@ -46,11 +54,14 @@
12309  int __do_clear_user(void *mem, unsigned long len,
12310                     void **fault_addr, void **fault_catcher)
12311  {
12312 +       struct tt_regs save = TASK_REGS(get_current())->tt;
12313         unsigned long fault;
12314         int faulted;
12315  
12316         fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher,
12317                                __do_clear, &faulted);
12318 +       TASK_REGS(get_current())->tt = save;
12319 +
12320         if(!faulted) return(0);
12321         else return(len - (fault - (unsigned long) mem));
12322  }
12323 @@ -58,19 +69,20 @@
12324  int __do_strnlen_user(const char *str, unsigned long n,
12325                       void **fault_addr, void **fault_catcher)
12326  {
12327 +       struct tt_regs save = TASK_REGS(get_current())->tt;
12328         int ret;
12329         unsigned long *faddrp = (unsigned long *)fault_addr;
12330         jmp_buf jbuf;
12331  
12332         *fault_catcher = &jbuf;
12333 -       if(setjmp(jbuf) == 0){
12334 +       if(sigsetjmp(jbuf, 1) == 0)
12335                 ret = strlen(str) + 1;
12336 -       } 
12337 -       else {
12338 -               ret = *faddrp - (unsigned long) str;
12339 -       }
12340 +       else ret = *faddrp - (unsigned long) str;
12341 +
12342         *fault_addr = NULL;
12343         *fault_catcher = NULL;
12344 +
12345 +       TASK_REGS(get_current())->tt = save;
12346         return ret;
12347  }
12348  
12349 diff -Naur a/arch/um/kernel/tt/unmap.c b/arch/um/kernel/tt/unmap.c
12350 --- a/arch/um/kernel/tt/unmap.c 2004-02-11 12:16:26.000000000 -0500
12351 +++ b/arch/um/kernel/tt/unmap.c 2004-02-11 12:28:22.000000000 -0500
12352 @@ -3,10 +3,7 @@
12353   * Licensed under the GPL
12354   */
12355  
12356 -#include <stdio.h>
12357 -#include <errno.h>
12358  #include <sys/mman.h>
12359 -#include "user.h"
12360  
12361  int switcheroo(int fd, int prot, void *from, void *to, int size)
12362  {
12363 diff -Naur a/arch/um/kernel/tty_log.c b/arch/um/kernel/tty_log.c
12364 --- a/arch/um/kernel/tty_log.c  2004-02-11 12:15:58.000000000 -0500
12365 +++ b/arch/um/kernel/tty_log.c  2004-02-11 12:27:51.000000000 -0500
12366 @@ -9,10 +9,10 @@
12367  #include <stdio.h>
12368  #include <stdlib.h>
12369  #include <unistd.h>
12370 -#include <fcntl.h>
12371  #include <sys/time.h>
12372  #include "init.h"
12373  #include "user.h"
12374 +#include "kern_util.h"
12375  #include "os.h"
12376  
12377  #define TTY_LOG_DIR "./"
12378 @@ -24,29 +24,40 @@
12379  #define TTY_LOG_OPEN 1
12380  #define TTY_LOG_CLOSE 2
12381  #define TTY_LOG_WRITE 3
12382 +#define TTY_LOG_EXEC 4
12383 +
12384 +#define TTY_READ 1
12385 +#define TTY_WRITE 2
12386  
12387  struct tty_log_buf {
12388         int what;
12389         unsigned long tty;
12390         int len;
12391 +       int direction;
12392 +       unsigned long sec;
12393 +       unsigned long usec;
12394  };
12395  
12396 -int open_tty_log(void *tty)
12397 +int open_tty_log(void *tty, void *current_tty)
12398  {
12399         struct timeval tv;
12400         struct tty_log_buf data;
12401         char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")];
12402         int fd;
12403  
12404 +       gettimeofday(&tv, NULL);
12405         if(tty_log_fd != -1){
12406 -               data = ((struct tty_log_buf) { what :   TTY_LOG_OPEN,
12407 -                                              tty : (unsigned long) tty,
12408 -                                              len : 0 });
12409 -               write(tty_log_fd, &data, sizeof(data));
12410 +               data = ((struct tty_log_buf) { .what    = TTY_LOG_OPEN,
12411 +                                              .tty  = (unsigned long) tty,
12412 +                                              .len  = sizeof(current_tty),
12413 +                                              .direction = 0,
12414 +                                              .sec = tv.tv_sec,
12415 +                                              .usec = tv.tv_usec } );
12416 +               os_write_file(tty_log_fd, &data, sizeof(data));
12417 +               os_write_file(tty_log_fd, &current_tty, data.len);
12418                 return(tty_log_fd);
12419         }
12420  
12421 -       gettimeofday(&tv, NULL);
12422         sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec, 
12423                 (unsigned int) tv.tv_usec);
12424  
12425 @@ -62,30 +73,117 @@
12426  void close_tty_log(int fd, void *tty)
12427  {
12428         struct tty_log_buf data;
12429 +       struct timeval tv;
12430  
12431         if(tty_log_fd != -1){
12432 -               data = ((struct tty_log_buf) { what :   TTY_LOG_CLOSE,
12433 -                                              tty : (unsigned long) tty,
12434 -                                              len : 0 });
12435 -               write(tty_log_fd, &data, sizeof(data));
12436 +               gettimeofday(&tv, NULL);
12437 +               data = ((struct tty_log_buf) { .what    = TTY_LOG_CLOSE,
12438 +                                              .tty  = (unsigned long) tty,
12439 +                                              .len  = 0,
12440 +                                              .direction = 0,
12441 +                                              .sec = tv.tv_sec,
12442 +                                              .usec = tv.tv_usec } );
12443 +               os_write_file(tty_log_fd, &data, sizeof(data));
12444                 return;
12445         }
12446 -       close(fd);
12447 +       os_close_file(fd);
12448  }
12449  
12450 -int write_tty_log(int fd, char *buf, int len, void *tty)
12451 +static int log_chunk(int fd, const char *buf, int len)
12452  {
12453 +       int total = 0, try, missed, n;
12454 +       char chunk[64];
12455 +
12456 +       while(len > 0){
12457 +               try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
12458 +               missed = copy_from_user_proc(chunk, (char *) buf, try);
12459 +               try -= missed;
12460 +               n = os_write_file(fd, chunk, try);
12461 +               if(n != try) {
12462 +                       if(n < 0) 
12463 +                               return(n);
12464 +                       return(-EIO);
12465 +               }
12466 +               if(missed != 0)
12467 +                       return(-EFAULT);
12468 +
12469 +               len -= try;
12470 +               total += try;
12471 +               buf += try;
12472 +       }
12473 +
12474 +       return(total);
12475 +}
12476 +
12477 +int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
12478 +{
12479 +       struct timeval tv;
12480         struct tty_log_buf data;
12481 +       int direction;
12482  
12483         if(fd == tty_log_fd){
12484 -               data = ((struct tty_log_buf) { what :   TTY_LOG_WRITE,
12485 -                                              tty : (unsigned long) tty,
12486 -                                              len : len });
12487 -               write(tty_log_fd, &data, sizeof(data));
12488 +               gettimeofday(&tv, NULL);
12489 +               direction = is_read ? TTY_READ : TTY_WRITE;
12490 +               data = ((struct tty_log_buf) { .what    = TTY_LOG_WRITE,
12491 +                                              .tty  = (unsigned long) tty,
12492 +                                              .len  = len,
12493 +                                              .direction = direction,
12494 +                                              .sec = tv.tv_sec,
12495 +                                              .usec = tv.tv_usec } );
12496 +               os_write_file(tty_log_fd, &data, sizeof(data));
12497         }
12498 -       return(write(fd, buf, len));
12499 +
12500 +       return(log_chunk(fd, buf, len));
12501  }
12502  
12503 +void log_exec(char **argv, void *tty)
12504 +{
12505 +       struct timeval tv;
12506 +       struct tty_log_buf data;
12507 +       char **ptr,*arg;
12508 +       int len;
12509 +       
12510 +       if(tty_log_fd == -1) return;
12511 +
12512 +       gettimeofday(&tv, NULL);
12513 +
12514 +       len = 0;
12515 +       for(ptr = argv; ; ptr++){
12516 +               if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
12517 +                       return;
12518 +               if(arg == NULL) break;
12519 +               len += strlen_user_proc(arg);
12520 +       }
12521 +
12522 +       data = ((struct tty_log_buf) { .what    = TTY_LOG_EXEC,
12523 +                                      .tty  = (unsigned long) tty,
12524 +                                      .len  = len,
12525 +                                      .direction = 0,
12526 +                                      .sec = tv.tv_sec,
12527 +                                      .usec = tv.tv_usec } );
12528 +       os_write_file(tty_log_fd, &data, sizeof(data));
12529 +
12530 +       for(ptr = argv; ; ptr++){
12531 +               if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
12532 +                       return;
12533 +               if(arg == NULL) break;
12534 +               log_chunk(tty_log_fd, arg, strlen_user_proc(arg));
12535 +       }
12536 +}
12537 +
12538 +extern void register_tty_logger(int (*opener)(void *, void *),
12539 +                               int (*writer)(int, const char *, int, 
12540 +                                             void *, int),
12541 +                               void (*closer)(int, void *));
12542 +
12543 +static int register_logger(void)
12544 +{
12545 +       register_tty_logger(open_tty_log, write_tty_log, close_tty_log);
12546 +       return(0);
12547 +}
12548 +
12549 +__uml_initcall(register_logger);
12550 +
12551  static int __init set_tty_log_dir(char *name, int *add)
12552  {
12553         tty_log_dir = name;
12554 @@ -104,7 +202,7 @@
12555  
12556         tty_log_fd = strtoul(name, &end, 0);
12557         if((*end != '\0') || (end == name)){
12558 -               printk("set_tty_log_fd - strtoul failed on '%s'\n", name);
12559 +               printf("set_tty_log_fd - strtoul failed on '%s'\n", name);
12560                 tty_log_fd = -1;
12561         }
12562         return 0;
12563 diff -Naur a/arch/um/kernel/uaccess_user.c b/arch/um/kernel/uaccess_user.c
12564 --- a/arch/um/kernel/uaccess_user.c     2004-02-11 12:16:09.000000000 -0500
12565 +++ b/arch/um/kernel/uaccess_user.c     2004-02-11 12:28:20.000000000 -0500
12566 @@ -20,7 +20,7 @@
12567  
12568         jmp_buf jbuf;
12569         *fault_catcher = &jbuf;
12570 -       if(setjmp(jbuf) == 0){
12571 +       if(sigsetjmp(jbuf, 1) == 0){
12572                 (*op)(to, from, n);
12573                 ret = 0;
12574                 *faulted_out = 0;
12575 diff -Naur a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
12576 --- a/arch/um/kernel/um_arch.c  2004-02-11 12:16:29.000000000 -0500
12577 +++ b/arch/um/kernel/um_arch.c  2004-02-11 12:28:28.000000000 -0500
12578 @@ -38,13 +38,18 @@
12579  #include "mode_kern.h"
12580  #include "mode.h"
12581  
12582 -#define DEFAULT_COMMAND_LINE "root=6200"
12583 +#define DEFAULT_COMMAND_LINE "root=98:0"
12584  
12585  struct cpuinfo_um boot_cpu_data = { 
12586         .loops_per_jiffy        = 0,
12587         .ipi_pipe               = { -1, -1 }
12588  };
12589  
12590 +/* Placeholder to make UML link until the vsyscall stuff is actually 
12591 + * implemented
12592 + */
12593 +void *__kernel_vsyscall;
12594 +
12595  unsigned long thread_saved_pc(struct task_struct *task)
12596  {
12597         return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
12598 @@ -53,18 +58,22 @@
12599  
12600  static int show_cpuinfo(struct seq_file *m, void *v)
12601  {
12602 -       int index;
12603 +       int index = 0;
12604  
12605 -       index = (struct cpuinfo_um *)v - cpu_data;
12606  #ifdef CONFIG_SMP
12607 +       index = (struct cpuinfo_um *) v - cpu_data;
12608         if (!cpu_online(index))
12609                 return 0;
12610  #endif
12611  
12612 -       seq_printf(m, "bogomips\t: %lu.%02lu\n",
12613 +       seq_printf(m, "processor\t: %d\n", index);
12614 +       seq_printf(m, "vendor_id\t: User Mode Linux\n");
12615 +       seq_printf(m, "model name\t: UML\n");
12616 +       seq_printf(m, "mode\t\t: %s\n", CHOOSE_MODE("tt", "skas"));
12617 +       seq_printf(m, "host\t\t: %s\n", host_info);
12618 +       seq_printf(m, "bogomips\t: %lu.%02lu\n\n",
12619                    loops_per_jiffy/(500000/HZ),
12620                    (loops_per_jiffy/(5000/HZ)) % 100);
12621 -       seq_printf(m, "host\t\t: %s\n", host_info);
12622  
12623         return(0);
12624  }
12625 @@ -134,12 +143,12 @@
12626         if(umid != NULL){
12627                 snprintf(argv1_begin, 
12628                          (argv1_end - argv1_begin) * sizeof(*ptr), 
12629 -                        "(%s)", umid);
12630 +                        "(%s) ", umid);
12631                 ptr = &argv1_begin[strlen(argv1_begin)];
12632         }
12633         else ptr = argv1_begin;
12634  
12635 -       snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), " [%s]", cmd);
12636 +       snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd);
12637         memset(argv1_begin + strlen(argv1_begin), '\0', 
12638                argv1_end - argv1_begin - strlen(argv1_begin));
12639  #endif
12640 @@ -179,7 +188,7 @@
12641  static int __init uml_ncpus_setup(char *line, int *add)
12642  {
12643         if (!sscanf(line, "%d", &ncpus)) {
12644 -               printk("Couldn't parse [%s]\n", line);
12645 +               printf("Couldn't parse [%s]\n", line);
12646                 return -1;
12647         }
12648  
12649 @@ -210,7 +219,7 @@
12650  
12651  static int __init mode_tt_setup(char *line, int *add)
12652  {
12653 -       printk("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
12654 +       printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
12655         return(0);
12656  }
12657  
12658 @@ -221,7 +230,7 @@
12659  
12660  static int __init mode_tt_setup(char *line, int *add)
12661  {
12662 -       printk("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
12663 +       printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
12664         return(0);
12665  }
12666  
12667 @@ -291,7 +300,7 @@
12668  
12669  /* Set during early boot */
12670  unsigned long brk_start;
12671 -static struct vm_reserved kernel_vm_reserved;
12672 +unsigned long end_iomem;
12673  
12674  #define MIN_VMALLOC (32 * 1024 * 1024)
12675  
12676 @@ -299,7 +308,7 @@
12677  {
12678         unsigned long avail;
12679         unsigned long virtmem_size, max_physmem;
12680 -       unsigned int i, add, err;
12681 +       unsigned int i, add;
12682  
12683         for (i = 1; i < argc; i++){
12684                 if((i == 1) && (argv[i][0] == ' ')) continue;
12685 @@ -328,12 +337,16 @@
12686         argv1_end = &argv[1][strlen(argv[1])];
12687  #endif
12688    
12689 -       set_usable_vm(uml_physmem, get_kmem_end());
12690 -
12691         highmem = 0;
12692 -       max_physmem = get_kmem_end() - uml_physmem - MIN_VMALLOC;
12693 -       if(physmem_size > max_physmem){
12694 -               highmem = physmem_size - max_physmem;
12695 +       iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK;
12696 +       max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC;
12697 +
12698 +       /* Zones have to begin on a 1 << MAX_ORDER page boundary,
12699 +        * so this makes sure that's true for highmem
12700 +        */
12701 +       max_physmem &= ~((1 << (PAGE_SHIFT + MAX_ORDER)) - 1);
12702 +       if(physmem_size + iomem_size > max_physmem){
12703 +               highmem = physmem_size + iomem_size - max_physmem;
12704                 physmem_size -= highmem;
12705  #ifndef CONFIG_HIGHMEM
12706                 highmem = 0;
12707 @@ -343,11 +356,19 @@
12708         }
12709  
12710         high_physmem = uml_physmem + physmem_size;
12711 -       high_memory = (void *) high_physmem;
12712 +       end_iomem = high_physmem + iomem_size;
12713 +       high_memory = (void *) end_iomem;
12714  
12715         start_vm = VMALLOC_START;
12716  
12717 -       setup_physmem(uml_physmem, uml_reserved, physmem_size);
12718 +       setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem);
12719 +       if(init_maps(physmem_size, iomem_size, highmem)){
12720 +               printf("Failed to allocate mem_map for %ld bytes of physical "
12721 +                      "memory and %ld bytes of highmem\n", physmem_size,
12722 +                      highmem);
12723 +               exit(1);
12724 +       }
12725 +
12726         virtmem_size = physmem_size;
12727         avail = get_kmem_end() - start_vm;
12728         if(physmem_size > avail) virtmem_size = avail;
12729 @@ -357,18 +378,13 @@
12730                 printf("Kernel virtual memory size shrunk to %ld bytes\n",
12731                        virtmem_size);
12732  
12733 -       err = reserve_vm(high_physmem, end_vm, &kernel_vm_reserved);
12734 -       if(err){
12735 -               printf("Failed to reserve VM area for kernel VM\n");
12736 -               exit(1);
12737 -       }
12738 -
12739         uml_postsetup();
12740  
12741         init_task.thread.kernel_stack = (unsigned long) &init_thread_info + 
12742                 2 * PAGE_SIZE;
12743  
12744         task_protections((unsigned long) &init_thread_info);
12745 +       os_flush_stdout();
12746  
12747         return(CHOOSE_MODE(start_uml_tt(), start_uml_skas()));
12748  }
12749 @@ -377,7 +393,7 @@
12750                       void *unused2)
12751  {
12752  #ifdef CONFIG_MAGIC_SYSRQ
12753 -       handle_sysrq('p', &current->thread.regs, NULL, NULL);
12754 +       handle_sysrq('p', &current->thread.regs, NULL);
12755  #endif
12756         machine_halt();
12757         return(0);
12758 @@ -403,6 +419,11 @@
12759         arch_check_bugs();
12760         check_ptrace();
12761         check_sigio();
12762 +       check_devanon();
12763 +}
12764 +
12765 +void apply_alternatives(void *start, void *end)
12766 +{
12767  }
12768  
12769  /*
12770 diff -Naur a/arch/um/kernel/umid.c b/arch/um/kernel/umid.c
12771 --- a/arch/um/kernel/umid.c     2004-02-11 12:16:43.000000000 -0500
12772 +++ b/arch/um/kernel/umid.c     2004-02-11 12:28:42.000000000 -0500
12773 @@ -5,7 +5,6 @@
12774  
12775  #include <stdio.h>
12776  #include <unistd.h>
12777 -#include <fcntl.h>
12778  #include <errno.h>
12779  #include <string.h>
12780  #include <stdlib.h>
12781 @@ -33,18 +32,19 @@
12782  static int umid_is_random = 1;
12783  static int umid_inited = 0;
12784  
12785 -static int make_umid(void);
12786 +static int make_umid(int (*printer)(const char *fmt, ...));
12787  
12788 -static int __init set_umid(char *name, int is_random)
12789 +static int __init set_umid(char *name, int is_random, 
12790 +                          int (*printer)(const char *fmt, ...))
12791  {
12792         if(umid_inited){
12793 -               printk("Unique machine name can't be set twice\n");
12794 +               (*printer)("Unique machine name can't be set twice\n");
12795                 return(-1);
12796         }
12797  
12798         if(strlen(name) > UMID_LEN - 1)
12799 -               printk("Unique machine name is being truncated to %s "
12800 -                      "characters\n", UMID_LEN);
12801 +               (*printer)("Unique machine name is being truncated to %s "
12802 +                          "characters\n", UMID_LEN);
12803         strlcpy(umid, name, sizeof(umid));
12804  
12805         umid_is_random = is_random;
12806 @@ -54,7 +54,7 @@
12807  
12808  static int __init set_umid_arg(char *name, int *add)
12809  {
12810 -       return(set_umid(name, 0));
12811 +       return(set_umid(name, 0, printf));
12812  }
12813  
12814  __uml_setup("umid=", set_umid_arg,
12815 @@ -67,7 +67,7 @@
12816  {
12817         int n;
12818  
12819 -       if(!umid_inited && make_umid()) return(-1);
12820 +       if(!umid_inited && make_umid(printk)) return(-1);
12821  
12822         n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1;
12823         if(n > len){
12824 @@ -85,22 +85,23 @@
12825  {
12826         char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
12827         char pid[sizeof("nnnnn\0")];
12828 -       int fd;
12829 +       int fd, n;
12830  
12831         if(umid_file_name("pid", file, sizeof(file))) return 0;
12832  
12833         fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), 
12834                           0644);
12835         if(fd < 0){
12836 -               printk("Open of machine pid file \"%s\" failed - "
12837 -                      "errno = %d\n", file, -fd);
12838 +               printf("Open of machine pid file \"%s\" failed - "
12839 +                      "err = %d\n", file, -fd);
12840                 return 0;
12841         }
12842  
12843         sprintf(pid, "%d\n", os_getpid());
12844 -       if(write(fd, pid, strlen(pid)) != strlen(pid))
12845 -               printk("Write of pid file failed - errno = %d\n", errno);
12846 -       close(fd);
12847 +       n = os_write_file(fd, pid, strlen(pid));
12848 +       if(n != strlen(pid))
12849 +               printf("Write of pid file failed - err = %d\n", -n);
12850 +       os_close_file(fd);
12851         return 0;
12852  }
12853  
12854 @@ -111,7 +112,8 @@
12855         int len;
12856         char file[256];
12857  
12858 -       if((directory = opendir(dir)) == NULL){
12859 +       directory = opendir(dir);
12860 +       if(directory == NULL){
12861                 printk("actually_do_remove : couldn't open directory '%s', "
12862                        "errno = %d\n", dir, errno);
12863                 return(1);
12864 @@ -160,22 +162,24 @@
12865  {
12866         char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")];
12867         char pid[sizeof("nnnnn\0")], *end;
12868 -       int dead, fd, p;
12869 +       int dead, fd, p, n;
12870  
12871         sprintf(file, "%s/pid", dir);
12872         dead = 0;
12873 -       if((fd = os_open_file(file, of_read(OPENFLAGS()), 0)) < 0){
12874 +       fd = os_open_file(file, of_read(OPENFLAGS()), 0);
12875 +       if(fd < 0){
12876                 if(fd != -ENOENT){
12877                         printk("not_dead_yet : couldn't open pid file '%s', "
12878 -                              "errno = %d\n", file, -fd);
12879 +                              "err = %d\n", file, -fd);
12880                         return(1);
12881                 }
12882                 dead = 1;
12883         }
12884         if(fd > 0){
12885 -               if(read(fd, pid, sizeof(pid)) < 0){
12886 +               n = os_read_file(fd, pid, sizeof(pid));
12887 +               if(n < 0){
12888                         printk("not_dead_yet : couldn't read pid file '%s', "
12889 -                              "errno = %d\n", file, errno);
12890 +                              "err = %d\n", file, -n);
12891                         return(1);
12892                 }
12893                 p = strtoul(pid, &end, 0);
12894 @@ -197,7 +201,7 @@
12895         if((strlen(name) > 0) && (name[strlen(name) - 1] != '/')){
12896                 uml_dir = malloc(strlen(name) + 1);
12897                 if(uml_dir == NULL){
12898 -                       printk("Failed to malloc uml_dir - error = %d\n",
12899 +                       printf("Failed to malloc uml_dir - error = %d\n",
12900                                errno);
12901                         uml_dir = name;
12902                         return(0);
12903 @@ -217,7 +221,7 @@
12904                 char *home = getenv("HOME");
12905  
12906                 if(home == NULL){
12907 -                       printk("make_uml_dir : no value in environment for "
12908 +                       printf("make_uml_dir : no value in environment for "
12909                                "$HOME\n");
12910                         exit(1);
12911                 }
12912 @@ -232,57 +236,59 @@
12913                 dir[len + 1] = '\0';
12914         }
12915  
12916 -       if((uml_dir = malloc(strlen(dir) + 1)) == NULL){
12917 +       uml_dir = malloc(strlen(dir) + 1);
12918 +       if(uml_dir == NULL){
12919                 printf("make_uml_dir : malloc failed, errno = %d\n", errno);
12920                 exit(1);
12921         }
12922         strcpy(uml_dir, dir);
12923         
12924         if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
12925 -               printk("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
12926 +               printf("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
12927                 return(-1);
12928         }
12929         return 0;
12930  }
12931  
12932 -static int __init make_umid(void)
12933 +static int __init make_umid(int (*printer)(const char *fmt, ...))
12934  {
12935         int fd, err;
12936         char tmp[strlen(uml_dir) + UMID_LEN + 1];
12937  
12938         strlcpy(tmp, uml_dir, sizeof(tmp));
12939  
12940 -       if(*umid == 0){
12941 +       if(!umid_inited){
12942                 strcat(tmp, "XXXXXX");
12943                 fd = mkstemp(tmp);
12944                 if(fd < 0){
12945 -                       printk("make_umid - mkstemp failed, errno = %d\n",
12946 -                              errno);
12947 +                       (*printer)("make_umid - mkstemp failed, errno = %d\n",
12948 +                                  errno);
12949                         return(1);
12950                 }
12951  
12952 -               close(fd);
12953 +               os_close_file(fd);
12954                 /* There's a nice tiny little race between this unlink and
12955                  * the mkdir below.  It'd be nice if there were a mkstemp
12956                  * for directories.
12957                  */
12958                 unlink(tmp);
12959 -               set_umid(&tmp[strlen(uml_dir)], 1);
12960 +               set_umid(&tmp[strlen(uml_dir)], 1, printer);
12961         }
12962         
12963         sprintf(tmp, "%s%s", uml_dir, umid);
12964  
12965 -       if((err = mkdir(tmp, 0777)) < 0){
12966 +       err = mkdir(tmp, 0777);
12967 +       if(err < 0){
12968                 if(errno == EEXIST){
12969                         if(not_dead_yet(tmp)){
12970 -                               printk("umid '%s' is in use\n", umid);
12971 +                               (*printer)("umid '%s' is in use\n", umid);
12972                                 return(-1);
12973                         }
12974                         err = mkdir(tmp, 0777);
12975                 }
12976         }
12977         if(err < 0){
12978 -               printk("Failed to create %s - errno = %d\n", umid, errno);
12979 +               (*printer)("Failed to create %s - errno = %d\n", umid, errno);
12980                 return(-1);
12981         }
12982  
12983 @@ -295,7 +301,13 @@
12984  );
12985  
12986  __uml_postsetup(make_uml_dir);
12987 -__uml_postsetup(make_umid);
12988 +
12989 +static int __init make_umid_setup(void)
12990 +{
12991 +       return(make_umid(printf));
12992 +}
12993 +
12994 +__uml_postsetup(make_umid_setup);
12995  __uml_postsetup(create_pid_file);
12996  
12997  /*
12998 diff -Naur a/arch/um/kernel/user_syms.c b/arch/um/kernel/user_syms.c
12999 --- a/arch/um/kernel/user_syms.c        2004-02-11 12:16:42.000000000 -0500
13000 +++ b/arch/um/kernel/user_syms.c        2004-02-11 12:28:41.000000000 -0500
13001 @@ -1,7 +1,7 @@
13002  #include <stdio.h>
13003  #include <unistd.h>
13004 -#include <fcntl.h>
13005  #include <dirent.h>
13006 +#include <fcntl.h>
13007  #include <errno.h>
13008  #include <utime.h>
13009  #include <string.h>
13010 @@ -16,46 +16,61 @@
13011   * since this includes various user-level headers.
13012   */
13013  
13014 -struct module_symbol
13015 +/* Had to update this: this changed in late 2.5 to add CRC and other beasts
13016 + * and was never updated here- 13 Dec 2003-Blaisorblade
13017 + */
13018 +
13019 +/* v850 toolchain uses a `_' prefix for all user symbols */
13020 +#ifndef MODULE_SYMBOL_PREFIX
13021 +#define MODULE_SYMBOL_PREFIX ""
13022 +#endif
13023 +
13024 +struct kernel_symbol
13025  {
13026         unsigned long value;
13027         const char *name;
13028  };
13029  
13030 -/* Indirect stringification.  */
13031 -
13032 -#define __MODULE_STRING_1(x)   #x
13033 -#define __MODULE_STRING(x)     __MODULE_STRING_1(x)
13034 -
13035 -#if !defined(__AUTOCONF_INCLUDED__)
13036 -
13037 -#define __EXPORT_SYMBOL(sym,str)   error config_must_be_included_before_module
13038 -#define EXPORT_SYMBOL(var)        error config_must_be_included_before_module
13039 -#define EXPORT_SYMBOL_NOVERS(var)  error config_must_be_included_before_module
13040 -
13041 -#elif !defined(UML_CONFIG_MODULES)
13042 +#if !defined(UML_CONFIG_MODULES)
13043 +#define EXPORT_SYMBOL(sym)
13044 +#define EXPORT_SYMBOL_GPL(sym)
13045 +#define EXPORT_SYMBOL_NOVERS(sym)
13046 +
13047 +#else /*UML_CONFIG_MODULES*/
13048 +#ifndef __GENKSYMS__
13049 +#ifdef UML_CONFIG_MODVERSIONS
13050 +/* Mark the CRC weak since genksyms apparently decides not to
13051 + * generate a checksums for some symbols */
13052 +#define __CRC_SYMBOL(sym, sec)                                 \
13053 +       extern void *__crc_##sym __attribute__((weak));         \
13054 +       static const unsigned long __kcrctab_##sym              \
13055 +       __attribute__((section("__kcrctab" sec), unused))       \
13056 +       = (unsigned long) &__crc_##sym;
13057 +#else
13058 +#define __CRC_SYMBOL(sym, sec)
13059 +#endif
13060  
13061 -#define __EXPORT_SYMBOL(sym,str)
13062 -#define EXPORT_SYMBOL(var)
13063 -#define EXPORT_SYMBOL_NOVERS(var)
13064 +/* For every exported symbol, place a struct in the __ksymtab section */
13065 +#define __EXPORT_SYMBOL(sym, sec)                              \
13066 +       __CRC_SYMBOL(sym, sec)                                  \
13067 +       static const char __kstrtab_##sym[]                     \
13068 +       __attribute__((section("__ksymtab_strings")))           \
13069 +       = MODULE_SYMBOL_PREFIX #sym;                            \
13070 +       static const struct kernel_symbol __ksymtab_##sym       \
13071 +       __attribute__((section("__ksymtab" sec), unused))       \
13072 +       = { (unsigned long)&sym, __kstrtab_##sym }
13073  
13074 -#else
13075 +#define EXPORT_SYMBOL(sym)                                     \
13076 +       __EXPORT_SYMBOL(sym, "")
13077  
13078 -#define __EXPORT_SYMBOL(sym, str)                      \
13079 -const char __kstrtab_##sym[]                           \
13080 -__attribute__((section(".kstrtab"))) = str;            \
13081 -const struct module_symbol __ksymtab_##sym             \
13082 -__attribute__((section("__ksymtab"))) =                        \
13083 -{ (unsigned long)&sym, __kstrtab_##sym }
13084 +#define EXPORT_SYMBOL_GPL(sym)                                 \
13085 +       __EXPORT_SYMBOL(sym, "_gpl")
13086  
13087 -#if defined(__MODVERSIONS__) || !defined(UML_CONFIG_MODVERSIONS)
13088 -#define EXPORT_SYMBOL(var)  __EXPORT_SYMBOL(var, __MODULE_STRING(var))
13089 -#else
13090 -#define EXPORT_SYMBOL(var)  __EXPORT_SYMBOL(var, __MODULE_STRING(__VERSIONED_SYMBOL(var)))
13091  #endif
13092  
13093 -#define EXPORT_SYMBOL_NOVERS(var)  __EXPORT_SYMBOL(var, __MODULE_STRING(var))
13094 -
13095 +/* We don't mangle the actual symbol anymore, so no need for
13096 + * special casing EXPORT_SYMBOL_NOVERS.  FIXME: Deprecated */
13097 +#define EXPORT_SYMBOL_NOVERS(sym) EXPORT_SYMBOL(sym)
13098  #endif
13099  
13100  EXPORT_SYMBOL(__errno_location);
13101 @@ -109,5 +124,18 @@
13102  
13103  EXPORT_SYMBOL(memset);
13104  EXPORT_SYMBOL(strstr);
13105 +EXPORT_SYMBOL(printf);
13106 +EXPORT_SYMBOL(strlen);
13107  
13108  EXPORT_SYMBOL(find_iomem);
13109 +
13110 +/*
13111 + * Overrides for Emacs so that we follow Linus's tabbing style.
13112 + * Emacs will notice this stuff at the end of the file and automatically
13113 + * adjust the settings for this buffer only.  This must remain at the end
13114 + * of the file.
13115 + * ---------------------------------------------------------------------------
13116 + * Local variables:
13117 + * c-file-style: "linux"
13118 + * End:
13119 + */
13120 diff -Naur a/arch/um/kernel/user_util.c b/arch/um/kernel/user_util.c
13121 --- a/arch/um/kernel/user_util.c        2004-02-11 12:14:27.000000000 -0500
13122 +++ b/arch/um/kernel/user_util.c        2004-02-11 12:26:09.000000000 -0500
13123 @@ -5,7 +5,6 @@
13124  
13125  #include <stdio.h>
13126  #include <stdlib.h>
13127 -#include <fcntl.h>
13128  #include <unistd.h>
13129  #include <limits.h>
13130  #include <sys/mman.h> 
13131 @@ -82,7 +81,8 @@
13132         int status, ret;
13133  
13134         while(1){
13135 -               if(((ret = waitpid(pid, &status, WUNTRACED)) < 0) ||
13136 +               ret = waitpid(pid, &status, WUNTRACED);
13137 +               if((ret < 0) ||
13138                    !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){
13139                         if(ret < 0){
13140                                 if(errno == EINTR) continue;
13141 @@ -119,17 +119,6 @@
13142         }
13143  }
13144  
13145 -int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags)
13146 -{
13147 -       int pid;
13148 -
13149 -       pid = clone(fn, sp, flags, arg);
13150 -       if(pid < 0) return(-1);
13151 -       wait_for_stop(pid, SIGSTOP, PTRACE_CONT, NULL);
13152 -       ptrace(PTRACE_CONT, pid, 0, 0);
13153 -       return(pid);
13154 -}
13155 -
13156  int raw(int fd, int complain)
13157  {
13158         struct termios tt;
13159 diff -Naur a/arch/um/main.c b/arch/um/main.c
13160 --- a/arch/um/main.c    2004-02-11 12:16:28.000000000 -0500
13161 +++ b/arch/um/main.c    2004-02-11 12:28:27.000000000 -0500
13162 @@ -8,6 +8,7 @@
13163  #include <stdlib.h>
13164  #include <string.h>
13165  #include <signal.h>
13166 +#include <errno.h>
13167  #include <sys/resource.h>
13168  #include <sys/mman.h>
13169  #include <sys/user.h>
13170 @@ -123,12 +124,14 @@
13171  
13172         set_stklim();
13173  
13174 -       if((new_argv = malloc((argc + 1) * sizeof(char *))) == NULL){
13175 +       new_argv = malloc((argc + 1) * sizeof(char *));
13176 +       if(new_argv == NULL){
13177                 perror("Mallocing argv");
13178                 exit(1);
13179         }
13180         for(i=0;i<argc;i++){
13181 -               if((new_argv[i] = strdup(argv[i])) == NULL){
13182 +               new_argv[i] = strdup(argv[i]);
13183 +               if(new_argv[i] == NULL){
13184                         perror("Mallocing an arg");
13185                         exit(1);
13186                 }
13187 diff -Naur a/arch/um/Makefile b/arch/um/Makefile
13188 --- a/arch/um/Makefile  2004-02-11 12:15:58.000000000 -0500
13189 +++ b/arch/um/Makefile  2004-02-11 12:27:51.000000000 -0500
13190 @@ -22,17 +22,21 @@
13191                            $(ARCH_DIR)/sys-$(SUBARCH)/
13192  
13193  # Have to precede the include because the included Makefiles reference them.
13194 -SYMLINK_HEADERS = include/asm-um/archparam.h include/asm-um/system.h \
13195 -       include/asm-um/sigcontext.h include/asm-um/processor.h \
13196 -       include/asm-um/ptrace.h include/asm-um/arch-signal.h
13197 +SYMLINK_HEADERS = archparam.h system.h sigcontext.h processor.h ptrace.h \
13198 +       arch-signal.h module.h
13199 +SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header))
13200  
13201  ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \
13202         $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
13203  
13204  GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h
13205  
13206 -include $(ARCH_DIR)/Makefile-$(SUBARCH)
13207 -include $(ARCH_DIR)/Makefile-os-$(OS)
13208 +# This target adds dependencies to "prepare". They are defined in the included
13209 +# Makefiles (see Makefile-i386).
13210 +
13211 +.PHONY: sys_prepare
13212 +sys_prepare:
13213 +       @:
13214  
13215  MAKEFILE-$(CONFIG_MODE_TT) += Makefile-tt
13216  MAKEFILE-$(CONFIG_MODE_SKAS) += Makefile-skas
13217 @@ -41,6 +45,9 @@
13218    include $(addprefix $(ARCH_DIR)/,$(MAKEFILE-y))
13219  endif
13220  
13221 +include $(ARCH_DIR)/Makefile-$(SUBARCH)
13222 +include $(ARCH_DIR)/Makefile-os-$(OS)
13223 +
13224  EXTRAVERSION := $(EXTRAVERSION)-1um
13225  
13226  ARCH_INCLUDE = -I$(ARCH_DIR)/include
13227 @@ -52,14 +59,20 @@
13228  
13229  CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
13230         -D_LARGEFILE64_SOURCE $(ARCH_INCLUDE) -Derrno=kernel_errno \
13231 -       $(MODE_INCLUDE)
13232 +       -Dsigprocmask=kernel_sigprocmask $(MODE_INCLUDE)
13233  
13234  LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
13235  
13236 +# These are needed for clean and mrproper, since in that case .config is not
13237 +# included; the values here are meaningless
13238 +
13239 +CONFIG_NEST_LEVEL ?= 0
13240 +CONFIG_KERNEL_HALF_GIGS ?=  0
13241 +
13242  SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
13243  
13244  ifeq ($(CONFIG_MODE_SKAS), y)
13245 -$(SYS_HEADERS) : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
13246 +$(SYS_HEADERS) : $(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h
13247  endif
13248  
13249  include/linux/version.h: arch/$(ARCH)/Makefile
13250 @@ -98,17 +111,17 @@
13251  CONFIG_KERNEL_STACK_ORDER ?= 2
13252  STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
13253  
13254 -AFLAGS_vmlinux.lds.o = -U$(SUBARCH) \
13255 +AFLAGS_vmlinux.lds.o = $(shell echo -U$(SUBARCH) \
13256         -DSTART=$$(($(TOP_ADDR) - $(SIZE))) -DELF_ARCH=$(ELF_ARCH) \
13257         -DELF_FORMAT=\"$(ELF_FORMAT)\" $(CPP_MODE_TT) \
13258 -       -DKERNEL_STACK_SIZE=$(STACK_SIZE)
13259 +       -DKERNEL_STACK_SIZE=$(STACK_SIZE))
13260  
13261 -AFLAGS_$(LD_SCRIPT-y:.s=).o = $(AFLAGS_vmlinux.lds.o) -P -C -Uum
13262 +export AFLAGS_$(LD_SCRIPT-y:.s=).o = $(AFLAGS_vmlinux.lds.o) -P -C -Uum
13263  
13264  LD_SCRIPT-y := $(ARCH_DIR)/$(LD_SCRIPT-y)
13265  
13266 -$(LD_SCRIPT-y) : $(LD_SCRIPT-y:.s=.S) scripts FORCE
13267 -       $(call if_changed_dep,as_s_S)
13268 +#$(LD_SCRIPT-y) : $(LD_SCRIPT-y:.s=.S) scripts FORCE
13269 +#      $(call if_changed_dep,as_s_S)
13270  
13271  linux: vmlinux $(LD_SCRIPT-y)
13272         $(CC) -Wl,-T,$(LD_SCRIPT-y) $(LINK-y) $(LINK_WRAPS) \
13273 @@ -116,37 +129,47 @@
13274  
13275  USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
13276  USER_CFLAGS := $(patsubst -Derrno=kernel_errno,,$(USER_CFLAGS))
13277 +USER_CFLAGS := $(patsubst -Dsigprocmask=kernel_sigprocmask,,$(USER_CFLAGS))
13278  USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
13279         $(MODE_INCLUDE)
13280  
13281  # To get a definition of F_SETSIG
13282  USER_CFLAGS += -D_GNU_SOURCE
13283  
13284 +# From main Makefile, these options are set after including the ARCH makefile.
13285 +# So copy them here.
13286 +
13287 +ifdef CONFIG_CC_OPTIMIZE_FOR_SIZE
13288 +USER_CFLAGS            += -Os
13289 +else
13290 +USER_CFLAGS            += -O2
13291 +endif
13292 +
13293 +ifndef CONFIG_FRAME_POINTER
13294 +USER_CFLAGS            += -fomit-frame-pointer
13295 +endif
13296 +
13297 +ifdef CONFIG_DEBUG_INFO
13298 +USER_CFLAGS            += -g
13299 +endif
13300 +
13301  CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/uml.lds.s \
13302 -       $(ARCH_DIR)/dyn_link.ld.s $(GEN_HEADERS)
13303 +       $(ARCH_DIR)/dyn_link.ld.s $(ARCH_DIR)/include/uml-config.h \
13304 +       $(GEN_HEADERS)
13305  
13306 -$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c
13307 -       $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
13308 +MRPROPER_FILES += $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) \
13309 +       $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS))
13310 +
13311 +$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c sys_prepare
13312 +       @ echo '  MAIN    $@'
13313 +       @ $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
13314  
13315  archmrproper:
13316 -       for d in $(ARCH_SUBDIRS) $(ARCH_DIR)/util; \
13317 -       do \
13318 -               $(MAKE) -C $$d archmrproper; \
13319 -       done
13320 -       rm -f $(CLEAN_FILES) $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) include/asm \
13321 -               $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS))
13322 -
13323 -archclean: sysclean
13324 -       for d in $(ARCH_SUBDIRS) $(ARCH_DIR)/util; \
13325 -       do \
13326 -               $(MAKE) -C $$d clean; \
13327 -       done
13328 -       find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
13329 -               -o -name '*.gcov' \) -type f -print | xargs rm -f
13330 -       rm -f linux x.i gmon.out $(ARCH_DIR)/link.ld $(GEN_HEADERS)
13331 +       @:
13332  
13333 -archdep: 
13334 -       for d in $(ARCH_SUBDIRS); do $(MAKE) -C $$d fastdep; done
13335 +archclean:
13336 +       @find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \
13337 +               -o -name '*.gcov' \) -type f -print | xargs rm -f
13338  
13339  $(SYMLINK_HEADERS):
13340         cd $(TOPDIR)/$(dir $@) ; \
13341 @@ -161,19 +184,26 @@
13342  $(ARCH_DIR)/os:
13343         cd $(ARCH_DIR) && ln -sf os-$(OS) os
13344  
13345 -$(ARCH_DIR)/include/uml-config.h :
13346 -       sed 's/ CONFIG/ UML_CONFIG/' $(TOPDIR)/include/linux/autoconf.h > $@
13347 +# Generated files
13348 +define filechk_umlconfig
13349 +       sed 's/ CONFIG/ UML_CONFIG/'
13350 +endef
13351 +
13352 +$(ARCH_DIR)/include/uml-config.h : $(TOPDIR)/include/linux/autoconf.h
13353 +       $(call filechk,umlconfig)
13354 +
13355 +filechk_gen_header = $<
13356  
13357  $(ARCH_DIR)/include/task.h : $(ARCH_DIR)/util/mk_task
13358 -       $< > $@
13359 +       $(call filechk,gen_header)
13360  
13361  $(ARCH_DIR)/include/kern_constants.h : $(ARCH_DIR)/util/mk_constants
13362 -       $< > $@
13363 +       $(call filechk,gen_header)
13364  
13365 -$(ARCH_DIR)/util/mk_task : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h \
13366 -       $(ARCH_DIR)/util FORCE ;
13367 +$(ARCH_DIR)/util/mk_task $(ARCH_DIR)/util/mk_constants : $(ARCH_DIR)/util \
13368 +       sys_prepare FORCE ;
13369  
13370  $(ARCH_DIR)/util: FORCE
13371 -       @$(call descend,$@,)
13372 +       $(Q)$(MAKE) $(build)=$@
13373  
13374 -export SUBARCH USER_CFLAGS OS
13375 +export SUBARCH USER_CFLAGS OS 
13376 diff -Naur a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
13377 --- a/arch/um/Makefile-i386     2004-02-11 12:16:28.000000000 -0500
13378 +++ b/arch/um/Makefile-i386     2004-02-11 12:28:27.000000000 -0500
13379 @@ -16,22 +16,27 @@
13380  
13381  SYS_HEADERS = $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
13382  
13383 +sys_prepare: $(SYS_DIR)/sc.h
13384 +
13385  prepare: $(SYS_HEADERS)
13386  
13387 +filechk_$(SYS_DIR)/sc.h := $(SYS_UTIL_DIR)/mk_sc
13388 +
13389  $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
13390 -       $< > $@
13391 +       $(call filechk,$@)
13392 +
13393 +filechk_$(SYS_DIR)/thread.h := $(SYS_UTIL_DIR)/mk_thread 
13394  
13395  $(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread 
13396 -       $< > $@
13397 +       $(call filechk,$@)
13398  
13399 -$(SYS_UTIL_DIR)/mk_sc: FORCE ; 
13400 -       @$(call descend,$(SYS_UTIL_DIR),$@)
13401 +$(SYS_UTIL_DIR)/mk_sc: scripts/fixdep include/config/MARKER FORCE ; 
13402 +       $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
13403  
13404 -$(SYS_UTIL_DIR)/mk_thread: $(ARCH_SYMLINKS) $(GEN_HEADERS) FORCE ; 
13405 -       @$(call descend,$(SYS_UTIL_DIR),$@)
13406 +$(SYS_UTIL_DIR)/mk_thread: $(ARCH_SYMLINKS) $(GEN_HEADERS) sys_prepare FORCE ; 
13407 +       $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR) $@
13408  
13409  $(SYS_UTIL_DIR): include/asm FORCE
13410 -       @$(call descend,$@,)
13411 +       $(Q)$(MAKE) $(build)=$(SYS_UTIL_DIR)
13412  
13413 -sysclean :
13414 -       rm -f $(SYS_HEADERS)
13415 +CLEAN_FILES += $(SYS_HEADERS)
13416 diff -Naur a/arch/um/Makefile-skas b/arch/um/Makefile-skas
13417 --- a/arch/um/Makefile-skas     2004-02-11 12:15:22.000000000 -0500
13418 +++ b/arch/um/Makefile-skas     2004-02-11 12:27:10.000000000 -0500
13419 @@ -14,7 +14,7 @@
13420  LINK_SKAS = -Wl,-rpath,/lib 
13421  LD_SCRIPT_SKAS = dyn.lds.s
13422  
13423 -GEN_HEADERS += $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
13424 +GEN_HEADERS += $(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h
13425  
13426 -$(ARCH_DIR)/kernel/skas/include/skas_ptregs.h :
13427 -       $(MAKE) -C $(ARCH_DIR)/kernel/skas include/skas_ptregs.h
13428 +$(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h :
13429 +       $(Q)$(MAKE) $(build)=$(ARCH_DIR)/kernel/skas $@
13430 diff -Naur a/arch/um/os-Linux/drivers/ethertap_kern.c b/arch/um/os-Linux/drivers/ethertap_kern.c
13431 --- a/arch/um/os-Linux/drivers/ethertap_kern.c  2004-02-11 12:14:17.000000000 -0500
13432 +++ b/arch/um/os-Linux/drivers/ethertap_kern.c  2004-02-11 12:26:00.000000000 -0500
13433 @@ -8,7 +8,6 @@
13434  #include "linux/init.h"
13435  #include "linux/netdevice.h"
13436  #include "linux/etherdevice.h"
13437 -#include "linux/init.h"
13438  #include "net_kern.h"
13439  #include "net_user.h"
13440  #include "etap.h"
13441 diff -Naur a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
13442 --- a/arch/um/os-Linux/drivers/ethertap_user.c  2004-02-11 12:15:29.000000000 -0500
13443 +++ b/arch/um/os-Linux/drivers/ethertap_user.c  2004-02-11 12:27:17.000000000 -0500
13444 @@ -8,7 +8,6 @@
13445  #include <stdio.h>
13446  #include <unistd.h>
13447  #include <stddef.h>
13448 -#include <fcntl.h>
13449  #include <stdlib.h>
13450  #include <sys/errno.h>
13451  #include <sys/socket.h>
13452 @@ -42,13 +41,14 @@
13453  {
13454         struct addr_change change;
13455         void *output;
13456 +       int n;
13457  
13458         change.what = op;
13459         memcpy(change.addr, addr, sizeof(change.addr));
13460         memcpy(change.netmask, netmask, sizeof(change.netmask));
13461 -       if(write(fd, &change, sizeof(change)) != sizeof(change))
13462 -               printk("etap_change - request failed, errno = %d\n",
13463 -                      errno);
13464 +       n = os_write_file(fd, &change, sizeof(change));
13465 +       if(n != sizeof(change))
13466 +               printk("etap_change - request failed, err = %d\n", -n);
13467         output = um_kmalloc(page_size());
13468         if(output == NULL)
13469                 printk("etap_change : Failed to allocate output buffer\n");
13470 @@ -82,15 +82,15 @@
13471         struct etap_pre_exec_data *data = arg;
13472  
13473         dup2(data->control_remote, 1);
13474 -       close(data->data_me);
13475 -       close(data->control_me);
13476 +       os_close_file(data->data_me);
13477 +       os_close_file(data->control_me);
13478  }
13479  
13480  static int etap_tramp(char *dev, char *gate, int control_me, 
13481                       int control_remote, int data_me, int data_remote)
13482  {
13483         struct etap_pre_exec_data pe_data;
13484 -       int pid, status, err;
13485 +       int pid, status, err, n;
13486         char version_buf[sizeof("nnnnn\0")];
13487         char data_fd_buf[sizeof("nnnnnn\0")];
13488         char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
13489 @@ -114,21 +114,21 @@
13490         pe_data.data_me = data_me;
13491         pid = run_helper(etap_pre_exec, &pe_data, args, NULL);
13492  
13493 -       if(pid < 0) err = errno;
13494 -       close(data_remote);
13495 -       close(control_remote);
13496 -       if(read(control_me, &c, sizeof(c)) != sizeof(c)){
13497 -               printk("etap_tramp : read of status failed, errno = %d\n",
13498 -                      errno);
13499 -               return(EINVAL);
13500 +       if(pid < 0) err = pid;
13501 +       os_close_file(data_remote);
13502 +       os_close_file(control_remote);
13503 +       n = os_read_file(control_me, &c, sizeof(c));
13504 +       if(n != sizeof(c)){
13505 +               printk("etap_tramp : read of status failed, err = %d\n", -n);
13506 +               return(-EINVAL);
13507         }
13508         if(c != 1){
13509                 printk("etap_tramp : uml_net failed\n");
13510 -               err = EINVAL;
13511 -               if(waitpid(pid, &status, 0) < 0) err = errno;
13512 -               else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1)){
13513 +               err = -EINVAL;
13514 +               if(waitpid(pid, &status, 0) < 0)
13515 +                       err = -errno;
13516 +               else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1))
13517                         printk("uml_net didn't exit with status 1\n");
13518 -               }
13519         }
13520         return(err);
13521  }
13522 @@ -143,14 +143,14 @@
13523         if(err) return(err);
13524  
13525         err = os_pipe(data_fds, 0, 0);
13526 -       if(err){
13527 -               printk("data os_pipe failed - errno = %d\n", -err);
13528 +       if(err < 0){
13529 +               printk("data os_pipe failed - err = %d\n", -err);
13530                 return(err);
13531         }
13532  
13533         err = os_pipe(control_fds, 1, 0);
13534 -       if(err){
13535 -               printk("control os_pipe failed - errno = %d\n", -err);
13536 +       if(err < 0){
13537 +               printk("control os_pipe failed - err = %d\n", -err);
13538                 return(err);
13539         }
13540         
13541 @@ -167,9 +167,9 @@
13542                 kfree(output);
13543         }
13544  
13545 -       if(err != 0){
13546 -               printk("etap_tramp failed - errno = %d\n", err);
13547 -               return(-err);
13548 +       if(err < 0){
13549 +               printk("etap_tramp failed - err = %d\n", -err);
13550 +               return(err);
13551         }
13552  
13553         pri->data_fd = data_fds[0];
13554 @@ -183,11 +183,11 @@
13555         struct ethertap_data *pri = data;
13556  
13557         iter_addresses(pri->dev, etap_close_addr, &pri->control_fd);
13558 -       close(fd);
13559 +       os_close_file(fd);
13560         os_shutdown_socket(pri->data_fd, 1, 1);
13561 -       close(pri->data_fd);
13562 +       os_close_file(pri->data_fd);
13563         pri->data_fd = -1;
13564 -       close(pri->control_fd);
13565 +       os_close_file(pri->control_fd);
13566         pri->control_fd = -1;
13567  }
13568  
13569 diff -Naur a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
13570 --- a/arch/um/os-Linux/drivers/tuntap_user.c    2004-02-11 12:17:08.000000000 -0500
13571 +++ b/arch/um/os-Linux/drivers/tuntap_user.c    2004-02-11 12:29:13.000000000 -0500
13572 @@ -8,7 +8,6 @@
13573  #include <stdlib.h>
13574  #include <unistd.h>
13575  #include <errno.h>
13576 -#include <fcntl.h>
13577  #include <sys/wait.h>
13578  #include <sys/socket.h>
13579  #include <sys/un.h>
13580 @@ -61,7 +60,7 @@
13581         struct tuntap_pre_exec_data *data = arg;
13582         
13583         dup2(data->stdout, 1);
13584 -       close(data->close_me);
13585 +       os_close_file(data->close_me);
13586  }
13587  
13588  static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
13589 @@ -86,7 +85,7 @@
13590  
13591         if(pid < 0) return(-pid);
13592  
13593 -       close(remote);
13594 +       os_close_file(remote);
13595  
13596         msg.msg_name = NULL;
13597         msg.msg_namelen = 0;
13598 @@ -107,19 +106,19 @@
13599         if(n < 0){
13600                 printk("tuntap_open_tramp : recvmsg failed - errno = %d\n", 
13601                        errno);
13602 -               return(errno);
13603 +               return(-errno);
13604         }
13605         waitpid(pid, NULL, 0);
13606  
13607         cmsg = CMSG_FIRSTHDR(&msg);
13608         if(cmsg == NULL){
13609                 printk("tuntap_open_tramp : didn't receive a message\n");
13610 -               return(EINVAL);
13611 +               return(-EINVAL);
13612         }
13613         if((cmsg->cmsg_level != SOL_SOCKET) || 
13614            (cmsg->cmsg_type != SCM_RIGHTS)){
13615                 printk("tuntap_open_tramp : didn't receive a descriptor\n");
13616 -               return(EINVAL);
13617 +               return(-EINVAL);
13618         }
13619         *fd_out = ((int *) CMSG_DATA(cmsg))[0];
13620         return(0);
13621 @@ -133,27 +132,29 @@
13622         int err, fds[2], len, used;
13623  
13624         err = tap_open_common(pri->dev, pri->gate_addr);
13625 -       if(err) return(err);
13626 +       if(err < 0) 
13627 +               return(err);
13628  
13629         if(pri->fixed_config){
13630 -               if((pri->fd = open("/dev/net/tun", O_RDWR)) < 0){
13631 -                       printk("Failed to open /dev/net/tun, errno = %d\n",
13632 -                              errno);
13633 -                       return(-errno);
13634 +               pri->fd = os_open_file("/dev/net/tun", of_rdwr(OPENFLAGS()), 0);
13635 +               if(pri->fd < 0){
13636 +                       printk("Failed to open /dev/net/tun, err = %d\n",
13637 +                              -pri->fd);
13638 +                       return(pri->fd);
13639                 }
13640                 memset(&ifr, 0, sizeof(ifr));
13641 -               ifr.ifr_flags = IFF_TAP;
13642 +               ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
13643                 strlcpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name));
13644                 if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){
13645 -                       printk("TUNSETIFF failed, errno = %d", errno);
13646 -                       close(pri->fd);
13647 +                       printk("TUNSETIFF failed, errno = %d\n", errno);
13648 +                       os_close_file(pri->fd);
13649                         return(-errno);
13650                 }
13651         }
13652         else {
13653                 err = os_pipe(fds, 0, 0);
13654 -               if(err){
13655 -                       printk("tuntap_open : os_pipe failed - errno = %d\n",
13656 +               if(err < 0){
13657 +                       printk("tuntap_open : os_pipe failed - err = %d\n",
13658                                -err);
13659                         return(err);
13660                 }
13661 @@ -166,19 +167,19 @@
13662                                         fds[1], buffer, len, &used);
13663  
13664                 output = buffer;
13665 -               if(err == 0){
13666 -                       pri->dev_name = uml_strdup(buffer);
13667 -                       output += IFNAMSIZ;
13668 -                       printk(output);
13669 -                       free_output_buffer(buffer);
13670 -               }
13671 -               else {
13672 -                       printk(output);
13673 +               if(err < 0) {
13674 +                       printk("%s", output);
13675                         free_output_buffer(buffer);
13676 -                       printk("tuntap_open_tramp failed - errno = %d\n", err);
13677 -                       return(-err);
13678 +                       printk("tuntap_open_tramp failed - err = %d\n", -err);
13679 +                       return(err);
13680                 }
13681 -               close(fds[0]);
13682 +
13683 +               pri->dev_name = uml_strdup(buffer);
13684 +               output += IFNAMSIZ;
13685 +               printk("%s", output);
13686 +               free_output_buffer(buffer);
13687 +
13688 +               os_close_file(fds[0]);
13689                 iter_addresses(pri->dev, open_addr, pri->dev_name);
13690         }
13691  
13692 @@ -191,7 +192,7 @@
13693  
13694         if(!pri->fixed_config) 
13695                 iter_addresses(pri->dev, close_addr, pri->dev_name);
13696 -       close(fd);
13697 +       os_close_file(fd);
13698         pri->fd = -1;
13699  }
13700  
13701 diff -Naur a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
13702 --- a/arch/um/os-Linux/file.c   2004-02-11 12:17:07.000000000 -0500
13703 +++ b/arch/um/os-Linux/file.c   2004-02-11 12:29:09.000000000 -0500
13704 @@ -8,6 +8,8 @@
13705  #include <errno.h>
13706  #include <fcntl.h>
13707  #include <signal.h>
13708 +#include <sys/types.h>
13709 +#include <sys/stat.h>
13710  #include <sys/socket.h>
13711  #include <sys/un.h>
13712  #include <sys/ioctl.h>
13713 @@ -17,33 +19,235 @@
13714  #include "user.h"
13715  #include "kern_util.h"
13716  
13717 -int os_file_type(char *file)
13718 +static void copy_stat(struct uml_stat *dst, struct stat64 *src)
13719 +{
13720 +       *dst = ((struct uml_stat) {
13721 +               .ust_dev     = src->st_dev,     /* device */
13722 +               .ust_ino     = src->st_ino,     /* inode */
13723 +               .ust_mode    = src->st_mode,    /* protection */
13724 +               .ust_nlink   = src->st_nlink,   /* number of hard links */
13725 +               .ust_uid     = src->st_uid,     /* user ID of owner */
13726 +               .ust_gid     = src->st_gid,     /* group ID of owner */
13727 +               .ust_size    = src->st_size,    /* total size, in bytes */
13728 +               .ust_blksize = src->st_blksize, /* blocksize for filesys I/O */
13729 +               .ust_blocks  = src->st_blocks,  /* number of blocks allocated */
13730 +               .ust_atime   = src->st_atime,   /* time of last access */
13731 +               .ust_mtime   = src->st_mtime,   /* time of last modification */
13732 +               .ust_ctime   = src->st_ctime,   /* time of last change */
13733 +       });
13734 +}
13735 +
13736 +int os_stat_fd(const int fd, struct uml_stat *ubuf)
13737 +{
13738 +       struct stat64 sbuf;
13739 +       int err;
13740 +
13741 +       do {
13742 +               err = fstat64(fd, &sbuf);
13743 +       } while((err < 0) && (errno == EINTR)) ;
13744 +
13745 +       if(err < 0) 
13746 +               return(-errno);
13747 +
13748 +       if(ubuf != NULL)
13749 +               copy_stat(ubuf, &sbuf);
13750 +       return(err);
13751 +}
13752 +
13753 +int os_stat_file(const char *file_name, struct uml_stat *ubuf)
13754 +{
13755 +       struct stat64 sbuf;
13756 +       int err;
13757 +
13758 +       do {
13759 +               err = stat64(file_name, &sbuf);
13760 +       } while((err < 0) && (errno == EINTR)) ;
13761 +
13762 +       if(err < 0) 
13763 +               return(-errno);
13764 +
13765 +       if(ubuf != NULL)
13766 +               copy_stat(ubuf, &sbuf);
13767 +       return(err);
13768 +}
13769 +
13770 +int os_access(const char* file, int mode)
13771 +{
13772 +       int amode, err;
13773 +
13774 +       amode=(mode&OS_ACC_R_OK ? R_OK : 0) | (mode&OS_ACC_W_OK ? W_OK : 0) |
13775 +             (mode&OS_ACC_X_OK ? X_OK : 0) | (mode&OS_ACC_F_OK ? F_OK : 0) ;
13776 +
13777 +       err = access(file, amode);
13778 +       if(err < 0)
13779 +               return(-errno);
13780 +
13781 +       return(0);
13782 +}
13783 +
13784 +void os_print_error(int error, const char* str)
13785 +{
13786 +       errno = error < 0 ? -error : error;
13787 +
13788 +       perror(str);
13789 +}
13790 +
13791 +/* FIXME? required only by hostaudio (because it passes ioctls verbatim) */
13792 +int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg)
13793 +{
13794 +       int err;
13795 +
13796 +       err = ioctl(fd, cmd, arg);
13797 +       if(err < 0)
13798 +               return(-errno);
13799 +
13800 +       return(err);
13801 +}
13802 +
13803 +int os_window_size(int fd, int *rows, int *cols)
13804 +{
13805 +       struct winsize size;
13806 +
13807 +       if(ioctl(fd, TIOCGWINSZ, &size) < 0)
13808 +               return(-errno);
13809 +
13810 +       *rows = size.ws_row;
13811 +       *cols = size.ws_col;
13812 +
13813 +       return(0);
13814 +}
13815 +
13816 +int os_new_tty_pgrp(int fd, int pid)
13817  {
13818 -       struct stat64 buf;
13819 +       if(ioctl(fd, TIOCSCTTY, 0) < 0){
13820 +               printk("TIOCSCTTY failed, errno = %d\n", errno);
13821 +               return(-errno);
13822 +       }
13823 +
13824 +       if(tcsetpgrp(fd, pid) < 0){
13825 +               printk("tcsetpgrp failed, errno = %d\n", errno);
13826 +               return(-errno);
13827 +       }
13828 +
13829 +       return(0);
13830 +}
13831 +
13832 +/* FIXME: ensure namebuf in os_get_if_name is big enough */
13833 +int os_get_ifname(int fd, char* namebuf)
13834 +{
13835 +       if(ioctl(fd, SIOCGIFNAME, namebuf) < 0)
13836 +               return(-errno);
13837 +
13838 +       return(0);
13839 +}
13840 +
13841 +int os_set_slip(int fd)
13842 +{
13843 +       int disc, sencap;
13844 +
13845 +       disc = N_SLIP;
13846 +       if(ioctl(fd, TIOCSETD, &disc) < 0){
13847 +               printk("Failed to set slip line discipline - "
13848 +                      "errno = %d\n", errno);
13849 +               return(-errno);
13850 +       }
13851 +
13852 +       sencap = 0;
13853 +       if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0){
13854 +               printk("Failed to set slip encapsulation - "
13855 +                      "errno = %d\n", errno);
13856 +               return(-errno);
13857 +       }
13858 +
13859 +       return(0);
13860 +}
13861 +
13862 +int os_set_owner(int fd, int pid)
13863 +{
13864 +       if(fcntl(fd, F_SETOWN, pid) < 0){
13865 +               int save_errno = errno;
13866 +
13867 +               if(fcntl(fd, F_GETOWN, 0) != pid)
13868 +                       return(-save_errno);
13869 +       }
13870 +
13871 +       return(0);
13872 +}
13873 +
13874 +/* FIXME? moved wholesale from sigio_user.c to get fcntls out of that file */ 
13875 +int os_sigio_async(int master, int slave)
13876 +{
13877 +       int flags;
13878  
13879 -       if(stat64(file, &buf) == -1)
13880 +       flags = fcntl(master, F_GETFL);
13881 +       if(flags < 0) {
13882 +               printk("fcntl F_GETFL failed, errno = %d\n", errno);
13883                 return(-errno);
13884 +       }
13885 +
13886 +       if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) ||
13887 +          (fcntl(master, F_SETOWN, os_getpid()) < 0)){
13888 +               printk("fcntl F_SETFL or F_SETOWN failed, errno = %d\n", errno);
13889 +               return(-errno);
13890 +       }
13891 +
13892 +       if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)){
13893 +               printk("fcntl F_SETFL failed, errno = %d\n", errno);
13894 +               return(-errno);
13895 +       }
13896  
13897 -       if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
13898 -       else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
13899 -       else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV);
13900 -       else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV);
13901 -       else if(S_ISFIFO(buf.st_mode)) return(OS_TYPE_FIFO);
13902 -       else if(S_ISSOCK(buf.st_mode)) return(OS_TYPE_SOCK);
13903 +       return(0);
13904 +}
13905 +
13906 +int os_mode_fd(int fd, int mode)
13907 +{
13908 +       int err;
13909 +
13910 +       do {
13911 +               err = fchmod(fd, mode);
13912 +       } while((err < 0) && (errno==EINTR)) ;
13913 +
13914 +       if(err < 0)
13915 +               return(-errno);
13916 +
13917 +       return(0);
13918 +}
13919 +
13920 +int os_file_type(char *file)
13921 +{
13922 +       struct uml_stat buf;
13923 +       int err;
13924 +
13925 +       err = os_stat_file(file, &buf);
13926 +       if(err < 0)
13927 +               return(err);
13928 +
13929 +       if(S_ISDIR(buf.ust_mode)) return(OS_TYPE_DIR);
13930 +       else if(S_ISLNK(buf.ust_mode)) return(OS_TYPE_SYMLINK);
13931 +       else if(S_ISCHR(buf.ust_mode)) return(OS_TYPE_CHARDEV);
13932 +       else if(S_ISBLK(buf.ust_mode)) return(OS_TYPE_BLOCKDEV);
13933 +       else if(S_ISFIFO(buf.ust_mode)) return(OS_TYPE_FIFO);
13934 +       else if(S_ISSOCK(buf.ust_mode)) return(OS_TYPE_SOCK);
13935         else return(OS_TYPE_FILE);
13936  }
13937  
13938  int os_file_mode(char *file, struct openflags *mode_out)
13939  {
13940 +       int err;
13941 +
13942         *mode_out = OPENFLAGS();
13943  
13944 -       if(!access(file, W_OK)) *mode_out = of_write(*mode_out);
13945 -       else if(errno != EACCES) 
13946 -               return(-errno);
13947 +       err = os_access(file, OS_ACC_W_OK);
13948 +       if((err < 0) && (err != -EACCES))
13949 +               return(err);
13950  
13951 -       if(!access(file, R_OK)) *mode_out = of_read(*mode_out);
13952 -       else if(errno != EACCES) 
13953 -               return(-errno);
13954 +       *mode_out = of_write(*mode_out);
13955 +
13956 +       err = os_access(file, OS_ACC_R_OK);
13957 +       if((err < 0) && (err != -EACCES))
13958 +               return(err);
13959 +
13960 +       *mode_out = of_read(*mode_out);
13961  
13962         return(0);
13963  }
13964 @@ -63,16 +267,14 @@
13965         if(flags.e) f |= O_EXCL;
13966  
13967         fd = open64(file, f, mode);
13968 -       if(fd < 0) return(-errno);
13969 -       
13970 -       if(flags.cl){
13971 -               if(fcntl(fd, F_SETFD, 1)){
13972 -                       close(fd);
13973 -                       return(-errno);
13974 -               }
13975 +       if(fd < 0)
13976 +               return(-errno);
13977 +
13978 +       if(flags.cl && fcntl(fd, F_SETFD, 1)){
13979 +               os_close_file(fd);
13980 +               return(-errno);
13981         }
13982  
13983 -       return(fd);
13984         return(fd);
13985  }
13986  
13987 @@ -90,7 +292,7 @@
13988  
13989         err = connect(fd, (struct sockaddr *) &sock, sizeof(sock));
13990         if(err)
13991 -               return(err);
13992 +               return(-errno);
13993  
13994         return(fd);
13995  }
13996 @@ -109,88 +311,162 @@
13997         return(0);
13998  }
13999  
14000 -int os_read_file(int fd, void *buf, int len)
14001 +static int fault_buffer(void *start, int len, 
14002 +                       int (*copy_proc)(void *addr, void *buf, int len))
14003  {
14004 -       int n;
14005 +       int page = getpagesize(), i;
14006 +       char c;
14007  
14008 -       /* Force buf into memory if it's not already. */
14009 +       for(i = 0; i < len; i += page){
14010 +               if((*copy_proc)(start + i, &c, sizeof(c)))
14011 +                       return(-EFAULT);
14012 +       }
14013 +       if((len % page) != 0){
14014 +               if((*copy_proc)(start + len - 1, &c, sizeof(c)))
14015 +                       return(-EFAULT);
14016 +       }
14017 +       return(0);
14018 +}
14019  
14020 -       /* XXX This fails if buf is kernel memory */
14021 -#ifdef notdef
14022 -       if(copy_to_user_proc(buf, &c, sizeof(c)))
14023 -               return(-EFAULT);
14024 -#endif
14025 +static int file_io(int fd, void *buf, int len,
14026 +                  int (*io_proc)(int fd, void *buf, int len),
14027 +                  int (*copy_user_proc)(void *addr, void *buf, int len))
14028 +{
14029 +       int n, err;
14030 +
14031 +       do {
14032 +               n = (*io_proc)(fd, buf, len);
14033 +               if((n < 0) && (errno == EFAULT)){
14034 +                       err = fault_buffer(buf, len, copy_user_proc);
14035 +                       if(err)
14036 +                               return(err);
14037 +                       n = (*io_proc)(fd, buf, len);
14038 +               }
14039 +       } while((n < 0) && (errno == EINTR));
14040  
14041 -       n = read(fd, buf, len);
14042         if(n < 0)
14043                 return(-errno);
14044         return(n);
14045  }
14046  
14047 -int os_write_file(int fd, void *buf, int count)
14048 +int os_read_file(int fd, void *buf, int len)
14049  {
14050 -       int n;
14051 -
14052 -       /* Force buf into memory if it's not already. */
14053 -       
14054 -       /* XXX This fails if buf is kernel memory */
14055 -#ifdef notdef
14056 -       if(copy_to_user_proc(buf, buf, buf[0]))
14057 -               return(-EFAULT);
14058 -#endif
14059 +       return(file_io(fd, buf, len, (int (*)(int, void *, int)) read, 
14060 +                      copy_from_user_proc));
14061 +}
14062  
14063 -       n = write(fd, buf, count);
14064 -       if(n < 0)
14065 -               return(-errno);
14066 -       return(n);
14067 +int os_write_file(int fd, const void *buf, int len)
14068 +{
14069 +       return(file_io(fd, (void *) buf, len, 
14070 +                      (int (*)(int, void *, int)) write, copy_to_user_proc));
14071  }
14072  
14073  int os_file_size(char *file, long long *size_out)
14074  {
14075 -       struct stat64 buf;
14076 +       struct uml_stat buf;
14077 +       int err;
14078  
14079 -       if(stat64(file, &buf) == -1){
14080 -               printk("Couldn't stat \"%s\" : errno = %d\n", file, errno);
14081 -               return(-errno);
14082 +       err = os_stat_file(file, &buf);
14083 +       if(err < 0){
14084 +               printk("Couldn't stat \"%s\" : err = %d\n", file, -err);
14085 +               return(err);
14086         }
14087 -       if(S_ISBLK(buf.st_mode)){
14088 +
14089 +       if(S_ISBLK(buf.ust_mode)){
14090                 int fd, blocks;
14091  
14092 -               if((fd = open64(file, O_RDONLY)) < 0){
14093 -                       printk("Couldn't open \"%s\", errno = %d\n", file,
14094 -                              errno);
14095 -                       return(-errno);
14096 +               fd = os_open_file(file, of_read(OPENFLAGS()), 0);
14097 +               if(fd < 0){
14098 +                       printk("Couldn't open \"%s\", errno = %d\n", file, -fd);
14099 +                       return(fd);
14100                 }
14101                 if(ioctl(fd, BLKGETSIZE, &blocks) < 0){
14102                         printk("Couldn't get the block size of \"%s\", "
14103                                "errno = %d\n", file, errno);
14104 -                       close(fd);
14105 -                       return(-errno);
14106 +                       err = -errno;
14107 +                       os_close_file(fd);
14108 +                       return(err);
14109                 }
14110                 *size_out = ((long long) blocks) * 512;
14111 -               close(fd);
14112 +               os_close_file(fd);
14113                 return(0);
14114         }
14115 -       *size_out = buf.st_size;
14116 +       *size_out = buf.ust_size;
14117 +       return(0);
14118 +}
14119 +
14120 +int os_file_modtime(char *file, unsigned long *modtime)
14121 +{
14122 +       struct uml_stat buf;
14123 +       int err;
14124 +
14125 +       err = os_stat_file(file, &buf);
14126 +       if(err < 0){
14127 +               printk("Couldn't stat \"%s\" : err = %d\n", file, -err);
14128 +               return(err);
14129 +       }
14130 +
14131 +       *modtime = buf.ust_mtime;
14132         return(0);
14133  }
14134  
14135 +int os_get_exec_close(int fd, int* close_on_exec)
14136 +{
14137 +       int ret;
14138 +
14139 +       do {
14140 +               ret = fcntl(fd, F_GETFD);
14141 +       } while((ret < 0) && (errno == EINTR)) ;
14142 +
14143 +       if(ret < 0)
14144 +               return(-errno);
14145 +
14146 +       *close_on_exec = (ret&FD_CLOEXEC) ? 1 : 0;
14147 +       return(ret);
14148 +}
14149 +
14150 +int os_set_exec_close(int fd, int close_on_exec)
14151 +{
14152 +       int flag, err;
14153 +
14154 +       if(close_on_exec) flag = FD_CLOEXEC;
14155 +       else flag = 0;
14156 +
14157 +       do {
14158 +               err = fcntl(fd, F_SETFD, flag);
14159 +       } while((err < 0) && (errno == EINTR)) ;
14160 +
14161 +       if(err < 0)
14162 +               return(-errno);
14163 +       return(err);
14164 +}
14165 +
14166  int os_pipe(int *fds, int stream, int close_on_exec)
14167  {
14168         int err, type = stream ? SOCK_STREAM : SOCK_DGRAM;
14169  
14170         err = socketpair(AF_UNIX, type, 0, fds);
14171 -       if(err) 
14172 +       if(err < 0) 
14173                 return(-errno);
14174  
14175         if(!close_on_exec)
14176                 return(0);
14177  
14178 -       if((fcntl(fds[0], F_SETFD, 1) < 0) || (fcntl(fds[1], F_SETFD, 1) < 0))
14179 -               printk("os_pipe : Setting FD_CLOEXEC failed, errno = %d", 
14180 -                      errno);
14181 +       err = os_set_exec_close(fds[0], 1);
14182 +       if(err < 0)
14183 +               goto error;
14184 +
14185 +       err = os_set_exec_close(fds[1], 1);
14186 +       if(err < 0)
14187 +               goto error;
14188  
14189         return(0);
14190 +
14191 + error:
14192 +       printk("os_pipe : Setting FD_CLOEXEC failed, err = %d\n", -err);
14193 +       os_close_file(fds[1]);
14194 +       os_close_file(fds[0]);
14195 +       return(err);
14196  }
14197  
14198  int os_set_fd_async(int fd, int owner)
14199 @@ -270,7 +546,7 @@
14200                 return(-EINVAL);
14201         }
14202         err = shutdown(fd, what);
14203 -       if(err)
14204 +       if(err < 0)
14205                 return(-errno);
14206         return(0);
14207  }
14208 @@ -315,7 +591,7 @@
14209         return(new);
14210  }
14211  
14212 -int create_unix_socket(char *file, int len)
14213 +int os_create_unix_socket(char *file, int len, int close_on_exec)
14214  {
14215         struct sockaddr_un addr;
14216         int sock, err;
14217 @@ -327,6 +603,13 @@
14218                 return(-errno);
14219         }
14220  
14221 +       if(close_on_exec) {
14222 +               err = os_set_exec_close(sock, 1);
14223 +               if(err < 0)
14224 +                       printk("create_unix_socket : close_on_exec failed, "
14225 +                      "err = %d", -err);
14226 +       }
14227 +
14228         addr.sun_family = AF_UNIX;
14229  
14230         /* XXX Be more careful about overflow */
14231 @@ -334,14 +617,45 @@
14232  
14233         err = bind(sock, (struct sockaddr *) &addr, sizeof(addr));
14234         if (err < 0){
14235 -               printk("create_listening_socket - bind failed, errno = %d\n",
14236 -                      errno);
14237 +               printk("create_listening_socket at '%s' - bind failed, "
14238 +                      "errno = %d\n", file, errno);
14239                 return(-errno);
14240         }
14241  
14242         return(sock);
14243  }
14244  
14245 +void os_flush_stdout(void)
14246 +{
14247 +       fflush(stdout);
14248 +}
14249 +
14250 +int os_lock_file(int fd, int excl)
14251 +{
14252 +       int type = excl ? F_WRLCK : F_RDLCK;
14253 +       struct flock lock = ((struct flock) { .l_type   = type,
14254 +                                             .l_whence = SEEK_SET,
14255 +                                             .l_start  = 0,
14256 +                                             .l_len    = 0 } );
14257 +       int err, save;
14258 +
14259 +       err = fcntl(fd, F_SETLK, &lock);
14260 +       if(!err)
14261 +               goto out;
14262 +
14263 +       save = -errno;
14264 +       err = fcntl(fd, F_GETLK, &lock);
14265 +       if(err){
14266 +               err = -errno;
14267 +               goto out;
14268 +       }
14269 +
14270 +       printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid);
14271 +       err = save;
14272 + out:
14273 +       return(err);
14274 +}
14275 +
14276  /*
14277   * Overrides for Emacs so that we follow Linus's tabbing style.
14278   * Emacs will notice this stuff at the end of the file and automatically
14279 diff -Naur a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
14280 --- a/arch/um/os-Linux/Makefile 2004-02-11 12:15:56.000000000 -0500
14281 +++ b/arch/um/os-Linux/Makefile 2004-02-11 12:27:48.000000000 -0500
14282 @@ -9,7 +9,3 @@
14283  
14284  $(USER_OBJS) : %.o: %.c
14285         $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
14286 -
14287 -clean :
14288 -
14289 -archmrproper:
14290 diff -Naur a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
14291 --- a/arch/um/os-Linux/process.c        2004-02-11 12:14:23.000000000 -0500
14292 +++ b/arch/um/os-Linux/process.c        2004-02-11 12:26:04.000000000 -0500
14293 @@ -1,5 +1,5 @@
14294  /* 
14295 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14296 + * Copyright (C) 2002 Jeff Dike (jdike@addtoit.com)
14297   * Licensed under the GPL
14298   */
14299  
14300 @@ -7,32 +7,37 @@
14301  #include <stdio.h>
14302  #include <errno.h>
14303  #include <signal.h>
14304 +#include <linux/unistd.h>
14305  #include <sys/mman.h>
14306  #include <sys/wait.h>
14307  #include "os.h"
14308  #include "user.h"
14309  
14310 +#define ARBITRARY_ADDR -1
14311 +#define FAILURE_PID    -1
14312 +
14313  unsigned long os_process_pc(int pid)
14314  {
14315         char proc_stat[sizeof("/proc/#####/stat\0")], buf[256];
14316         unsigned long pc;
14317 -       int fd;
14318 +       int fd, err;
14319  
14320         sprintf(proc_stat, "/proc/%d/stat", pid);
14321         fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0);
14322         if(fd < 0){
14323 -               printk("os_process_pc - couldn't open '%s', errno = %d\n", 
14324 -                      proc_stat, errno);
14325 -               return(-1);
14326 +               printk("os_process_pc - couldn't open '%s', err = %d\n", 
14327 +                      proc_stat, -fd);
14328 +               return(ARBITRARY_ADDR);
14329         }
14330 -       if(read(fd, buf, sizeof(buf)) < 0){
14331 -               printk("os_process_pc - couldn't read '%s', errno = %d\n", 
14332 -                      proc_stat, errno);
14333 -               close(fd);
14334 -               return(-1);
14335 +       err = os_read_file(fd, buf, sizeof(buf));
14336 +       if(err < 0){
14337 +               printk("os_process_pc - couldn't read '%s', err = %d\n", 
14338 +                      proc_stat, -err);
14339 +               os_close_file(fd);
14340 +               return(ARBITRARY_ADDR);
14341         }
14342 -       close(fd);
14343 -       pc = -1;
14344 +       os_close_file(fd);
14345 +       pc = ARBITRARY_ADDR;
14346         if(sscanf(buf, "%*d %*s %*c %*d %*d %*d %*d %*d %*d %*d %*d "
14347                   "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
14348                   "%*d %*d %*d %*d %ld", &pc) != 1){
14349 @@ -52,22 +57,23 @@
14350         snprintf(stat, sizeof(stat), "/proc/%d/stat", pid);
14351         fd = os_open_file(stat, of_read(OPENFLAGS()), 0);
14352         if(fd < 0){
14353 -               printk("Couldn't open '%s', errno = %d\n", stat, -fd);
14354 -               return(-1);
14355 +               printk("Couldn't open '%s', err = %d\n", stat, -fd);
14356 +               return(FAILURE_PID);
14357         }
14358  
14359 -       n = read(fd, data, sizeof(data));
14360 -       close(fd);
14361 +       n = os_read_file(fd, data, sizeof(data));
14362 +       os_close_file(fd);
14363  
14364         if(n < 0){
14365 -               printk("Couldn't read '%s', errno = %d\n", stat);
14366 -               return(-1);
14367 +               printk("Couldn't read '%s', err = %d\n", stat, -n);
14368 +               return(FAILURE_PID);
14369         }
14370  
14371 -       parent = -1;
14372 +       parent = FAILURE_PID;
14373         /* XXX This will break if there is a space in the command */
14374         n = sscanf(data, "%*d %*s %*c %d", &parent);
14375 -       if(n != 1) printk("Failed to scan '%s'\n", data);
14376 +       if(n != 1) 
14377 +               printk("Failed to scan '%s'\n", data);
14378  
14379         return(parent);
14380  }
14381 @@ -87,7 +93,8 @@
14382  
14383  void os_usr1_process(int pid)
14384  {
14385 -       kill(pid, SIGUSR1);
14386 +       syscall(__NR_tkill, pid, SIGUSR1); 
14387 +       /* kill(pid, SIGUSR1); */
14388  }
14389  
14390  int os_getpid(void)
14391 @@ -95,7 +102,7 @@
14392         return(getpid());
14393  }
14394  
14395 -int os_map_memory(void *virt, int fd, unsigned long off, unsigned long len, 
14396 +int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len,
14397                   int r, int w, int x)
14398  {
14399         void *loc;
14400 @@ -104,8 +111,8 @@
14401         prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 
14402                 (x ? PROT_EXEC : 0);
14403  
14404 -       loc = mmap((void *) virt, len, prot, MAP_SHARED | MAP_FIXED, 
14405 -                  fd, off);
14406 +       loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED, 
14407 +                    fd, off);
14408         if(loc == MAP_FAILED)
14409                 return(-errno);
14410         return(0);
14411 @@ -126,7 +133,8 @@
14412          int err;
14413  
14414          err = munmap(addr, len);
14415 -        if(err < 0) return(-errno);
14416 +       if(err < 0)
14417 +               return(-errno);
14418          return(0);
14419  }
14420  
14421 diff -Naur a/arch/um/os-Linux/tty.c b/arch/um/os-Linux/tty.c
14422 --- a/arch/um/os-Linux/tty.c    2004-02-11 12:15:53.000000000 -0500
14423 +++ b/arch/um/os-Linux/tty.c    2004-02-11 12:27:46.000000000 -0500
14424 @@ -28,10 +28,10 @@
14425         struct grantpt_info info;
14426         int fd;
14427  
14428 -       if((fd = os_open_file("/dev/ptmx", of_rdwr(OPENFLAGS()), 0)) < 0){
14429 -               printk("get_pty : Couldn't open /dev/ptmx - errno = %d\n",
14430 -                      errno);
14431 -               return(-1);
14432 +       fd = os_open_file("/dev/ptmx", of_rdwr(OPENFLAGS()), 0);
14433 +       if(fd < 0){
14434 +               printk("get_pty : Couldn't open /dev/ptmx - err = %d\n", -fd);
14435 +               return(fd);
14436         }
14437  
14438         info.fd = fd;
14439 @@ -39,7 +39,7 @@
14440  
14441         if(info.res < 0){
14442                 printk("get_pty : Couldn't grant pty - errno = %d\n", 
14443 -                      info.err);
14444 +                      -info.err);
14445                 return(-1);
14446         }
14447         if(unlockpt(fd) < 0){
14448 diff -Naur a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c
14449 --- a/arch/um/sys-i386/bugs.c   2004-02-11 12:16:28.000000000 -0500
14450 +++ b/arch/um/sys-i386/bugs.c   2004-02-11 12:28:27.000000000 -0500
14451 @@ -4,20 +4,21 @@
14452   */
14453  
14454  #include <unistd.h>
14455 -#include <fcntl.h>
14456  #include <errno.h>
14457  #include <string.h>
14458  #include <sys/signal.h>
14459 +#include <asm/ldt.h>
14460  #include "kern_util.h"
14461  #include "user.h"
14462  #include "sysdep/ptrace.h"
14463  #include "task.h"
14464 +#include "os.h"
14465  
14466  #define MAXTOKEN 64
14467  
14468  /* Set during early boot */
14469 -int cpu_has_cmov = 1;
14470 -int cpu_has_xmm = 0;
14471 +int host_has_cmov = 1;
14472 +int host_has_xmm = 0;
14473  
14474  static char token(int fd, char *buf, int len, char stop)
14475  {
14476 @@ -27,13 +28,15 @@
14477         ptr = buf;
14478         end = &buf[len];
14479         do {
14480 -               n = read(fd, ptr, sizeof(*ptr));
14481 +               n = os_read_file(fd, ptr, sizeof(*ptr));
14482                 c = *ptr++;
14483 -               if(n == 0) return(0);
14484 -               else if(n != sizeof(*ptr)){
14485 -                       printk("Reading /proc/cpuinfo failed, "
14486 -                              "errno = %d\n", errno);
14487 -                       return(-errno);
14488 +               if(n != sizeof(*ptr)){
14489 +                       if(n == 0) return(0);
14490 +                       printk("Reading /proc/cpuinfo failed, err = %d\n", -n);
14491 +                       if(n < 0) 
14492 +                               return(n);
14493 +                       else 
14494 +                               return(-EIO);
14495                 }
14496         } while((c != '\n') && (c != stop) && (ptr < end));
14497  
14498 @@ -45,45 +48,79 @@
14499         return(c);
14500  }
14501  
14502 -static int check_cpu_feature(char *feature, int *have_it)
14503 +static int find_cpuinfo_line(int fd, char *key, char *scratch, int len)
14504  {
14505 -       char buf[MAXTOKEN], c;
14506 -       int fd, len = sizeof(buf)/sizeof(buf[0]), n;
14507 -
14508 -       printk("Checking for host processor %s support...", feature);
14509 -       fd = open("/proc/cpuinfo", O_RDONLY);
14510 -       if(fd < 0){
14511 -               printk("Couldn't open /proc/cpuinfo, errno = %d\n", errno);
14512 -               return(0);
14513 -       }
14514 +       int n;
14515 +       char c;
14516  
14517 -       *have_it = 0;
14518 -       buf[len - 1] = '\0';
14519 +       scratch[len - 1] = '\0';
14520         while(1){
14521 -               c = token(fd, buf, len - 1, ':');
14522 -               if(c <= 0) goto out;
14523 +               c = token(fd, scratch, len - 1, ':');
14524 +               if(c <= 0)
14525 +                       return(0);
14526                 else if(c != ':'){
14527                         printk("Failed to find ':' in /proc/cpuinfo\n");
14528 -                       goto out;
14529 +                       return(0);
14530                 }
14531  
14532 -               if(!strncmp(buf, "flags", strlen("flags"))) break;
14533 +               if(!strncmp(scratch, key, strlen(key))) 
14534 +                       return(1);
14535  
14536                 do {
14537 -                       n = read(fd, &c, sizeof(c));
14538 +                       n = os_read_file(fd, &c, sizeof(c));
14539                         if(n != sizeof(c)){
14540                                 printk("Failed to find newline in "
14541 -                                      "/proc/cpuinfo, n = %d, errno = %d\n",
14542 -                                      n, errno);
14543 -                               goto out;
14544 +                                      "/proc/cpuinfo, err = %d\n", -n);
14545 +                               return(0);
14546                         }
14547                 } while(c != '\n');
14548         }
14549 +       return(0);
14550 +}
14551 +
14552 +int cpu_feature(char *what, char *buf, int len)
14553 +{
14554 +       int fd, ret = 0;
14555 +
14556 +       fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
14557 +       if(fd < 0){
14558 +               printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
14559 +               return(0);
14560 +       }
14561 +
14562 +       if(!find_cpuinfo_line(fd, what, buf, len)){
14563 +               printk("Couldn't find '%s' line in /proc/cpuinfo\n", what);
14564 +               goto out_close;
14565 +       }
14566 +
14567 +       token(fd, buf, len, '\n');
14568 +       ret = 1;
14569 +
14570 + out_close:
14571 +       os_close_file(fd);
14572 +       return(ret);
14573 +}
14574 +
14575 +static int check_cpu_flag(char *feature, int *have_it)
14576 +{
14577 +       char buf[MAXTOKEN], c;
14578 +       int fd, len = sizeof(buf)/sizeof(buf[0]);
14579 +
14580 +       printk("Checking for host processor %s support...", feature);
14581 +       fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
14582 +       if(fd < 0){
14583 +               printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd);
14584 +               return(0);
14585 +       }
14586 +
14587 +       *have_it = 0;
14588 +       if(!find_cpuinfo_line(fd, "flags", buf, sizeof(buf) / sizeof(buf[0])))
14589 +               goto out;
14590  
14591         c = token(fd, buf, len - 1, ' ');
14592         if(c < 0) goto out;
14593         else if(c != ' '){
14594 -               printk("Failed to find ':' in /proc/cpuinfo\n");
14595 +               printk("Failed to find ' ' in /proc/cpuinfo\n");
14596                 goto out;
14597         }
14598  
14599 @@ -100,21 +137,48 @@
14600   out:
14601         if(*have_it == 0) printk("No\n");
14602         else if(*have_it == 1) printk("Yes\n");
14603 -       close(fd);
14604 +       os_close_file(fd);
14605         return(1);
14606  }
14607  
14608 +#if 0 /* This doesn't work in tt mode, plus it's causing compilation problems
14609 +       * for some people.
14610 +       */
14611 +static void disable_lcall(void)
14612 +{
14613 +       struct modify_ldt_ldt_s ldt;
14614 +       int err;
14615 +
14616 +       bzero(&ldt, sizeof(ldt));
14617 +       ldt.entry_number = 7;
14618 +       ldt.base_addr = 0;
14619 +       ldt.limit = 0;
14620 +       err = modify_ldt(1, &ldt, sizeof(ldt));
14621 +       if(err)
14622 +               printk("Failed to disable lcall7 - errno = %d\n", errno);
14623 +}
14624 +#endif
14625 +
14626 +void arch_init_thread(void)
14627 +{
14628 +#if 0
14629 +       disable_lcall();
14630 +#endif
14631 +}
14632 +
14633  void arch_check_bugs(void)
14634  {
14635         int have_it;
14636  
14637 -       if(access("/proc/cpuinfo", R_OK)){
14638 +       if(os_access("/proc/cpuinfo", OS_ACC_R_OK) < 0){
14639                 printk("/proc/cpuinfo not available - skipping CPU capability "
14640                        "checks\n");
14641                 return;
14642         }
14643 -       if(check_cpu_feature("cmov", &have_it)) cpu_has_cmov = have_it;
14644 -       if(check_cpu_feature("xmm", &have_it)) cpu_has_xmm = have_it;
14645 +       if(check_cpu_flag("cmov", &have_it)) 
14646 +               host_has_cmov = have_it;
14647 +       if(check_cpu_flag("xmm", &have_it)) 
14648 +               host_has_xmm = have_it;
14649  }
14650  
14651  int arch_handle_signal(int sig, union uml_pt_regs *regs)
14652 @@ -130,18 +194,18 @@
14653         if((*((char *) ip) != 0x0f) || ((*((char *) (ip + 1)) & 0xf0) != 0x40))
14654                 return(0);
14655  
14656 -       if(cpu_has_cmov == 0)
14657 +       if(host_has_cmov == 0)
14658                 panic("SIGILL caused by cmov, which this processor doesn't "
14659                       "implement, boot a filesystem compiled for older "
14660                       "processors");
14661 -       else if(cpu_has_cmov == 1)
14662 +       else if(host_has_cmov == 1)
14663                 panic("SIGILL caused by cmov, which this processor claims to "
14664                       "implement");
14665 -       else if(cpu_has_cmov == -1)
14666 +       else if(host_has_cmov == -1)
14667                 panic("SIGILL caused by cmov, couldn't tell if this processor "
14668                       "implements it, boot a filesystem compiled for older "
14669                       "processors");
14670 -       else panic("Bad value for cpu_has_cmov (%d)", cpu_has_cmov);
14671 +       else panic("Bad value for host_has_cmov (%d)", host_has_cmov);
14672         return(0);
14673  }
14674  
14675 diff -Naur a/arch/um/sys-i386/extable.c b/arch/um/sys-i386/extable.c
14676 --- a/arch/um/sys-i386/extable.c        2004-02-11 12:16:45.000000000 -0500
14677 +++ b/arch/um/sys-i386/extable.c        1969-12-31 19:00:00.000000000 -0500
14678 @@ -1,30 +0,0 @@
14679 -/*
14680 - * linux/arch/i386/mm/extable.c
14681 - */
14682 -
14683 -#include <linux/config.h>
14684 -#include <linux/module.h>
14685 -#include <linux/spinlock.h>
14686 -#include <asm/uaccess.h>
14687 -
14688 -/* Simple binary search */
14689 -const struct exception_table_entry *
14690 -search_extable(const struct exception_table_entry *first,
14691 -              const struct exception_table_entry *last,
14692 -              unsigned long value)
14693 -{
14694 -        while (first <= last) {
14695 -               const struct exception_table_entry *mid;
14696 -               long diff;
14697 -
14698 -               mid = (last - first) / 2 + first;
14699 -               diff = mid->insn - value;
14700 -                if (diff == 0)
14701 -                        return mid;
14702 -                else if (diff < 0)
14703 -                        first = mid+1;
14704 -                else
14705 -                        last = mid-1;
14706 -        }
14707 -        return NULL;
14708 -}
14709 diff -Naur a/arch/um/sys-i386/fault.c b/arch/um/sys-i386/fault.c
14710 --- a/arch/um/sys-i386/fault.c  2004-02-11 12:15:44.000000000 -0500
14711 +++ b/arch/um/sys-i386/fault.c  2004-02-11 12:27:19.000000000 -0500
14712 @@ -1,5 +1,5 @@
14713  /* 
14714 - * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
14715 + * Copyright (C) 2002 - 2004 Jeff Dike (jdike@addtoit.com)
14716   * Licensed under the GPL
14717   */
14718  
14719 @@ -7,16 +7,24 @@
14720  #include "sysdep/ptrace.h"
14721  #include "sysdep/sigcontext.h"
14722  
14723 -extern unsigned long search_exception_table(unsigned long addr);
14724 +/* These two are from asm-um/uaccess.h and linux/module.h, check them. */
14725 +struct exception_table_entry
14726 +{
14727 +       unsigned long insn;
14728 +       unsigned long fixup;
14729 +};
14730  
14731 +const struct exception_table_entry *search_exception_tables(unsigned long add);
14732
14733 +/* Compare this to arch/i386/mm/extable.c:fixup_exception() */
14734  int arch_fixup(unsigned long address, void *sc_ptr)
14735  {
14736         struct sigcontext *sc = sc_ptr;
14737 -       unsigned long fixup;
14738 +       const struct exception_table_entry *fixup;
14739  
14740         fixup = search_exception_tables(address);
14741         if(fixup != 0){
14742 -               sc->eip = fixup;
14743 +               sc->eip = fixup->fixup;
14744                 return(1);
14745         }
14746         return(0);
14747 diff -Naur a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
14748 --- a/arch/um/sys-i386/Makefile 2004-02-11 12:14:27.000000000 -0500
14749 +++ b/arch/um/sys-i386/Makefile 2004-02-11 12:26:08.000000000 -0500
14750 @@ -1,7 +1,8 @@
14751 -obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o module.o \
14752 -       ptrace.o ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o
14753 +obj-y = bugs.o checksum.o fault.o ksyms.o ldt.o ptrace.o ptrace_user.o \
14754 +       semaphore.o sigcontext.o syscalls.o sysrq.o time.o
14755  
14756  obj-$(CONFIG_HIGHMEM) += highmem.o
14757 +obj-$(CONFIG_MODULES) += module.o
14758  
14759  USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o
14760  USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
14761 @@ -9,6 +10,8 @@
14762  SYMLINKS = semaphore.c highmem.c module.c
14763  SYMLINKS := $(foreach f,$(SYMLINKS),$(src)/$f)
14764  
14765 +clean-files := $(SYMLINKS)
14766 +
14767  semaphore.c-dir = kernel
14768  highmem.c-dir = mm
14769  module.c-dir = kernel
14770 @@ -24,19 +27,4 @@
14771  $(SYMLINKS): 
14772         $(call make_link,$@)
14773  
14774 -clean:
14775 -       $(MAKE) -C util clean
14776 -
14777 -fastdep:
14778 -
14779 -dep:
14780 -
14781 -archmrproper:
14782 -       rm -f $(SYMLINKS)
14783 -
14784 -archclean:
14785 -
14786 -archdep:
14787 -
14788 -modules:
14789 -
14790 +subdir- := util
14791 diff -Naur a/arch/um/sys-i386/ptrace_user.c b/arch/um/sys-i386/ptrace_user.c
14792 --- a/arch/um/sys-i386/ptrace_user.c    2004-02-11 12:14:33.000000000 -0500
14793 +++ b/arch/um/sys-i386/ptrace_user.c    2004-02-11 12:26:15.000000000 -0500
14794 @@ -39,10 +39,10 @@
14795         nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]);
14796         for(i = 0; i < nregs; i++){
14797                 if((i == 4) || (i == 5)) continue;
14798 -               if(ptrace(PTRACE_POKEUSR, pid, &dummy->u_debugreg[i],
14799 +               if(ptrace(PTRACE_POKEUSER, pid, &dummy->u_debugreg[i],
14800                           regs[i]) < 0)
14801 -                       printk("write_debugregs - ptrace failed, "
14802 -                              "errno = %d\n", errno);
14803 +                       printk("write_debugregs - ptrace failed on "
14804 +                              "register %d, errno = %d\n", errno);
14805         }
14806  }
14807  
14808 @@ -54,7 +54,7 @@
14809         dummy = NULL;
14810         nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]);
14811         for(i = 0; i < nregs; i++){
14812 -               regs[i] = ptrace(PTRACE_PEEKUSR, pid, 
14813 +               regs[i] = ptrace(PTRACE_PEEKUSER, pid, 
14814                                  &dummy->u_debugreg[i], 0);
14815         }
14816  }
14817 diff -Naur a/arch/um/sys-i386/time.c b/arch/um/sys-i386/time.c
14818 --- a/arch/um/sys-i386/time.c   1969-12-31 19:00:00.000000000 -0500
14819 +++ b/arch/um/sys-i386/time.c   2004-02-11 12:26:16.000000000 -0500
14820 @@ -0,0 +1,24 @@
14821 +/*
14822 + * sys-i386/time.c 
14823 + * Created             25.9.2002       Sapan Bhatia
14824 + *
14825 + */
14826 +
14827 +unsigned long long time_stamp(void)
14828 +{
14829 +       unsigned long low, high;
14830 +
14831 +       asm("rdtsc" : "=a" (low), "=d" (high));
14832 +       return((((unsigned long long) high) << 32) + low);
14833 +}
14834 +
14835 +/*
14836 + * Overrides for Emacs so that we follow Linus's tabbing style.
14837 + * Emacs will notice this stuff at the end of the file and automatically
14838 + * adjust the settings for this buffer only.  This must remain at the end
14839 + * of the file.
14840 + * ---------------------------------------------------------------------------
14841 + * Local variables:
14842 + * c-file-style: "linux"
14843 + * End:
14844 + */
14845 diff -Naur a/arch/um/sys-i386/util/Makefile b/arch/um/sys-i386/util/Makefile
14846 --- a/arch/um/sys-i386/util/Makefile    2004-02-11 12:16:48.000000000 -0500
14847 +++ b/arch/um/sys-i386/util/Makefile    2004-02-11 12:29:04.000000000 -0500
14848 @@ -1,15 +1,10 @@
14849 +host-progs     := mk_sc mk_thread
14850 +always         := $(host-progs)
14851  
14852 -host-progs     := mk_sc
14853 -always         := $(host-progs) mk_thread
14854 -targets                := mk_thread_kern.o mk_thread_user.o
14855 +mk_thread-objs := mk_thread_kern.o mk_thread_user.o
14856  
14857 -mk_sc-objs     := mk_sc.o
14858 -
14859 -$(obj)/mk_thread : $(obj)/mk_thread_kern.o $(obj)/mk_thread_user.o
14860 -       $(CC) $(CFLAGS) -o $@ $^
14861 -
14862 -$(obj)/mk_thread_user.o : $(src)/mk_thread_user.c
14863 -       $(CC) $(USER_CFLAGS) -c -o $@ $<
14864 +HOSTCFLAGS_mk_thread_kern.o    := $(CFLAGS)
14865 +HOSTCFLAGS_mk_thread_user.o    := $(USER_CFLAGS)
14866  
14867  clean :
14868         $(RM) -f $(build-targets)
14869 diff -Naur a/arch/um/sys-i386/util/mk_sc.c b/arch/um/sys-i386/util/mk_sc.c
14870 --- a/arch/um/sys-i386/util/mk_sc.c     2004-02-11 12:16:38.000000000 -0500
14871 +++ b/arch/um/sys-i386/util/mk_sc.c     2004-02-11 12:28:37.000000000 -0500
14872 @@ -38,6 +38,7 @@
14873    SC_OFFSET("SC_ERR", err);
14874    SC_OFFSET("SC_CR2", cr2);
14875    SC_OFFSET("SC_FPSTATE", fpstate);
14876 +  SC_OFFSET("SC_SIGMASK", oldmask);
14877    SC_FP_OFFSET("SC_FP_CW", cw);
14878    SC_FP_OFFSET("SC_FP_SW", sw);
14879    SC_FP_OFFSET("SC_FP_TAG", tag);
14880 diff -Naur a/arch/um/sys-ia64/Makefile b/arch/um/sys-ia64/Makefile
14881 --- a/arch/um/sys-ia64/Makefile 2004-02-11 12:14:16.000000000 -0500
14882 +++ b/arch/um/sys-ia64/Makefile 2004-02-11 12:25:43.000000000 -0500
14883 @@ -7,18 +7,5 @@
14884  $(OBJ): $(OBJS)
14885         rm -f $@
14886         $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@
14887 -clean:
14888 -       rm -f $(OBJS)
14889  
14890 -fastdep:
14891 -
14892 -archmrproper:
14893 -
14894 -archclean:
14895 -       rm -f link.ld
14896 -       @$(MAKEBOOT) clean
14897 -
14898 -archdep:
14899 -       @$(MAKEBOOT) dep
14900 -
14901 -modules:
14902 +clean-files := $(OBJS) link.ld
14903 diff -Naur a/arch/um/sys-ppc/Makefile b/arch/um/sys-ppc/Makefile
14904 --- a/arch/um/sys-ppc/Makefile  2004-02-11 12:15:23.000000000 -0500
14905 +++ b/arch/um/sys-ppc/Makefile  2004-02-11 12:27:11.000000000 -0500
14906 @@ -66,13 +66,4 @@
14907         $(CC) $(EXTRA_AFLAGS) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o
14908         rm -f asm
14909  
14910 -clean:
14911 -       rm -f $(OBJS)
14912 -       rm -f ppc_defs.h
14913 -       rm -f checksum.S semaphore.c mk_defs.c
14914 -
14915 -fastdep:
14916 -
14917 -dep:
14918 -
14919 -modules:
14920 +clean-files := $(OBJS) ppc_defs.h checksum.S semaphore.c mk_defs.c
14921 diff -Naur a/arch/um/uml.lds.S b/arch/um/uml.lds.S
14922 --- a/arch/um/uml.lds.S 2004-02-11 12:15:21.000000000 -0500
14923 +++ b/arch/um/uml.lds.S 2004-02-11 12:27:08.000000000 -0500
14924 @@ -9,7 +9,6 @@
14925  {
14926    . = START + SIZEOF_HEADERS;
14927  
14928 -  . = ALIGN(4096);
14929    __binary_start = .;
14930  #ifdef MODE_TT
14931    .thread_private : {
14932 @@ -26,7 +25,11 @@
14933    . = ALIGN(4096);             /* Init code and data */
14934    _stext = .;
14935    __init_begin = .;
14936 -  .text.init : { *(.text.init) }
14937 +  .init.text : { 
14938 +       _sinittext = .;
14939 +       *(.init.text)
14940 +       _einittext = .;
14941 +  }
14942    . = ALIGN(4096);
14943    .text      :
14944    {
14945 @@ -38,7 +41,7 @@
14946  
14947    #include "asm/common.lds.S"
14948  
14949 -  .data.init : { *(.data.init) }
14950 +  init.data : { *(init.data) }
14951    .data    :
14952    {
14953      . = ALIGN(KERNEL_STACK_SIZE);              /* init_task */
14954 diff -Naur a/arch/um/util/Makefile b/arch/um/util/Makefile
14955 --- a/arch/um/util/Makefile     2004-02-11 12:17:07.000000000 -0500
14956 +++ b/arch/um/util/Makefile     2004-02-11 12:29:10.000000000 -0500
14957 @@ -1,23 +1,8 @@
14958 -always         := mk_task mk_constants
14959 -targets                := mk_task_user.o mk_task_kern.o \
14960 -                  mk_constants_user.o mk_constants_kern.o
14961 +host-progs             := mk_task mk_constants
14962 +always                 := $(host-progs)
14963  
14964 -$(obj)/mk_task: $(obj)/mk_task_user.o $(obj)/mk_task_kern.o
14965 -       $(CC) -o $@ $^
14966 +mk_task-objs           := mk_task_user.o mk_task_kern.o
14967 +mk_constants-objs      := mk_constants_user.o mk_constants_kern.o
14968  
14969 -$(obj)/mk_task_user.o: $(src)/mk_task_user.c
14970 -       $(CC) -o $@ -c $< 
14971 -
14972 -$(obj)/mk_constants : $(obj)/mk_constants_user.o $(obj)/mk_constants_kern.o
14973 -       $(CC) -o $@ $^
14974 -
14975 -$(obj)/mk_constants_user.o : $(src)/mk_constants_user.c
14976 -       $(CC) -c $< -o $@
14977 -
14978 -$(obj)/mk_constants_kern.o : $(src)/mk_constants_kern.c
14979 -       $(CC) $(CFLAGS) -c $< -o $@
14980 -
14981 -clean:
14982 -       $(RM) $(build-targets)
14983 -
14984 -archmrproper:
14985 +HOSTCFLAGS_mk_task_kern.o      := $(CFLAGS)
14986 +HOSTCFLAGS_mk_constants_kern.o := $(CFLAGS)
14987 diff -Naur a/arch/um/util/mk_constants_kern.c b/arch/um/util/mk_constants_kern.c
14988 --- a/arch/um/util/mk_constants_kern.c  2004-02-11 12:14:19.000000000 -0500
14989 +++ b/arch/um/util/mk_constants_kern.c  2004-02-11 12:26:02.000000000 -0500
14990 @@ -1,5 +1,6 @@
14991  #include "linux/kernel.h"
14992  #include "linux/stringify.h"
14993 +#include "linux/time.h"
14994  #include "asm/page.h"
14995  
14996  extern void print_head(void);
14997 @@ -11,6 +12,7 @@
14998  {
14999    print_head();
15000    print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE);
15001 +
15002    print_constant_str("UM_KERN_EMERG", KERN_EMERG);
15003    print_constant_str("UM_KERN_ALERT", KERN_ALERT);
15004    print_constant_str("UM_KERN_CRIT", KERN_CRIT);
15005 @@ -19,6 +21,8 @@
15006    print_constant_str("UM_KERN_NOTICE", KERN_NOTICE);
15007    print_constant_str("UM_KERN_INFO", KERN_INFO);
15008    print_constant_str("UM_KERN_DEBUG", KERN_DEBUG);
15009 +
15010 +  print_constant_int("UM_NSEC_PER_SEC", NSEC_PER_SEC);
15011    print_tail();
15012    return(0);
15013  }
15014 diff -Naur a/drivers/base/Makefile b/drivers/base/Makefile
15015 --- a/drivers/base/Makefile     2004-02-11 12:16:32.000000000 -0500
15016 +++ b/drivers/base/Makefile     2004-02-11 12:28:31.000000000 -0500
15017 @@ -2,7 +2,8 @@
15018  
15019  obj-y                  := core.o sys.o interface.o bus.o \
15020                            driver.o class.o class_simple.o platform.o \
15021 -                          cpu.o firmware.o init.o map.o dmapool.o
15022 +                          cpu.o firmware.o init.o map.o
15023  obj-y                  += power/
15024  obj-$(CONFIG_FW_LOADER)        += firmware_class.o
15025  obj-$(CONFIG_NUMA)     += node.o
15026 +obj-$(CONFIG_PCI)      += dmapool.o
15027 diff -Naur a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h
15028 --- a/fs/hostfs/hostfs.h        1969-12-31 19:00:00.000000000 -0500
15029 +++ b/fs/hostfs/hostfs.h        2004-02-11 12:25:42.000000000 -0500
15030 @@ -0,0 +1,79 @@
15031 +#ifndef __UM_FS_HOSTFS
15032 +#define __UM_FS_HOSTFS
15033 +
15034 +#include "os.h"
15035 +
15036 +/* These are exactly the same definitions as in fs.h, but the names are 
15037 + * changed so that this file can be included in both kernel and user files.
15038 + */
15039 +
15040 +#define HOSTFS_ATTR_MODE       1
15041 +#define HOSTFS_ATTR_UID        2
15042 +#define HOSTFS_ATTR_GID        4
15043 +#define HOSTFS_ATTR_SIZE       8
15044 +#define HOSTFS_ATTR_ATIME      16
15045 +#define HOSTFS_ATTR_MTIME      32
15046 +#define HOSTFS_ATTR_CTIME      64
15047 +#define HOSTFS_ATTR_ATIME_SET  128
15048 +#define HOSTFS_ATTR_MTIME_SET  256
15049 +#define HOSTFS_ATTR_FORCE      512     /* Not a change, but a change it */
15050 +#define HOSTFS_ATTR_ATTR_FLAG  1024
15051 +
15052 +struct hostfs_iattr {
15053 +       unsigned int    ia_valid;
15054 +       mode_t          ia_mode;
15055 +       uid_t           ia_uid;
15056 +       gid_t           ia_gid;
15057 +       loff_t          ia_size;
15058 +       struct timespec ia_atime;
15059 +       struct timespec ia_mtime;
15060 +       struct timespec ia_ctime;
15061 +       unsigned int    ia_attr_flags;
15062 +};
15063 +
15064 +extern int stat_file(const char *path, unsigned long long *inode_out, 
15065 +                    int *mode_out, int *nlink_out, int *uid_out, int *gid_out,
15066 +                    unsigned long long *size_out, struct timespec *atime_out, 
15067 +                    struct timespec *mtime_out, struct timespec *ctime_out, 
15068 +                    int *blksize_out, unsigned long long *blocks_out);
15069 +extern int access_file(char *path, int r, int w, int x);
15070 +extern int open_file(char *path, int r, int w, int append);
15071 +extern int file_type(const char *path, int *rdev);
15072 +extern void *open_dir(char *path, int *err_out);
15073 +extern char *read_dir(void *stream, unsigned long long *pos, 
15074 +                     unsigned long long *ino_out, int *len_out);
15075 +extern void close_file(void *stream);
15076 +extern void close_dir(void *stream);
15077 +extern int read_file(int fd, unsigned long long *offset, char *buf, int len);
15078 +extern int write_file(int fd, unsigned long long *offset, const char *buf,
15079 +                     int len);
15080 +extern int lseek_file(int fd, long long offset, int whence);
15081 +extern int file_create(char *name, int ur, int uw, int ux, int gr, 
15082 +                      int gw, int gx, int or, int ow, int ox);
15083 +extern int set_attr(const char *file, struct hostfs_iattr *attrs);
15084 +extern int make_symlink(const char *from, const char *to);
15085 +extern int unlink_file(const char *file);
15086 +extern int do_mkdir(const char *file, int mode);
15087 +extern int do_rmdir(const char *file);
15088 +extern int do_mknod(const char *file, int mode, int dev);
15089 +extern int link_file(const char *from, const char *to);
15090 +extern int do_readlink(char *file, char *buf, int size);
15091 +extern int rename_file(char *from, char *to);
15092 +extern int do_statfs(char *root, long *bsize_out, long long *blocks_out, 
15093 +                    long long *bfree_out, long long *bavail_out, 
15094 +                    long long *files_out, long long *ffree_out, 
15095 +                    void *fsid_out, int fsid_size, long *namelen_out, 
15096 +                    long *spare_out);
15097 +
15098 +#endif
15099 +
15100 +/*
15101 + * Overrides for Emacs so that we follow Linus's tabbing style.
15102 + * Emacs will notice this stuff at the end of the file and automatically
15103 + * adjust the settings for this buffer only.  This must remain at the end
15104 + * of the file.
15105 + * ---------------------------------------------------------------------------
15106 + * Local variables:
15107 + * c-file-style: "linux"
15108 + * End:
15109 + */
15110 diff -Naur a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
15111 --- a/fs/hostfs/hostfs_kern.c   1969-12-31 19:00:00.000000000 -0500
15112 +++ b/fs/hostfs/hostfs_kern.c   2004-02-11 12:25:59.000000000 -0500
15113 @@ -0,0 +1,1008 @@
15114 +/* 
15115 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
15116 + * Licensed under the GPL
15117 + *
15118 + * Ported the filesystem routines to 2.5.
15119 + * 2003-02-10 Petr Baudis <pasky@ucw.cz>
15120 + */
15121 +
15122 +#include <linux/stddef.h>
15123 +#include <linux/fs.h>
15124 +#include <linux/version.h>
15125 +#include <linux/module.h>
15126 +#include <linux/init.h>
15127 +#include <linux/slab.h>
15128 +#include <linux/pagemap.h>
15129 +#include <linux/blkdev.h>
15130 +#include <linux/list.h>
15131 +#include <linux/buffer_head.h>
15132 +#include <linux/root_dev.h>
15133 +#include <linux/statfs.h>
15134 +#include <asm/uaccess.h>
15135 +#include "hostfs.h"
15136 +#include "kern_util.h"
15137 +#include "kern.h"
15138 +#include "user_util.h"
15139 +#include "2_5compat.h"
15140 +#include "init.h"
15141 +
15142 +struct hostfs_inode_info {
15143 +       char *host_filename;
15144 +       int fd;
15145 +       int mode;
15146 +       struct inode vfs_inode;
15147 +};
15148 +
15149 +static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode)
15150 +{
15151 +       return(list_entry(inode, struct hostfs_inode_info, vfs_inode));
15152 +}
15153 +
15154 +#define FILE_HOSTFS_I(file) HOSTFS_I((file)->f_dentry->d_inode)
15155 +
15156 +int hostfs_d_delete(struct dentry *dentry)
15157 +{
15158 +       return(1);
15159 +}
15160 +
15161 +struct dentry_operations hostfs_dentry_ops = {
15162 +       .d_delete               = hostfs_d_delete,
15163 +};
15164 +
15165 +/* Changed in hostfs_args before the kernel starts running */
15166 +static char *root_ino = "/";
15167 +static int append = 0;
15168 +
15169 +#define HOSTFS_SUPER_MAGIC 0x00c0ffee
15170 +
15171 +static struct inode_operations hostfs_iops;
15172 +static struct inode_operations hostfs_dir_iops;
15173 +static struct address_space_operations hostfs_link_aops;
15174 +
15175 +static int __init hostfs_args(char *options, int *add)
15176 +{
15177 +       char *ptr;
15178 +
15179 +       ptr = strchr(options, ',');
15180 +       if(ptr != NULL)
15181 +               *ptr++ = '\0';
15182 +       if(*options != '\0')
15183 +               root_ino = options;
15184 +
15185 +       options = ptr;
15186 +       while(options){
15187 +               ptr = strchr(options, ',');
15188 +               if(ptr != NULL)
15189 +                       *ptr++ = '\0';
15190 +               if(*options != '\0'){
15191 +                       if(!strcmp(options, "append"))
15192 +                               append = 1;
15193 +                       else printf("hostfs_args - unsupported option - %s\n",
15194 +                                   options);
15195 +               }
15196 +               options = ptr;
15197 +       }
15198 +       return(0);
15199 +}
15200 +
15201 +__uml_setup("hostfs=", hostfs_args,
15202 +"hostfs=<root dir>,<flags>,...\n"
15203 +"    This is used to set hostfs parameters.  The root directory argument\n"
15204 +"    is used to confine all hostfs mounts to within the specified directory\n"
15205 +"    tree on the host.  If this isn't specified, then a user inside UML can\n"
15206 +"    mount anything on the host that's accessible to the user that's running\n"
15207 +"    it.\n"
15208 +"    The only flag currently supported is 'append', which specifies that all\n"
15209 +"    files opened by hostfs will be opened in append mode.\n\n"
15210 +);
15211 +
15212 +static char *dentry_name(struct dentry *dentry, int extra)
15213 +{
15214 +       struct dentry *parent;
15215 +       char *root, *name;
15216 +       int len;
15217 +
15218 +       len = 0;
15219 +       parent = dentry;
15220 +       while(parent->d_parent != parent){
15221 +               len += parent->d_name.len + 1;
15222 +               parent = parent->d_parent;
15223 +       }
15224 +       
15225 +       root = HOSTFS_I(parent->d_inode)->host_filename;
15226 +       len += strlen(root);
15227 +       name = kmalloc(len + extra + 1, GFP_KERNEL);
15228 +       if(name == NULL) return(NULL);
15229 +
15230 +       name[len] = '\0';
15231 +       parent = dentry;
15232 +       while(parent->d_parent != parent){
15233 +               len -= parent->d_name.len + 1;
15234 +               name[len] = '/';
15235 +               strncpy(&name[len + 1], parent->d_name.name, 
15236 +                       parent->d_name.len);
15237 +               parent = parent->d_parent;
15238 +       }
15239 +       strncpy(name, root, strlen(root));
15240 +       return(name);
15241 +}
15242 +
15243 +static char *inode_name(struct inode *ino, int extra)
15244 +{
15245 +       struct dentry *dentry;
15246 +
15247 +       dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias);
15248 +       return(dentry_name(dentry, extra));
15249 +}
15250 +
15251 +static int read_name(struct inode *ino, char *name)
15252 +{
15253 +       /* The non-int inode fields are copied into ints by stat_file and
15254 +        * then copied into the inode because passing the actual pointers
15255 +        * in and having them treated as int * breaks on big-endian machines
15256 +        */
15257 +       int err;
15258 +       int i_mode, i_nlink, i_blksize;
15259 +       unsigned long long i_size;
15260 +       unsigned long long i_ino;
15261 +       unsigned long long i_blocks;
15262 +
15263 +       err = stat_file(name, &i_ino, &i_mode, &i_nlink, &ino->i_uid, 
15264 +                       &ino->i_gid, &i_size, &ino->i_atime, &ino->i_mtime, 
15265 +                       &ino->i_ctime, &i_blksize, &i_blocks);
15266 +       if(err) 
15267 +               return(err);
15268 +
15269 +       ino->i_ino = i_ino;
15270 +       ino->i_mode = i_mode;
15271 +       ino->i_nlink = i_nlink;
15272 +       ino->i_size = i_size;
15273 +       ino->i_blksize = i_blksize;
15274 +       ino->i_blocks = i_blocks;
15275 +       if((ino->i_sb->s_dev == ROOT_DEV) && (ino->i_uid == getuid()))
15276 +               ino->i_uid = 0;
15277 +       return(0);
15278 +}
15279 +
15280 +static char *follow_link(char *link)
15281 +{
15282 +       int len, n;
15283 +       char *name, *resolved, *end;
15284 +
15285 +       len = 64;
15286 +       while(1){
15287 +               n = -ENOMEM;
15288 +               name = kmalloc(len, GFP_KERNEL);
15289 +               if(name == NULL)
15290 +                       goto out;
15291 +
15292 +               n = do_readlink(link, name, len);
15293 +               if(n < len)
15294 +                       break;
15295 +               len *= 2;
15296 +               kfree(name);
15297 +       }
15298 +       if(n < 0)
15299 +               goto out_free;
15300 +
15301 +       if(*name == '/')
15302 +               return(name);
15303 +
15304 +       end = strrchr(link, '/');
15305 +       if(end == NULL)
15306 +               return(name);
15307 +
15308 +       *(end + 1) = '\0';
15309 +       len = strlen(link) + strlen(name) + 1;
15310 +
15311 +       resolved = kmalloc(len, GFP_KERNEL);
15312 +       if(resolved == NULL){
15313 +               n = -ENOMEM;
15314 +               goto out_free;
15315 +       }
15316 +
15317 +       sprintf(resolved, "%s%s", link, name);
15318 +       kfree(name);
15319 +       kfree(link);
15320 +       return(resolved);
15321 +
15322 + out_free:
15323 +       kfree(name);
15324 + out:
15325 +       return(ERR_PTR(n));
15326 +}
15327 +
15328 +static int read_inode(struct inode *ino)
15329 +{
15330 +       char *name;
15331 +       int err = 0;
15332 +
15333 +       /* Unfortunately, we are called from iget() when we don't have a dentry
15334 +        * allocated yet.
15335 +        */
15336 +       if(list_empty(&ino->i_dentry))
15337 +               goto out;
15338
15339 +       err = -ENOMEM;
15340 +       name = inode_name(ino, 0);
15341 +       if(name == NULL) 
15342 +               goto out;
15343 +
15344 +       if(file_type(name, NULL) == OS_TYPE_SYMLINK){
15345 +               name = follow_link(name);
15346 +               if(IS_ERR(name)){
15347 +                       err = PTR_ERR(name);
15348 +                       goto out;
15349 +               }
15350 +       }
15351 +       
15352 +       err = read_name(ino, name);
15353 +       kfree(name);
15354 + out:
15355 +       return(err);
15356 +}
15357 +
15358 +int hostfs_statfs(struct super_block *sb, struct kstatfs *sf)
15359 +{
15360 +       /* do_statfs uses struct statfs64 internally, but the linux kernel
15361 +        * struct statfs still has 32-bit versions for most of these fields,
15362 +        * so we convert them here
15363 +        */
15364 +       int err;
15365 +       long long f_blocks;
15366 +       long long f_bfree;
15367 +       long long f_bavail;
15368 +       long long f_files;
15369 +       long long f_ffree;
15370 +
15371 +       err = do_statfs(HOSTFS_I(sb->s_root->d_inode)->host_filename,
15372 +                       &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files,
15373 +                       &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid), 
15374 +                       &sf->f_namelen, sf->f_spare);
15375 +       if(err) return(err);
15376 +       sf->f_blocks = f_blocks;
15377 +       sf->f_bfree = f_bfree;
15378 +       sf->f_bavail = f_bavail;
15379 +       sf->f_files = f_files;
15380 +       sf->f_ffree = f_ffree;
15381 +       sf->f_type = HOSTFS_SUPER_MAGIC;
15382 +       return(0);
15383 +}
15384 +
15385 +static struct inode *hostfs_alloc_inode(struct super_block *sb)
15386 +{
15387 +       struct hostfs_inode_info *hi;
15388 +
15389 +       hi = kmalloc(sizeof(*hi), GFP_KERNEL);
15390 +       if(hi == NULL) 
15391 +               return(NULL);
15392 +
15393 +       *hi = ((struct hostfs_inode_info) { .host_filename      = NULL,
15394 +                                           .fd                 = -1,
15395 +                                           .mode               = 0 });
15396 +       inode_init_once(&hi->vfs_inode);
15397 +       return(&hi->vfs_inode);
15398 +}
15399 +
15400 +static void hostfs_destroy_inode(struct inode *inode)
15401 +{
15402 +       if(HOSTFS_I(inode)->host_filename) 
15403 +               kfree(HOSTFS_I(inode)->host_filename);
15404 +
15405 +       if(HOSTFS_I(inode)->fd != -1) 
15406 +               close_file(&HOSTFS_I(inode)->fd);
15407 +
15408 +       kfree(HOSTFS_I(inode));
15409 +}
15410 +
15411 +static void hostfs_read_inode(struct inode *inode)
15412 +{
15413 +       read_inode(inode);
15414 +}
15415 +
15416 +static struct super_operations hostfs_sbops = { 
15417 +       .alloc_inode    = hostfs_alloc_inode,
15418 +       .destroy_inode  = hostfs_destroy_inode,
15419 +       .read_inode     = hostfs_read_inode,
15420 +       .statfs         = hostfs_statfs,
15421 +};
15422 +
15423 +int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
15424 +{
15425 +       void *dir;
15426 +       char *name;
15427 +       unsigned long long next, ino;
15428 +       int error, len;
15429 +
15430 +       name = dentry_name(file->f_dentry, 0);
15431 +       if(name == NULL) return(-ENOMEM);
15432 +       dir = open_dir(name, &error);
15433 +       kfree(name);
15434 +       if(dir == NULL) return(-error);
15435 +       next = file->f_pos;
15436 +       while((name = read_dir(dir, &next, &ino, &len)) != NULL){
15437 +               error = (*filldir)(ent, name, len, file->f_pos, 
15438 +                                  ino, DT_UNKNOWN);
15439 +               if(error) break;
15440 +               file->f_pos = next;
15441 +       }
15442 +       close_dir(dir);
15443 +       return(0);
15444 +}
15445 +
15446 +int hostfs_file_open(struct inode *ino, struct file *file)
15447 +{
15448 +       char *name;
15449 +       int mode = 0, r = 0, w = 0, fd;
15450 +
15451 +       mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
15452 +       if((mode & HOSTFS_I(ino)->mode) == mode)
15453 +               return(0);
15454 +
15455 +       /* The file may already have been opened, but with the wrong access,
15456 +        * so this resets things and reopens the file with the new access.
15457 +        */
15458 +       if(HOSTFS_I(ino)->fd != -1){
15459 +               close_file(&HOSTFS_I(ino)->fd);
15460 +               HOSTFS_I(ino)->fd = -1;
15461 +       }
15462 +
15463 +       HOSTFS_I(ino)->mode |= mode;
15464 +       if(HOSTFS_I(ino)->mode & FMODE_READ) 
15465 +               r = 1;
15466 +       if(HOSTFS_I(ino)->mode & FMODE_WRITE) 
15467 +               w = 1;
15468 +       if(w) 
15469 +               r = 1;
15470 +
15471 +       name = dentry_name(file->f_dentry, 0);
15472 +       if(name == NULL) 
15473 +               return(-ENOMEM);
15474 +
15475 +       fd = open_file(name, r, w, append);
15476 +       kfree(name);
15477 +       if(fd < 0) return(fd);
15478 +       FILE_HOSTFS_I(file)->fd = fd;
15479 +
15480 +       return(0);
15481 +}
15482 +
15483 +int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
15484 +{
15485 +       return(0);
15486 +}
15487 +
15488 +static struct file_operations hostfs_file_fops = {
15489 +       .llseek         = generic_file_llseek,
15490 +       .read           = generic_file_read,
15491 +       .write          = generic_file_write,
15492 +       .mmap           = generic_file_mmap,
15493 +       .open           = hostfs_file_open,
15494 +       .release        = NULL,
15495 +       .fsync          = hostfs_fsync,
15496 +};
15497 +
15498 +static struct file_operations hostfs_dir_fops = {
15499 +       .readdir        = hostfs_readdir,
15500 +       .read           = generic_read_dir,
15501 +};
15502 +
15503 +int hostfs_writepage(struct page *page, struct writeback_control *wbc)
15504 +{
15505 +       struct address_space *mapping = page->mapping;
15506 +       struct inode *inode = mapping->host;
15507 +       char *buffer;
15508 +       unsigned long long base;
15509 +       int count = PAGE_CACHE_SIZE;
15510 +       int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
15511 +       int err;
15512 +
15513 +       if (page->index >= end_index)
15514 +               count = inode->i_size & (PAGE_CACHE_SIZE-1);
15515 +
15516 +       buffer = kmap(page);
15517 +       base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
15518 +
15519 +       err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count);
15520 +       if(err != count){
15521 +               ClearPageUptodate(page);
15522 +               goto out;
15523 +       }
15524 +
15525 +       if (base > inode->i_size)
15526 +               inode->i_size = base;
15527 +
15528 +       if (PageError(page))
15529 +               ClearPageError(page);   
15530 +       err = 0;
15531 +
15532 + out:  
15533 +       kunmap(page);
15534 +
15535 +       unlock_page(page);
15536 +       return err; 
15537 +}
15538 +
15539 +int hostfs_readpage(struct file *file, struct page *page)
15540 +{
15541 +       char *buffer;
15542 +       long long start;
15543 +       int err = 0;
15544 +
15545 +       start = (long long) page->index << PAGE_CACHE_SHIFT;
15546 +       buffer = kmap(page);
15547 +       err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer,
15548 +                       PAGE_CACHE_SIZE);
15549 +       if(err < 0) goto out;
15550 +
15551 +       memset(&buffer[err], 0, PAGE_CACHE_SIZE - err);
15552 +
15553 +       flush_dcache_page(page);
15554 +       SetPageUptodate(page);
15555 +       if (PageError(page)) ClearPageError(page);
15556 +       err = 0;
15557 + out:
15558 +       kunmap(page);
15559 +       unlock_page(page);
15560 +       return(err);
15561 +}
15562 +
15563 +int hostfs_prepare_write(struct file *file, struct page *page, 
15564 +                        unsigned int from, unsigned int to)
15565 +{
15566 +       char *buffer;
15567 +       long long start, tmp;
15568 +       int err;
15569 +
15570 +       start = (long long) page->index << PAGE_CACHE_SHIFT;
15571 +       buffer = kmap(page);
15572 +       if(from != 0){
15573 +               tmp = start;
15574 +               err = read_file(FILE_HOSTFS_I(file)->fd, &tmp, buffer,
15575 +                               from);
15576 +               if(err < 0) goto out;
15577 +       }
15578 +       if(to != PAGE_CACHE_SIZE){
15579 +               start += to;
15580 +               err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer + to,
15581 +                               PAGE_CACHE_SIZE - to);
15582 +               if(err < 0) goto out;           
15583 +       }
15584 +       err = 0;
15585 + out:
15586 +       kunmap(page);
15587 +       return(err);
15588 +}
15589 +
15590 +int hostfs_commit_write(struct file *file, struct page *page, unsigned from,
15591 +                unsigned to)
15592 +{
15593 +       struct address_space *mapping = page->mapping;
15594 +       struct inode *inode = mapping->host;
15595 +       char *buffer;
15596 +       long long start;
15597 +       int err = 0;
15598 +
15599 +       start = (long long) (page->index << PAGE_CACHE_SHIFT) + from;
15600 +       buffer = kmap(page);
15601 +       err = write_file(FILE_HOSTFS_I(file)->fd, &start, buffer + from, 
15602 +                        to - from);
15603 +       if(err > 0) err = 0;
15604 +       if(!err && (start > inode->i_size))
15605 +               inode->i_size = start;
15606 +
15607 +       kunmap(page);
15608 +       return(err);
15609 +}
15610 +
15611 +static struct address_space_operations hostfs_aops = {
15612 +       .writepage      = hostfs_writepage,
15613 +       .readpage       = hostfs_readpage,
15614 +/*     .set_page_dirty = __set_page_dirty_nobuffers, */
15615 +       .prepare_write  = hostfs_prepare_write,
15616 +       .commit_write   = hostfs_commit_write
15617 +};
15618 +
15619 +static int init_inode(struct inode *inode, struct dentry *dentry)
15620 +{
15621 +       char *name;
15622 +       int type, err = -ENOMEM, rdev;
15623 +
15624 +       if(dentry){
15625 +               name = dentry_name(dentry, 0);
15626 +               if(name == NULL)
15627 +                       goto out;
15628 +               type = file_type(name, &rdev);
15629 +               kfree(name);
15630 +       }
15631 +       else type = OS_TYPE_DIR;
15632 +
15633 +       err = 0;
15634 +       if(type == OS_TYPE_SYMLINK)
15635 +               inode->i_op = &page_symlink_inode_operations;
15636 +       else if(type == OS_TYPE_DIR)
15637 +               inode->i_op = &hostfs_dir_iops;
15638 +       else inode->i_op = &hostfs_iops;
15639 +
15640 +       if(type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops;
15641 +       else inode->i_fop = &hostfs_file_fops;
15642 +
15643 +       if(type == OS_TYPE_SYMLINK) 
15644 +               inode->i_mapping->a_ops = &hostfs_link_aops;
15645 +       else inode->i_mapping->a_ops = &hostfs_aops;
15646 +
15647 +       switch (type) {
15648 +       case OS_TYPE_CHARDEV:
15649 +               init_special_inode(inode, S_IFCHR, rdev);
15650 +               break;
15651 +       case OS_TYPE_BLOCKDEV:
15652 +               init_special_inode(inode, S_IFBLK, rdev);
15653 +               break;
15654 +       case OS_TYPE_FIFO:
15655 +               init_special_inode(inode, S_IFIFO, 0);
15656 +               break;
15657 +       case OS_TYPE_SOCK:
15658 +               init_special_inode(inode, S_IFSOCK, 0);
15659 +               break;
15660 +       }
15661 + out:
15662 +       return(err);
15663 +}
15664 +
15665 +int hostfs_create(struct inode *dir, struct dentry *dentry, int mode, 
15666 +                 struct nameidata *nd)
15667 +{
15668 +       struct inode *inode;
15669 +       char *name;
15670 +       int error, fd;
15671 +
15672 +       error = -ENOMEM;
15673 +       inode = iget(dir->i_sb, 0);
15674 +       if(inode == NULL) goto out;
15675 +
15676 +       error = init_inode(inode, dentry);
15677 +       if(error) 
15678 +               goto out_put;
15679 +       
15680 +       error = -ENOMEM;
15681 +       name = dentry_name(dentry, 0);
15682 +       if(name == NULL)
15683 +               goto out_put;
15684 +
15685 +       fd = file_create(name, 
15686 +                        mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR, 
15687 +                        mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP, 
15688 +                        mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH);
15689 +       if(fd < 0) 
15690 +               error = fd;
15691 +       else error = read_name(inode, name);
15692 +
15693 +       kfree(name);
15694 +       if(error)
15695 +               goto out_put;
15696 +
15697 +       HOSTFS_I(inode)->fd = fd;
15698 +       HOSTFS_I(inode)->mode = FMODE_READ | FMODE_WRITE;
15699 +       d_instantiate(dentry, inode);
15700 +       return(0);
15701 +
15702 + out_put:
15703 +       iput(inode);
15704 + out:
15705 +       return(error);
15706 +}
15707 +
15708 +struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry, 
15709 +                            struct nameidata *nd)
15710 +{
15711 +       struct inode *inode;
15712 +       char *name;
15713 +       int err;
15714 +
15715 +       err = -ENOMEM;
15716 +       inode = iget(ino->i_sb, 0);
15717 +       if(inode == NULL) 
15718 +               goto out;
15719
15720 +       err = init_inode(inode, dentry);
15721 +       if(err) 
15722 +               goto out_put;
15723 +
15724 +       err = -ENOMEM;
15725 +       name = dentry_name(dentry, 0);
15726 +       if(name == NULL)
15727 +               goto out_put;
15728 +
15729 +       err = read_name(inode, name);
15730 +       kfree(name);
15731 +       if(err == -ENOENT){
15732 +               iput(inode);
15733 +               inode = NULL;
15734 +       }
15735 +       else if(err)
15736 +               goto out_put;
15737 +
15738 +       d_add(dentry, inode);
15739 +       dentry->d_op = &hostfs_dentry_ops;
15740 +       return(NULL);
15741 +
15742 + out_put:
15743 +       iput(inode);
15744 + out:
15745 +       return(ERR_PTR(err));
15746 +}
15747 +
15748 +static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
15749 +{
15750 +        char *file;
15751 +       int len;
15752 +
15753 +       file = inode_name(ino, dentry->d_name.len + 1);
15754 +       if(file == NULL) return(NULL);
15755 +        strcat(file, "/");
15756 +       len = strlen(file);
15757 +        strncat(file, dentry->d_name.name, dentry->d_name.len);
15758 +       file[len + dentry->d_name.len] = '\0';
15759 +        return(file);
15760 +}
15761 +
15762 +int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
15763 +{
15764 +        char *from_name, *to_name;
15765 +        int err;
15766 +
15767 +        if((from_name = inode_dentry_name(ino, from)) == NULL) 
15768 +                return(-ENOMEM);
15769 +        to_name = dentry_name(to, 0);
15770 +       if(to_name == NULL){
15771 +               kfree(from_name);
15772 +               return(-ENOMEM);
15773 +       }
15774 +        err = link_file(to_name, from_name);
15775 +        kfree(from_name);
15776 +        kfree(to_name);
15777 +        return(err);
15778 +}
15779 +
15780 +int hostfs_unlink(struct inode *ino, struct dentry *dentry)
15781 +{
15782 +       char *file;
15783 +       int err;
15784 +
15785 +       if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
15786 +       if(append)
15787 +               return(-EPERM);
15788 +
15789 +       err = unlink_file(file);
15790 +       kfree(file);
15791 +       return(err);
15792 +}
15793 +
15794 +int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
15795 +{
15796 +       char *file;
15797 +       int err;
15798 +
15799 +       if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
15800 +       err = make_symlink(file, to);
15801 +       kfree(file);
15802 +       return(err);
15803 +}
15804 +
15805 +int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode)
15806 +{
15807 +       char *file;
15808 +       int err;
15809 +
15810 +       if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
15811 +       err = do_mkdir(file, mode);
15812 +       kfree(file);
15813 +       return(err);
15814 +}
15815 +
15816 +int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
15817 +{
15818 +       char *file;
15819 +       int err;
15820 +
15821 +       if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
15822 +       err = do_rmdir(file);
15823 +       kfree(file);
15824 +       return(err);
15825 +}
15826 +
15827 +int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
15828 +{
15829 +       struct inode *inode;
15830 +       char *name;
15831 +       int err = -ENOMEM;
15832
15833 +       inode = iget(dir->i_sb, 0);
15834 +       if(inode == NULL) 
15835 +               goto out;
15836 +
15837 +       err = init_inode(inode, dentry);
15838 +       if(err) 
15839 +               goto out_put;
15840 +
15841 +       err = -ENOMEM;
15842 +       name = dentry_name(dentry, 0);
15843 +       if(name == NULL)
15844 +               goto out_put;
15845 +
15846 +       init_special_inode(inode, mode, dev);
15847 +       err = do_mknod(name, mode, dev);
15848 +       if(err)
15849 +               goto out_free;
15850 +
15851 +       err = read_name(inode, name);
15852 +       kfree(name);
15853 +       if(err)
15854 +               goto out_put;
15855 +
15856 +       d_instantiate(dentry, inode);
15857 +       return(0);
15858 +
15859 + out_free:
15860 +       kfree(name);
15861 + out_put:
15862 +       iput(inode);
15863 + out:
15864 +       return(err);
15865 +}
15866 +
15867 +int hostfs_rename(struct inode *from_ino, struct dentry *from,
15868 +                 struct inode *to_ino, struct dentry *to)
15869 +{
15870 +       char *from_name, *to_name;
15871 +       int err;
15872 +
15873 +       if((from_name = inode_dentry_name(from_ino, from)) == NULL)
15874 +               return(-ENOMEM);
15875 +       if((to_name = inode_dentry_name(to_ino, to)) == NULL){
15876 +               kfree(from_name);
15877 +               return(-ENOMEM);
15878 +       }
15879 +       err = rename_file(from_name, to_name);
15880 +       kfree(from_name);
15881 +       kfree(to_name);
15882 +       return(err);
15883 +}
15884 +
15885 +void hostfs_truncate(struct inode *ino)
15886 +{
15887 +       not_implemented();
15888 +}
15889 +
15890 +int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd)
15891 +{
15892 +       char *name;
15893 +       int r = 0, w = 0, x = 0, err;
15894 +
15895 +       if(desired & MAY_READ) r = 1;
15896 +       if(desired & MAY_WRITE) w = 1;
15897 +       if(desired & MAY_EXEC) x = 1;
15898 +       name = inode_name(ino, 0);
15899 +       if(name == NULL) return(-ENOMEM);
15900 +       err = access_file(name, r, w, x);
15901 +       kfree(name);
15902 +       if(!err) err = vfs_permission(ino, desired);
15903 +       return(err);
15904 +}
15905 +
15906 +int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
15907 +{
15908 +       struct hostfs_iattr attrs;
15909 +       char *name;
15910 +       int err;
15911 +       
15912 +       if(append) 
15913 +               attr->ia_valid &= ~ATTR_SIZE;
15914 +
15915 +       attrs.ia_valid = 0;
15916 +       if(attr->ia_valid & ATTR_MODE){
15917 +               attrs.ia_valid |= HOSTFS_ATTR_MODE;
15918 +               attrs.ia_mode = attr->ia_mode;
15919 +       }
15920 +       if(attr->ia_valid & ATTR_UID){
15921 +               if((dentry->d_inode->i_sb->s_dev == ROOT_DEV) && 
15922 +                  (attr->ia_uid == 0))
15923 +                       attr->ia_uid = getuid();
15924 +               attrs.ia_valid |= HOSTFS_ATTR_UID;
15925 +               attrs.ia_uid = attr->ia_uid;
15926 +       }
15927 +       if(attr->ia_valid & ATTR_GID){
15928 +               if((dentry->d_inode->i_sb->s_dev == ROOT_DEV) && 
15929 +                  (attr->ia_gid == 0))
15930 +                       attr->ia_gid = getuid();
15931 +               attrs.ia_valid |= HOSTFS_ATTR_GID;
15932 +               attrs.ia_gid = attr->ia_gid;
15933 +       }
15934 +       if(attr->ia_valid & ATTR_SIZE){
15935 +               attrs.ia_valid |= HOSTFS_ATTR_SIZE;
15936 +               attrs.ia_size = attr->ia_size;
15937 +       }
15938 +       if(attr->ia_valid & ATTR_ATIME){
15939 +               attrs.ia_valid |= HOSTFS_ATTR_ATIME;
15940 +               attrs.ia_atime = attr->ia_atime;
15941 +       }
15942 +       if(attr->ia_valid & ATTR_MTIME){
15943 +               attrs.ia_valid |= HOSTFS_ATTR_MTIME;
15944 +               attrs.ia_mtime = attr->ia_mtime;
15945 +       }
15946 +       if(attr->ia_valid & ATTR_CTIME){
15947 +               attrs.ia_valid |= HOSTFS_ATTR_CTIME;
15948 +               attrs.ia_ctime = attr->ia_ctime;
15949 +       }
15950 +       if(attr->ia_valid & ATTR_ATIME_SET){
15951 +               attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
15952 +       }
15953 +       if(attr->ia_valid & ATTR_MTIME_SET){
15954 +               attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
15955 +       }
15956 +       name = dentry_name(dentry, 0);
15957 +       if(name == NULL) return(-ENOMEM);
15958 +       err = set_attr(name, &attrs);
15959 +       kfree(name);
15960 +       if(err)
15961 +               return(err);
15962 +
15963 +       return(inode_setattr(dentry->d_inode, attr));
15964 +}
15965 +
15966 +int hostfs_getattr(struct vfsmount *mnt, struct dentry *dentry, 
15967 +          struct kstat *stat)
15968 +{
15969 +       generic_fillattr(dentry->d_inode, stat);
15970 +       return(0);
15971 +}
15972 +
15973 +static struct inode_operations hostfs_iops = {
15974 +       .create         = hostfs_create,
15975 +       .link           = hostfs_link,
15976 +       .unlink         = hostfs_unlink,
15977 +       .symlink        = hostfs_symlink,
15978 +       .mkdir          = hostfs_mkdir,
15979 +       .rmdir          = hostfs_rmdir,
15980 +       .mknod          = hostfs_mknod,
15981 +       .rename         = hostfs_rename,
15982 +       .truncate       = hostfs_truncate,
15983 +       .permission     = hostfs_permission,
15984 +       .setattr        = hostfs_setattr,
15985 +       .getattr        = hostfs_getattr,
15986 +};
15987 +
15988 +static struct inode_operations hostfs_dir_iops = {
15989 +       .create         = hostfs_create,
15990 +       .lookup         = hostfs_lookup,
15991 +       .link           = hostfs_link,
15992 +       .unlink         = hostfs_unlink,
15993 +       .symlink        = hostfs_symlink,
15994 +       .mkdir          = hostfs_mkdir,
15995 +       .rmdir          = hostfs_rmdir,
15996 +       .mknod          = hostfs_mknod,
15997 +       .rename         = hostfs_rename,
15998 +       .truncate       = hostfs_truncate,
15999 +       .permission     = hostfs_permission,
16000 +       .setattr        = hostfs_setattr,
16001 +       .getattr        = hostfs_getattr,
16002 +};
16003 +
16004 +int hostfs_link_readpage(struct file *file, struct page *page)
16005 +{
16006 +       char *buffer, *name;
16007 +       long long start;
16008 +       int err;
16009 +
16010 +       start = page->index << PAGE_CACHE_SHIFT;
16011 +       buffer = kmap(page);
16012 +       name = inode_name(page->mapping->host, 0);
16013 +       if(name == NULL) return(-ENOMEM);
16014 +       err = do_readlink(name, buffer, PAGE_CACHE_SIZE);
16015 +       kfree(name);
16016 +       if(err == PAGE_CACHE_SIZE)
16017 +               err = -E2BIG;
16018 +       else if(err > 0){
16019 +               flush_dcache_page(page);
16020 +               SetPageUptodate(page);
16021 +               if (PageError(page)) ClearPageError(page);
16022 +               err = 0;
16023 +       }
16024 +       kunmap(page);
16025 +       unlock_page(page);
16026 +       return(err);
16027 +}
16028 +
16029 +static struct address_space_operations hostfs_link_aops = {
16030 +       .readpage       = hostfs_link_readpage,
16031 +};
16032 +
16033 +static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
16034 +{
16035 +       struct inode *root_inode;
16036 +       char *name, *data = d;
16037 +       int err;
16038 +
16039 +       sb->s_blocksize = 1024;
16040 +       sb->s_blocksize_bits = 10;
16041 +       sb->s_magic = HOSTFS_SUPER_MAGIC;
16042 +       sb->s_op = &hostfs_sbops;
16043 +
16044 +       if((data == NULL) || (*data == '\0')) 
16045 +               data = root_ino;
16046 +
16047 +       err = -ENOMEM;
16048 +       name = kmalloc(strlen(data) + 1, GFP_KERNEL);
16049 +       if(name == NULL) 
16050 +               goto out;
16051 +
16052 +       strcpy(name, data);
16053 +
16054 +       root_inode = iget(sb, 0);
16055 +       if(root_inode == NULL)
16056 +               goto out_free;
16057 +
16058 +       err = init_inode(root_inode, NULL);
16059 +       if(err)
16060 +               goto out_put;
16061 +
16062 +       HOSTFS_I(root_inode)->host_filename = name;
16063 +
16064 +       err = -ENOMEM;
16065 +       sb->s_root = d_alloc_root(root_inode);
16066 +       if(sb->s_root == NULL)
16067 +               goto out_put;
16068 +
16069 +       err = read_inode(root_inode);
16070 +       if(err)
16071 +               goto out_put;
16072 +
16073 +       return(0);
16074 +
16075 + out_put:
16076 +       iput(root_inode);
16077 + out_free:
16078 +       kfree(name);
16079 + out:
16080 +       return(err);
16081 +}
16082 +
16083 +static struct super_block *hostfs_read_sb(struct file_system_type *type,
16084 +                                            int flags, const char *dev_name,
16085 +                                            void *data)
16086 +{
16087 +       return(get_sb_nodev(type, flags, data, hostfs_fill_sb_common));
16088 +}
16089 +
16090 +static struct file_system_type hostfs_type = {
16091 +       .owner          = THIS_MODULE,
16092 +       .name           = "hostfs",
16093 +       .get_sb         = hostfs_read_sb,
16094 +       .kill_sb        = kill_anon_super,
16095 +       .fs_flags       = 0,
16096 +};
16097 +
16098 +static int __init init_hostfs(void)
16099 +{
16100 +       return(register_filesystem(&hostfs_type));
16101 +}
16102 +
16103 +static void __exit exit_hostfs(void)
16104 +{
16105 +       unregister_filesystem(&hostfs_type);
16106 +}
16107 +
16108 +module_init(init_hostfs)
16109 +module_exit(exit_hostfs)
16110 +MODULE_LICENSE("GPL");
16111 +
16112 +/*
16113 + * Overrides for Emacs so that we follow Linus's tabbing style.
16114 + * Emacs will notice this stuff at the end of the file and automatically
16115 + * adjust the settings for this buffer only.  This must remain at the end
16116 + * of the file.
16117 + * ---------------------------------------------------------------------------
16118 + * Local variables:
16119 + * c-file-style: "linux"
16120 + * End:
16121 + */
16122 diff -Naur a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c
16123 --- a/fs/hostfs/hostfs_user.c   1969-12-31 19:00:00.000000000 -0500
16124 +++ b/fs/hostfs/hostfs_user.c   2004-02-11 12:26:11.000000000 -0500
16125 @@ -0,0 +1,361 @@
16126 +/* 
16127 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
16128 + * Licensed under the GPL
16129 + */
16130 +
16131 +#include <unistd.h>
16132 +#include <stdio.h>
16133 +#include <fcntl.h>
16134 +#include <dirent.h>
16135 +#include <errno.h>
16136 +#include <utime.h>
16137 +#include <string.h>
16138 +#include <sys/stat.h>
16139 +#include <sys/time.h>
16140 +#include <sys/vfs.h>
16141 +#include "hostfs.h"
16142 +#include "kern_util.h"
16143 +#include "user.h"
16144 +
16145 +int stat_file(const char *path, unsigned long long *inode_out, int *mode_out,
16146 +             int *nlink_out, int *uid_out, int *gid_out, 
16147 +             unsigned long long *size_out, struct timespec *atime_out,
16148 +             struct timespec *mtime_out, struct timespec *ctime_out,
16149 +             int *blksize_out, unsigned long long *blocks_out)
16150 +{
16151 +       struct stat64 buf;
16152 +
16153 +       if(lstat64(path, &buf) < 0) 
16154 +               return(-errno);
16155 +
16156 +       /* See the Makefile for why STAT64_INO_FIELD is passed in
16157 +        * by the build
16158 +        */
16159 +       if(inode_out != NULL) *inode_out = buf.STAT64_INO_FIELD;
16160 +       if(mode_out != NULL) *mode_out = buf.st_mode;
16161 +       if(nlink_out != NULL) *nlink_out = buf.st_nlink;
16162 +       if(uid_out != NULL) *uid_out = buf.st_uid;
16163 +       if(gid_out != NULL) *gid_out = buf.st_gid;
16164 +       if(size_out != NULL) *size_out = buf.st_size;
16165 +       if(atime_out != NULL) {
16166 +               atime_out->tv_sec = buf.st_atime;
16167 +               atime_out->tv_nsec = 0;
16168 +       }
16169 +       if(mtime_out != NULL) {
16170 +               mtime_out->tv_sec = buf.st_mtime;
16171 +               mtime_out->tv_nsec = 0;
16172 +       }
16173 +       if(ctime_out != NULL) {
16174 +               ctime_out->tv_sec = buf.st_ctime;
16175 +               ctime_out->tv_nsec = 0;
16176 +       }
16177 +       if(blksize_out != NULL) *blksize_out = buf.st_blksize;
16178 +       if(blocks_out != NULL) *blocks_out = buf.st_blocks;
16179 +       return(0);
16180 +}
16181 +
16182 +int file_type(const char *path, int *rdev)
16183 +{
16184 +       struct stat64 buf;
16185 +
16186 +       if(lstat64(path, &buf) < 0) 
16187 +               return(-errno);
16188 +       if(rdev != NULL) 
16189 +               *rdev = buf.st_rdev;
16190 +
16191 +       if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
16192 +       else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
16193 +       else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV);
16194 +       else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV);
16195 +       else if(S_ISFIFO(buf.st_mode))return(OS_TYPE_FIFO);
16196 +       else if(S_ISSOCK(buf.st_mode))return(OS_TYPE_SOCK);
16197 +       else return(OS_TYPE_FILE);
16198 +}
16199 +
16200 +int access_file(char *path, int r, int w, int x)
16201 +{
16202 +       int mode = 0;
16203 +
16204 +       if(r) mode = R_OK;
16205 +       if(w) mode |= W_OK;
16206 +       if(x) mode |= X_OK;
16207 +       if(access(path, mode) != 0) return(-errno);
16208 +       else return(0);
16209 +}
16210 +
16211 +int open_file(char *path, int r, int w, int append)
16212 +{
16213 +       int mode = 0, fd;
16214 +
16215 +       if(r && !w) 
16216 +               mode = O_RDONLY;
16217 +       else if(!r && w) 
16218 +               mode = O_WRONLY;
16219 +       else if(r && w) 
16220 +               mode = O_RDWR;
16221 +       else panic("Impossible mode in open_file");
16222 +
16223 +       if(append)
16224 +               mode |= O_APPEND;
16225 +       fd = open64(path, mode);
16226 +       if(fd < 0) return(-errno);
16227 +       else return(fd);
16228 +}
16229 +
16230 +void *open_dir(char *path, int *err_out)
16231 +{
16232 +       DIR *dir;
16233 +
16234 +       dir = opendir(path);
16235 +       *err_out = errno;
16236 +       if(dir == NULL) return(NULL);
16237 +       return(dir);
16238 +}
16239 +
16240 +char *read_dir(void *stream, unsigned long long *pos, 
16241 +              unsigned long long *ino_out, int *len_out)
16242 +{
16243 +       DIR *dir = stream;
16244 +       struct dirent *ent;
16245 +
16246 +       seekdir(dir, *pos);
16247 +       ent = readdir(dir);
16248 +       if(ent == NULL) return(NULL);
16249 +       *len_out = strlen(ent->d_name);
16250 +       *ino_out = ent->d_ino;
16251 +       *pos = telldir(dir);
16252 +       return(ent->d_name);
16253 +}
16254 +
16255 +int read_file(int fd, unsigned long long *offset, char *buf, int len)
16256 +{
16257 +       int n;
16258 +
16259 +       n = pread64(fd, buf, len, *offset);
16260 +       if(n < 0) return(-errno);
16261 +       *offset += n;
16262 +       return(n);
16263 +}
16264 +
16265 +int write_file(int fd, unsigned long long *offset, const char *buf, int len)
16266 +{
16267 +       int n;
16268 +
16269 +       n = pwrite64(fd, buf, len, *offset);
16270 +       if(n < 0) return(-errno);
16271 +       *offset += n;
16272 +       return(n);
16273 +}
16274 +
16275 +int lseek_file(int fd, long long offset, int whence)
16276 +{
16277 +       int ret;
16278 +
16279 +       ret = lseek64(fd, offset, whence);
16280 +       if(ret < 0) return(-errno);
16281 +       return(0);
16282 +}
16283 +
16284 +void close_file(void *stream)
16285 +{
16286 +       close(*((int *) stream));
16287 +}
16288 +
16289 +void close_dir(void *stream)
16290 +{
16291 +       closedir(stream);
16292 +}
16293 +
16294 +int file_create(char *name, int ur, int uw, int ux, int gr, 
16295 +               int gw, int gx, int or, int ow, int ox)
16296 +{
16297 +       int mode, fd;
16298 +
16299 +       mode = 0;
16300 +       mode |= ur ? S_IRUSR : 0;
16301 +       mode |= uw ? S_IWUSR : 0;
16302 +       mode |= ux ? S_IXUSR : 0;
16303 +       mode |= gr ? S_IRGRP : 0;
16304 +       mode |= gw ? S_IWGRP : 0;
16305 +       mode |= gx ? S_IXGRP : 0;
16306 +       mode |= or ? S_IROTH : 0;
16307 +       mode |= ow ? S_IWOTH : 0;
16308 +       mode |= ox ? S_IXOTH : 0;
16309 +       fd = open64(name, O_CREAT | O_RDWR, mode);
16310 +       if(fd < 0) 
16311 +               return(-errno);
16312 +       return(fd);
16313 +}
16314 +
16315 +int set_attr(const char *file, struct hostfs_iattr *attrs)
16316 +{
16317 +       struct utimbuf buf;
16318 +       int err, ma;
16319 +
16320 +       if(attrs->ia_valid & HOSTFS_ATTR_MODE){
16321 +               if(chmod(file, attrs->ia_mode) != 0) return(-errno);
16322 +       }
16323 +       if(attrs->ia_valid & HOSTFS_ATTR_UID){
16324 +               if(chown(file, attrs->ia_uid, -1)) return(-errno);
16325 +       }
16326 +       if(attrs->ia_valid & HOSTFS_ATTR_GID){
16327 +               if(chown(file, -1, attrs->ia_gid)) return(-errno);
16328 +       }
16329 +       if(attrs->ia_valid & HOSTFS_ATTR_SIZE){
16330 +               if(truncate(file, attrs->ia_size)) return(-errno);
16331 +       }
16332 +       ma = HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET;
16333 +       if((attrs->ia_valid & ma) == ma){
16334 +               buf.actime = attrs->ia_atime.tv_sec;
16335 +               buf.modtime = attrs->ia_mtime.tv_sec;
16336 +               if(utime(file, &buf) != 0) return(-errno);
16337 +       }
16338 +       else {
16339 +               struct timespec ts;
16340 +
16341 +               if(attrs->ia_valid & HOSTFS_ATTR_ATIME_SET){
16342 +                       err = stat_file(file, NULL, NULL, NULL, NULL, NULL, 
16343 +                                       NULL, NULL, &ts, NULL, NULL, NULL);
16344 +                       if(err != 0) 
16345 +                               return(err);
16346 +                       buf.actime = attrs->ia_atime.tv_sec;
16347 +                       buf.modtime = ts.tv_sec;
16348 +                       if(utime(file, &buf) != 0) 
16349 +                               return(-errno);
16350 +               }
16351 +               if(attrs->ia_valid & HOSTFS_ATTR_MTIME_SET){
16352 +                       err = stat_file(file, NULL, NULL, NULL, NULL, NULL, 
16353 +                                       NULL, &ts, NULL, NULL, NULL, NULL);
16354 +                       if(err != 0) 
16355 +                               return(err);
16356 +                       buf.actime = ts.tv_sec;
16357 +                       buf.modtime = attrs->ia_mtime.tv_sec;
16358 +                       if(utime(file, &buf) != 0) 
16359 +                               return(-errno);
16360 +               }
16361 +       }
16362 +       if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ;
16363 +       if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){
16364 +               err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL, 
16365 +                               &attrs->ia_atime, &attrs->ia_mtime, NULL, 
16366 +                               NULL, NULL);
16367 +               if(err != 0) return(err);
16368 +       }
16369 +       return(0);
16370 +}
16371 +
16372 +int make_symlink(const char *from, const char *to)
16373 +{
16374 +       int err;
16375 +
16376 +       err = symlink(to, from);
16377 +       if(err) return(-errno);
16378 +       return(0);
16379 +}
16380 +
16381 +int unlink_file(const char *file)
16382 +{
16383 +       int err;
16384 +
16385 +       err = unlink(file);
16386 +       if(err) return(-errno);
16387 +       return(0);
16388 +}
16389 +
16390 +int do_mkdir(const char *file, int mode)
16391 +{
16392 +       int err;
16393 +
16394 +       err = mkdir(file, mode);
16395 +       if(err) return(-errno);
16396 +       return(0);
16397 +}
16398 +
16399 +int do_rmdir(const char *file)
16400 +{
16401 +       int err;
16402 +
16403 +       err = rmdir(file);
16404 +       if(err) return(-errno);
16405 +       return(0);
16406 +}
16407 +
16408 +int do_mknod(const char *file, int mode, int dev)
16409 +{
16410 +       int err;
16411 +
16412 +       err = mknod(file, mode, dev);
16413 +       if(err) return(-errno);
16414 +       return(0);
16415 +}
16416 +
16417 +int link_file(const char *to, const char *from)
16418 +{
16419 +       int err;
16420 +
16421 +       err = link(to, from);
16422 +       if(err) return(-errno);
16423 +       return(0);
16424 +}
16425 +
16426 +int do_readlink(char *file, char *buf, int size)
16427 +{
16428 +       int n;
16429 +
16430 +       n = readlink(file, buf, size);
16431 +       if(n < 0) 
16432 +               return(-errno);
16433 +       if(n < size) 
16434 +               buf[n] = '\0';
16435 +       return(n);
16436 +}
16437 +
16438 +int rename_file(char *from, char *to)
16439 +{
16440 +       int err;
16441 +
16442 +       err = rename(from, to);
16443 +       if(err < 0) return(-errno);
16444 +       return(0);      
16445 +}
16446 +
16447 +int do_statfs(char *root, long *bsize_out, long long *blocks_out, 
16448 +             long long *bfree_out, long long *bavail_out, 
16449 +             long long *files_out, long long *ffree_out,
16450 +             void *fsid_out, int fsid_size, long *namelen_out, 
16451 +             long *spare_out)
16452 +{
16453 +       struct statfs64 buf;
16454 +       int err;
16455 +
16456 +       err = statfs64(root, &buf);
16457 +       if(err < 0) return(-errno);
16458 +       *bsize_out = buf.f_bsize;
16459 +       *blocks_out = buf.f_blocks;
16460 +       *bfree_out = buf.f_bfree;
16461 +       *bavail_out = buf.f_bavail;
16462 +       *files_out = buf.f_files;
16463 +       *ffree_out = buf.f_ffree;
16464 +       memcpy(fsid_out, &buf.f_fsid, 
16465 +              sizeof(buf.f_fsid) > fsid_size ? fsid_size : 
16466 +              sizeof(buf.f_fsid));
16467 +       *namelen_out = buf.f_namelen;
16468 +       spare_out[0] = buf.f_spare[0];
16469 +       spare_out[1] = buf.f_spare[1];
16470 +       spare_out[2] = buf.f_spare[2];
16471 +       spare_out[3] = buf.f_spare[3];
16472 +       spare_out[4] = buf.f_spare[4];
16473 +       spare_out[5] = buf.f_spare[5];
16474 +       return(0);
16475 +}
16476 +
16477 +/*
16478 + * Overrides for Emacs so that we follow Linus's tabbing style.
16479 + * Emacs will notice this stuff at the end of the file and automatically
16480 + * adjust the settings for this buffer only.  This must remain at the end
16481 + * of the file.
16482 + * ---------------------------------------------------------------------------
16483 + * Local variables:
16484 + * c-file-style: "linux"
16485 + * End:
16486 + */
16487 diff -Naur a/fs/hostfs/Makefile b/fs/hostfs/Makefile
16488 --- a/fs/hostfs/Makefile        1969-12-31 19:00:00.000000000 -0500
16489 +++ b/fs/hostfs/Makefile        2004-02-11 12:25:42.000000000 -0500
16490 @@ -0,0 +1,26 @@
16491 +# 
16492 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
16493 +# Licensed under the GPL
16494 +#
16495 +
16496 +# struct stat64 changed the inode field name between 2.2 and 2.4 from st_ino
16497 +# to __st_ino.  It stayed in the same place, so as long as the correct name
16498 +# is used, hostfs compiled on 2.2 should work on 2.4 and vice versa.
16499 +
16500 +STAT64_INO_FIELD := $(shell grep -q __st_ino /usr/include/bits/stat.h && \
16501 +                               echo __)st_ino
16502 +
16503 +hostfs-objs := hostfs_kern.o hostfs_user.o
16504 +
16505 +obj-y = 
16506 +obj-$(CONFIG_HOSTFS) += hostfs.o
16507 +
16508 +SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
16509 +
16510 +USER_OBJS := $(filter %_user.o,$(obj-y) $(obj-m) $(SINGLE_OBJS))
16511 +USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
16512 +
16513 +USER_CFLAGS += -DSTAT64_INO_FIELD=$(STAT64_INO_FIELD)
16514 +
16515 +$(USER_OBJS) : %.o: %.c
16516 +       $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
16517 diff -Naur a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c
16518 --- a/fs/hppfs/hppfs_kern.c     1969-12-31 19:00:00.000000000 -0500
16519 +++ b/fs/hppfs/hppfs_kern.c     2004-02-11 12:27:10.000000000 -0500
16520 @@ -0,0 +1,811 @@
16521 +/* 
16522 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
16523 + * Licensed under the GPL
16524 + */
16525 +
16526 +#include <linux/fs.h>
16527 +#include <linux/module.h>
16528 +#include <linux/init.h>
16529 +#include <linux/slab.h>
16530 +#include <linux/list.h>
16531 +#include <linux/kernel.h>
16532 +#include <linux/ctype.h>
16533 +#include <linux/dcache.h>
16534 +#include <linux/statfs.h>
16535 +#include <asm/uaccess.h>
16536 +#include <asm/fcntl.h>
16537 +#include "os.h"
16538 +
16539 +static int init_inode(struct inode *inode, struct dentry *dentry);
16540 +
16541 +struct hppfs_data {
16542 +       struct list_head list;
16543 +       char contents[PAGE_SIZE - sizeof(struct list_head)];
16544 +};
16545 +
16546 +struct hppfs_private {
16547 +       struct file proc_file;
16548 +       int host_fd;
16549 +       loff_t len;
16550 +       struct hppfs_data *contents;
16551 +};
16552 +
16553 +struct hppfs_inode_info {
16554 +        struct dentry *proc_dentry;
16555 +       struct inode vfs_inode;
16556 +};
16557 +
16558 +static inline struct hppfs_inode_info *HPPFS_I(struct inode *inode)
16559 +{
16560 +       return(list_entry(inode, struct hppfs_inode_info, vfs_inode));
16561 +}
16562 +
16563 +#define HPPFS_SUPER_MAGIC 0xb00000ee
16564 +
16565 +static struct super_operations hppfs_sbops;
16566 +
16567 +static int is_pid(struct dentry *dentry)
16568 +{
16569 +       struct super_block *sb;
16570 +       int i;
16571 +
16572 +       sb = dentry->d_sb;
16573 +       if((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root))
16574 +               return(0);
16575 +
16576 +       for(i = 0; i < dentry->d_name.len; i++){
16577 +               if(!isdigit(dentry->d_name.name[i]))
16578 +                       return(0);
16579 +       }
16580 +       return(1);
16581 +}
16582 +
16583 +static char *dentry_name(struct dentry *dentry, int extra)
16584 +{
16585 +       struct dentry *parent;
16586 +       char *root, *name;
16587 +       const char *seg_name;
16588 +       int len, seg_len;
16589 +
16590 +       len = 0;
16591 +       parent = dentry;
16592 +       while(parent->d_parent != parent){
16593 +               if(is_pid(parent))
16594 +                       len += strlen("pid") + 1;
16595 +               else len += parent->d_name.len + 1;
16596 +               parent = parent->d_parent;
16597 +       }
16598 +       
16599 +       root = "proc";
16600 +       len += strlen(root);
16601 +       name = kmalloc(len + extra + 1, GFP_KERNEL);
16602 +       if(name == NULL) return(NULL);
16603 +
16604 +       name[len] = '\0';
16605 +       parent = dentry;
16606 +       while(parent->d_parent != parent){
16607 +               if(is_pid(parent)){
16608 +                       seg_name = "pid";
16609 +                       seg_len = strlen("pid");
16610 +               }
16611 +               else {
16612 +                       seg_name = parent->d_name.name;
16613 +                       seg_len = parent->d_name.len;
16614 +               }
16615 +
16616 +               len -= seg_len + 1;
16617 +               name[len] = '/';
16618 +               strncpy(&name[len + 1], seg_name, seg_len);
16619 +               parent = parent->d_parent;
16620 +       }
16621 +       strncpy(name, root, strlen(root));
16622 +       return(name);
16623 +}
16624 +
16625 +struct dentry_operations hppfs_dentry_ops = {
16626 +};
16627 +
16628 +static int file_removed(struct dentry *dentry, const char *file)
16629 +{
16630 +       char *host_file;
16631 +       int extra, fd;
16632 +
16633 +       extra = 0;
16634 +       if(file != NULL) extra += strlen(file) + 1;
16635 +
16636 +       host_file = dentry_name(dentry, extra + strlen("/remove"));
16637 +       if(host_file == NULL){
16638 +               printk("file_removed : allocation failed\n");
16639 +               return(-ENOMEM);
16640 +       }
16641 +
16642 +       if(file != NULL){
16643 +               strcat(host_file, "/");
16644 +               strcat(host_file, file);
16645 +       }
16646 +       strcat(host_file, "/remove");
16647 +
16648 +       fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
16649 +       kfree(host_file);
16650 +       if(fd > 0){
16651 +               os_close_file(fd);
16652 +               return(1);
16653 +       }
16654 +       return(0);
16655 +}
16656 +
16657 +static void hppfs_read_inode(struct inode *ino)
16658 +{
16659 +       struct inode *proc_ino;
16660 +
16661 +       if(HPPFS_I(ino)->proc_dentry == NULL)
16662 +               return;
16663 +
16664 +       proc_ino = HPPFS_I(ino)->proc_dentry->d_inode;
16665 +       ino->i_uid = proc_ino->i_uid;
16666 +       ino->i_gid = proc_ino->i_gid;
16667 +       ino->i_atime = proc_ino->i_atime;
16668 +       ino->i_mtime = proc_ino->i_mtime;
16669 +       ino->i_ctime = proc_ino->i_ctime;
16670 +       ino->i_ino = proc_ino->i_ino;
16671 +       ino->i_mode = proc_ino->i_mode;
16672 +       ino->i_nlink = proc_ino->i_nlink;
16673 +       ino->i_size = proc_ino->i_size;
16674 +       ino->i_blksize = proc_ino->i_blksize;
16675 +       ino->i_blocks = proc_ino->i_blocks;
16676 +}
16677 +
16678 +static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, 
16679 +                                  struct nameidata *nd)
16680 +{
16681 +       struct dentry *proc_dentry, *new, *parent;
16682 +       struct inode *inode;
16683 +       int err, deleted;
16684 +
16685 +       deleted = file_removed(dentry, NULL);
16686 +       if(deleted < 0)
16687 +               return(ERR_PTR(deleted));
16688 +       else if(deleted)
16689 +               return(ERR_PTR(-ENOENT));
16690 +
16691 +       err = -ENOMEM;
16692 +       parent = HPPFS_I(ino)->proc_dentry;
16693 +       down(&parent->d_inode->i_sem);
16694 +       proc_dentry = d_lookup(parent, &dentry->d_name);
16695 +       if(proc_dentry == NULL){
16696 +               proc_dentry = d_alloc(parent, &dentry->d_name);
16697 +               if(proc_dentry == NULL){
16698 +                       up(&parent->d_inode->i_sem);
16699 +                       goto out;
16700 +               }
16701 +               new = (*parent->d_inode->i_op->lookup)(parent->d_inode, 
16702 +                                                      proc_dentry, NULL);
16703 +               if(new){
16704 +                       dput(proc_dentry);
16705 +                       proc_dentry = new;
16706 +               }
16707 +       }
16708 +       up(&parent->d_inode->i_sem);
16709 +
16710 +       if(IS_ERR(proc_dentry))
16711 +               return(proc_dentry);
16712 +
16713 +       inode = iget(ino->i_sb, 0);
16714 +       if(inode == NULL) 
16715 +               goto out_dput;
16716 +
16717 +       err = init_inode(inode, proc_dentry);
16718 +       if(err) 
16719 +               goto out_put;
16720 +       
16721 +       hppfs_read_inode(inode);
16722 +
16723 +       d_add(dentry, inode);
16724 +       dentry->d_op = &hppfs_dentry_ops;
16725 +       return(NULL);
16726 +
16727 + out_put:
16728 +       iput(inode);
16729 + out_dput:
16730 +       dput(proc_dentry);
16731 + out:
16732 +       return(ERR_PTR(err));
16733 +}
16734 +
16735 +static struct inode_operations hppfs_file_iops = {
16736 +};
16737 +
16738 +static ssize_t read_proc(struct file *file, char *buf, ssize_t count, 
16739 +                        loff_t *ppos, int is_user)
16740 +{
16741 +       ssize_t (*read)(struct file *, char *, size_t, loff_t *);
16742 +       ssize_t n;
16743 +
16744 +       read = file->f_dentry->d_inode->i_fop->read;
16745 +
16746 +       if(!is_user)
16747 +               set_fs(KERNEL_DS);
16748 +               
16749 +       n = (*read)(file, buf, count, &file->f_pos);
16750 +
16751 +       if(!is_user)
16752 +               set_fs(USER_DS);
16753 +
16754 +       if(ppos) *ppos = file->f_pos;
16755 +       return(n);
16756 +}
16757 +
16758 +static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
16759 +{
16760 +       ssize_t n;
16761 +       int cur, err;
16762 +       char *new_buf;
16763 +
16764 +       n = -ENOMEM;
16765 +       new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
16766 +       if(new_buf == NULL){
16767 +               printk("hppfs_read_file : kmalloc failed\n");
16768 +               goto out;
16769 +       }
16770 +       n = 0;
16771 +       while(count > 0){
16772 +               cur = min_t(ssize_t, count, PAGE_SIZE);
16773 +               err = os_read_file(fd, new_buf, cur);
16774 +               if(err < 0){
16775 +                       printk("hppfs_read : read failed, errno = %d\n",
16776 +                              count);
16777 +                       n = err;
16778 +                       goto out_free;
16779 +               }
16780 +               else if(err == 0)
16781 +                       break;
16782 +
16783 +               if(copy_to_user(buf, new_buf, err)){
16784 +                       n = -EFAULT;
16785 +                       goto out_free;
16786 +               }
16787 +               n += err;
16788 +               count -= err;
16789 +       }
16790 + out_free:
16791 +       kfree(new_buf);
16792 + out:
16793 +       return(n);
16794 +}
16795 +
16796 +static ssize_t hppfs_read(struct file *file, char *buf, size_t count, 
16797 +                         loff_t *ppos)
16798 +{
16799 +       struct hppfs_private *hppfs = file->private_data;
16800 +       struct hppfs_data *data;
16801 +       loff_t off;
16802 +       int err;
16803 +
16804 +       if(hppfs->contents != NULL){
16805 +               if(*ppos >= hppfs->len) return(0);
16806 +
16807 +               data = hppfs->contents;
16808 +               off = *ppos;
16809 +               while(off >= sizeof(data->contents)){
16810 +                       data = list_entry(data->list.next, struct hppfs_data,
16811 +                                         list);
16812 +                       off -= sizeof(data->contents);
16813 +               }
16814 +
16815 +               if(off + count > hppfs->len)
16816 +                       count = hppfs->len - off;
16817 +               copy_to_user(buf, &data->contents[off], count);
16818 +               *ppos += count;
16819 +       }
16820 +       else if(hppfs->host_fd != -1){
16821 +               err = os_seek_file(hppfs->host_fd, *ppos);
16822 +               if(err){
16823 +                       printk("hppfs_read : seek failed, errno = %d\n", err);
16824 +                       return(err);
16825 +               }
16826 +               count = hppfs_read_file(hppfs->host_fd, buf, count);
16827 +               if(count > 0)
16828 +                       *ppos += count;
16829 +       }
16830 +       else count = read_proc(&hppfs->proc_file, buf, count, ppos, 1);
16831 +
16832 +       return(count);
16833 +}
16834 +
16835 +static ssize_t hppfs_write(struct file *file, const char *buf, size_t len, 
16836 +                          loff_t *ppos)
16837 +{
16838 +       struct hppfs_private *data = file->private_data;
16839 +       struct file *proc_file = &data->proc_file;
16840 +       ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
16841 +       int err;
16842 +
16843 +       write = proc_file->f_dentry->d_inode->i_fop->write;
16844 +
16845 +       proc_file->f_pos = file->f_pos;
16846 +       err = (*write)(proc_file, buf, len, &proc_file->f_pos);
16847 +       file->f_pos = proc_file->f_pos;
16848 +
16849 +       return(err);
16850 +}
16851 +
16852 +static int open_host_sock(char *host_file, int *filter_out)
16853 +{
16854 +       char *end;
16855 +       int fd;
16856 +
16857 +       end = &host_file[strlen(host_file)];
16858 +       strcpy(end, "/rw");
16859 +       *filter_out = 1;
16860 +       fd = os_connect_socket(host_file);
16861 +       if(fd > 0)
16862 +               return(fd);
16863 +
16864 +       strcpy(end, "/r");
16865 +       *filter_out = 0;
16866 +       fd = os_connect_socket(host_file);
16867 +       return(fd);
16868 +}
16869 +
16870 +static void free_contents(struct hppfs_data *head)
16871 +{
16872 +       struct hppfs_data *data;
16873 +       struct list_head *ele, *next;
16874 +
16875 +       if(head == NULL) return;
16876 +
16877 +       list_for_each_safe(ele, next, &head->list){
16878 +               data = list_entry(ele, struct hppfs_data, list);
16879 +               kfree(data);
16880 +       }
16881 +       kfree(head);
16882 +}
16883 +
16884 +static struct hppfs_data *hppfs_get_data(int fd, int filter, 
16885 +                                        struct file *proc_file, 
16886 +                                        struct file *hppfs_file, 
16887 +                                        loff_t *size_out)
16888 +{
16889 +       struct hppfs_data *data, *new, *head;
16890 +       int n, err;
16891 +
16892 +       err = -ENOMEM;
16893 +       data = kmalloc(sizeof(*data), GFP_KERNEL);
16894 +       if(data == NULL){
16895 +               printk("hppfs_get_data : head allocation failed\n");
16896 +               goto failed;
16897 +       }
16898 +
16899 +       INIT_LIST_HEAD(&data->list);
16900 +
16901 +       head = data;
16902 +       *size_out = 0;
16903 +
16904 +       if(filter){
16905 +               while((n = read_proc(proc_file, data->contents,
16906 +                                    sizeof(data->contents), NULL, 0)) > 0)
16907 +                       os_write_file(fd, data->contents, n);
16908 +               err = os_shutdown_socket(fd, 0, 1);
16909 +               if(err){
16910 +                       printk("hppfs_get_data : failed to shut down "
16911 +                              "socket\n");
16912 +                       goto failed_free;
16913 +               }
16914 +       }
16915 +       while(1){
16916 +               n = os_read_file(fd, data->contents, sizeof(data->contents));
16917 +               if(n < 0){
16918 +                       err = n;
16919 +                       printk("hppfs_get_data : read failed, errno = %d\n",
16920 +                              err);
16921 +                       goto failed_free;
16922 +               }
16923 +               else if(n == 0)
16924 +                       break;
16925 +
16926 +               *size_out += n;
16927 +
16928 +               if(n < sizeof(data->contents))
16929 +                       break;
16930 +
16931 +               new = kmalloc(sizeof(*data), GFP_KERNEL);
16932 +               if(new == 0){
16933 +                       printk("hppfs_get_data : data allocation failed\n");
16934 +                       err = -ENOMEM;
16935 +                       goto failed_free;
16936 +               }
16937 +       
16938 +               INIT_LIST_HEAD(&new->list);
16939 +               list_add(&new->list, &data->list);
16940 +               data = new;
16941 +       }
16942 +       return(head);
16943 +
16944 + failed_free:
16945 +       free_contents(head);
16946 + failed:               
16947 +       return(ERR_PTR(err));
16948 +}
16949 +
16950 +static struct hppfs_private *hppfs_data(void)
16951 +{
16952 +       struct hppfs_private *data;
16953 +
16954 +       data = kmalloc(sizeof(*data), GFP_KERNEL);
16955 +       if(data == NULL)
16956 +               return(data);
16957 +
16958 +       *data = ((struct hppfs_private ) { .host_fd             = -1,
16959 +                                          .len                 = -1,
16960 +                                          .contents            = NULL } );
16961 +       return(data);
16962 +}
16963 +
16964 +static int file_mode(int fmode)
16965 +{
16966 +       if(fmode == (FMODE_READ | FMODE_WRITE))
16967 +               return(O_RDWR);
16968 +       if(fmode == FMODE_READ)
16969 +               return(O_RDONLY);
16970 +       if(fmode == FMODE_WRITE)
16971 +               return(O_WRONLY);
16972 +       return(0);
16973 +}
16974 +
16975 +static int hppfs_open(struct inode *inode, struct file *file)
16976 +{
16977 +       struct hppfs_private *data;
16978 +       struct dentry *proc_dentry;
16979 +       char *host_file;
16980 +       int err, fd, type, filter;
16981 +
16982 +       err = -ENOMEM;
16983 +       data = hppfs_data();
16984 +       if(data == NULL)
16985 +               goto out;
16986 +
16987 +       host_file = dentry_name(file->f_dentry, strlen("/rw"));
16988 +       if(host_file == NULL)
16989 +               goto out_free2;
16990 +
16991 +       proc_dentry = HPPFS_I(inode)->proc_dentry;
16992 +
16993 +       /* XXX This isn't closed anywhere */
16994 +       err = open_private_file(&data->proc_file, proc_dentry, 
16995 +                               file_mode(file->f_mode));
16996 +       if(err)
16997 +               goto out_free1;
16998 +
16999 +       type = os_file_type(host_file);
17000 +       if(type == OS_TYPE_FILE){
17001 +               fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
17002 +               if(fd >= 0) 
17003 +                       data->host_fd = fd;
17004 +               else printk("hppfs_open : failed to open '%s', errno = %d\n",
17005 +                           host_file, -fd);
17006 +
17007 +               data->contents = NULL;
17008 +       }
17009 +       else if(type == OS_TYPE_DIR){
17010 +               fd = open_host_sock(host_file, &filter);
17011 +               if(fd > 0){
17012 +                       data->contents = hppfs_get_data(fd, filter, 
17013 +                                                       &data->proc_file, 
17014 +                                                       file, &data->len);
17015 +                       if(!IS_ERR(data->contents))
17016 +                               data->host_fd = fd;
17017 +               }
17018 +               else printk("hppfs_open : failed to open a socket in "
17019 +                           "'%s', errno = %d\n", host_file, -fd);
17020 +       }
17021 +       kfree(host_file);
17022 +
17023 +       file->private_data = data;
17024 +       return(0);
17025 +
17026 + out_free1:
17027 +       kfree(host_file);
17028 + out_free2:
17029 +       free_contents(data->contents);
17030 +       kfree(data);
17031 + out:
17032 +       return(err);
17033 +}
17034 +
17035 +static int hppfs_dir_open(struct inode *inode, struct file *file)
17036 +{
17037 +       struct hppfs_private *data;
17038 +       struct dentry *proc_dentry;
17039 +       int err;
17040 +
17041 +       err = -ENOMEM;
17042 +       data = hppfs_data();
17043 +       if(data == NULL)
17044 +               goto out;
17045 +
17046 +       proc_dentry = HPPFS_I(inode)->proc_dentry;
17047 +       err = open_private_file(&data->proc_file, proc_dentry, 
17048 +                               file_mode(file->f_mode));
17049 +       if(err)
17050 +               goto out_free;
17051 +
17052 +       file->private_data = data;
17053 +       return(0);
17054 +
17055 + out_free:
17056 +       kfree(data);
17057 + out:
17058 +       return(err);
17059 +}
17060 +
17061 +static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
17062 +{
17063 +       struct hppfs_private *data = file->private_data;
17064 +       struct file *proc_file = &data->proc_file;
17065 +       loff_t (*llseek)(struct file *, loff_t, int);
17066 +       loff_t ret;
17067 +
17068 +       llseek = proc_file->f_dentry->d_inode->i_fop->llseek;
17069 +       if(llseek != NULL){
17070 +               ret = (*llseek)(proc_file, off, where);
17071 +               if(ret < 0)
17072 +                       return(ret);
17073 +       }
17074 +
17075 +       return(default_llseek(file, off, where));
17076 +}
17077 +
17078 +static struct file_operations hppfs_file_fops = {
17079 +       .owner          = NULL,
17080 +       .llseek         = hppfs_llseek,
17081 +       .read           = hppfs_read,
17082 +       .write          = hppfs_write,
17083 +       .open           = hppfs_open,
17084 +};
17085 +
17086 +struct hppfs_dirent {
17087 +       void *vfs_dirent;
17088 +       filldir_t filldir;
17089 +       struct dentry *dentry;
17090 +};
17091 +
17092 +static int hppfs_filldir(void *d, const char *name, int size, 
17093 +                        loff_t offset, ino_t inode, unsigned int type)
17094 +{
17095 +       struct hppfs_dirent *dirent = d;
17096 +
17097 +       if(file_removed(dirent->dentry, name))
17098 +               return(0);
17099 +
17100 +       return((*dirent->filldir)(dirent->vfs_dirent, name, size, offset, 
17101 +                                 inode, type));
17102 +}
17103 +
17104 +static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
17105 +{
17106 +       struct hppfs_private *data = file->private_data;
17107 +       struct file *proc_file = &data->proc_file;
17108 +       int (*readdir)(struct file *, void *, filldir_t);
17109 +       struct hppfs_dirent dirent = ((struct hppfs_dirent)
17110 +                                     { .vfs_dirent     = ent,
17111 +                                       .filldir        = filldir,
17112 +                                       .dentry         = file->f_dentry } );
17113 +       int err;
17114 +
17115 +       readdir = proc_file->f_dentry->d_inode->i_fop->readdir;
17116 +
17117 +       proc_file->f_pos = file->f_pos;
17118 +       err = (*readdir)(proc_file, &dirent, hppfs_filldir);
17119 +       file->f_pos = proc_file->f_pos;
17120 +
17121 +       return(err);
17122 +}
17123 +
17124 +static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync)
17125 +{
17126 +       return(0);
17127 +}
17128 +
17129 +static struct file_operations hppfs_dir_fops = {
17130 +       .owner          = NULL,
17131 +       .readdir        = hppfs_readdir,
17132 +       .open           = hppfs_dir_open,
17133 +       .fsync          = hppfs_fsync,
17134 +};
17135 +
17136 +static int hppfs_statfs(struct super_block *sb, struct kstatfs *sf)
17137 +{
17138 +       sf->f_blocks = 0;
17139 +       sf->f_bfree = 0;
17140 +       sf->f_bavail = 0;
17141 +       sf->f_files = 0;
17142 +       sf->f_ffree = 0;
17143 +       sf->f_type = HPPFS_SUPER_MAGIC;
17144 +       return(0);
17145 +}
17146 +
17147 +static struct inode *hppfs_alloc_inode(struct super_block *sb)
17148 +{
17149 +       struct hppfs_inode_info *hi;
17150 +
17151 +       hi = kmalloc(sizeof(*hi), GFP_KERNEL);
17152 +       if(hi == NULL) 
17153 +               return(NULL);
17154 +
17155 +       *hi = ((struct hppfs_inode_info) { .proc_dentry = NULL });
17156 +       inode_init_once(&hi->vfs_inode);
17157 +       return(&hi->vfs_inode);
17158 +}
17159 +
17160 +void hppfs_delete_inode(struct inode *ino)
17161 +{
17162 +       clear_inode(ino);
17163 +}
17164 +
17165 +static void hppfs_destroy_inode(struct inode *inode)
17166 +{
17167 +       kfree(HPPFS_I(inode));
17168 +}
17169 +
17170 +static struct super_operations hppfs_sbops = { 
17171 +       .alloc_inode    = hppfs_alloc_inode,
17172 +       .destroy_inode  = hppfs_destroy_inode,
17173 +       .read_inode     = hppfs_read_inode,
17174 +       .delete_inode   = hppfs_delete_inode,
17175 +       .statfs         = hppfs_statfs,
17176 +};
17177 +
17178 +static int hppfs_readlink(struct dentry *dentry, char *buffer, int buflen)
17179 +{
17180 +       struct file proc_file;
17181 +       struct dentry *proc_dentry;
17182 +       int (*readlink)(struct dentry *, char *, int);
17183 +       int err, n;
17184 +
17185 +       proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
17186 +       err = open_private_file(&proc_file, proc_dentry, O_RDONLY);
17187 +       if(err) 
17188 +               return(err);
17189 +
17190 +       readlink = proc_dentry->d_inode->i_op->readlink;
17191 +       n = (*readlink)(proc_dentry, buffer, buflen);
17192 +
17193 +       close_private_file(&proc_file);
17194 +       
17195 +       return(n);
17196 +}
17197 +
17198 +static int hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
17199 +{
17200 +       struct file proc_file;
17201 +       struct dentry *proc_dentry;
17202 +       int (*follow_link)(struct dentry *, struct nameidata *);
17203 +       int err, n;
17204 +
17205 +       proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
17206 +       err = open_private_file(&proc_file, proc_dentry, O_RDONLY);
17207 +       if(err) 
17208 +               return(err);
17209 +
17210 +       follow_link = proc_dentry->d_inode->i_op->follow_link;
17211 +       n = (*follow_link)(proc_dentry, nd);
17212 +
17213 +       close_private_file(&proc_file);
17214 +       
17215 +       return(n);
17216 +}
17217 +
17218 +static struct inode_operations hppfs_dir_iops = {
17219 +       .lookup         = hppfs_lookup,
17220 +};
17221 +
17222 +static struct inode_operations hppfs_link_iops = {
17223 +       .readlink       = hppfs_readlink,
17224 +       .follow_link    = hppfs_follow_link,
17225 +};
17226 +
17227 +static int init_inode(struct inode *inode, struct dentry *dentry)
17228 +{
17229 +       if(S_ISDIR(dentry->d_inode->i_mode)){
17230 +               inode->i_op = &hppfs_dir_iops;
17231 +               inode->i_fop = &hppfs_dir_fops;
17232 +       }
17233 +       else if(S_ISLNK(dentry->d_inode->i_mode)){
17234 +               inode->i_op = &hppfs_link_iops;
17235 +               inode->i_fop = &hppfs_file_fops;
17236 +       }
17237 +       else {
17238 +               inode->i_op = &hppfs_file_iops;
17239 +               inode->i_fop = &hppfs_file_fops;
17240 +       }
17241 +
17242 +       HPPFS_I(inode)->proc_dentry = dentry;
17243 +
17244 +       return(0);
17245 +}
17246 +
17247 +static int hppfs_fill_super(struct super_block *sb, void *d, int silent)
17248 +{
17249 +       struct inode *root_inode;
17250 +       struct file_system_type *procfs;
17251 +       struct super_block *proc_sb;
17252 +       int err;
17253 +
17254 +       err = -ENOENT;
17255 +       procfs = get_fs_type("proc");
17256 +       if(procfs == NULL) 
17257 +               goto out;
17258 +
17259 +       if(list_empty(&procfs->fs_supers))
17260 +               goto out;
17261 +
17262 +       proc_sb = list_entry(procfs->fs_supers.next, struct super_block,
17263 +                            s_instances);
17264 +       
17265 +       sb->s_blocksize = 1024;
17266 +       sb->s_blocksize_bits = 10;
17267 +       sb->s_magic = HPPFS_SUPER_MAGIC;
17268 +       sb->s_op = &hppfs_sbops;
17269 +
17270 +       root_inode = iget(sb, 0);
17271 +       if(root_inode == NULL)
17272 +               goto out;
17273 +
17274 +       err = init_inode(root_inode, proc_sb->s_root);
17275 +       if(err)
17276 +               goto out_put;
17277 +
17278 +       err = -ENOMEM;
17279 +       sb->s_root = d_alloc_root(root_inode);
17280 +       if(sb->s_root == NULL)
17281 +               goto out_put;
17282 +
17283 +       hppfs_read_inode(root_inode);
17284 +
17285 +       return(0);
17286 +
17287 + out_put:
17288 +       iput(root_inode);
17289 + out:
17290 +       return(err);
17291 +}
17292 +
17293 +static struct super_block *hppfs_read_super(struct file_system_type *type,
17294 +                                            int flags, const char *dev_name,
17295 +                                            void *data)
17296 +{
17297 +       return(get_sb_nodev(type, flags, data, hppfs_fill_super));
17298 +}
17299 +
17300 +static struct file_system_type hppfs_type = {
17301 +       .owner          = THIS_MODULE,
17302 +       .name           = "hppfs",
17303 +       .get_sb         = hppfs_read_super,
17304 +       .kill_sb        = kill_anon_super,
17305 +       .fs_flags       = 0,
17306 +};
17307 +
17308 +static int __init init_hppfs(void)
17309 +{
17310 +       return(register_filesystem(&hppfs_type));
17311 +}
17312 +
17313 +static void __exit exit_hppfs(void)
17314 +{
17315 +       unregister_filesystem(&hppfs_type);
17316 +}
17317 +
17318 +module_init(init_hppfs)
17319 +module_exit(exit_hppfs)
17320 +MODULE_LICENSE("GPL");
17321 +
17322 +/*
17323 + * Overrides for Emacs so that we follow Linus's tabbing style.
17324 + * Emacs will notice this stuff at the end of the file and automatically
17325 + * adjust the settings for this buffer only.  This must remain at the end
17326 + * of the file.
17327 + * ---------------------------------------------------------------------------
17328 + * Local variables:
17329 + * c-file-style: "linux"
17330 + * End:
17331 + */
17332 diff -Naur a/fs/hppfs/Makefile b/fs/hppfs/Makefile
17333 --- a/fs/hppfs/Makefile 1969-12-31 19:00:00.000000000 -0500
17334 +++ b/fs/hppfs/Makefile 2004-02-11 12:27:35.000000000 -0500
17335 @@ -0,0 +1,19 @@
17336 +# 
17337 +# Copyright (C) 2002, 2003 Jeff Dike (jdike@karaya.com)
17338 +# Licensed under the GPL
17339 +#
17340 +
17341 +hppfs-objs := hppfs_kern.o
17342 +
17343 +obj-y = 
17344 +obj-$(CONFIG_HPPFS) += hppfs.o
17345 +
17346 +clean:
17347 +
17348 +modules:
17349 +
17350 +fastdep:
17351 +
17352 +dep:
17353 +
17354 +archmrproper: clean
17355 diff -Naur a/fs/Makefile b/fs/Makefile
17356 --- a/fs/Makefile       2004-02-11 12:15:52.000000000 -0500
17357 +++ b/fs/Makefile       2004-02-11 12:27:45.000000000 -0500
17358 @@ -91,3 +91,5 @@
17359  obj-$(CONFIG_XFS_FS)           += xfs/
17360  obj-$(CONFIG_AFS_FS)           += afs/
17361  obj-$(CONFIG_BEFS_FS)          += befs/
17362 +obj-$(CONFIG_HOSTFS)           += hostfs/
17363 +obj-$(CONFIG_HPPFS)            += hppfs/
17364 diff -Naur a/include/asm-um/archparam-i386.h b/include/asm-um/archparam-i386.h
17365 --- a/include/asm-um/archparam-i386.h   2004-02-11 12:16:32.000000000 -0500
17366 +++ b/include/asm-um/archparam-i386.h   2004-02-11 12:28:31.000000000 -0500
17367 @@ -1,5 +1,5 @@
17368  /* 
17369 - * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com)
17370 + * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
17371   * Licensed under the GPL
17372   */
17373  
17374 @@ -56,6 +56,83 @@
17375         pr_reg[16] = PT_REGS_SS(regs);          \
17376  } while(0);
17377  
17378 +#if 0 /* Turn this back on when UML has VSYSCALL working */
17379 +#define VSYSCALL_BASE  (__fix_to_virt(FIX_VSYSCALL))
17380 +#else
17381 +#define VSYSCALL_BASE  NULL
17382 +#endif
17383 +
17384 +#define VSYSCALL_EHDR  ((const struct elfhdr *) VSYSCALL_BASE)
17385 +#define VSYSCALL_ENTRY ((unsigned long) &__kernel_vsyscall)
17386 +extern void *__kernel_vsyscall;
17387 +
17388 +/*
17389 + * Architecture-neutral AT_ values in 0-17, leave some room
17390 + * for more of them, start the x86-specific ones at 32.
17391 + */
17392 +#define AT_SYSINFO             32
17393 +#define AT_SYSINFO_EHDR                33
17394 +
17395 +#define ARCH_DLINFO                                            \
17396 +do {                                                           \
17397 +               NEW_AUX_ENT(AT_SYSINFO, VSYSCALL_ENTRY);        \
17398 +               NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE);    \
17399 +} while (0)
17400 +
17401 +/*
17402 + * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
17403 + * extra segments containing the vsyscall DSO contents.  Dumping its
17404 + * contents makes post-mortem fully interpretable later without matching up
17405 + * the same kernel and hardware config to see what PC values meant.
17406 + * Dumping its extra ELF program headers includes all the other information
17407 + * a debugger needs to easily find how the vsyscall DSO was being used.
17408 + */
17409 +#define ELF_CORE_EXTRA_PHDRS           (VSYSCALL_EHDR->e_phnum)
17410 +#define ELF_CORE_WRITE_EXTRA_PHDRS                                           \
17411 +do {                                                                         \
17412 +       const struct elf_phdr *const vsyscall_phdrs =                         \
17413 +               (const struct elf_phdr *) (VSYSCALL_BASE                      \
17414 +                                          + VSYSCALL_EHDR->e_phoff);         \
17415 +       int i;                                                                \
17416 +       Elf32_Off ofs = 0;                                                    \
17417 +       for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {                        \
17418 +               struct elf_phdr phdr = vsyscall_phdrs[i];                     \
17419 +               if (phdr.p_type == PT_LOAD) {                                 \
17420 +                       ofs = phdr.p_offset = offset;                         \
17421 +                       offset += phdr.p_filesz;                              \
17422 +               }                                                             \
17423 +               else                                                          \
17424 +                       phdr.p_offset += ofs;                                 \
17425 +               phdr.p_paddr = 0; /* match other core phdrs */                \
17426 +               DUMP_WRITE(&phdr, sizeof(phdr));                              \
17427 +       }                                                                     \
17428 +} while (0)
17429 +#define ELF_CORE_WRITE_EXTRA_DATA                                            \
17430 +do {                                                                         \
17431 +       const struct elf_phdr *const vsyscall_phdrs =                         \
17432 +               (const struct elf_phdr *) (VSYSCALL_BASE                      \
17433 +                                          + VSYSCALL_EHDR->e_phoff);         \
17434 +       int i;                                                                \
17435 +       for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {                        \
17436 +               if (vsyscall_phdrs[i].p_type == PT_LOAD)                      \
17437 +                       DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr,        \
17438 +                                  vsyscall_phdrs[i].p_filesz);               \
17439 +       }                                                                     \
17440 +} while (0)
17441 +
17442 +#define R_386_NONE     0
17443 +#define R_386_32       1
17444 +#define R_386_PC32     2
17445 +#define R_386_GOT32    3
17446 +#define R_386_PLT32    4
17447 +#define R_386_COPY     5
17448 +#define R_386_GLOB_DAT 6
17449 +#define R_386_JMP_SLOT 7
17450 +#define R_386_RELATIVE 8
17451 +#define R_386_GOTOFF   9
17452 +#define R_386_GOTPC    10
17453 +#define R_386_NUM      11
17454 +
17455  /********* Bits for asm-um/delay.h **********/
17456  
17457  typedef unsigned long um_udelay_t;
17458 diff -Naur a/include/asm-um/common.lds.S b/include/asm-um/common.lds.S
17459 --- a/include/asm-um/common.lds.S       2004-02-11 12:14:28.000000000 -0500
17460 +++ b/include/asm-um/common.lds.S       2004-02-11 12:26:11.000000000 -0500
17461 @@ -1,3 +1,5 @@
17462 +#include <asm-generic/vmlinux.lds.h>
17463 +
17464    .fini      : { *(.fini)    } =0x9090
17465    _etext = .;
17466    PROVIDE (etext = .);
17467 @@ -13,18 +15,6 @@
17468  
17469    RODATA
17470  
17471 -  __start___ksymtab = .;       /* Kernel symbol table */
17472 -  __ksymtab : { *(__ksymtab) }
17473 -  __stop___ksymtab = .;
17474 -
17475 -  __start___gpl_ksymtab = .;   /* Kernel symbol table: GPL-only symbols */
17476 -  __gpl_ksymtab : { *(__gpl_ksymtab) }
17477 -  __stop___gpl_ksymtab = .;
17478 -
17479 -  __start___kallsyms = .;       /* All kernel symbols */
17480 -  __kallsyms : { *(__kallsyms) }
17481 -  __stop___kallsyms = .;
17482 -
17483    .unprotected : { *(.unprotected) }
17484    . = ALIGN(4096);
17485    PROVIDE (_unprotected_end = .);
17486 @@ -67,11 +57,17 @@
17487    }
17488    __initcall_end = .;
17489  
17490 +  __con_initcall_start = .;
17491 +  .con_initcall.init : { *(.con_initcall.init) }
17492 +  __con_initcall_end = .;
17493 +
17494    __uml_initcall_start = .;
17495    .uml.initcall.init : { *(.uml.initcall.init) }
17496    __uml_initcall_end = .;
17497    __init_end = .;
17498  
17499 +  SECURITY_INIT
17500 +
17501    __exitcall_begin = .;
17502    .exitcall : { *(.exitcall.exit) }
17503    __exitcall_end = .;
17504 @@ -80,7 +76,33 @@
17505    .uml.exitcall : { *(.uml.exitcall.exit) }
17506    __uml_exitcall_end = .;
17507  
17508 -  . = ALIGN(4096);
17509 +  . = ALIGN(4);
17510 +  __alt_instructions = .;
17511 +  .altinstructions : { *(.altinstructions) } 
17512 +  __alt_instructions_end = .; 
17513 +  .altinstr_replacement : { *(.altinstr_replacement) } 
17514 +  /* .exit.text is discard at runtime, not link time, to deal with references
17515 +     from .altinstructions and .eh_frame */
17516 +  .exit.text : { *(.exit.text) }
17517 +  .exit.data : { *(.exit.data) }
17518
17519 +  __preinit_array_start = .;
17520 +  .preinit_array : { *(.preinit_array) }
17521 +  __preinit_array_end = .;
17522 +  __init_array_start = .;
17523 +  .init_array : { *(.init_array) }
17524 +  __init_array_end = .;
17525 +  __fini_array_start = .;
17526 +  .fini_array : { *(.fini_array) }
17527 +  __fini_array_end = .;
17528 +
17529 +   . = ALIGN(4096);
17530    __initramfs_start = .;
17531    .init.ramfs : { *(.init.ramfs) }
17532    __initramfs_end = .;
17533 +
17534 +  /* Sections to be discarded */
17535 +  /DISCARD/ : {
17536 +       *(.exitcall.exit)
17537 +  }
17538
17539 diff -Naur a/include/asm-um/cpufeature.h b/include/asm-um/cpufeature.h
17540 --- a/include/asm-um/cpufeature.h       1969-12-31 19:00:00.000000000 -0500
17541 +++ b/include/asm-um/cpufeature.h       2004-02-11 12:25:42.000000000 -0500
17542 @@ -0,0 +1,6 @@
17543 +#ifndef __UM_CPUFEATURE_H
17544 +#define __UM_CPUFEATURE_H
17545 +
17546 +#include "asm/arch/cpufeature.h"
17547 +
17548 +#endif
17549 diff -Naur a/include/asm-um/current.h b/include/asm-um/current.h
17550 --- a/include/asm-um/current.h  2004-02-11 12:14:18.000000000 -0500
17551 +++ b/include/asm-um/current.h  2004-02-11 12:26:01.000000000 -0500
17552 @@ -16,8 +16,10 @@
17553  #define CURRENT_THREAD(dummy) (((unsigned long) &dummy) & \
17554                                 (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER))
17555  
17556 -#define current ({ int dummy; \
17557 -                   ((struct thread_info *) CURRENT_THREAD(dummy))->task; })
17558 +#define current_thread \
17559 +       ({ int dummy; ((struct thread_info *) CURRENT_THREAD(dummy)); })
17560 +
17561 +#define current (current_thread->task)
17562  
17563  #endif /* __ASSEMBLY__ */
17564  
17565 diff -Naur a/include/asm-um/elf.h b/include/asm-um/elf.h
17566 --- a/include/asm-um/elf.h      2004-02-11 12:16:01.000000000 -0500
17567 +++ b/include/asm-um/elf.h      2004-02-11 12:27:55.000000000 -0500
17568 @@ -15,4 +15,17 @@
17569  
17570  #define USE_ELF_CORE_DUMP
17571  
17572 +#define R_386_NONE     0
17573 +#define R_386_32       1
17574 +#define R_386_PC32     2
17575 +#define R_386_GOT32    3
17576 +#define R_386_PLT32    4
17577 +#define R_386_COPY     5
17578 +#define R_386_GLOB_DAT 6
17579 +#define R_386_JMP_SLOT 7
17580 +#define R_386_RELATIVE 8
17581 +#define R_386_GOTOFF   9
17582 +#define R_386_GOTPC    10
17583 +#define R_386_NUM      11
17584 +
17585  #endif
17586 diff -Naur a/include/asm-um/fixmap.h b/include/asm-um/fixmap.h
17587 --- a/include/asm-um/fixmap.h   2004-02-11 12:16:42.000000000 -0500
17588 +++ b/include/asm-um/fixmap.h   2004-02-11 12:28:41.000000000 -0500
17589 @@ -34,6 +34,7 @@
17590         FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
17591         FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
17592  #endif
17593 +       FIX_VSYSCALL,
17594         __end_of_fixed_addresses
17595  };
17596  
17597 @@ -63,6 +64,13 @@
17598  #define __fix_to_virt(x)       (FIXADDR_TOP - ((x) << PAGE_SHIFT))
17599  #define __virt_to_fix(x)      ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
17600  
17601 +/*
17602 + * This is the range that is readable by user mode, and things
17603 + * acting like user mode such as get_user_pages.
17604 + */
17605 +#define FIXADDR_USER_START     (__fix_to_virt(FIX_VSYSCALL))
17606 +#define FIXADDR_USER_END       (FIXADDR_USER_START + PAGE_SIZE)
17607 +
17608  extern void __this_fixmap_does_not_exist(void);
17609  
17610  /*
17611 diff -Naur a/include/asm-um/irq.h b/include/asm-um/irq.h
17612 --- a/include/asm-um/irq.h      2004-02-11 12:17:06.000000000 -0500
17613 +++ b/include/asm-um/irq.h      2004-02-11 12:29:07.000000000 -0500
17614 @@ -1,15 +1,6 @@
17615  #ifndef __UM_IRQ_H
17616  #define __UM_IRQ_H
17617  
17618 -/* The i386 irq.h has a struct task_struct in a prototype without including
17619 - * sched.h.  This forward declaration kills the resulting warning.
17620 - */
17621 -struct task_struct;
17622 -
17623 -#include "asm/ptrace.h"
17624 -
17625 -#undef NR_IRQS
17626 -
17627  #define TIMER_IRQ              0
17628  #define UMN_IRQ                        1
17629  #define CONSOLE_IRQ            2
17630 @@ -28,8 +19,4 @@
17631  #define LAST_IRQ XTERM_IRQ
17632  #define NR_IRQS (LAST_IRQ + 1)
17633  
17634 -extern int um_request_irq(unsigned int irq, int fd, int type,
17635 -                         void (*handler)(int, void *, struct pt_regs *),
17636 -                         unsigned long irqflags,  const char * devname,
17637 -                         void *dev_id);
17638  #endif
17639 diff -Naur a/include/asm-um/local.h b/include/asm-um/local.h
17640 --- a/include/asm-um/local.h    1969-12-31 19:00:00.000000000 -0500
17641 +++ b/include/asm-um/local.h    2004-02-11 12:27:52.000000000 -0500
17642 @@ -0,0 +1,6 @@
17643 +#ifndef __UM_LOCAL_H
17644 +#define __UM_LOCAL_H
17645 +
17646 +#include "asm/arch/local.h"
17647 +
17648 +#endif
17649 diff -Naur a/include/asm-um/module-generic.h b/include/asm-um/module-generic.h
17650 --- a/include/asm-um/module-generic.h   1969-12-31 19:00:00.000000000 -0500
17651 +++ b/include/asm-um/module-generic.h   2004-02-11 12:27:42.000000000 -0500
17652 @@ -0,0 +1,6 @@
17653 +#ifndef __UM_MODULE_GENERIC_H
17654 +#define __UM_MODULE_GENERIC_H
17655 +
17656 +#include "asm/arch/module.h"
17657 +
17658 +#endif
17659 diff -Naur a/include/asm-um/module-i386.h b/include/asm-um/module-i386.h
17660 --- a/include/asm-um/module-i386.h      1969-12-31 19:00:00.000000000 -0500
17661 +++ b/include/asm-um/module-i386.h      2004-02-11 12:27:42.000000000 -0500
17662 @@ -0,0 +1,13 @@
17663 +#ifndef __UM_MODULE_I386_H
17664 +#define __UM_MODULE_I386_H
17665 +
17666 +/* UML is simple */
17667 +struct mod_arch_specific
17668 +{
17669 +};
17670 +
17671 +#define Elf_Shdr Elf32_Shdr
17672 +#define Elf_Sym Elf32_Sym
17673 +#define Elf_Ehdr Elf32_Ehdr
17674 +
17675 +#endif
17676 diff -Naur a/include/asm-um/page.h b/include/asm-um/page.h
17677 --- a/include/asm-um/page.h     2004-02-11 12:15:52.000000000 -0500
17678 +++ b/include/asm-um/page.h     2004-02-11 12:27:45.000000000 -0500
17679 @@ -1,10 +1,14 @@
17680 +/* 
17681 + *  Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
17682 + * Licensed under the GPL
17683 + */
17684 +
17685  #ifndef __UM_PAGE_H
17686  #define __UM_PAGE_H
17687  
17688  struct page;
17689  
17690  #include "asm/arch/page.h"
17691 -#include "asm/bug.h"
17692  
17693  #undef __pa
17694  #undef __va
17695 @@ -24,25 +28,36 @@
17696  
17697  #define __va_space (8*1024*1024)
17698  
17699 -extern unsigned long region_pa(void *virt);
17700 -extern void *region_va(unsigned long phys);
17701 -
17702 -#define __pa(virt) region_pa((void *) (virt))
17703 -#define __va(phys) region_va((unsigned long) (phys))
17704 -
17705 -extern unsigned long page_to_pfn(struct page *page);
17706 -extern struct page *pfn_to_page(unsigned long pfn);
17707 +extern unsigned long to_phys(void *virt);
17708 +extern void *to_virt(unsigned long phys);
17709  
17710 -extern struct page *phys_to_page(unsigned long phys);
17711 +#define __pa(virt) to_phys((void *) virt)
17712 +#define __va(phys) to_virt((unsigned long) phys)
17713  
17714 -#define virt_to_page(v) (phys_to_page(__pa(v)))
17715 +#define page_to_pfn(page) ((page) - mem_map)
17716 +#define pfn_to_page(pfn) (mem_map + (pfn))
17717  
17718 -extern struct page *page_mem_map(struct page *page);
17719 +#define phys_to_pfn(p) ((p) >> PAGE_SHIFT)
17720 +#define pfn_to_phys(pfn) ((pfn) << PAGE_SHIFT)
17721  
17722 -#define pfn_valid(pfn) (page_mem_map(pfn_to_page(pfn)) != NULL)
17723 -#define virt_addr_valid(v) pfn_valid(__pa(v) >> PAGE_SHIFT)
17724 +#define pfn_valid(pfn) ((pfn) < max_mapnr)
17725 +#define virt_addr_valid(v) pfn_valid(phys_to_pfn(__pa(v)))
17726  
17727  extern struct page *arch_validate(struct page *page, int mask, int order);
17728  #define HAVE_ARCH_VALIDATE
17729  
17730 +extern void arch_free_page(struct page *page, int order);
17731 +#define HAVE_ARCH_FREE_PAGE
17732 +
17733  #endif
17734 +
17735 +/*
17736 + * Overrides for Emacs so that we follow Linus's tabbing style.
17737 + * Emacs will notice this stuff at the end of the file and automatically
17738 + * adjust the settings for this buffer only.  This must remain at the end
17739 + * of the file.
17740 + * ---------------------------------------------------------------------------
17741 + * Local variables:
17742 + * c-file-style: "linux"
17743 + * End:
17744 + */
17745 diff -Naur a/include/asm-um/pgtable.h b/include/asm-um/pgtable.h
17746 --- a/include/asm-um/pgtable.h  2004-02-11 12:17:12.000000000 -0500
17747 +++ b/include/asm-um/pgtable.h  2004-02-11 12:29:17.000000000 -0500
17748 @@ -12,8 +12,6 @@
17749  #include "asm/page.h"
17750  #include "asm/fixmap.h"
17751  
17752 -extern pgd_t swapper_pg_dir[1024];
17753 -
17754  extern void *um_virt_to_phys(struct task_struct *task, unsigned long virt,
17755                              pte_t *pte_out);
17756  
17757 @@ -49,6 +47,8 @@
17758  #define pgd_ERROR(e) \
17759          printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e))
17760  
17761 +extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
17762 +
17763  /*
17764   * pgd entries used up by user/kernel:
17765   */
17766 @@ -65,10 +65,10 @@
17767   * area for the same reason. ;)
17768   */
17769  
17770 -extern unsigned long high_physmem;
17771 +extern unsigned long end_iomem;
17772  
17773  #define VMALLOC_OFFSET (__va_space)
17774 -#define VMALLOC_START  (((unsigned long) high_physmem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
17775 +#define VMALLOC_START  ((end_iomem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
17776  
17777  #ifdef CONFIG_HIGHMEM
17778  # define VMALLOC_END   (PKMAP_BASE-2*PAGE_SIZE)
17779 @@ -78,12 +78,13 @@
17780  
17781  #define _PAGE_PRESENT  0x001
17782  #define _PAGE_NEWPAGE  0x002
17783 -#define _PAGE_PROTNONE 0x004   /* If not present */
17784 -#define _PAGE_RW       0x008
17785 -#define _PAGE_USER     0x010
17786 -#define _PAGE_ACCESSED 0x020
17787 -#define _PAGE_DIRTY    0x040
17788 -#define _PAGE_NEWPROT   0x080
17789 +#define _PAGE_NEWPROT   0x004
17790 +#define _PAGE_FILE     0x008   /* set:pagecache unset:swap */
17791 +#define _PAGE_PROTNONE 0x010   /* If not present */
17792 +#define _PAGE_RW       0x020
17793 +#define _PAGE_USER     0x040
17794 +#define _PAGE_ACCESSED 0x080
17795 +#define _PAGE_DIRTY    0x100
17796  
17797  #define REGION_MASK    0xf0000000
17798  #define REGION_SHIFT   28
17799 @@ -143,7 +144,8 @@
17800  
17801  #define BAD_PAGETABLE __bad_pagetable()
17802  #define BAD_PAGE __bad_page()
17803 -#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
17804 +
17805 +#define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page)
17806  
17807  /* number of bits that fit into a memory pointer */
17808  #define BITS_PER_PTR                   (8*sizeof(unsigned long))
17809 @@ -164,9 +166,6 @@
17810  
17811  #define pte_clear(xp)  do { pte_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
17812  
17813 -#define phys_region_index(x) (((x) & REGION_MASK) >> REGION_SHIFT)
17814 -#define pte_region_index(x) phys_region_index(pte_val(x))
17815 -
17816  #define pmd_none(x)    (!(pmd_val(x) & ~_PAGE_NEWPAGE))
17817  #define        pmd_bad(x)      ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
17818  #define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT)
17819 @@ -188,19 +187,25 @@
17820  
17821  #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT))
17822  
17823 -extern struct page *pte_mem_map(pte_t pte);
17824 -extern struct page *phys_mem_map(unsigned long phys);
17825 -extern unsigned long phys_to_pfn(unsigned long p);
17826 -extern unsigned long pfn_to_phys(unsigned long pfn);
17827 -
17828 -#define pte_page(x) pfn_to_page(pte_pfn(x))
17829 -#define pte_address(x) (__va(pte_val(x) & PAGE_MASK))
17830 -#define mk_phys(a, r) ((a) + (r << REGION_SHIFT))
17831 -#define phys_addr(p) ((p) & ~REGION_MASK)
17832 -#define phys_page(p) (phys_mem_map(p) + ((phys_addr(p)) >> PAGE_SHIFT))
17833 +#define pte_page(pte) phys_to_page(pte_val(pte))
17834 +#define pmd_page(pmd) phys_to_page(pmd_val(pmd) & PAGE_MASK)
17835 +
17836  #define pte_pfn(x) phys_to_pfn(pte_val(x))
17837  #define pfn_pte(pfn, prot) __pte(pfn_to_phys(pfn) | pgprot_val(prot))
17838 -#define pfn_pmd(pfn, prot) __pmd(pfn_to_phys(pfn) | pgprot_val(prot))
17839 +
17840 +extern struct page *phys_to_page(const unsigned long phys);
17841 +extern struct page *__virt_to_page(const unsigned long virt);
17842 +#define virt_to_page(addr) __virt_to_page((const unsigned long) addr)
17843 +  
17844 +/*
17845 + * Bits 0 through 3 are taken
17846 + */
17847 +#define PTE_FILE_MAX_BITS      28
17848 +
17849 +#define pte_to_pgoff(pte) ((pte).pte_low >> 4)
17850 +
17851 +#define pgoff_to_pte(off) \
17852 +       ((pte_t) { ((off) << 4) + _PAGE_FILE })
17853  
17854  static inline pte_t pte_mknewprot(pte_t pte)
17855  {
17856 @@ -235,6 +240,12 @@
17857   * The following only work if pte_present() is true.
17858   * Undefined behaviour if not..
17859   */
17860 +static inline int pte_user(pte_t pte)
17861 +{ 
17862 +       return((pte_val(pte) & _PAGE_USER) && 
17863 +              !(pte_val(pte) & _PAGE_PROTNONE));
17864 +}
17865 +
17866  static inline int pte_read(pte_t pte)
17867  { 
17868         return((pte_val(pte) & _PAGE_USER) && 
17869 @@ -252,6 +263,14 @@
17870                !(pte_val(pte) & _PAGE_PROTNONE));
17871  }
17872  
17873 +/*
17874 + * The following only works if pte_present() is not true.
17875 + */
17876 +static inline int pte_file(pte_t pte)
17877 +{ 
17878 +       return (pte).pte_low & _PAGE_FILE; 
17879 +}
17880 +
17881  static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
17882  static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
17883  static inline int pte_newpage(pte_t pte) { return pte_val(pte) & _PAGE_NEWPAGE; }
17884 @@ -334,14 +353,7 @@
17885   * and a page entry and page directory to the page they refer to.
17886   */
17887  
17888 -#define mk_pte(page, pgprot) \
17889 -({                                     \
17890 -       pte_t __pte;                    \
17891 -                                        \
17892 -       pte_val(__pte) = page_to_phys(page) + pgprot_val(pgprot);\
17893 -       if(pte_present(__pte)) pte_mknewprot(pte_mknewpage(__pte)); \
17894 -       __pte;                          \
17895 -})
17896 +extern pte_t mk_pte(struct page *page, pgprot_t pgprot);
17897  
17898  static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
17899  {
17900 @@ -351,17 +363,27 @@
17901  }
17902  
17903  #define pmd_page_kernel(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
17904 -#define pmd_page(pmd) (phys_mem_map(pmd_val(pmd) & PAGE_MASK) + \
17905 -                      ((phys_addr(pmd_val(pmd)) >> PAGE_SHIFT)))
17906  
17907 -/* to find an entry in a page-table-directory. */
17908 +/*
17909 + * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
17910 + *
17911 + * this macro returns the index of the entry in the pgd page which would
17912 + * control the given virtual address
17913 + */
17914  #define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
17915  
17916 -/* to find an entry in a page-table-directory */
17917 +/*
17918 + * pgd_offset() returns a (pgd_t *)
17919 + * pgd_index() is used get the offset into the pgd page's array of pgd_t's;
17920 + */
17921  #define pgd_offset(mm, address) \
17922  ((mm)->pgd + ((address) >> PGDIR_SHIFT))
17923  
17924 -/* to find an entry in a kernel page-table-directory */
17925 +
17926 +/*
17927 + * a shortcut which implies the use of the kernel's pgd, instead
17928 + * of a process's
17929 + */
17930  #define pgd_offset_k(address) pgd_offset(&init_mm, address)
17931  
17932  #define pmd_index(address) \
17933 @@ -373,7 +395,12 @@
17934         return (pmd_t *) dir;
17935  }
17936  
17937 -/* Find an entry in the third-level page table.. */ 
17938 +/*
17939 + * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
17940 + *
17941 + * this macro returns the index of the entry in the pte page which would
17942 + * control the given virtual address
17943 + */
17944  #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
17945  #define pte_offset_kernel(dir, address) \
17946         ((pte_t *) pmd_page_kernel(*(dir)) +  pte_index(address))
17947 @@ -399,11 +426,11 @@
17948  #define update_mmu_cache(vma,address,pte) do ; while (0)
17949  
17950  /* Encode and de-code a swap entry */
17951 -#define __swp_type(x)                  (((x).val >> 3) & 0x7f)
17952 -#define __swp_offset(x)                        ((x).val >> 10)
17953 +#define __swp_type(x)                  (((x).val >> 4) & 0x3f)
17954 +#define __swp_offset(x)                        ((x).val >> 11)
17955  
17956  #define __swp_entry(type, offset) \
17957 -       ((swp_entry_t) { ((type) << 3) | ((offset) << 10) })
17958 +       ((swp_entry_t) { ((type) << 4) | ((offset) << 11) })
17959  #define __pte_to_swp_entry(pte) \
17960         ((swp_entry_t) { pte_val(pte_mkuptodate(pte)) })
17961  #define __swp_entry_to_pte(x)          ((pte_t) { (x).val })
17962 diff -Naur a/include/asm-um/processor-generic.h b/include/asm-um/processor-generic.h
17963 --- a/include/asm-um/processor-generic.h        2004-02-11 12:14:28.000000000 -0500
17964 +++ b/include/asm-um/processor-generic.h        2004-02-11 12:26:10.000000000 -0500
17965 @@ -11,9 +11,7 @@
17966  struct task_struct;
17967  
17968  #include "linux/config.h"
17969 -#include "linux/signal.h"
17970  #include "asm/ptrace.h"
17971 -#include "asm/siginfo.h"
17972  #include "choose-mode.h"
17973  
17974  struct mm_struct;
17975 @@ -22,23 +20,6 @@
17976  
17977  #define cpu_relax()    do ; while (0)
17978  
17979 -#ifdef CONFIG_MODE_TT
17980 -struct proc_tt_mode {
17981 -       int extern_pid;
17982 -       int tracing;
17983 -       int switch_pipe[2];
17984 -       int singlestep_syscall;
17985 -       int vm_seq;
17986 -};
17987 -#endif
17988 -
17989 -#ifdef CONFIG_MODE_SKAS
17990 -struct proc_skas_mode {
17991 -       void *switch_buf;
17992 -       void *fork_buf;
17993 -};
17994 -#endif
17995 -
17996  struct thread_struct {
17997         int forking;
17998         unsigned long kernel_stack;
17999 @@ -46,6 +27,7 @@
18000         struct pt_regs regs;
18001         unsigned long cr2;
18002         int err;
18003 +       unsigned long trap_no;
18004         void *fault_addr;
18005         void *fault_catcher;
18006         struct task_struct *prev_sched;
18007 @@ -54,10 +36,20 @@
18008         struct arch_thread arch;
18009         union {
18010  #ifdef CONFIG_MODE_TT
18011 -               struct proc_tt_mode tt;
18012 +               struct {
18013 +                       int extern_pid;
18014 +                       int tracing;
18015 +                       int switch_pipe[2];
18016 +                       int singlestep_syscall;
18017 +                       int vm_seq;
18018 +               } tt;
18019  #endif
18020  #ifdef CONFIG_MODE_SKAS
18021 -               struct proc_skas_mode skas;
18022 +               struct {
18023 +                       void *switch_buf;
18024 +                       void *fork_buf;
18025 +                       int mm_count;
18026 +               } skas;
18027  #endif
18028         } mode;
18029         struct {
18030 @@ -101,14 +93,19 @@
18031  } mm_segment_t;
18032  
18033  extern struct task_struct *alloc_task_struct(void);
18034 -extern void free_task_struct(struct task_struct *task);
18035  
18036  extern void release_thread(struct task_struct *);
18037  extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
18038  extern void dump_thread(struct pt_regs *regs, struct user *u);
18039 +extern void prepare_to_copy(struct task_struct *tsk);
18040  
18041  extern unsigned long thread_saved_pc(struct task_struct *t);
18042  
18043 +static inline void mm_copy_segments(struct mm_struct *from_mm, 
18044 +                                   struct mm_struct *new_mm)
18045 +{
18046 +}
18047 +
18048  #define init_stack     (init_thread_union.stack)
18049  
18050  /*
18051 diff -Naur a/include/asm-um/processor-i386.h b/include/asm-um/processor-i386.h
18052 --- a/include/asm-um/processor-i386.h   2004-02-11 12:14:17.000000000 -0500
18053 +++ b/include/asm-um/processor-i386.h   2004-02-11 12:26:00.000000000 -0500
18054 @@ -6,8 +6,8 @@
18055  #ifndef __UM_PROCESSOR_I386_H
18056  #define __UM_PROCESSOR_I386_H
18057  
18058 -extern int cpu_has_xmm;
18059 -extern int cpu_has_cmov;
18060 +extern int host_has_xmm;
18061 +extern int host_has_cmov;
18062  
18063  struct arch_thread {
18064         unsigned long debugregs[8];
18065 diff -Naur a/include/asm-um/sections.h b/include/asm-um/sections.h
18066 --- a/include/asm-um/sections.h 1969-12-31 19:00:00.000000000 -0500
18067 +++ b/include/asm-um/sections.h 2004-02-11 12:27:57.000000000 -0500
18068 @@ -0,0 +1,7 @@
18069 +#ifndef _UM_SECTIONS_H
18070 +#define _UM_SECTIONS_H
18071 +
18072 +/* nothing to see, move along */
18073 +#include <asm-generic/sections.h>
18074 +
18075 +#endif
18076 diff -Naur a/include/asm-um/smp.h b/include/asm-um/smp.h
18077 --- a/include/asm-um/smp.h      2004-02-11 12:14:12.000000000 -0500
18078 +++ b/include/asm-um/smp.h      2004-02-11 12:25:41.000000000 -0500
18079 @@ -10,7 +10,7 @@
18080  
18081  extern cpumask_t cpu_online_map;
18082  
18083 -#define smp_processor_id() (current->thread_info->cpu)
18084 +#define smp_processor_id() (current_thread->cpu)
18085  #define cpu_logical_map(n) (n)
18086  #define cpu_number_map(n) (n)
18087  #define PROC_CHANGE_PENALTY    15 /* Pick a number, any number */
18088 diff -Naur a/include/asm-um/smplock.h b/include/asm-um/smplock.h
18089 --- a/include/asm-um/smplock.h  2004-02-11 12:14:27.000000000 -0500
18090 +++ b/include/asm-um/smplock.h  1969-12-31 19:00:00.000000000 -0500
18091 @@ -1,6 +0,0 @@
18092 -#ifndef __UM_SMPLOCK_H
18093 -#define __UM_SMPLOCK_H
18094 -
18095 -#include "asm/arch/smplock.h"
18096 -
18097 -#endif
18098 diff -Naur a/include/asm-um/spinlock.h b/include/asm-um/spinlock.h
18099 --- a/include/asm-um/spinlock.h 2004-02-11 12:16:39.000000000 -0500
18100 +++ b/include/asm-um/spinlock.h 1969-12-31 19:00:00.000000000 -0500
18101 @@ -1,10 +0,0 @@
18102 -#ifndef __UM_SPINLOCK_H
18103 -#define __UM_SPINLOCK_H
18104 -
18105 -#include "linux/config.h"
18106 -
18107 -#ifdef CONFIG_SMP
18108 -#include "asm/arch/spinlock.h"
18109 -#endif
18110 -
18111 -#endif
18112 diff -Naur a/include/asm-um/system-generic.h b/include/asm-um/system-generic.h
18113 --- a/include/asm-um/system-generic.h   2004-02-11 12:17:08.000000000 -0500
18114 +++ b/include/asm-um/system-generic.h   2004-02-11 12:29:12.000000000 -0500
18115 @@ -23,8 +23,10 @@
18116  extern void block_signals(void);
18117  extern void unblock_signals(void);
18118  
18119 -#define local_save_flags(flags) do { (flags) = get_signals(); } while(0)
18120 -#define local_irq_restore(flags) do { set_signals(flags); } while(0)
18121 +#define local_save_flags(flags) do { typecheck(unsigned long, flags); \
18122 +                                    (flags) = get_signals(); } while(0)
18123 +#define local_irq_restore(flags) do { typecheck(unsigned long, flags); \
18124 +                                     set_signals(flags); } while(0)
18125  
18126  #define local_irq_save(flags) do { local_save_flags(flags); \
18127                                     local_irq_disable(); } while(0)
18128 @@ -39,4 +41,7 @@
18129          (flags == 0);                   \
18130  })
18131  
18132 +extern void *_switch_to(void *prev, void *next, void *last);
18133 +#define switch_to(prev, next, last) prev = _switch_to(prev, next, last)
18134 +
18135  #endif
18136 diff -Naur a/include/asm-um/thread_info.h b/include/asm-um/thread_info.h
18137 --- a/include/asm-um/thread_info.h      2004-02-11 12:14:39.000000000 -0500
18138 +++ b/include/asm-um/thread_info.h      2004-02-11 12:26:45.000000000 -0500
18139 @@ -9,6 +9,7 @@
18140  #ifndef __ASSEMBLY__
18141  
18142  #include <asm/processor.h>
18143 +#include <asm/types.h>
18144  
18145  struct thread_info {
18146         struct task_struct      *task;          /* main task structure */
18147 @@ -43,15 +44,18 @@
18148  static inline struct thread_info *current_thread_info(void)
18149  {
18150         struct thread_info *ti;
18151 -       __asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~16383UL));
18152 +       unsigned long mask = PAGE_SIZE * 
18153 +               (1 << CONFIG_KERNEL_STACK_ORDER) - 1;
18154 +       __asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~mask));
18155         return ti;
18156  }
18157  
18158  /* thread information allocation */
18159 -#define THREAD_SIZE (4*PAGE_SIZE)
18160 -#define alloc_thread_info(tsk) ((struct thread_info *) \
18161 -       __get_free_pages(GFP_KERNEL,2))
18162 -#define free_thread_info(ti) free_pages((unsigned long) (ti), 2)
18163 +#define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
18164 +#define alloc_thread_info(tsk) \
18165 +       ((struct thread_info *) kmalloc(THREAD_SIZE, GFP_KERNEL))
18166 +#define free_thread_info(ti) kfree(ti)
18167 +       
18168  #define get_thread_info(ti) get_task_struct((ti)->task)
18169  #define put_thread_info(ti) put_task_struct((ti)->task)
18170  
18171 @@ -65,11 +69,13 @@
18172  #define TIF_POLLING_NRFLAG      3       /* true if poll_idle() is polling 
18173                                          * TIF_NEED_RESCHED 
18174                                          */
18175 +#define TIF_RESTART_BLOCK      4
18176  
18177  #define _TIF_SYSCALL_TRACE     (1 << TIF_SYSCALL_TRACE)
18178  #define _TIF_SIGPENDING                (1 << TIF_SIGPENDING)
18179  #define _TIF_NEED_RESCHED      (1 << TIF_NEED_RESCHED)
18180  #define _TIF_POLLING_NRFLAG     (1 << TIF_POLLING_NRFLAG)
18181 +#define _TIF_RESTART_BLOCK     (1 << TIF_RESTART_BLOCK)
18182  
18183  #endif
18184  
18185 diff -Naur a/include/asm-um/timex.h b/include/asm-um/timex.h
18186 --- a/include/asm-um/timex.h    2004-02-11 12:16:00.000000000 -0500
18187 +++ b/include/asm-um/timex.h    2004-02-11 12:27:53.000000000 -0500
18188 @@ -1,8 +1,6 @@
18189  #ifndef __UM_TIMEX_H
18190  #define __UM_TIMEX_H
18191  
18192 -#include "linux/time.h"
18193 -
18194  typedef unsigned long cycles_t;
18195  
18196  #define cacheflush_time (0)
18197 diff -Naur a/include/asm-um/uaccess.h b/include/asm-um/uaccess.h
18198 --- a/include/asm-um/uaccess.h  2004-02-11 12:16:04.000000000 -0500
18199 +++ b/include/asm-um/uaccess.h  2004-02-11 12:28:00.000000000 -0500
18200 @@ -6,6 +6,8 @@
18201  #ifndef __UM_UACCESS_H
18202  #define __UM_UACCESS_H
18203  
18204 +#include "linux/sched.h"
18205 +
18206  #define VERIFY_READ 0
18207  #define VERIFY_WRITE 1
18208  
18209 diff -Naur a/include/asm-um/unistd.h b/include/asm-um/unistd.h
18210 --- a/include/asm-um/unistd.h   2004-02-11 12:16:33.000000000 -0500
18211 +++ b/include/asm-um/unistd.h   2004-02-11 12:28:32.000000000 -0500
18212 @@ -33,7 +33,10 @@
18213         set_fs(KERNEL_DS);                      \
18214         ret = sys(args);                        \
18215         set_fs(fs);                             \
18216 -       return ret;
18217 +       if (ret >= 0)                           \
18218 +               return ret;                     \
18219 +       errno = -(long)ret;                     \
18220 +       return -1;
18221  
18222  static inline long open(const char *pathname, int flags, int mode) 
18223  {
18224 diff -Naur a/include/linux/gfp.h b/include/linux/gfp.h
18225 --- a/include/linux/gfp.h       2004-02-11 12:14:33.000000000 -0500
18226 +++ b/include/linux/gfp.h       2004-02-11 12:26:16.000000000 -0500
18227 @@ -63,6 +63,11 @@
18228   * For the normal case of non-DISCONTIGMEM systems the NODE_DATA() gets
18229   * optimized to &contig_page_data at compile-time.
18230   */
18231 +
18232 +#ifndef HAVE_ARCH_FREE_PAGE
18233 +static inline void arch_free_page(struct page *page, int order) { }
18234 +#endif
18235 +
18236  extern struct page * FASTCALL(__alloc_pages(unsigned int, unsigned int, struct zonelist *));
18237  static inline struct page * alloc_pages_node(int nid, unsigned int gfp_mask, unsigned int order)
18238  {
18239 diff -Naur a/include/linux/ghash.h b/include/linux/ghash.h
18240 --- a/include/linux/ghash.h     1969-12-31 19:00:00.000000000 -0500
18241 +++ b/include/linux/ghash.h     2004-02-11 12:26:13.000000000 -0500
18242 @@ -0,0 +1,236 @@
18243 +/*
18244 + * include/linux/ghash.h -- generic hashing with fuzzy retrieval
18245 + *
18246 + * (C) 1997 Thomas Schoebel-Theuer
18247 + *
18248 + * The algorithms implemented here seem to be a completely new invention,
18249 + * and I'll publish the fundamentals in a paper.
18250 + */
18251 +
18252 +#ifndef _GHASH_H
18253 +#define _GHASH_H
18254 +/* HASHSIZE _must_ be a power of two!!! */
18255 +
18256 +
18257 +#define DEF_HASH_FUZZY_STRUCTS(NAME,HASHSIZE,TYPE) \
18258 +\
18259 +struct NAME##_table {\
18260 +       TYPE * hashtable[HASHSIZE];\
18261 +       TYPE * sorted_list;\
18262 +       int nr_entries;\
18263 +};\
18264 +\
18265 +struct NAME##_ptrs {\
18266 +       TYPE * next_hash;\
18267 +       TYPE * prev_hash;\
18268 +       TYPE * next_sorted;\
18269 +       TYPE * prev_sorted;\
18270 +};
18271 +
18272 +#define DEF_HASH_FUZZY(LINKAGE,NAME,HASHSIZE,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,KEYEQ,HASHFN)\
18273 +\
18274 +LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
18275 +{\
18276 +       int ix = HASHFN(elem->KEY);\
18277 +       TYPE ** base = &tbl->hashtable[ix];\
18278 +       TYPE * ptr = *base;\
18279 +       TYPE * prev = NULL;\
18280 +\
18281 +       tbl->nr_entries++;\
18282 +       while(ptr && KEYCMP(ptr->KEY, elem->KEY)) {\
18283 +               base = &ptr->PTRS.next_hash;\
18284 +               prev = ptr;\
18285 +               ptr = *base;\
18286 +       }\
18287 +       elem->PTRS.next_hash = ptr;\
18288 +       elem->PTRS.prev_hash = prev;\
18289 +       if(ptr) {\
18290 +               ptr->PTRS.prev_hash = elem;\
18291 +       }\
18292 +       *base = elem;\
18293 +\
18294 +       ptr = prev;\
18295 +       if(!ptr) {\
18296 +               ptr = tbl->sorted_list;\
18297 +               prev = NULL;\
18298 +       } else {\
18299 +               prev = ptr->PTRS.prev_sorted;\
18300 +       }\
18301 +       while(ptr) {\
18302 +               TYPE * next = ptr->PTRS.next_hash;\
18303 +               if(next && KEYCMP(next->KEY, elem->KEY)) {\
18304 +                       prev = ptr;\
18305 +                       ptr = next;\
18306 +               } else if(KEYCMP(ptr->KEY, elem->KEY)) {\
18307 +                       prev = ptr;\
18308 +                       ptr = ptr->PTRS.next_sorted;\
18309 +               } else\
18310 +                       break;\
18311 +       }\
18312 +       elem->PTRS.next_sorted = ptr;\
18313 +       elem->PTRS.prev_sorted = prev;\
18314 +       if(ptr) {\
18315 +               ptr->PTRS.prev_sorted = elem;\
18316 +       }\
18317 +       if(prev) {\
18318 +               prev->PTRS.next_sorted = elem;\
18319 +       } else {\
18320 +               tbl->sorted_list = elem;\
18321 +       }\
18322 +}\
18323 +\
18324 +LINKAGE void remove_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
18325 +{\
18326 +       TYPE * next = elem->PTRS.next_hash;\
18327 +       TYPE * prev = elem->PTRS.prev_hash;\
18328 +\
18329 +       tbl->nr_entries--;\
18330 +       if(next)\
18331 +               next->PTRS.prev_hash = prev;\
18332 +       if(prev)\
18333 +               prev->PTRS.next_hash = next;\
18334 +       else {\
18335 +               int ix = HASHFN(elem->KEY);\
18336 +               tbl->hashtable[ix] = next;\
18337 +       }\
18338 +\
18339 +       next = elem->PTRS.next_sorted;\
18340 +       prev = elem->PTRS.prev_sorted;\
18341 +       if(next)\
18342 +               next->PTRS.prev_sorted = prev;\
18343 +       if(prev)\
18344 +               prev->PTRS.next_sorted = next;\
18345 +       else\
18346 +               tbl->sorted_list = next;\
18347 +}\
18348 +\
18349 +LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\
18350 +{\
18351 +       int ix = hashfn(pos);\
18352 +       TYPE * ptr = tbl->hashtable[ix];\
18353 +       while(ptr && KEYCMP(ptr->KEY, pos))\
18354 +               ptr = ptr->PTRS.next_hash;\
18355 +       if(ptr && !KEYEQ(ptr->KEY, pos))\
18356 +               ptr = NULL;\
18357 +       return ptr;\
18358 +}\
18359 +\
18360 +LINKAGE TYPE * find_##NAME##_hash_fuzzy(struct NAME##_table * tbl, KEYTYPE pos)\
18361 +{\
18362 +       int ix;\
18363 +       int offset;\
18364 +       TYPE * ptr;\
18365 +       TYPE * next;\
18366 +\
18367 +       ptr = tbl->sorted_list;\
18368 +       if(!ptr || KEYCMP(pos, ptr->KEY))\
18369 +               return NULL;\
18370 +       ix = HASHFN(pos);\
18371 +       offset = HASHSIZE;\
18372 +       do {\
18373 +               offset >>= 1;\
18374 +               next = tbl->hashtable[(ix+offset) & ((HASHSIZE)-1)];\
18375 +               if(next && (KEYCMP(next->KEY, pos) || KEYEQ(next->KEY, pos))\
18376 +                  && KEYCMP(ptr->KEY, next->KEY))\
18377 +                       ptr = next;\
18378 +       } while(offset);\
18379 +\
18380 +       for(;;) {\
18381 +               next = ptr->PTRS.next_hash;\
18382 +               if(next) {\
18383 +                       if(KEYCMP(next->KEY, pos)) {\
18384 +                               ptr = next;\
18385 +                               continue;\
18386 +                       }\
18387 +               }\
18388 +               next = ptr->PTRS.next_sorted;\
18389 +               if(next && KEYCMP(next->KEY, pos)) {\
18390 +                       ptr = next;\
18391 +                       continue;\
18392 +               }\
18393 +               return ptr;\
18394 +       }\
18395 +       return NULL;\
18396 +}
18397 +
18398 +/* LINKAGE - empty or "static", depending on whether you want the definitions to
18399 + *     be public or not
18400 + * NAME - a string to stick in names to make this hash table type distinct from
18401 + *     any others
18402 + * HASHSIZE - number of buckets
18403 + * TYPE - type of data contained in the buckets - must be a structure, one 
18404 + *     field is of type NAME_ptrs, another is the hash key
18405 + * PTRS - TYPE must contain a field of type NAME_ptrs, PTRS is the name of that
18406 + *     field
18407 + * KEYTYPE - type of the key field within TYPE
18408 + * KEY - name of the key field within TYPE
18409 + * KEYCMP - pointer to function that compares KEYTYPEs to each other - the
18410 + *     prototype is int KEYCMP(KEYTYPE, KEYTYPE), it returns zero for equal, 
18411 + *     non-zero for not equal
18412 + * HASHFN - the hash function - the prototype is int HASHFN(KEYTYPE),
18413 + *     it returns a number in the range 0 ... HASHSIZE - 1
18414 + * Call DEF_HASH_STRUCTS, define your hash table as a NAME_table, then call
18415 + * DEF_HASH.
18416 + */
18417 +
18418 +#define DEF_HASH_STRUCTS(NAME,HASHSIZE,TYPE) \
18419 +\
18420 +struct NAME##_table {\
18421 +       TYPE * hashtable[HASHSIZE];\
18422 +       int nr_entries;\
18423 +};\
18424 +\
18425 +struct NAME##_ptrs {\
18426 +       TYPE * next_hash;\
18427 +       TYPE * prev_hash;\
18428 +};
18429 +
18430 +#define DEF_HASH(LINKAGE,NAME,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,HASHFN)\
18431 +\
18432 +LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
18433 +{\
18434 +       int ix = HASHFN(elem->KEY);\
18435 +       TYPE ** base = &tbl->hashtable[ix];\
18436 +       TYPE * ptr = *base;\
18437 +       TYPE * prev = NULL;\
18438 +\
18439 +       tbl->nr_entries++;\
18440 +       while(ptr && KEYCMP(ptr->KEY, elem->KEY)) {\
18441 +               base = &ptr->PTRS.next_hash;\
18442 +               prev = ptr;\
18443 +               ptr = *base;\
18444 +       }\
18445 +       elem->PTRS.next_hash = ptr;\
18446 +       elem->PTRS.prev_hash = prev;\
18447 +       if(ptr) {\
18448 +               ptr->PTRS.prev_hash = elem;\
18449 +       }\
18450 +       *base = elem;\
18451 +}\
18452 +\
18453 +LINKAGE void remove_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\
18454 +{\
18455 +       TYPE * next = elem->PTRS.next_hash;\
18456 +       TYPE * prev = elem->PTRS.prev_hash;\
18457 +\
18458 +       tbl->nr_entries--;\
18459 +       if(next)\
18460 +               next->PTRS.prev_hash = prev;\
18461 +       if(prev)\
18462 +               prev->PTRS.next_hash = next;\
18463 +       else {\
18464 +               int ix = HASHFN(elem->KEY);\
18465 +               tbl->hashtable[ix] = next;\
18466 +       }\
18467 +}\
18468 +\
18469 +LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\
18470 +{\
18471 +       int ix = HASHFN(pos);\
18472 +       TYPE * ptr = tbl->hashtable[ix];\
18473 +       while(ptr && KEYCMP(ptr->KEY, pos))\
18474 +               ptr = ptr->PTRS.next_hash;\
18475 +       return ptr;\
18476 +}
18477 +
18478 +#endif
18479 diff -Naur a/include/linux/mm.h b/include/linux/mm.h
18480 --- a/include/linux/mm.h        2004-02-11 12:14:17.000000000 -0500
18481 +++ b/include/linux/mm.h        2004-02-11 12:26:00.000000000 -0500
18482 @@ -507,6 +507,9 @@
18483         return __set_page_dirty_buffers(page);
18484  }
18485  
18486 +extern long do_mprotect(struct mm_struct *mm, unsigned long start, 
18487 +                       size_t len, unsigned long prot);
18488 +
18489  /*
18490   * On a two-level page table, this ends up being trivial. Thus the
18491   * inlining and the symmetry break with pte_alloc_map() that does all
18492 @@ -537,9 +540,10 @@
18493  
18494  extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
18495  
18496 -extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
18497 -       unsigned long len, unsigned long prot,
18498 -       unsigned long flag, unsigned long pgoff);
18499 +extern unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file *file, 
18500 +                                  unsigned long addr, unsigned long len,
18501 +                                  unsigned long prot, unsigned long flag,
18502 +                                  unsigned long pgoff);
18503  
18504  static inline unsigned long do_mmap(struct file *file, unsigned long addr,
18505         unsigned long len, unsigned long prot,
18506 @@ -549,7 +553,8 @@
18507         if ((offset + PAGE_ALIGN(len)) < offset)
18508                 goto out;
18509         if (!(offset & ~PAGE_MASK))
18510 -               ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
18511 +               ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flag, 
18512 +                                   offset >> PAGE_SHIFT);
18513  out:
18514         return ret;
18515  }
18516 diff -Naur a/include/linux/proc_mm.h b/include/linux/proc_mm.h
18517 --- a/include/linux/proc_mm.h   1969-12-31 19:00:00.000000000 -0500
18518 +++ b/include/linux/proc_mm.h   2004-02-11 12:25:40.000000000 -0500
18519 @@ -0,0 +1,48 @@
18520 +/* 
18521 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18522 + * Licensed under the GPL
18523 + */
18524 +
18525 +#ifndef __PROC_MM_H
18526 +#define __PROC_MM_H
18527 +
18528 +#include "linux/sched.h"
18529 +
18530 +#define MM_MMAP 54
18531 +#define MM_MUNMAP 55
18532 +#define MM_MPROTECT 56
18533 +#define MM_COPY_SEGMENTS 57
18534 +
18535 +struct mm_mmap {
18536 +       unsigned long addr;
18537 +       unsigned long len;
18538 +       unsigned long prot;
18539 +       unsigned long flags;
18540 +       unsigned long fd;
18541 +       unsigned long offset;
18542 +};
18543 +
18544 +struct mm_munmap {
18545 +       unsigned long addr;
18546 +       unsigned long len;      
18547 +};
18548 +
18549 +struct mm_mprotect {
18550 +       unsigned long addr;
18551 +       unsigned long len;
18552 +        unsigned int prot;
18553 +};
18554 +
18555 +struct proc_mm_op {
18556 +       int op;
18557 +       union {
18558 +               struct mm_mmap mmap;
18559 +               struct mm_munmap munmap;
18560 +               struct mm_mprotect mprotect;
18561 +               int copy_segments;
18562 +       } u;
18563 +};
18564 +
18565 +extern struct mm_struct *proc_mm_get_mm(int fd);
18566 +
18567 +#endif
18568 diff -Naur a/include/linux/time.h b/include/linux/time.h
18569 --- a/include/linux/time.h      2004-02-11 12:15:59.000000000 -0500
18570 +++ b/include/linux/time.h      2004-02-11 12:27:52.000000000 -0500
18571 @@ -41,7 +41,7 @@
18572   * Have the 32 bit jiffies value wrap 5 minutes after boot
18573   * so jiffies wrap bugs show up earlier.
18574   */
18575 -#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ))
18576 +#define INITIAL_JIFFIES ((unsigned long)(0))
18577  
18578  /*
18579   * Change timeval to jiffies, trying to avoid the
18580 diff -Naur a/mm/Makefile b/mm/Makefile
18581 --- a/mm/Makefile       2004-02-11 12:15:59.000000000 -0500
18582 +++ b/mm/Makefile       2004-02-11 12:27:53.000000000 -0500
18583 @@ -12,3 +12,5 @@
18584                            slab.o swap.o truncate.o vmscan.o $(mmu-y)
18585  
18586  obj-$(CONFIG_SWAP)     += page_io.o swap_state.o swapfile.o
18587 +obj-$(CONFIG_PROC_MM)  += proc_mm.o
18588 +
18589 diff -Naur a/mm/mmap.c b/mm/mmap.c
18590 --- a/mm/mmap.c 2004-02-11 12:15:58.000000000 -0500
18591 +++ b/mm/mmap.c 2004-02-11 12:27:51.000000000 -0500
18592 @@ -460,11 +460,11 @@
18593   * The caller must hold down_write(current->mm->mmap_sem).
18594   */
18595  
18596 -unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
18597 -                       unsigned long len, unsigned long prot,
18598 -                       unsigned long flags, unsigned long pgoff)
18599 +unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file * file, 
18600 +                           unsigned long addr, unsigned long len,
18601 +                           unsigned long prot, unsigned long flags,
18602 +                           unsigned long pgoff)
18603  {
18604 -       struct mm_struct * mm = current->mm;
18605         struct vm_area_struct * vma, * prev;
18606         struct inode *inode;
18607         unsigned int vm_flags;
18608 diff -Naur a/mm/mprotect.c b/mm/mprotect.c
18609 --- a/mm/mprotect.c     2004-02-11 12:15:11.000000000 -0500
18610 +++ b/mm/mprotect.c     2004-02-11 12:26:58.000000000 -0500
18611 @@ -222,7 +222,8 @@
18612  }
18613  
18614  asmlinkage long
18615 -sys_mprotect(unsigned long start, size_t len, unsigned long prot)
18616 +do_mprotect(struct mm_struct *mm, unsigned long start, size_t len, 
18617 +            unsigned long prot)
18618  {
18619         unsigned long vm_flags, nstart, end, tmp;
18620         struct vm_area_struct * vma, * next, * prev;
18621 @@ -245,9 +246,9 @@
18622  
18623         vm_flags = calc_vm_prot_bits(prot);
18624  
18625 -       down_write(&current->mm->mmap_sem);
18626 +       down_write(&mm->mmap_sem);
18627  
18628 -       vma = find_vma_prev(current->mm, start, &prev);
18629 +       vma = find_vma_prev(mm, start, &prev);
18630         error = -ENOMEM;
18631         if (!vma)
18632                 goto out;
18633 @@ -326,6 +327,11 @@
18634                 prev->vm_mm->map_count--;
18635         }
18636  out:
18637 -       up_write(&current->mm->mmap_sem);
18638 +       up_write(&mm->mmap_sem);
18639         return error;
18640  }
18641 +
18642 +asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
18643 +{
18644 +        return(do_mprotect(current->mm, start, len, prot));
18645 +}
18646 diff -Naur a/mm/page_alloc.c b/mm/page_alloc.c
18647 --- a/mm/page_alloc.c   2004-02-11 12:14:18.000000000 -0500
18648 +++ b/mm/page_alloc.c   2004-02-11 12:26:01.000000000 -0500
18649 @@ -268,6 +268,8 @@
18650         LIST_HEAD(list);
18651         int i;
18652  
18653 +       arch_free_page(page, order);
18654 +
18655         mod_page_state(pgfree, 1 << order);
18656         for (i = 0 ; i < (1 << order) ; ++i)
18657                 free_pages_check(__FUNCTION__, page + i);
18658 @@ -449,6 +451,8 @@
18659         struct per_cpu_pages *pcp;
18660         unsigned long flags;
18661  
18662 +       arch_free_page(page, 0);
18663 +
18664         kernel_map_pages(page, 1, 0);
18665         inc_page_state(pgfree);
18666         free_pages_check(__FUNCTION__, page);
18667 diff -Naur a/mm/proc_mm.c b/mm/proc_mm.c
18668 --- a/mm/proc_mm.c      1969-12-31 19:00:00.000000000 -0500
18669 +++ b/mm/proc_mm.c      2004-02-11 12:27:05.000000000 -0500
18670 @@ -0,0 +1,174 @@
18671 +/* 
18672 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
18673 + * Licensed under the GPL
18674 + */
18675 +
18676 +#include "linux/mm.h"
18677 +#include "linux/init.h"
18678 +#include "linux/proc_fs.h"
18679 +#include "linux/proc_mm.h"
18680 +#include "linux/file.h"
18681 +#include "asm/uaccess.h"
18682 +#include "asm/mmu_context.h"
18683 +
18684 +static struct file_operations proc_mm_fops;
18685 +
18686 +struct mm_struct *proc_mm_get_mm(int fd)
18687 +{
18688 +       struct mm_struct *ret = ERR_PTR(-EBADF);
18689 +       struct file *file;
18690 +
18691 +       file = fget(fd);
18692 +       if (!file)
18693 +               goto out;
18694 +
18695 +       ret = ERR_PTR(-EINVAL);
18696 +       if(file->f_op != &proc_mm_fops)
18697 +               goto out_fput;
18698 +
18699 +       ret = file->private_data;
18700 + out_fput:
18701 +       fput(file);
18702 + out:
18703 +       return(ret);
18704 +}
18705 +
18706 +extern long do_mmap2(struct mm_struct *mm, unsigned long addr, 
18707 +                    unsigned long len, unsigned long prot, 
18708 +                    unsigned long flags, unsigned long fd,
18709 +                    unsigned long pgoff);
18710 +
18711 +static ssize_t write_proc_mm(struct file *file, const char *buffer,
18712 +                            size_t count, loff_t *ppos)
18713 +{
18714 +       struct mm_struct *mm = file->private_data;
18715 +       struct proc_mm_op req;
18716 +       int n, ret;
18717 +
18718 +       if(count > sizeof(req))
18719 +               return(-EINVAL);
18720 +
18721 +       n = copy_from_user(&req, buffer, count);
18722 +       if(n != 0)
18723 +               return(-EFAULT);
18724 +
18725 +       ret = count;
18726 +       switch(req.op){
18727 +       case MM_MMAP: {
18728 +               struct mm_mmap *map = &req.u.mmap;
18729 +
18730 +               ret = do_mmap2(mm, map->addr, map->len, map->prot, 
18731 +                              map->flags, map->fd, map->offset >> PAGE_SHIFT);
18732 +               if((ret & ~PAGE_MASK) == 0)
18733 +                       ret = count;
18734 +       
18735 +               break;
18736 +       }
18737 +       case MM_MUNMAP: {
18738 +               struct mm_munmap *unmap = &req.u.munmap;
18739 +
18740 +               down_write(&mm->mmap_sem);
18741 +               ret = do_munmap(mm, unmap->addr, unmap->len);
18742 +               up_write(&mm->mmap_sem);
18743 +
18744 +               if(ret == 0)
18745 +                       ret = count;
18746 +               break;
18747 +       }
18748 +       case MM_MPROTECT: {
18749 +               struct mm_mprotect *protect = &req.u.mprotect;
18750 +
18751 +               ret = do_mprotect(mm, protect->addr, protect->len, 
18752 +                                 protect->prot);
18753 +               if(ret == 0)
18754 +                       ret = count;
18755 +               break;
18756 +       }
18757 +
18758 +       case MM_COPY_SEGMENTS: {
18759 +               struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
18760 +
18761 +               if(IS_ERR(from)){
18762 +                       ret = PTR_ERR(from);
18763 +                       break;
18764 +               }
18765 +
18766 +               mm_copy_segments(from, mm);
18767 +               break;
18768 +       }
18769 +       default:
18770 +               ret = -EINVAL;
18771 +               break;
18772 +       }
18773 +
18774 +       return(ret);
18775 +}
18776 +
18777 +static int open_proc_mm(struct inode *inode, struct file *file)
18778 +{
18779 +       struct mm_struct *mm = mm_alloc();
18780 +       int ret;
18781 +
18782 +       ret = -ENOMEM;
18783 +       if(mm == NULL)
18784 +               goto out_mem;
18785 +
18786 +       ret = init_new_context(current, mm);
18787 +       if(ret)
18788 +               goto out_free;
18789 +
18790 +       spin_lock(&mmlist_lock);
18791 +       list_add(&mm->mmlist, &current->mm->mmlist);
18792 +       mmlist_nr++;
18793 +       spin_unlock(&mmlist_lock);
18794 +
18795 +       file->private_data = mm;
18796 +
18797 +       return(0);
18798 +
18799 + out_free:
18800 +       mmput(mm);
18801 + out_mem:
18802 +       return(ret);
18803 +}
18804 +
18805 +static int release_proc_mm(struct inode *inode, struct file *file)
18806 +{
18807 +       struct mm_struct *mm = file->private_data;
18808 +
18809 +       mmput(mm);
18810 +       return(0);
18811 +}
18812 +
18813 +static struct file_operations proc_mm_fops = {
18814 +       .open           = open_proc_mm,
18815 +       .release        = release_proc_mm,
18816 +       .write          = write_proc_mm,
18817 +};
18818 +
18819 +static int make_proc_mm(void)
18820 +{
18821 +       struct proc_dir_entry *ent;
18822 +
18823 +       ent = create_proc_entry("mm", 0222, &proc_root);
18824 +       if(ent == NULL){
18825 +               printk("make_proc_mm : Failed to register /proc/mm\n");
18826 +               return(0);
18827 +       }
18828 +       ent->proc_fops = &proc_mm_fops;
18829 +
18830 +       return(0);
18831 +}
18832 +
18833 +__initcall(make_proc_mm);
18834 +
18835 +/*
18836 + * Overrides for Emacs so that we follow Linus's tabbing style.
18837 + * Emacs will notice this stuff at the end of the file and automatically
18838 + * adjust the settings for this buffer only.  This must remain at the end
18839 + * of the file.
18840 + * ---------------------------------------------------------------------------
18841 + * Local variables:
18842 + * c-file-style: "linux"
18843 + * End:
18844 + */