Whamcloud - gitweb
- mds->lmv->mdc propagate lower timeout down to import
[fs/lustre-release.git] / lustre / kernel_patches / patches / uml-patch-2.6.0-test5.patch
1 diff -Naur a/arch/um/Kconfig b/arch/um/Kconfig
2 --- a/arch/um/Kconfig   Tue Sep  9 16:43:10 2003
3 +++ b/arch/um/Kconfig   Tue Sep  9 16:48:54 2003
4 @@ -61,6 +61,20 @@
5  
6  config NET
7         bool "Networking support"
8 +       help
9 +       Unless you really know what you are doing, you should say Y here.
10 +       The reason is that some programs need kernel networking support even
11 +       when running on a stand-alone machine that isn't connected to any
12 +       other computer. If you are upgrading from an older kernel, you
13 +       should consider updating your networking tools too because changes
14 +       in the kernel and the tools often go hand in hand. The tools are
15 +       contained in the package net-tools, the location and version number
16 +       of which are given in Documentation/Changes.
17 +
18 +       For a general introduction to Linux networking, it is highly
19 +       recommended to read the NET-HOWTO, available from
20 +       <http://www.tldp.org/docs.html#howto>.
21 +
22  
23  source "fs/Kconfig.binfmt"
24  
25 @@ -85,6 +99,19 @@
26          If you'd like to be able to work with files stored on the host, 
27          say Y or M here; otherwise say N.
28  
29 +config HPPFS
30 +       tristate "HoneyPot ProcFS"
31 +       help
32 +       hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc 
33 +       entries to be overridden, removed, or fabricated from the host.
34 +       Its purpose is to allow a UML to appear to be a physical machine
35 +       by removing or changing anything in /proc which gives away the
36 +       identity of a UML.
37 +
38 +       See http://user-mode-linux.sf.net/hppfs.html for more information.
39 +
40 +       You only need this if you are setting up a UML honeypot.  Otherwise,
41 +       it is safe to say 'N' here.
42  
43  config MCONSOLE
44         bool "Management console"
45 @@ -105,6 +132,16 @@
46  config MAGIC_SYSRQ
47         bool "Magic SysRq key"
48         depends on MCONSOLE
49 +       help
50 +       If you say Y here, you will have some control over the system even
51 +       if the system crashes for example during kernel debugging (e.g., you
52 +       will be able to flush the buffer cache to disk, reboot the system
53 +       immediately or dump some status information). This is accomplished
54 +       by pressing various keys while holding SysRq (Alt+PrintScreen). It
55 +       also works on a serial console (on PC hardware at least), if you
56 +       send a BREAK and then within 5 seconds a command keypress. The
57 +       keys are documented in Documentation/sysrq.txt. Don't say Y
58 +       unless you really know what this hack does.
59  
60  config HOST_2G_2G
61         bool "2G/2G host address space split"
62 @@ -159,6 +196,9 @@
63  config HIGHMEM
64         bool "Highmem support"
65  
66 +config PROC_MM
67 +       bool "/proc/mm support"
68 +
69  config KERNEL_STACK_ORDER
70         int "Kernel stack size order"
71         default 2
72 @@ -239,6 +279,10 @@
73  config PT_PROXY
74         bool "Enable ptrace proxy"
75         depends on XTERM_CHAN && DEBUG_INFO
76 +       help
77 +       This option enables a debugging interface which allows gdb to debug
78 +       the kernel without needing to actually attach to kernel threads.
79 +       If you want to do kernel debugging, say Y here; otherwise say N.
80  
81  config GPROF
82         bool "Enable gprof support"
83 diff -Naur a/arch/um/Kconfig_block b/arch/um/Kconfig_block
84 --- a/arch/um/Kconfig_block     Tue Sep  9 16:44:02 2003
85 +++ b/arch/um/Kconfig_block     Tue Sep  9 16:49:30 2003
86 @@ -29,6 +29,20 @@
87          wise choice too.  In all other cases (for example, if you're just
88          playing around with User-Mode Linux) you can choose N.
89  
90 +# Turn this back on when the driver actually works
91 +#
92 +#config BLK_DEV_COW
93 +#      tristate "COW block device"
94 +#      help
95 +#      This is a layered driver which sits above two other block devices.
96 +#      One is read-only, and the other is a read-write layer which stores
97 +#      all changes.  This provides the illusion that the read-only layer
98 +#      can be mounted read-write and changed.
99 +
100 +config BLK_DEV_COW_COMMON
101 +       bool
102 +       default BLK_DEV_COW || BLK_DEV_UBD
103 +
104  config BLK_DEV_LOOP
105         tristate "Loopback device support"
106  
107 diff -Naur a/arch/um/Kconfig_net b/arch/um/Kconfig_net
108 --- a/arch/um/Kconfig_net       Tue Sep  9 16:43:43 2003
109 +++ b/arch/um/Kconfig_net       Tue Sep  9 16:49:20 2003
110 @@ -1,5 +1,5 @@
111  
112 -menu "Network Devices"
113 +menu "UML Network Devices"
114         depends on NET
115  
116  # UML virtual driver
117 @@ -176,73 +176,5 @@
118         
119          Startup example: "eth0=slirp,FE:FD:01:02:03:04,/usr/local/bin/slirp"
120  
121 -
122 -# Below are hardware-independent drivers mirrored from
123 -# drivers/net/Config.in. It would be nice if Linux
124 -# had HW independent drivers separated from the other
125 -# but it does not. Until then each non-ISA/PCI arch
126 -# needs to provide it's own menu of network drivers
127 -config DUMMY
128 -       tristate "Dummy net driver support"
129 -
130 -config BONDING
131 -       tristate "Bonding driver support"
132 -
133 -config EQUALIZER
134 -       tristate "EQL (serial line load balancing) support"
135 -
136 -config TUN
137 -       tristate "Universal TUN/TAP device driver support"
138 -
139 -config ETHERTAP
140 -       tristate "Ethertap network tap (OBSOLETE)"
141 -       depends on EXPERIMENTAL && NETLINK
142 -
143 -config PPP
144 -       tristate "PPP (point-to-point protocol) support"
145 -
146 -config PPP_MULTILINK
147 -       bool "PPP multilink support (EXPERIMENTAL)"
148 -       depends on PPP && EXPERIMENTAL
149 -
150 -config PPP_FILTER
151 -       bool "PPP filtering"
152 -       depends on PPP && FILTER
153 -
154 -config PPP_ASYNC
155 -       tristate "PPP support for async serial ports"
156 -       depends on PPP
157 -
158 -config PPP_SYNC_TTY
159 -       tristate "PPP support for sync tty ports"
160 -       depends on PPP
161 -
162 -config PPP_DEFLATE
163 -       tristate "PPP Deflate compression"
164 -       depends on PPP
165 -
166 -config PPP_BSDCOMP
167 -       tristate "PPP BSD-Compress compression"
168 -       depends on PPP
169 -
170 -config PPPOE
171 -       tristate "PPP over Ethernet (EXPERIMENTAL)"
172 -       depends on PPP && EXPERIMENTAL
173 -
174 -config SLIP
175 -       tristate "SLIP (serial line) support"
176 -
177 -config SLIP_COMPRESSED
178 -       bool "CSLIP compressed headers"
179 -       depends on SLIP=y
180 -
181 -config SLIP_SMART
182 -       bool "Keepalive and linefill"
183 -       depends on SLIP=y
184 -
185 -config SLIP_MODE_SLIP6
186 -       bool "Six bit SLIP encapsulation"
187 -       depends on SLIP=y
188 -
189  endmenu
190  
191 diff -Naur a/arch/um/Makefile b/arch/um/Makefile
192 --- a/arch/um/Makefile  Tue Sep  9 16:43:50 2003
193 +++ b/arch/um/Makefile  Tue Sep  9 16:49:24 2003
194 @@ -24,15 +24,17 @@
195  # Have to precede the include because the included Makefiles reference them.
196  SYMLINK_HEADERS = include/asm-um/archparam.h include/asm-um/system.h \
197         include/asm-um/sigcontext.h include/asm-um/processor.h \
198 -       include/asm-um/ptrace.h include/asm-um/arch-signal.h
199 +       include/asm-um/ptrace.h include/asm-um/arch-signal.h \
200 +       include/asm-um/module.h
201  
202  ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \
203         $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
204  
205  GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h
206  
207 -include $(ARCH_DIR)/Makefile-$(SUBARCH)
208 -include $(ARCH_DIR)/Makefile-os-$(OS)
209 +.PHONY: sys_prepare
210 +sys_prepare:
211 +       @:
212  
213  MAKEFILE-$(CONFIG_MODE_TT) += Makefile-tt
214  MAKEFILE-$(CONFIG_MODE_SKAS) += Makefile-skas
215 @@ -41,6 +43,9 @@
216    include $(addprefix $(ARCH_DIR)/,$(MAKEFILE-y))
217  endif
218  
219 +include $(ARCH_DIR)/Makefile-$(SUBARCH)
220 +include $(ARCH_DIR)/Makefile-os-$(OS)
221 +
222  EXTRAVERSION := $(EXTRAVERSION)-1um
223  
224  ARCH_INCLUDE = -I$(ARCH_DIR)/include
225 @@ -52,14 +57,14 @@
226  
227  CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
228         -D_LARGEFILE64_SOURCE $(ARCH_INCLUDE) -Derrno=kernel_errno \
229 -       $(MODE_INCLUDE)
230 +       -Dsigprocmask=kernel_sigprocmask $(MODE_INCLUDE)
231  
232  LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
233  
234  SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
235  
236  ifeq ($(CONFIG_MODE_SKAS), y)
237 -$(SYS_HEADERS) : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
238 +$(SYS_HEADERS) : $(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h
239  endif
240  
241  include/linux/version.h: arch/$(ARCH)/Makefile
242 @@ -98,17 +103,17 @@
243  CONFIG_KERNEL_STACK_ORDER ?= 2
244  STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
245  
246 -AFLAGS_vmlinux.lds.o = -U$(SUBARCH) \
247 +AFLAGS_vmlinux.lds.o = $(shell echo -U$(SUBARCH) \
248         -DSTART=$$(($(TOP_ADDR) - $(SIZE))) -DELF_ARCH=$(ELF_ARCH) \
249         -DELF_FORMAT=\"$(ELF_FORMAT)\" $(CPP_MODE_TT) \
250 -       -DKERNEL_STACK_SIZE=$(STACK_SIZE)
251 +       -DKERNEL_STACK_SIZE=$(STACK_SIZE))
252  
253 -AFLAGS_$(LD_SCRIPT-y:.s=).o = $(AFLAGS_vmlinux.lds.o) -P -C -Uum
254 +export AFLAGS_$(LD_SCRIPT-y:.s=).o = $(AFLAGS_vmlinux.lds.o) -P -C -Uum
255  
256  LD_SCRIPT-y := $(ARCH_DIR)/$(LD_SCRIPT-y)
257  
258 -$(LD_SCRIPT-y) : $(LD_SCRIPT-y:.s=.S) scripts FORCE
259 -       $(call if_changed_dep,as_s_S)
260 +#$(LD_SCRIPT-y) : $(LD_SCRIPT-y:.s=.S) scripts FORCE
261 +#      $(call if_changed_dep,as_s_S)
262  
263  linux: vmlinux $(LD_SCRIPT-y)
264         $(CC) -Wl,-T,$(LD_SCRIPT-y) $(LINK-y) $(LINK_WRAPS) \
265 @@ -116,6 +121,7 @@
266  
267  USER_CFLAGS := $(patsubst -I%,,$(CFLAGS))
268  USER_CFLAGS := $(patsubst -Derrno=kernel_errno,,$(USER_CFLAGS))
269 +USER_CFLAGS := $(patsubst -Dsigprocmask=kernel_sigprocmask,,$(USER_CFLAGS))
270  USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \
271         $(MODE_INCLUDE)
272  
273 @@ -123,9 +129,10 @@
274  USER_CFLAGS += -D_GNU_SOURCE
275  
276  CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/uml.lds.s \
277 -       $(ARCH_DIR)/dyn_link.ld.s $(GEN_HEADERS)
278 +       $(ARCH_DIR)/dyn_link.ld.s $(ARCH_DIR)/include/uml-config.h \
279 +       $(GEN_HEADERS)
280  
281 -$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c
282 +$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c sys_prepare
283         $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $<
284  
285  archmrproper:
286 @@ -161,19 +168,23 @@
287  $(ARCH_DIR)/os:
288         cd $(ARCH_DIR) && ln -sf os-$(OS) os
289  
290 -$(ARCH_DIR)/include/uml-config.h :
291 +$(ARCH_DIR)/include/uml-config.h : $(TOPDIR)/include/linux/autoconf.h
292         sed 's/ CONFIG/ UML_CONFIG/' $(TOPDIR)/include/linux/autoconf.h > $@
293  
294 +filechk_$(ARCH_DIR)/include/task.h := $(ARCH_DIR)/util/mk_task
295 +
296  $(ARCH_DIR)/include/task.h : $(ARCH_DIR)/util/mk_task
297 -       $< > $@
298 +       $(call filechk,$@)
299 +
300 +filechk_$(ARCH_DIR)/include/kern_constants.h := $(ARCH_DIR)/util/mk_constants
301  
302  $(ARCH_DIR)/include/kern_constants.h : $(ARCH_DIR)/util/mk_constants
303 -       $< > $@
304 +       $(call filechk,$@)
305  
306 -$(ARCH_DIR)/util/mk_task : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h \
307 -       $(ARCH_DIR)/util FORCE ;
308 +$(ARCH_DIR)/util/mk_task $(ARCH_DIR)/util/mk_constants : $(ARCH_DIR)/util \
309 +       sys_prepare FORCE ;
310  
311  $(ARCH_DIR)/util: FORCE
312 -       @$(call descend,$@,)
313 +       $(MAKE) -f scripts/Makefile.build obj=$@
314  
315 -export SUBARCH USER_CFLAGS OS
316 +export SUBARCH USER_CFLAGS OS 
317 diff -Naur a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
318 --- a/arch/um/Makefile-i386     Tue Sep  9 16:45:38 2003
319 +++ b/arch/um/Makefile-i386     Tue Sep  9 16:50:11 2003
320 @@ -16,22 +16,28 @@
321  
322  SYS_HEADERS = $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
323  
324 +sys_prepare: $(SYS_DIR)/sc.h
325 +
326  prepare: $(SYS_HEADERS)
327  
328 +filechk_$(SYS_DIR)/sc.h := $(SYS_UTIL_DIR)/mk_sc
329 +
330  $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
331 -       $< > $@
332 +       $(call filechk,$@)
333 +
334 +filechk_$(SYS_DIR)/thread.h := $(SYS_UTIL_DIR)/mk_thread 
335  
336  $(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread 
337 -       $< > $@
338 +       $(call filechk,$@)
339  
340 -$(SYS_UTIL_DIR)/mk_sc: FORCE ; 
341 -       @$(call descend,$(SYS_UTIL_DIR),$@)
342 +$(SYS_UTIL_DIR)/mk_sc: scripts/fixdep include/config/MARKER FORCE ; 
343 +       +@$(call descend,$(SYS_UTIL_DIR),$@)
344  
345 -$(SYS_UTIL_DIR)/mk_thread: $(ARCH_SYMLINKS) $(GEN_HEADERS) FORCE ; 
346 -       @$(call descend,$(SYS_UTIL_DIR),$@)
347 +$(SYS_UTIL_DIR)/mk_thread: $(ARCH_SYMLINKS) $(GEN_HEADERS) sys_prepare FORCE ; 
348 +       +@$(call descend,$(SYS_UTIL_DIR),$@)
349  
350  $(SYS_UTIL_DIR): include/asm FORCE
351 -       @$(call descend,$@,)
352 +       +@$(call descend,$@,)
353  
354  sysclean :
355         rm -f $(SYS_HEADERS)
356 diff -Naur a/arch/um/Makefile-skas b/arch/um/Makefile-skas
357 --- a/arch/um/Makefile-skas     Tue Sep  9 16:43:05 2003
358 +++ b/arch/um/Makefile-skas     Tue Sep  9 16:48:52 2003
359 @@ -14,7 +14,7 @@
360  LINK_SKAS = -Wl,-rpath,/lib 
361  LD_SCRIPT_SKAS = dyn.lds.s
362  
363 -GEN_HEADERS += $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
364 +GEN_HEADERS += $(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h
365  
366 -$(ARCH_DIR)/kernel/skas/include/skas_ptregs.h :
367 -       $(MAKE) -C $(ARCH_DIR)/kernel/skas include/skas_ptregs.h
368 +$(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h :
369 +       $(call descend,$(ARCH_DIR)/kernel/skas,$@)
370 diff -Naur a/arch/um/config.release b/arch/um/config.release
371 --- a/arch/um/config.release    Tue Sep  9 16:46:07 2003
372 +++ b/arch/um/config.release    Tue Sep  9 16:51:08 2003
373 @@ -228,7 +228,6 @@
374  CONFIG_EXT2_FS=y
375  CONFIG_SYSV_FS=m
376  CONFIG_UDF_FS=m
377 -# CONFIG_UDF_RW is not set
378  CONFIG_UFS_FS=m
379  # CONFIG_UFS_FS_WRITE is not set
380  
381 diff -Naur a/arch/um/defconfig b/arch/um/defconfig
382 --- a/arch/um/defconfig Tue Sep  9 16:43:55 2003
383 +++ b/arch/um/defconfig Tue Sep  9 16:49:28 2003
384 @@ -3,29 +3,19 @@
385  #
386  CONFIG_USERMODE=y
387  CONFIG_MMU=y
388 -CONFIG_SWAP=y
389  CONFIG_UID16=y
390  CONFIG_RWSEM_GENERIC_SPINLOCK=y
391 -CONFIG_CONFIG_LOG_BUF_SHIFT=14
392 -
393 -#
394 -# Code maturity level options
395 -#
396 -CONFIG_EXPERIMENTAL=y
397  
398  #
399 -# General Setup
400 +# UML-specific options
401  #
402  CONFIG_MODE_TT=y
403  CONFIG_MODE_SKAS=y
404  CONFIG_NET=y
405 -CONFIG_SYSVIPC=y
406 -CONFIG_BSD_PROCESS_ACCT=y
407 -CONFIG_SYSCTL=y
408 -CONFIG_BINFMT_AOUT=y
409  CONFIG_BINFMT_ELF=y
410  CONFIG_BINFMT_MISC=y
411  CONFIG_HOSTFS=y
412 +CONFIG_HPPFS=y
413  CONFIG_MCONSOLE=y
414  CONFIG_MAGIC_SYSRQ=y
415  # CONFIG_HOST_2G_2G is not set
416 @@ -38,10 +28,38 @@
417  CONFIG_KERNEL_STACK_ORDER=2
418  
419  #
420 +# Code maturity level options
421 +#
422 +CONFIG_EXPERIMENTAL=y
423 +CONFIG_CLEAN_COMPILE=y
424 +CONFIG_STANDALONE=y
425 +CONFIG_BROKEN_ON_SMP=y
426 +
427 +#
428 +# General setup
429 +#
430 +CONFIG_SWAP=y
431 +CONFIG_SYSVIPC=y
432 +CONFIG_BSD_PROCESS_ACCT=y
433 +CONFIG_SYSCTL=y
434 +CONFIG_LOG_BUF_SHIFT=14
435 +# CONFIG_IKCONFIG is not set
436 +# CONFIG_EMBEDDED is not set
437 +CONFIG_KALLSYMS=y
438 +CONFIG_FUTEX=y
439 +CONFIG_EPOLL=y
440 +CONFIG_IOSCHED_NOOP=y
441 +CONFIG_IOSCHED_AS=y
442 +CONFIG_IOSCHED_DEADLINE=y
443 +
444 +#
445  # Loadable module support
446  #
447 -CONFIG_MODULES=y
448 -# CONFIG_KMOD is not set
449 +# CONFIG_MODULES is not set
450 +
451 +#
452 +# Generic Driver Options
453 +#
454  
455  #
456  # Character Devices
457 @@ -69,6 +87,7 @@
458  #
459  CONFIG_BLK_DEV_UBD=y
460  # CONFIG_BLK_DEV_UBD_SYNC is not set
461 +CONFIG_BLK_DEV_COW_COMMON=y
462  CONFIG_BLK_DEV_LOOP=y
463  CONFIG_BLK_DEV_NBD=y
464  CONFIG_BLK_DEV_RAM=y
465 @@ -78,7 +97,7 @@
466  CONFIG_NETDEVICES=y
467  
468  #
469 -# Network Devices
470 +# UML Network Devices
471  #
472  CONFIG_UML_NET=y
473  CONFIG_UML_NET_ETHERTAP=y
474 @@ -88,22 +107,6 @@
475  CONFIG_UML_NET_MCAST=y
476  # CONFIG_UML_NET_PCAP is not set
477  CONFIG_UML_NET_SLIRP=y
478 -CONFIG_DUMMY=y
479 -# CONFIG_BONDING is not set
480 -# CONFIG_EQUALIZER is not set
481 -CONFIG_TUN=y
482 -# CONFIG_ETHERTAP is not set
483 -CONFIG_PPP=y
484 -# CONFIG_PPP_MULTILINK is not set
485 -# CONFIG_PPP_ASYNC is not set
486 -# CONFIG_PPP_SYNC_TTY is not set
487 -# CONFIG_PPP_DEFLATE is not set
488 -# CONFIG_PPP_BSDCOMP is not set
489 -# CONFIG_PPPOE is not set
490 -CONFIG_SLIP=y
491 -# CONFIG_SLIP_COMPRESSED is not set
492 -# CONFIG_SLIP_SMART is not set
493 -# CONFIG_SLIP_MODE_SLIP6 is not set
494  
495  #
496  # Networking support
497 @@ -115,8 +118,6 @@
498  CONFIG_PACKET=y
499  CONFIG_PACKET_MMAP=y
500  # CONFIG_NETLINK_DEV is not set
501 -# CONFIG_NETFILTER is not set
502 -# CONFIG_FILTER is not set
503  CONFIG_UNIX=y
504  # CONFIG_NET_KEY is not set
505  CONFIG_INET=y
506 @@ -130,8 +131,11 @@
507  # CONFIG_SYN_COOKIES is not set
508  # CONFIG_INET_AH is not set
509  # CONFIG_INET_ESP is not set
510 -# CONFIG_XFRM_USER is not set
511 +# CONFIG_INET_IPCOMP is not set
512  # CONFIG_IPV6 is not set
513 +# CONFIG_DECNET is not set
514 +# CONFIG_BRIDGE is not set
515 +# CONFIG_NETFILTER is not set
516  
517  #
518  # SCTP Configuration (EXPERIMENTAL)
519 @@ -141,8 +145,6 @@
520  # CONFIG_ATM is not set
521  # CONFIG_VLAN_8021Q is not set
522  # CONFIG_LLC is not set
523 -# CONFIG_DECNET is not set
524 -# CONFIG_BRIDGE is not set
525  # CONFIG_X25 is not set
526  # CONFIG_LAPB is not set
527  # CONFIG_NET_DIVERT is not set
528 @@ -160,6 +162,10 @@
529  # Network testing
530  #
531  # CONFIG_NET_PKTGEN is not set
532 +CONFIG_DUMMY=y
533 +# CONFIG_BONDING is not set
534 +# CONFIG_EQUALIZER is not set
535 +CONFIG_TUN=y
536  
537  #
538  # Ethernet (10 or 100Mbit)
539 @@ -171,6 +177,22 @@
540  #
541  
542  #
543 +# Ethernet (10000 Mbit)
544 +#
545 +CONFIG_PPP=y
546 +# CONFIG_PPP_MULTILINK is not set
547 +# CONFIG_PPP_FILTER is not set
548 +# CONFIG_PPP_ASYNC is not set
549 +# CONFIG_PPP_SYNC_TTY is not set
550 +# CONFIG_PPP_DEFLATE is not set
551 +# CONFIG_PPP_BSDCOMP is not set
552 +# CONFIG_PPPOE is not set
553 +CONFIG_SLIP=y
554 +# CONFIG_SLIP_COMPRESSED is not set
555 +# CONFIG_SLIP_SMART is not set
556 +# CONFIG_SLIP_MODE_SLIP6 is not set
557 +
558 +#
559  # Wireless LAN (non-hamradio)
560  #
561  # CONFIG_NET_RADIO is not set
562 @@ -188,66 +210,82 @@
563  #
564  # File systems
565  #
566 +CONFIG_EXT2_FS=y
567 +# CONFIG_EXT2_FS_XATTR is not set
568 +# CONFIG_EXT3_FS is not set
569 +# CONFIG_JBD is not set
570 +CONFIG_REISERFS_FS=y
571 +# CONFIG_REISERFS_CHECK is not set
572 +# CONFIG_REISERFS_PROC_INFO is not set
573 +# CONFIG_JFS_FS is not set
574 +# CONFIG_XFS_FS is not set
575 +CONFIG_MINIX_FS=y
576 +# CONFIG_ROMFS_FS is not set
577  CONFIG_QUOTA=y
578  # CONFIG_QFMT_V1 is not set
579  # CONFIG_QFMT_V2 is not set
580  CONFIG_QUOTACTL=y
581 -CONFIG_AUTOFS_FS=m
582 -CONFIG_AUTOFS4_FS=m
583 -CONFIG_REISERFS_FS=m
584 -# CONFIG_REISERFS_CHECK is not set
585 -# CONFIG_REISERFS_PROC_INFO is not set
586 +CONFIG_AUTOFS_FS=y
587 +CONFIG_AUTOFS4_FS=y
588 +
589 +#
590 +# CD-ROM/DVD Filesystems
591 +#
592 +CONFIG_ISO9660_FS=y
593 +# CONFIG_JOLIET is not set
594 +# CONFIG_ZISOFS is not set
595 +# CONFIG_UDF_FS is not set
596 +
597 +#
598 +# DOS/FAT/NT Filesystems
599 +#
600 +CONFIG_FAT_FS=y
601 +CONFIG_MSDOS_FS=y
602 +CONFIG_VFAT_FS=y
603 +# CONFIG_NTFS_FS is not set
604 +
605 +#
606 +# Pseudo filesystems
607 +#
608 +CONFIG_PROC_FS=y
609 +CONFIG_DEVFS_FS=y
610 +CONFIG_DEVFS_MOUNT=y
611 +# CONFIG_DEVFS_DEBUG is not set
612 +CONFIG_DEVPTS_FS=y
613 +# CONFIG_DEVPTS_FS_XATTR is not set
614 +# CONFIG_TMPFS is not set
615 +CONFIG_RAMFS=y
616 +
617 +#
618 +# Miscellaneous filesystems
619 +#
620  # CONFIG_ADFS_FS is not set
621  # CONFIG_AFFS_FS is not set
622  # CONFIG_HFS_FS is not set
623  # CONFIG_BEFS_FS is not set
624  # CONFIG_BFS_FS is not set
625 -# CONFIG_EXT3_FS is not set
626 -# CONFIG_JBD is not set
627 -CONFIG_FAT_FS=m
628 -CONFIG_MSDOS_FS=m
629 -CONFIG_VFAT_FS=m
630  # CONFIG_EFS_FS is not set
631  CONFIG_JFFS_FS=y
632  CONFIG_JFFS_FS_VERBOSE=0
633 -CONFIG_JFFS_PROC_FS=y
634  # CONFIG_JFFS2_FS is not set
635  # CONFIG_CRAMFS is not set
636 -# CONFIG_TMPFS is not set
637 -CONFIG_RAMFS=y
638 -CONFIG_ISO9660_FS=m
639 -# CONFIG_JOLIET is not set
640 -# CONFIG_ZISOFS is not set
641 -# CONFIG_JFS_FS is not set
642 -CONFIG_MINIX_FS=m
643  # CONFIG_VXFS_FS is not set
644 -# CONFIG_NTFS_FS is not set
645  # CONFIG_HPFS_FS is not set
646 -CONFIG_PROC_FS=y
647 -CONFIG_DEVFS_FS=y
648 -CONFIG_DEVFS_MOUNT=y
649 -# CONFIG_DEVFS_DEBUG is not set
650 -CONFIG_DEVPTS_FS=y
651  # CONFIG_QNX4FS_FS is not set
652 -# CONFIG_ROMFS_FS is not set
653 -CONFIG_EXT2_FS=y
654 -# CONFIG_EXT2_FS_XATTR is not set
655  # CONFIG_SYSV_FS is not set
656 -# CONFIG_UDF_FS is not set
657  # CONFIG_UFS_FS is not set
658 -# CONFIG_XFS_FS is not set
659  
660  #
661  # Network File Systems
662  #
663 -# CONFIG_CODA_FS is not set
664 -# CONFIG_INTERMEZZO_FS is not set
665  # CONFIG_NFS_FS is not set
666  # CONFIG_NFSD is not set
667  # CONFIG_EXPORTFS is not set
668 -# CONFIG_CIFS is not set
669  # CONFIG_SMB_FS is not set
670 +# CONFIG_CIFS is not set
671  # CONFIG_NCP_FS is not set
672 +# CONFIG_CODA_FS is not set
673 +# CONFIG_INTERMEZZO_FS is not set
674  # CONFIG_AFS_FS is not set
675  
676  #
677 @@ -317,28 +355,7 @@
678  #
679  # SCSI support
680  #
681 -CONFIG_SCSI=y
682 -CONFIG_GENERIC_ISA_DMA=y
683 -
684 -#
685 -# SCSI support type (disk, tape, CD-ROM)
686 -#
687 -CONFIG_BLK_DEV_SD=y
688 -CONFIG_SD_EXTRA_DEVS=40
689 -CONFIG_CHR_DEV_ST=y
690 -CONFIG_BLK_DEV_SR=y
691 -CONFIG_BLK_DEV_SR_VENDOR=y
692 -CONFIG_SR_EXTRA_DEVS=2
693 -CONFIG_CHR_DEV_SG=y
694 -
695 -#
696 -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
697 -#
698 -CONFIG_SCSI_DEBUG_QUEUES=y
699 -CONFIG_SCSI_MULTI_LUN=y
700 -CONFIG_SCSI_CONSTANTS=y
701 -CONFIG_SCSI_LOGGING=y
702 -CONFIG_SCSI_DEBUG=y
703 +# CONFIG_SCSI is not set
704  
705  #
706  # Multi-device support (RAID and LVM)
707 @@ -360,6 +377,7 @@
708  CONFIG_MTD_BLOCK=y
709  # CONFIG_FTL is not set
710  # CONFIG_NFTL is not set
711 +# CONFIG_INFTL is not set
712  
713  #
714  # RAM/ROM/Flash chip drivers
715 @@ -374,20 +392,21 @@
716  #
717  # Mapping drivers for chip access
718  #
719 +# CONFIG_MTD_COMPLEX_MAPPINGS is not set
720  
721  #
722  # Self-contained MTD device drivers
723  #
724  # CONFIG_MTD_SLRAM is not set
725  # CONFIG_MTD_MTDRAM is not set
726 -CONFIG_MTD_BLKMTD=m
727 +CONFIG_MTD_BLKMTD=y
728  
729  #
730  # Disk-On-Chip Device Drivers
731  #
732 -# CONFIG_MTD_DOC1000 is not set
733  # CONFIG_MTD_DOC2000 is not set
734  # CONFIG_MTD_DOC2001 is not set
735 +# CONFIG_MTD_DOC2001PLUS is not set
736  
737  #
738  # NAND Flash Device Drivers
739 diff -Naur a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
740 --- a/arch/um/drivers/Makefile  Tue Sep  9 16:43:32 2003
741 +++ b/arch/um/drivers/Makefile  Tue Sep  9 16:49:19 2003
742 @@ -1,5 +1,5 @@
743  # 
744 -# Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com)
745 +# Copyright (C) 2000, 2002, 2003 Jeff Dike (jdike@karaya.com)
746  # Licensed under the GPL
747  #
748  
749 @@ -39,6 +39,8 @@
750  obj-$(CONFIG_TTY_CHAN) += tty.o 
751  obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o
752  obj-$(CONFIG_UML_WATCHDOG) += harddog.o
753 +obj-$(CONFIG_BLK_DEV_COW) += cow_kern.o
754 +obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
755  
756  obj-y += stdio_console.o $(CHAN_OBJS)
757  
758 @@ -46,7 +48,7 @@
759  
760  USER_OBJS := $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) fd.o \
761         null.o pty.o tty.o xterm.o
762 -USER_OBJS := $(foreach file,$(USER_OBJS),arch/um/drivers/$(file))
763 +USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
764  
765  $(USER_OBJS) : %.o: %.c
766         $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
767 diff -Naur a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
768 --- a/arch/um/drivers/chan_kern.c       Tue Sep  9 16:46:09 2003
769 +++ b/arch/um/drivers/chan_kern.c       Tue Sep  9 16:51:12 2003
770 @@ -8,6 +8,7 @@
771  #include <linux/list.h>
772  #include <linux/slab.h>
773  #include <linux/tty.h>
774 +#include <linux/string.h>
775  #include <linux/tty_flip.h>
776  #include <asm/irq.h>
777  #include "chan_kern.h"
778 diff -Naur a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
779 --- a/arch/um/drivers/chan_user.c       Tue Sep  9 16:41:10 2003
780 +++ b/arch/um/drivers/chan_user.c       Tue Sep  9 16:47:22 2003
781 @@ -188,8 +188,8 @@
782         if(!isatty(fd)) return;
783  
784         pid = tcgetpgrp(fd);
785 -       if(!CHOOSE_MODE(is_tracer_winch(pid, fd, device_data), 0) && 
786 -          (pid == -1)){
787 +       if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd, 
788 +                            device_data) && (pid == -1)){
789                 thread = winch_tramp(fd, device_data, &thread_fd);
790                 if(fd != -1){
791                         register_winch_irq(thread_fd, fd, thread, device_data);
792 diff -Naur a/arch/um/drivers/cow.h b/arch/um/drivers/cow.h
793 --- a/arch/um/drivers/cow.h     Wed Dec 31 19:00:00 1969
794 +++ b/arch/um/drivers/cow.h     Tue Sep  9 16:47:42 2003
795 @@ -0,0 +1,40 @@
796 +#ifndef __COW_H__
797 +#define __COW_H__
798 +
799 +#include <asm/types.h>
800 +
801 +#if __BYTE_ORDER == __BIG_ENDIAN
802 +# define ntohll(x) (x)
803 +# define htonll(x) (x)
804 +#elif __BYTE_ORDER == __LITTLE_ENDIAN
805 +# define ntohll(x)  bswap_64(x)
806 +# define htonll(x)  bswap_64(x)
807 +#else
808 +#error "__BYTE_ORDER not defined"
809 +#endif
810 +
811 +extern int init_cow_file(int fd, char *cow_file, char *backing_file, 
812 +                        int sectorsize, int *bitmap_offset_out, 
813 +                        unsigned long *bitmap_len_out, int *data_offset_out);
814 +
815 +extern int file_reader(__u64 offset, char *buf, int len, void *arg);
816 +extern int read_cow_header(int (*reader)(__u64, char *, int, void *), 
817 +                          void *arg, __u32 *magic_out, 
818 +                          char **backing_file_out, time_t *mtime_out, 
819 +                          __u64 *size_out, int *sectorsize_out, 
820 +                          int *bitmap_offset_out);
821 +
822 +extern int write_cow_header(char *cow_file, int fd, char *backing_file, 
823 +                           int sectorsize, long long *size);
824 +
825 +extern void cow_sizes(__u64 size, int sectorsize, int bitmap_offset, 
826 +                     unsigned long *bitmap_len_out, int *data_offset_out);
827 +
828 +#endif
829 +
830 +/*
831 + * ---------------------------------------------------------------------------
832 + * Local variables:
833 + * c-file-style: "linux"
834 + * End:
835 + */
836 diff -Naur a/arch/um/drivers/cow_kern.c b/arch/um/drivers/cow_kern.c
837 --- a/arch/um/drivers/cow_kern.c        Wed Dec 31 19:00:00 1969
838 +++ b/arch/um/drivers/cow_kern.c        Tue Sep  9 16:51:12 2003
839 @@ -0,0 +1,628 @@
840 +#define COW_MAJOR 60
841 +#define MAJOR_NR COW_MAJOR
842 +
843 +#include <linux/stddef.h>
844 +#include <linux/kernel.h>
845 +#include <linux/ctype.h>
846 +#include <linux/stat.h>
847 +#include <linux/vmalloc.h>
848 +#include <linux/blkdev.h>
849 +#include <linux/blk.h>
850 +#include <linux/fs.h>
851 +#include <linux/genhd.h>
852 +#include <linux/devfs_fs.h>
853 +#include <asm/uaccess.h>
854 +#include "2_5compat.h"
855 +#include "cow.h"
856 +#include "ubd_user.h"
857 +
858 +#define COW_SHIFT 4
859 +
860 +struct cow {
861 +       int count;
862 +       char *cow_path;
863 +       dev_t cow_dev;
864 +       struct block_device *cow_bdev;
865 +       char *backing_path;
866 +       dev_t backing_dev;
867 +       struct block_device *backing_bdev;
868 +       int sectorsize;
869 +       unsigned long *bitmap;
870 +       unsigned long bitmap_len;
871 +       int bitmap_offset;
872 +       int data_offset;
873 +       devfs_handle_t devfs;
874 +       struct semaphore sem;
875 +       struct semaphore io_sem;
876 +       atomic_t working;
877 +       spinlock_t io_lock;
878 +       struct buffer_head *bh;
879 +       struct buffer_head *bhtail;
880 +       void *end_io;
881 +};
882 +
883 +#define DEFAULT_COW { \
884 +       .count                  = 0, \
885 +       .cow_path               = NULL, \
886 +       .cow_dev                = 0, \
887 +       .backing_path           = NULL, \
888 +       .backing_dev            = 0, \
889 +        .bitmap                        = NULL, \
890 +       .bitmap_len             = 0, \
891 +       .bitmap_offset          = 0, \
892 +        .data_offset           = 0, \
893 +       .devfs                  = NULL, \
894 +       .working                = ATOMIC_INIT(0), \
895 +       .io_lock                = SPIN_LOCK_UNLOCKED, \
896 +}
897 +
898 +#define MAX_DEV (8)
899 +#define MAX_MINOR (MAX_DEV << COW_SHIFT)
900 +
901 +struct cow cow_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_COW };
902 +
903 +/* Not modified by this driver */
904 +static int blk_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = BLOCK_SIZE };
905 +static int hardsect_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 512 };
906 +
907 +/* Protected by cow_lock */
908 +static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 };
909 +
910 +static struct hd_struct        cow_part[MAX_MINOR] =
911 +       { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } };
912 +
913 +/* Protected by io_request_lock */
914 +static request_queue_t *cow_queue;
915 +
916 +static int cow_open(struct inode *inode, struct file *filp);
917 +static int cow_release(struct inode * inode, struct file * file);
918 +static int cow_ioctl(struct inode * inode, struct file * file,
919 +                    unsigned int cmd, unsigned long arg);
920 +static int cow_revalidate(kdev_t rdev);
921 +
922 +static struct block_device_operations cow_blops = {
923 +       .open           = cow_open,
924 +       .release        = cow_release,
925 +       .ioctl          = cow_ioctl,
926 +       .revalidate     = cow_revalidate,
927 +};
928 +
929 +/* Initialized in an initcall, and unchanged thereafter */
930 +devfs_handle_t cow_dir_handle;
931 +
932 +#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \
933 +{ \
934 +       .major          = maj, \
935 +       .major_name     = name, \
936 +       .minor_shift    = shift, \
937 +       .max_p          = 1 << shift, \
938 +       .part           = parts, \
939 +       .sizes          = bsizes, \
940 +       .nr_real        = max, \
941 +       .real_devices   = NULL, \
942 +       .next           = NULL, \
943 +       .fops           = blops, \
944 +       .de_arr         = NULL, \
945 +       .flags          = 0 \
946 +}
947 +
948 +static spinlock_t cow_lock = SPIN_LOCK_UNLOCKED;
949 +
950 +static struct gendisk cow_gendisk = INIT_GENDISK(MAJOR_NR, "cow", cow_part,
951 +                                                COW_SHIFT, sizes, MAX_DEV, 
952 +                                                &cow_blops);
953 +
954 +static int cow_add(int n)
955 +{
956 +       struct cow *dev = &cow_dev[n];
957 +       char name[sizeof("nnnnnn\0")];
958 +       int err = -ENODEV;
959 +
960 +       if(dev->cow_path == NULL)
961 +               goto out;
962 +
963 +       sprintf(name, "%d", n);
964 +       dev->devfs = devfs_register(cow_dir_handle, name, DEVFS_FL_REMOVABLE,
965 +                                   MAJOR_NR, n << COW_SHIFT, S_IFBLK | 
966 +                                   S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
967 +                                   &cow_blops, NULL);
968 +
969 +       init_MUTEX_LOCKED(&dev->sem);
970 +       init_MUTEX(&dev->io_sem);
971 +
972 +       return(0);
973 +
974 +out:
975 +       return(err);
976 +}
977 +
978 +/*
979 +* Add buffer_head to back of pending list
980 +*/
981 +static void cow_add_bh(struct cow *cow, struct buffer_head *bh)
982 +{
983 +       unsigned long flags;
984 +
985 +       spin_lock_irqsave(&cow->io_lock, flags);
986 +       if(cow->bhtail != NULL){
987 +               cow->bhtail->b_reqnext = bh;
988 +               cow->bhtail = bh;
989 +       }
990 +       else {
991 +               cow->bh = bh;
992 +               cow->bhtail = bh;
993 +       }
994 +       spin_unlock_irqrestore(&cow->io_lock, flags);
995 +}
996 +
997 +/*
998 +* Grab first pending buffer
999 +*/
1000 +static struct buffer_head *cow_get_bh(struct cow *cow)
1001 +{
1002 +       struct buffer_head *bh;
1003 +
1004 +       spin_lock_irq(&cow->io_lock);
1005 +       bh = cow->bh;
1006 +       if(bh != NULL){
1007 +               if(bh == cow->bhtail)
1008 +                       cow->bhtail = NULL;
1009 +               cow->bh = bh->b_reqnext;
1010 +               bh->b_reqnext = NULL;
1011 +       }
1012 +       spin_unlock_irq(&cow->io_lock);
1013 +
1014 +       return(bh);
1015 +}
1016 +
1017 +static void cow_handle_bh(struct cow *cow, struct buffer_head *bh, 
1018 +                         struct buffer_head **cow_bh, int ncow_bh)
1019 +{
1020 +       int i;
1021 +
1022 +       if(ncow_bh > 0)
1023 +               ll_rw_block(WRITE, ncow_bh, cow_bh);
1024 +
1025 +       for(i = 0; i < ncow_bh ; i++){
1026 +               wait_on_buffer(cow_bh[i]);
1027 +               brelse(cow_bh[i]);
1028 +       }
1029 +
1030 +       ll_rw_block(WRITE, 1, &bh);
1031 +       brelse(bh);
1032 +}
1033 +
1034 +static struct buffer_head *cow_new_bh(struct cow *dev, int sector)
1035 +{
1036 +       struct buffer_head *bh;
1037 +
1038 +       sector = (dev->bitmap_offset + sector / 8) / dev->sectorsize;
1039 +       bh = getblk(dev->cow_dev, sector, dev->sectorsize);
1040 +       memcpy(bh->b_data, dev->bitmap + sector / (8 * sizeof(dev->bitmap[0])),
1041 +              dev->sectorsize);
1042 +       return(bh);
1043 +}
1044 +
1045 +/* Copied from loop.c, needed to avoid deadlocking in make_request. */
1046 +
1047 +static int cow_thread(void *data)
1048 +{
1049 +       struct cow *dev = data;
1050 +       struct buffer_head *bh;
1051 +
1052 +       daemonize();
1053 +       exit_files(current);
1054 +
1055 +       sprintf(current->comm, "cow%d", dev - cow_dev);
1056 +
1057 +       spin_lock_irq(&current->sigmask_lock);
1058 +       sigfillset(&current->blocked);
1059 +       flush_signals(current);
1060 +       spin_unlock_irq(&current->sigmask_lock);
1061 +
1062 +       atomic_inc(&dev->working);
1063 +
1064 +       current->policy = SCHED_OTHER;
1065 +       current->nice = -20;
1066 +
1067 +       current->flags |= PF_NOIO;
1068 +
1069 +       /*
1070 +        * up sem, we are running
1071 +        */
1072 +       up(&dev->sem);
1073 +
1074 +       for(;;){
1075 +               int start, len, nbh, i, update_bitmap = 0;
1076 +               struct buffer_head *cow_bh[2];
1077 +
1078 +               down_interruptible(&dev->io_sem);
1079 +               /*
1080 +                * could be upped because of tear-down, not because of
1081 +                * pending work
1082 +                */
1083 +               if(!atomic_read(&dev->working))
1084 +                       break;
1085 +
1086 +               bh = cow_get_bh(dev);
1087 +               if(bh == NULL){
1088 +                       printk(KERN_ERR "cow: missing bh\n");
1089 +                       continue;
1090 +               }
1091 +
1092 +               start = bh->b_blocknr * bh->b_size / dev->sectorsize;
1093 +               len = bh->b_size / dev->sectorsize;
1094 +               for(i = 0; i < len ; i++){
1095 +                       if(ubd_test_bit(start +ni, 
1096 +                                       (unsigned char *) dev->bitmap))
1097 +                               continue;
1098 +
1099 +                       update_bitmap = 1;
1100 +                       ubd_set_bit(start + i, (unsigned char *) dev->bitmap);
1101 +               }
1102 +
1103 +               cow_bh[0] = NULL;
1104 +               cow_bh[1] = NULL;
1105 +               nbh = 0;
1106 +               if(update_bitmap){
1107 +                       cow_bh[0] = cow_new_bh(dev, start);
1108 +                       nbh++;
1109 +                       if(start / dev->sectorsize != 
1110 +                          (start + len) / dev->sectorsize){
1111 +                               cow_bh[1] = cow_new_bh(dev, start + len);
1112 +                               nbh++;
1113 +                       }
1114 +               }
1115 +               
1116 +               bh->b_dev = dev->cow_dev;
1117 +               bh->b_blocknr += dev->data_offset / dev->sectorsize;
1118 +
1119 +               cow_handle_bh(dev, bh, cow_bh, nbh);
1120 +
1121 +               /*
1122 +                * upped both for pending work and tear-down, lo_pending
1123 +                * will hit zero then
1124 +                */
1125 +               if(atomic_dec_and_test(&dev->working))
1126 +                       break;
1127 +       }
1128 +
1129 +       up(&dev->sem);
1130 +       return(0);
1131 +}
1132 +
1133 +static int cow_make_request(request_queue_t *q, int rw, struct buffer_head *bh)
1134 +{
1135 +       struct cow *dev;
1136 +       int n, minor;
1137 +
1138 +       minor = MINOR(bh->b_rdev);
1139 +       n = minor >> COW_SHIFT;
1140 +       dev = &cow_dev[n];
1141 +
1142 +       dev->end_io = NULL;
1143 +       if(ubd_test_bit(bh->b_rsector, (unsigned char *) dev->bitmap)){
1144 +               bh->b_rdev = dev->cow_dev;
1145 +               bh->b_rsector += dev->data_offset / dev->sectorsize;
1146 +       }
1147 +       else if(rw == WRITE){
1148 +               bh->b_dev = dev->cow_dev;
1149 +               bh->b_blocknr += dev->data_offset / dev->sectorsize;
1150 +
1151 +               cow_add_bh(dev, bh);
1152 +               up(&dev->io_sem);
1153 +               return(0);
1154 +       }
1155 +       else {
1156 +               bh->b_rdev = dev->backing_dev;
1157 +       }
1158 +
1159 +       return(1);
1160 +}
1161 +
1162 +int cow_init(void)
1163 +{
1164 +       int i;
1165 +
1166 +       cow_dir_handle = devfs_mk_dir (NULL, "cow", NULL);
1167 +       if (devfs_register_blkdev(MAJOR_NR, "cow", &cow_blops)) {
1168 +               printk(KERN_ERR "cow: unable to get major %d\n", MAJOR_NR);
1169 +               return -1;
1170 +       }
1171 +       read_ahead[MAJOR_NR] = 8;               /* 8 sector (4kB) read-ahead */
1172 +       blksize_size[MAJOR_NR] = blk_sizes;
1173 +       blk_size[MAJOR_NR] = sizes;
1174 +       INIT_HARDSECT(hardsect_size, MAJOR_NR, hardsect_sizes);
1175 +
1176 +       cow_queue = BLK_DEFAULT_QUEUE(MAJOR_NR);
1177 +       blk_init_queue(cow_queue, NULL);
1178 +       INIT_ELV(cow_queue, &cow_queue->elevator);
1179 +       blk_queue_make_request(cow_queue, cow_make_request);
1180 +
1181 +       add_gendisk(&cow_gendisk);
1182 +
1183 +       for(i=0;i<MAX_DEV;i++) 
1184 +               cow_add(i);
1185 +
1186 +       return(0);
1187 +}
1188 +
1189 +__initcall(cow_init);
1190 +
1191 +static int reader(__u64 start, char *buf, int count, void *arg)
1192 +{
1193 +       dev_t dev = *((dev_t *) arg);
1194 +       struct buffer_head *bh;
1195 +       __u64 block;
1196 +       int cur, offset, left, n, blocksize = get_hardsect_size(dev);
1197 +
1198 +       if(blocksize == 0)
1199 +               panic("Zero blocksize");
1200 +
1201 +       block = start / blocksize;
1202 +       offset = start % blocksize;
1203 +       left = count;
1204 +       cur = 0;
1205 +       while(left > 0){
1206 +               n = (left > blocksize) ? blocksize : left;
1207 +
1208 +               bh = bread(dev, block, (n < 512) ? 512 : n);
1209 +               if(bh == NULL)
1210 +                       return(-EIO);
1211 +
1212 +               n -= offset;
1213 +               memcpy(&buf[cur], bh->b_data + offset, n);
1214 +               block++;
1215 +               left -= n;
1216 +               cur += n;
1217 +               offset = 0;
1218 +               brelse(bh);
1219 +       }
1220 +
1221 +       return(count);
1222 +}
1223 +
1224 +static int cow_open(struct inode *inode, struct file *filp)
1225 +{
1226 +       int (*dev_ioctl)(struct inode *, struct file *, unsigned int, 
1227 +                        unsigned long);
1228 +       mm_segment_t fs;
1229 +       struct cow *dev;
1230 +       __u64 size;
1231 +       __u32 magic;
1232 +       time_t mtime;
1233 +       char *backing_file;
1234 +       int n, offset, err = 0;
1235 +
1236 +       n = DEVICE_NR(inode->i_rdev);
1237 +       if(n >= MAX_DEV)
1238 +               return(-ENODEV);
1239 +       dev = &cow_dev[n];
1240 +       offset = n << COW_SHIFT;
1241 +
1242 +       spin_lock(&cow_lock);
1243 +
1244 +       if(dev->count == 0){
1245 +               dev->cow_dev = name_to_kdev_t(dev->cow_path);
1246 +               if(dev->cow_dev == 0){
1247 +                       printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") "
1248 +                              "failed\n", dev->cow_path);
1249 +                       err = -ENODEV;
1250 +               }
1251 +
1252 +               dev->backing_dev = name_to_kdev_t(dev->backing_path);
1253 +               if(dev->backing_dev == 0){
1254 +                       printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") "
1255 +                              "failed\n", dev->backing_path);
1256 +                       err = -ENODEV;
1257 +               }
1258 +
1259 +               if(err) 
1260 +                       goto out;
1261 +
1262 +               dev->cow_bdev = bdget(dev->cow_dev);
1263 +               if(dev->cow_bdev == NULL){
1264 +                       printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", 
1265 +                              dev->cow_path);
1266 +                       err = -ENOMEM;
1267 +               }
1268 +               dev->backing_bdev = bdget(dev->backing_dev);
1269 +               if(dev->backing_bdev == NULL){
1270 +                       printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", 
1271 +                              dev->backing_path);
1272 +                       err = -ENOMEM;
1273 +               }
1274 +
1275 +               if(err) 
1276 +                       goto out;
1277 +
1278 +               err = blkdev_get(dev->cow_bdev, FMODE_READ|FMODE_WRITE, 0, 
1279 +                                BDEV_RAW);
1280 +               if(err){
1281 +                       printk("cow_open - blkdev_get of COW device failed, "
1282 +                              "error = %d\n", err);
1283 +                       goto out;
1284 +               }
1285 +               
1286 +               err = blkdev_get(dev->backing_bdev, FMODE_READ, 0, BDEV_RAW);
1287 +               if(err){
1288 +                       printk("cow_open - blkdev_get of backing device "
1289 +                              "failed, error = %d\n", err);
1290 +                       goto out;
1291 +               }
1292 +               
1293 +               err = read_cow_header(reader, &dev->cow_dev, &magic, 
1294 +                                     &backing_file, &mtime, &size,
1295 +                                     &dev->sectorsize, &dev->bitmap_offset);
1296 +               if(err){
1297 +                       printk(KERN_ERR "cow_open - read_cow_header failed, "
1298 +                              "err = %d\n", err);
1299 +                       goto out;
1300 +               }
1301 +
1302 +               cow_sizes(size, dev->sectorsize, dev->bitmap_offset, 
1303 +                         &dev->bitmap_len, &dev->data_offset);
1304 +               dev->bitmap = (void *) vmalloc(dev->bitmap_len);
1305 +               if(dev->bitmap == NULL){
1306 +                       err = -ENOMEM;
1307 +                       printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
1308 +                       goto out;
1309 +               }
1310 +               flush_tlb_kernel_vm();
1311 +               
1312 +               err = reader(dev->bitmap_offset, (char *) dev->bitmap, 
1313 +                            dev->bitmap_len, &dev->cow_dev);
1314 +               if(err < 0){
1315 +                       printk(KERN_ERR "Failed to read COW bitmap\n");
1316 +                       vfree(dev->bitmap);
1317 +                       goto out;
1318 +               }
1319 +
1320 +               dev_ioctl = dev->backing_bdev->bd_op->ioctl;
1321 +               fs = get_fs();
1322 +               set_fs(KERNEL_DS);
1323 +               err = (*dev_ioctl)(inode, filp, BLKGETSIZE, 
1324 +                                  (unsigned long) &sizes[offset]);
1325 +               set_fs(fs);
1326 +               if(err){
1327 +                       printk(KERN_ERR "cow_open - BLKGETSIZE failed, "
1328 +                              "error = %d\n", err);
1329 +                       goto out;
1330 +               }
1331 +
1332 +               kernel_thread(cow_thread, dev, 
1333 +                             CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
1334 +               down(&dev->sem);
1335 +       }
1336 +       dev->count++;
1337 +out:
1338 +       spin_unlock(&cow_lock);
1339 +       return(err);
1340 +}
1341 +
1342 +static int cow_release(struct inode * inode, struct file * file)
1343 +{
1344 +       struct cow *dev;
1345 +       int n, err;
1346 +
1347 +       n = DEVICE_NR(inode->i_rdev);
1348 +       if(n >= MAX_DEV)
1349 +               return(-ENODEV);
1350 +       dev = &cow_dev[n];
1351 +
1352 +       spin_lock(&cow_lock);
1353 +
1354 +       if(--dev->count > 0)
1355 +               goto out;
1356 +
1357 +       err = blkdev_put(dev->cow_bdev, BDEV_RAW);
1358 +       if(err)
1359 +               printk("cow_release - blkdev_put of cow device failed, "
1360 +                      "error = %d\n", err);
1361 +       bdput(dev->cow_bdev);
1362 +       dev->cow_bdev = 0;
1363 +
1364 +       err = blkdev_put(dev->backing_bdev, BDEV_RAW);
1365 +       if(err)
1366 +               printk("cow_release - blkdev_put of backing device failed, "
1367 +                      "error = %d\n", err);
1368 +       bdput(dev->backing_bdev);
1369 +       dev->backing_bdev = 0;
1370 +
1371 +out:
1372 +       spin_unlock(&cow_lock);
1373 +       return(0);
1374 +}
1375 +
1376 +static int cow_ioctl(struct inode * inode, struct file * file,
1377 +                    unsigned int cmd, unsigned long arg)
1378 +{
1379 +       struct cow *dev;
1380 +       int (*dev_ioctl)(struct inode *, struct file *, unsigned int, 
1381 +                        unsigned long);
1382 +       int n;
1383 +
1384 +       n = DEVICE_NR(inode->i_rdev);
1385 +       if(n >= MAX_DEV)
1386 +               return(-ENODEV);
1387 +       dev = &cow_dev[n];
1388 +
1389 +       dev_ioctl = dev->backing_bdev->bd_op->ioctl;
1390 +       return((*dev_ioctl)(inode, file, cmd, arg));
1391 +}
1392 +
1393 +static int cow_revalidate(kdev_t rdev)
1394 +{
1395 +       printk(KERN_ERR "Need to implement cow_revalidate\n");
1396 +       return(0);
1397 +}
1398 +
1399 +static int parse_unit(char **ptr)
1400 +{
1401 +       char *str = *ptr, *end;
1402 +       int n = -1;
1403 +
1404 +       if(isdigit(*str)) {
1405 +               n = simple_strtoul(str, &end, 0);
1406 +               if(end == str)
1407 +                       return(-1);
1408 +               *ptr = end;
1409 +       }
1410 +       else if (('a' <= *str) && (*str <= 'h')) {
1411 +               n = *str - 'a';
1412 +               str++;
1413 +               *ptr = str;
1414 +       }
1415 +       return(n);
1416 +}
1417 +
1418 +static int cow_setup(char *str)
1419 +{
1420 +       struct cow *dev;
1421 +       char *cow_name, *backing_name;
1422 +       int unit;
1423 +
1424 +       unit = parse_unit(&str);
1425 +       if(unit < 0){
1426 +               printk(KERN_ERR "cow_setup - Couldn't parse unit number\n");
1427 +               return(1);
1428 +       }
1429 +
1430 +       if(*str != '='){
1431 +               printk(KERN_ERR "cow_setup - Missing '=' after unit "
1432 +                      "number\n");
1433 +               return(1);
1434 +       }
1435 +       str++;
1436 +
1437 +       cow_name = str;
1438 +       backing_name = strchr(str, ',');
1439 +       if(backing_name == NULL){
1440 +               printk(KERN_ERR "cow_setup - missing backing device name\n");
1441 +               return(0);
1442 +       }
1443 +       *backing_name = '\0';
1444 +       backing_name++;
1445 +
1446 +       spin_lock(&cow_lock);
1447 +
1448 +       dev = &cow_dev[unit];
1449 +       dev->cow_path = cow_name;
1450 +       dev->backing_path = backing_name;
1451 +       
1452 +       spin_unlock(&cow_lock);
1453 +       return(0);
1454 +}
1455 +
1456 +__setup("cow", cow_setup);
1457 +
1458 +/*
1459 + * Overrides for Emacs so that we follow Linus's tabbing style.
1460 + * Emacs will notice this stuff at the end of the file and automatically
1461 + * adjust the settings for this buffer only.  This must remain at the end
1462 + * of the file.
1463 + * ---------------------------------------------------------------------------
1464 + * Local variables:
1465 + * c-file-style: "linux"
1466 + * End:
1467 + */
1468 diff -Naur a/arch/um/drivers/cow_sys.h b/arch/um/drivers/cow_sys.h
1469 --- a/arch/um/drivers/cow_sys.h Wed Dec 31 19:00:00 1969
1470 +++ b/arch/um/drivers/cow_sys.h Tue Sep  9 16:49:10 2003
1471 @@ -0,0 +1,48 @@
1472 +#ifndef __COW_SYS_H__
1473 +#define __COW_SYS_H__
1474 +
1475 +#include "kern_util.h"
1476 +#include "user_util.h"
1477 +#include "os.h"
1478 +#include "user.h"
1479 +
1480 +static inline void *cow_malloc(int size)
1481 +{
1482 +       return(um_kmalloc(size));
1483 +}
1484 +
1485 +static inline void cow_free(void *ptr)
1486 +{
1487 +       kfree(ptr);
1488 +}
1489 +
1490 +#define cow_printf printk
1491 +
1492 +static inline char *cow_strdup(char *str)
1493 +{
1494 +       return(uml_strdup(str));
1495 +}
1496 +
1497 +static inline int cow_seek_file(int fd, __u64 offset)
1498 +{
1499 +       return(os_seek_file(fd, offset));
1500 +}
1501 +
1502 +static inline int cow_file_size(char *file, __u64 *size_out)
1503 +{
1504 +       return(os_file_size(file, size_out));
1505 +}
1506 +
1507 +static inline int cow_write_file(int fd, char *buf, int size)
1508 +{
1509 +       return(os_write_file(fd, buf, size));
1510 +}
1511 +
1512 +#endif
1513 +
1514 +/*
1515 + * ---------------------------------------------------------------------------
1516 + * Local variables:
1517 + * c-file-style: "linux"
1518 + * End:
1519 + */
1520 diff -Naur a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c
1521 --- a/arch/um/drivers/cow_user.c        Wed Dec 31 19:00:00 1969
1522 +++ b/arch/um/drivers/cow_user.c        Tue Sep  9 16:49:06 2003
1523 @@ -0,0 +1,296 @@
1524 +#include <stddef.h>
1525 +#include <string.h>
1526 +#include <errno.h>
1527 +#include <unistd.h>
1528 +#include <byteswap.h>
1529 +#include <sys/stat.h>
1530 +#include <sys/time.h>
1531 +#include <sys/param.h>
1532 +#include <netinet/in.h>
1533 +
1534 +#include "cow.h"
1535 +#include "cow_sys.h"
1536 +
1537 +#define PATH_LEN_V1 256
1538 +
1539 +struct cow_header_v1 {
1540 +       int magic;
1541 +       int version;
1542 +       char backing_file[PATH_LEN_V1];
1543 +       time_t mtime;
1544 +       __u64 size;
1545 +       int sectorsize;
1546 +};
1547 +
1548 +#define PATH_LEN_V2 MAXPATHLEN
1549 +
1550 +struct cow_header_v2 {
1551 +       unsigned long magic;
1552 +       unsigned long version;
1553 +       char backing_file[PATH_LEN_V2];
1554 +       time_t mtime;
1555 +       __u64 size;
1556 +       int sectorsize;
1557 +};
1558 +
1559 +union cow_header {
1560 +       struct cow_header_v1 v1;
1561 +       struct cow_header_v2 v2;
1562 +};
1563 +
1564 +#define COW_MAGIC 0x4f4f4f4d  /* MOOO */
1565 +#define COW_VERSION 2
1566 +
1567 +void cow_sizes(__u64 size, int sectorsize, int bitmap_offset, 
1568 +              unsigned long *bitmap_len_out, int *data_offset_out)
1569 +{
1570 +       *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
1571 +
1572 +       *data_offset_out = bitmap_offset + *bitmap_len_out;
1573 +       *data_offset_out = (*data_offset_out + sectorsize - 1) / sectorsize;
1574 +       *data_offset_out *= sectorsize;
1575 +}
1576 +
1577 +static int absolutize(char *to, int size, char *from)
1578 +{
1579 +       char save_cwd[256], *slash;
1580 +       int remaining;
1581 +
1582 +       if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
1583 +               cow_printf("absolutize : unable to get cwd - errno = %d\n", 
1584 +                          errno);
1585 +               return(-1);
1586 +       }
1587 +       slash = strrchr(from, '/');
1588 +       if(slash != NULL){
1589 +               *slash = '\0';
1590 +               if(chdir(from)){
1591 +                       *slash = '/';
1592 +                       cow_printf("absolutize : Can't cd to '%s' - " 
1593 +                                  "errno = %d\n", from, errno);
1594 +                       return(-1);
1595 +               }
1596 +               *slash = '/';
1597 +               if(getcwd(to, size) == NULL){
1598 +                       cow_printf("absolutize : unable to get cwd of '%s' - "
1599 +                              "errno = %d\n", from, errno);
1600 +                       return(-1);
1601 +               }
1602 +               remaining = size - strlen(to);
1603 +               if(strlen(slash) + 1 > remaining){
1604 +                       cow_printf("absolutize : unable to fit '%s' into %d "
1605 +                              "chars\n", from, size);
1606 +                       return(-1);
1607 +               }
1608 +               strcat(to, slash);
1609 +       }
1610 +       else {
1611 +               if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
1612 +                       cow_printf("absolutize : unable to fit '%s' into %d "
1613 +                              "chars\n", from, size);
1614 +                       return(-1);
1615 +               }
1616 +               strcpy(to, save_cwd);
1617 +               strcat(to, "/");
1618 +               strcat(to, from);
1619 +       }
1620 +       chdir(save_cwd);
1621 +       return(0);
1622 +}
1623 +
1624 +int write_cow_header(char *cow_file, int fd, char *backing_file, 
1625 +                    int sectorsize, long long *size)
1626 +{
1627 +       struct cow_header_v2 *header;
1628 +       struct stat64 buf;
1629 +       int err;
1630 +
1631 +       err = cow_seek_file(fd, 0);
1632 +       if(err != 0){
1633 +               cow_printf("write_cow_header - lseek failed, errno = %d\n", 
1634 +                          errno);
1635 +               return(-errno);
1636 +       }
1637 +
1638 +       err = -ENOMEM;
1639 +       header = cow_malloc(sizeof(*header));
1640 +       if(header == NULL){
1641 +               cow_printf("Failed to allocate COW V2 header\n");
1642 +               goto out;
1643 +       }
1644 +       header->magic = htonl(COW_MAGIC);
1645 +       header->version = htonl(COW_VERSION);
1646 +
1647 +       err = -EINVAL;
1648 +       if(strlen(backing_file) > sizeof(header->backing_file) - 1){
1649 +               cow_printf("Backing file name \"%s\" is too long - names are "
1650 +                          "limited to %d characters\n", backing_file, 
1651 +                          sizeof(header->backing_file) - 1);
1652 +               goto out_free;
1653 +       }
1654 +
1655 +       if(absolutize(header->backing_file, sizeof(header->backing_file), 
1656 +                     backing_file))
1657 +               goto out_free;
1658 +
1659 +       err = stat64(header->backing_file, &buf);
1660 +       if(err < 0){
1661 +               cow_printf("Stat of backing file '%s' failed, errno = %d\n",
1662 +                          header->backing_file, errno);
1663 +               err = -errno;
1664 +               goto out_free;
1665 +       }
1666 +
1667 +       err = cow_file_size(header->backing_file, size);
1668 +       if(err){
1669 +               cow_printf("Couldn't get size of backing file '%s', "
1670 +                          "errno = %d\n", header->backing_file, -*size);
1671 +               goto out_free;
1672 +       }
1673 +
1674 +       header->mtime = htonl(buf.st_mtime);
1675 +       header->size = htonll(*size);
1676 +       header->sectorsize = htonl(sectorsize);
1677 +
1678 +       err = write(fd, header, sizeof(*header));
1679 +       if(err != sizeof(*header)){
1680 +               cow_printf("Write of header to new COW file '%s' failed, "
1681 +                          "errno = %d\n", cow_file, errno);
1682 +               goto out_free;
1683 +       }
1684 +       err = 0;
1685 + out_free:
1686 +       cow_free(header);
1687 + out:
1688 +       return(err);
1689 +}
1690 +
1691 +int file_reader(__u64 offset, char *buf, int len, void *arg)
1692 +{
1693 +       int fd = *((int *) arg);
1694 +
1695 +       return(pread(fd, buf, len, offset));
1696 +}
1697 +
1698 +int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, 
1699 +                   __u32 *magic_out, char **backing_file_out, 
1700 +                   time_t *mtime_out, __u64 *size_out, 
1701 +                   int *sectorsize_out, int *bitmap_offset_out)
1702 +{
1703 +       union cow_header *header;
1704 +       char *file;
1705 +       int err, n;
1706 +       unsigned long version, magic;
1707 +
1708 +       header = cow_malloc(sizeof(*header));
1709 +       if(header == NULL){
1710 +               cow_printf("read_cow_header - Failed to allocate header\n");
1711 +               return(-ENOMEM);
1712 +       }
1713 +       err = -EINVAL;
1714 +       n = (*reader)(0, (char *) header, sizeof(*header), arg);
1715 +       if(n < offsetof(typeof(header->v1), backing_file)){
1716 +               cow_printf("read_cow_header - short header\n");
1717 +               goto out;
1718 +       }
1719 +
1720 +       magic = header->v1.magic;
1721 +       if(magic == COW_MAGIC) {
1722 +               version = header->v1.version;
1723 +       }
1724 +       else if(magic == ntohl(COW_MAGIC)){
1725 +               version = ntohl(header->v1.version);
1726 +       }
1727 +       /* No error printed because the non-COW case comes through here */
1728 +       else goto out;
1729 +
1730 +       *magic_out = COW_MAGIC;
1731 +
1732 +       if(version == 1){
1733 +               if(n < sizeof(header->v1)){
1734 +                       cow_printf("read_cow_header - failed to read V1 "
1735 +                                  "header\n");
1736 +                       goto out;
1737 +               }
1738 +               *mtime_out = header->v1.mtime;
1739 +               *size_out = header->v1.size;
1740 +               *sectorsize_out = header->v1.sectorsize;
1741 +               *bitmap_offset_out = sizeof(header->v1);
1742 +               file = header->v1.backing_file;
1743 +       }
1744 +       else if(version == 2){
1745 +               if(n < sizeof(header->v2)){
1746 +                       cow_printf("read_cow_header - failed to read V2 "
1747 +                                  "header\n");
1748 +                       goto out;
1749 +               }
1750 +               *mtime_out = ntohl(header->v2.mtime);
1751 +               *size_out = ntohll(header->v2.size);
1752 +               *sectorsize_out = ntohl(header->v2.sectorsize);
1753 +               *bitmap_offset_out = sizeof(header->v2);
1754 +               file = header->v2.backing_file;
1755 +       }
1756 +       else {
1757 +               cow_printf("read_cow_header - invalid COW version\n");
1758 +               goto out;
1759 +       }
1760 +       err = -ENOMEM;
1761 +       *backing_file_out = cow_strdup(file);
1762 +       if(*backing_file_out == NULL){
1763 +               cow_printf("read_cow_header - failed to allocate backing "
1764 +                          "file\n");
1765 +               goto out;
1766 +       }
1767 +       err = 0;
1768 + out:
1769 +       cow_free(header);
1770 +       return(err);
1771 +}
1772 +
1773 +int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
1774 +                 int *bitmap_offset_out, unsigned long *bitmap_len_out, 
1775 +                 int *data_offset_out)
1776 +{
1777 +       __u64 size, offset;
1778 +       char zero = 0;
1779 +       int err;
1780 +
1781 +       err = write_cow_header(cow_file, fd, backing_file, sectorsize, &size);
1782 +       if(err) 
1783 +               goto out;
1784 +       
1785 +       cow_sizes(size, sectorsize, sizeof(struct cow_header_v2), 
1786 +                 bitmap_len_out, data_offset_out);
1787 +       *bitmap_offset_out = sizeof(struct cow_header_v2);
1788 +
1789 +       offset = *data_offset_out + size - sizeof(zero);
1790 +       err = cow_seek_file(fd, offset);
1791 +       if(err != 0){
1792 +               cow_printf("cow bitmap lseek failed : errno = %d\n", errno);
1793 +               goto out;
1794 +       }
1795 +
1796 +       /* does not really matter how much we write it is just to set EOF 
1797 +        * this also sets the entire COW bitmap
1798 +        * to zero without having to allocate it 
1799 +        */
1800 +       err = cow_write_file(fd, &zero, sizeof(zero));
1801 +       if(err != sizeof(zero)){
1802 +               err = -EINVAL;
1803 +               cow_printf("Write of bitmap to new COW file '%s' failed, "
1804 +                          "errno = %d\n", cow_file, errno);
1805 +               goto out;
1806 +       }
1807 +
1808 +       return(0);
1809 +
1810 + out:
1811 +       return(err);
1812 +}
1813 +
1814 +/*
1815 + * ---------------------------------------------------------------------------
1816 + * Local variables:
1817 + * c-file-style: "linux"
1818 + * End:
1819 + */
1820 diff -Naur a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c
1821 --- a/arch/um/drivers/hostaudio_kern.c  Tue Sep  9 16:46:07 2003
1822 +++ b/arch/um/drivers/hostaudio_kern.c  Tue Sep  9 16:51:08 2003
1823 @@ -11,6 +11,7 @@
1824  #include "linux/fs.h"
1825  #include "linux/sound.h"
1826  #include "linux/soundcard.h"
1827 +#include "asm/uaccess.h"
1828  #include "kern_util.h"
1829  #include "init.h"
1830  #include "hostaudio.h"
1831 @@ -22,7 +23,7 @@
1832  #ifndef MODULE
1833  static int set_dsp(char *name, int *add)
1834  {
1835 -       dsp = uml_strdup(name);
1836 +       dsp = name;
1837         return(0);
1838  }
1839  
1840 @@ -34,7 +35,7 @@
1841  
1842  static int set_mixer(char *name, int *add)
1843  {
1844 -       mixer = uml_strdup(name);
1845 +       mixer = name;
1846         return(0);
1847  }
1848  
1849 @@ -51,23 +52,55 @@
1850                               loff_t *ppos)
1851  {
1852          struct hostaudio_state *state = file->private_data;
1853 +       void *kbuf;
1854 +       int err;
1855  
1856  #ifdef DEBUG
1857          printk("hostaudio: read called, count = %d\n", count);
1858  #endif
1859  
1860 -        return(hostaudio_read_user(state, buffer, count, ppos));
1861 +       kbuf = kmalloc(count, GFP_KERNEL);
1862 +       if(kbuf == NULL)
1863 +               return(-ENOMEM);
1864 +
1865 +        err = hostaudio_read_user(state, kbuf, count, ppos);
1866 +       if(err < 0)
1867 +               goto out;
1868 +
1869 +       if(copy_to_user(buffer, kbuf, err))
1870 +               err = -EFAULT;
1871 +
1872 + out:
1873 +       kfree(kbuf);
1874 +       return(err);
1875  }
1876  
1877  static ssize_t hostaudio_write(struct file *file, const char *buffer, 
1878                                size_t count, loff_t *ppos)
1879  {
1880          struct hostaudio_state *state = file->private_data;
1881 +       void *kbuf;
1882 +       int err;
1883  
1884  #ifdef DEBUG
1885          printk("hostaudio: write called, count = %d\n", count);
1886  #endif
1887 -        return(hostaudio_write_user(state, buffer, count, ppos));
1888 +
1889 +       kbuf = kmalloc(count, GFP_KERNEL);
1890 +       if(kbuf == NULL)
1891 +               return(-ENOMEM);
1892 +
1893 +       err = -EFAULT;
1894 +       if(copy_from_user(kbuf, buffer, count))
1895 +               goto out;
1896 +
1897 +        err = hostaudio_write_user(state, kbuf, count, ppos);
1898 +       if(err < 0)
1899 +               goto out;
1900 +
1901 + out:
1902 +       kfree(kbuf);
1903 +       return(err);
1904  }
1905  
1906  static unsigned int hostaudio_poll(struct file *file, 
1907 @@ -86,12 +119,43 @@
1908                            unsigned int cmd, unsigned long arg)
1909  {
1910          struct hostaudio_state *state = file->private_data;
1911 +       unsigned long data = 0;
1912 +       int err;
1913  
1914  #ifdef DEBUG
1915          printk("hostaudio: ioctl called, cmd = %u\n", cmd);
1916  #endif
1917 +       switch(cmd){
1918 +       case SNDCTL_DSP_SPEED:
1919 +       case SNDCTL_DSP_STEREO:
1920 +       case SNDCTL_DSP_GETBLKSIZE:
1921 +       case SNDCTL_DSP_CHANNELS:
1922 +       case SNDCTL_DSP_SUBDIVIDE:
1923 +       case SNDCTL_DSP_SETFRAGMENT:
1924 +               if(get_user(data, (int *) arg))
1925 +                       return(-EFAULT);
1926 +               break;
1927 +       default:
1928 +               break;
1929 +       }
1930 +
1931 +        err = hostaudio_ioctl_user(state, cmd, (unsigned long) &data);
1932 +
1933 +       switch(cmd){
1934 +       case SNDCTL_DSP_SPEED:
1935 +       case SNDCTL_DSP_STEREO:
1936 +       case SNDCTL_DSP_GETBLKSIZE:
1937 +       case SNDCTL_DSP_CHANNELS:
1938 +       case SNDCTL_DSP_SUBDIVIDE:
1939 +       case SNDCTL_DSP_SETFRAGMENT:
1940 +               if(put_user(data, (int *) arg))
1941 +                       return(-EFAULT);
1942 +               break;
1943 +       default:
1944 +               break;
1945 +       }
1946  
1947 -        return(hostaudio_ioctl_user(state, cmd, arg));
1948 +       return(err);
1949  }
1950  
1951  static int hostaudio_open(struct inode *inode, struct file *file)
1952 @@ -225,7 +289,8 @@
1953  
1954  static int __init hostaudio_init_module(void)
1955  {
1956 -        printk(KERN_INFO "UML Audio Relay\n");
1957 +        printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n",
1958 +              dsp, mixer);
1959  
1960         module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1);
1961          if(module_data.dev_audio < 0){
1962 diff -Naur a/arch/um/drivers/line.c b/arch/um/drivers/line.c
1963 --- a/arch/um/drivers/line.c    Tue Sep  9 16:45:58 2003
1964 +++ b/arch/um/drivers/line.c    Tue Sep  9 16:50:27 2003
1965 @@ -6,8 +6,8 @@
1966  #include "linux/sched.h"
1967  #include "linux/slab.h"
1968  #include "linux/list.h"
1969 +#include "linux/interrupt.h"
1970  #include "linux/devfs_fs_kernel.h"
1971 -#include "asm/irq.h"
1972  #include "asm/uaccess.h"
1973  #include "chan_kern.h"
1974  #include "irq_user.h"
1975 @@ -16,16 +16,18 @@
1976  #include "user_util.h"
1977  #include "kern_util.h"
1978  #include "os.h"
1979 +#include "irq_kern.h"
1980  
1981  #define LINE_BUFSIZE 4096
1982  
1983 -void line_interrupt(int irq, void *data, struct pt_regs *unused)
1984 +irqreturn_t line_interrupt(int irq, void *data, struct pt_regs *unused)
1985  {
1986         struct line *dev = data;
1987  
1988         if(dev->count > 0) 
1989                 chan_interrupt(&dev->chan_list, &dev->task, dev->tty, irq, 
1990                                dev);
1991 +       return IRQ_HANDLED;
1992  }
1993  
1994  void line_timer_cb(void *arg)
1995 @@ -136,20 +138,22 @@
1996         return(len);
1997  }
1998  
1999 -void line_write_interrupt(int irq, void *data, struct pt_regs *unused)
2000 +irqreturn_t line_write_interrupt(int irq, void *data, struct pt_regs *unused)
2001  {
2002         struct line *dev = data;
2003         struct tty_struct *tty = dev->tty;
2004         int err;
2005  
2006         err = flush_buffer(dev);
2007 -       if(err == 0) return;
2008 +       if(err == 0) 
2009 +               return(IRQ_NONE);
2010         else if(err < 0){
2011                 dev->head = dev->buffer;
2012                 dev->tail = dev->buffer;
2013         }
2014  
2015 -       if(tty == NULL) return;
2016 +       if(tty == NULL) 
2017 +               return(IRQ_NONE);
2018  
2019         if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
2020            (tty->ldisc.write_wakeup != NULL))
2021 @@ -161,9 +165,9 @@
2022          * writes.
2023          */
2024  
2025 -       if (waitqueue_active(&tty->write_wait))
2026 +       if(waitqueue_active(&tty->write_wait))
2027                 wake_up_interruptible(&tty->write_wait);
2028 -
2029 +       return(IRQ_HANDLED);
2030  }
2031  
2032  int line_write_room(struct tty_struct *tty)
2033 @@ -369,7 +373,7 @@
2034  
2035         dev = simple_strtoul(name, &end, 0);
2036         if((*end != '\0') || (end == name)){
2037 -               *error_out = "line_setup failed to parse device number";
2038 +               *error_out = "line_get_config failed to parse device number";
2039                 return(0);
2040         }
2041  
2042 @@ -379,15 +383,15 @@
2043         }
2044  
2045         line = &lines[dev];
2046 +
2047         down(&line->sem);
2048 -       
2049         if(!line->valid)
2050                 CONFIG_CHUNK(str, size, n, "none", 1);
2051         else if(line->count == 0)
2052                 CONFIG_CHUNK(str, size, n, line->init_str, 1);
2053         else n = chan_config_string(&line->chan_list, str, size, error_out);
2054 -
2055         up(&line->sem);
2056 +
2057         return(n);
2058  }
2059  
2060 @@ -412,7 +416,8 @@
2061                 return NULL;
2062  
2063         driver->driver_name = line_driver->name;
2064 -       driver->name = line_driver->devfs_name;
2065 +       driver->name = line_driver->device_name;
2066 +       driver->devfs_name = line_driver->devfs_name;
2067         driver->major = line_driver->major;
2068         driver->minor_start = line_driver->minor_start;
2069         driver->type = line_driver->type;
2070 @@ -432,7 +437,7 @@
2071  
2072         for(i = 0; i < nlines; i++){
2073                 if(!lines[i].valid) 
2074 -                       tty_unregister_devfs(driver, i);
2075 +                       tty_unregister_device(driver, i);
2076         }
2077  
2078         mconsole_register_dev(&line_driver->mc);
2079 @@ -465,24 +470,25 @@
2080         struct line *line;
2081  };
2082  
2083 -void winch_interrupt(int irq, void *data, struct pt_regs *unused)
2084 +irqreturn_t winch_interrupt(int irq, void *data, struct pt_regs *unused)
2085  {
2086         struct winch *winch = data;
2087         struct tty_struct *tty;
2088         int err;
2089         char c;
2090  
2091 -       err = generic_read(winch->fd, &c, NULL);
2092 -       if(err < 0){
2093 -               if(err != -EAGAIN){
2094 -                       printk("winch_interrupt : read failed, errno = %d\n", 
2095 -                              -err);
2096 -                       printk("fd %d is losing SIGWINCH support\n", 
2097 -                              winch->tty_fd);
2098 -                       free_irq(irq, data);
2099 -                       return;
2100 +       if(winch->fd != -1){
2101 +               err = generic_read(winch->fd, &c, NULL);
2102 +               if(err < 0){
2103 +                       if(err != -EAGAIN){
2104 +                               printk("winch_interrupt : read failed, "
2105 +                                      "errno = %d\n", -err);
2106 +                               printk("fd %d is losing SIGWINCH support\n", 
2107 +                                      winch->tty_fd);
2108 +                               return(IRQ_HANDLED);
2109 +                       }
2110 +                       goto out;
2111                 }
2112 -               goto out;
2113         }
2114         tty = winch->line->tty;
2115         if(tty != NULL){
2116 @@ -492,7 +498,9 @@
2117                 kill_pg(tty->pgrp, SIGWINCH, 1);
2118         }
2119   out:
2120 -       reactivate_fd(winch->fd, WINCH_IRQ);
2121 +       if(winch->fd != -1)
2122 +               reactivate_fd(winch->fd, WINCH_IRQ);
2123 +       return(IRQ_HANDLED);
2124  }
2125  
2126  DECLARE_MUTEX(winch_handler_sem);
2127 @@ -529,7 +537,10 @@
2128  
2129         list_for_each(ele, &winch_handlers){
2130                 winch = list_entry(ele, struct winch, list);
2131 -               close(winch->fd);
2132 +               if(winch->fd != -1){
2133 +                       deactivate_fd(winch->fd, WINCH_IRQ);
2134 +                       close(winch->fd);
2135 +               }
2136                 if(winch->pid != -1) 
2137                         os_kill_process(winch->pid, 1);
2138         }
2139 diff -Naur a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
2140 --- a/arch/um/drivers/mconsole_kern.c   Tue Sep  9 16:41:12 2003
2141 +++ b/arch/um/drivers/mconsole_kern.c   Tue Sep  9 16:47:22 2003
2142 @@ -27,6 +27,7 @@
2143  #include "init.h"
2144  #include "os.h"
2145  #include "umid.h"
2146 +#include "irq_kern.h"
2147  
2148  static int do_unlink_socket(struct notifier_block *notifier, 
2149                             unsigned long what, void *data)
2150 @@ -67,7 +68,7 @@
2151  
2152  DECLARE_WORK(mconsole_work, mc_work_proc, NULL);
2153  
2154 -void mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2155 +irqreturn_t mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2156  {
2157         int fd;
2158         struct mconsole_entry *new;
2159 @@ -88,6 +89,7 @@
2160         }
2161         if(!list_empty(&mc_requests)) schedule_work(&mconsole_work);
2162         reactivate_fd(fd, MCONSOLE_IRQ);
2163 +       return(IRQ_HANDLED);
2164  }
2165  
2166  void mconsole_version(struct mc_request *req)
2167 @@ -100,20 +102,34 @@
2168         mconsole_reply(req, version, 0, 0);
2169  }
2170  
2171 +void mconsole_log(struct mc_request *req)
2172 +{
2173 +       int len;
2174 +       char *ptr = req->request.data;
2175 +       
2176 +       ptr += strlen("log");
2177 +       while(isspace(*ptr)) ptr++;
2178 +
2179 +       len = ptr - req->request.data;
2180 +       printk("%.*s", len, ptr);
2181 +       mconsole_reply(req, "", 0, 0);
2182 +}
2183 +
2184  #define UML_MCONSOLE_HELPTEXT \
2185 -"Commands:
2186 -    version - Get kernel version
2187 -    help - Print this message
2188 -    halt - Halt UML
2189 -    reboot - Reboot UML
2190 -    config <dev>=<config> - Add a new device to UML; 
2191 -       same syntax as command line
2192 -    config <dev> - Query the configuration of a device
2193 -    remove <dev> - Remove a device from UML
2194 -    sysrq <letter> - Performs the SysRq action controlled by the letter
2195 -    cad - invoke the Ctl-Alt-Del handler
2196 -    stop - pause the UML; it will do nothing until it receives a 'go'
2197 -    go - continue the UML after a 'stop'
2198 +"Commands: \n\
2199 +    version - Get kernel version \n\
2200 +    help - Print this message \n\
2201 +    halt - Halt UML \n\
2202 +    reboot - Reboot UML \n\
2203 +    config <dev>=<config> - Add a new device to UML;  \n\
2204 +       same syntax as command line \n\
2205 +    config <dev> - Query the configuration of a device \n\
2206 +    remove <dev> - Remove a device from UML \n\
2207 +    sysrq <letter> - Performs the SysRq action controlled by the letter \n\
2208 +    cad - invoke the Ctl-Alt-Del handler \n\
2209 +    stop - pause the UML; it will do nothing until it receives a 'go' \n\
2210 +    go - continue the UML after a 'stop' \n\
2211 +    log <string> - make UML enter <string> into the kernel log\n\
2212  "
2213  
2214  void mconsole_help(struct mc_request *req)
2215 @@ -302,7 +318,7 @@
2216         if(umid_file_name("mconsole", file, sizeof(file))) return(-1);
2217         snprintf(mconsole_socket_name, sizeof(file), "%s", file);
2218  
2219 -       sock = create_unix_socket(file, sizeof(file));
2220 +       sock = create_unix_socket(file, sizeof(file), 1);
2221         if (sock < 0){
2222                 printk("Failed to initialize management console\n");
2223                 return(1);
2224 diff -Naur a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
2225 --- a/arch/um/drivers/mconsole_user.c   Tue Sep  9 16:41:40 2003
2226 +++ b/arch/um/drivers/mconsole_user.c   Tue Sep  9 16:47:42 2003
2227 @@ -28,6 +28,7 @@
2228         { "cad", mconsole_cad, 1 },
2229         { "stop", mconsole_stop, 0 },
2230         { "go", mconsole_go, 1 },
2231 +       { "log", mconsole_log, 1 },
2232  };
2233  
2234  /* Initialized in mconsole_init, which is an initcall */
2235 @@ -139,6 +140,7 @@
2236                 memcpy(reply.data, str, len);
2237                 reply.data[len] = '\0';
2238                 total -= len;
2239 +               str += len;
2240                 reply.len = len + 1;
2241  
2242                 len = sizeof(reply) + reply.len - sizeof(reply.data);
2243 diff -Naur a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
2244 --- a/arch/um/drivers/mmapper_kern.c    Tue Sep  9 16:41:34 2003
2245 +++ b/arch/um/drivers/mmapper_kern.c    Tue Sep  9 16:47:40 2003
2246 @@ -120,7 +120,10 @@
2247         printk(KERN_INFO "Mapper v0.1\n");
2248  
2249         v_buf = (char *) find_iomem("mmapper", &mmapper_size);
2250 -       if(mmapper_size == 0) return(0);
2251 +       if(mmapper_size == 0){
2252 +               printk(KERN_ERR "mmapper_init - find_iomem failed\n");
2253 +               return(0);
2254 +       }
2255  
2256         p_buf = __pa(v_buf);
2257  
2258 diff -Naur a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
2259 --- a/arch/um/drivers/net_kern.c        Tue Sep  9 16:43:06 2003
2260 +++ b/arch/um/drivers/net_kern.c        Tue Sep  9 16:48:52 2003
2261 @@ -26,6 +26,7 @@
2262  #include "mconsole_kern.h"
2263  #include "init.h"
2264  #include "irq_user.h"
2265 +#include "irq_kern.h"
2266  
2267  static spinlock_t opened_lock = SPIN_LOCK_UNLOCKED;
2268  LIST_HEAD(opened);
2269 @@ -61,14 +62,14 @@
2270         return pkt_len;
2271  }
2272  
2273 -void uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2274 +irqreturn_t uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs)
2275  {
2276         struct net_device *dev = dev_id;
2277         struct uml_net_private *lp = dev->priv;
2278         int err;
2279  
2280         if(!netif_running(dev))
2281 -               return;
2282 +               return(IRQ_NONE);
2283  
2284         spin_lock(&lp->lock);
2285         while((err = uml_net_rx(dev)) > 0) ;
2286 @@ -83,6 +84,7 @@
2287  
2288   out:
2289         spin_unlock(&lp->lock);
2290 +       return(IRQ_HANDLED);
2291  }
2292  
2293  static int uml_net_open(struct net_device *dev)
2294 @@ -252,37 +254,6 @@
2295  #endif
2296  }
2297  
2298 -/*
2299 - * default do nothing hard header packet routines for struct net_device init.
2300 - * real ethernet transports will overwrite with real routines.
2301 - */
2302 -static int uml_net_hard_header(struct sk_buff *skb, struct net_device *dev,
2303 -                 unsigned short type, void *daddr, void *saddr, unsigned len)
2304 -{
2305 -       return(0); /* no change */
2306 -}
2307 -
2308 -static int uml_net_rebuild_header(struct sk_buff *skb)
2309 -{
2310 -       return(0); /* ignore */ 
2311 -}
2312 -
2313 -static int uml_net_header_cache(struct neighbour *neigh, struct hh_cache *hh)
2314 -{
2315 -       return(-1); /* fail */
2316 -}
2317 -
2318 -static void uml_net_header_cache_update(struct hh_cache *hh,
2319 -                 struct net_device *dev, unsigned char * haddr)
2320 -{
2321 -       /* ignore */
2322 -}
2323 -
2324 -static int uml_net_header_parse(struct sk_buff *skb, unsigned char *haddr)
2325 -{
2326 -       return(0); /* nothing */
2327 -}
2328 -
2329  static spinlock_t devices_lock = SPIN_LOCK_UNLOCKED;
2330  static struct list_head devices = LIST_HEAD_INIT(devices);
2331  
2332 @@ -292,7 +263,7 @@
2333         struct uml_net *device;
2334         struct net_device *dev;
2335         struct uml_net_private *lp;
2336 -       int err, size;
2337 +       int save, err, size;
2338  
2339         size = transport->private_size + sizeof(struct uml_net_private) + 
2340                 sizeof(((struct uml_net_private *) 0)->user);
2341 @@ -334,12 +305,6 @@
2342         snprintf(dev->name, sizeof(dev->name), "eth%d", n);
2343         device->dev = dev;
2344  
2345 -        dev->hard_header = uml_net_hard_header;
2346 -        dev->rebuild_header = uml_net_rebuild_header;
2347 -        dev->hard_header_cache = uml_net_header_cache;
2348 -        dev->header_cache_update= uml_net_header_cache_update;
2349 -        dev->hard_header_parse = uml_net_header_parse;
2350 -
2351         (*transport->kern->init)(dev, init);
2352  
2353         dev->mtu = transport->user->max_packet;
2354 @@ -362,21 +327,29 @@
2355                 return 1;
2356         lp = dev->priv;
2357  
2358 -       INIT_LIST_HEAD(&lp->list);
2359 -       spin_lock_init(&lp->lock);
2360 -       lp->dev = dev;
2361 -       lp->fd = -1;
2362 -       lp->mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0 };
2363 -       lp->have_mac = device->have_mac;
2364 -       lp->protocol = transport->kern->protocol;
2365 -       lp->open = transport->user->open;
2366 -       lp->close = transport->user->close;
2367 -       lp->remove = transport->user->remove;
2368 -       lp->read = transport->kern->read;
2369 -       lp->write = transport->kern->write;
2370 -       lp->add_address = transport->user->add_address;
2371 -       lp->delete_address = transport->user->delete_address;
2372 -       lp->set_mtu = transport->user->set_mtu;
2373 +       /* lp.user is the first four bytes of the transport data, which
2374 +        * has already been initialized.  This structure assignment will
2375 +        * overwrite that, so we make sure that .user gets overwritten with
2376 +        * what it already has.
2377 +        */
2378 +       save = lp->user[0];
2379 +       *lp = ((struct uml_net_private) 
2380 +               { .list                 = LIST_HEAD_INIT(lp->list),
2381 +                 .lock                 = SPIN_LOCK_UNLOCKED,
2382 +                 .dev                  = dev,
2383 +                 .fd                   = -1,
2384 +                 .mac                  = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
2385 +                 .have_mac             = device->have_mac,
2386 +                 .protocol             = transport->kern->protocol,
2387 +                 .open                 = transport->user->open,
2388 +                 .close                = transport->user->close,
2389 +                 .remove               = transport->user->remove,
2390 +                 .read                 = transport->kern->read,
2391 +                 .write                = transport->kern->write,
2392 +                 .add_address          = transport->user->add_address,
2393 +                 .delete_address       = transport->user->delete_address,
2394 +                 .set_mtu              = transport->user->set_mtu,
2395 +                 .user                 = { save } });
2396  
2397         init_timer(&lp->tl);
2398         lp->tl.function = uml_net_user_timer_expire;
2399 @@ -609,7 +582,8 @@
2400         unregister_netdev(dev);
2401  
2402         list_del(&device->list);
2403 -       free_netdev(device);
2404 +       kfree(device);
2405 +       free_netdev(dev);
2406         return(0);
2407  }
2408  
2409 diff -Naur a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c
2410 --- a/arch/um/drivers/port_kern.c       Tue Sep  9 16:41:19 2003
2411 +++ b/arch/um/drivers/port_kern.c       Tue Sep  9 16:47:28 2003
2412 @@ -6,6 +6,7 @@
2413  #include "linux/list.h"
2414  #include "linux/sched.h"
2415  #include "linux/slab.h"
2416 +#include "linux/interrupt.h"
2417  #include "linux/irq.h"
2418  #include "linux/spinlock.h"
2419  #include "linux/errno.h"
2420 @@ -14,6 +15,7 @@
2421  #include "kern_util.h"
2422  #include "kern.h"
2423  #include "irq_user.h"
2424 +#include "irq_kern.h"
2425  #include "port.h"
2426  #include "init.h"
2427  #include "os.h"
2428 @@ -44,7 +46,7 @@
2429         struct port_list *port;
2430  };
2431  
2432 -static void pipe_interrupt(int irq, void *data, struct pt_regs *regs)
2433 +static irqreturn_t pipe_interrupt(int irq, void *data, struct pt_regs *regs)
2434  {
2435         struct connection *conn = data;
2436         int fd;
2437 @@ -52,7 +54,7 @@
2438         fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
2439         if(fd < 0){
2440                 if(fd == -EAGAIN)
2441 -                       return;
2442 +                       return(IRQ_NONE);
2443  
2444                 printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n", 
2445                        -fd);
2446 @@ -65,6 +67,7 @@
2447         list_add(&conn->list, &conn->port->connections);
2448  
2449         up(&conn->port->sem);
2450 +       return(IRQ_HANDLED);
2451  }
2452  
2453  static int port_accept(struct port_list *port)
2454 @@ -138,12 +141,13 @@
2455  
2456  DECLARE_WORK(port_work, port_work_proc, NULL);
2457  
2458 -static void port_interrupt(int irq, void *data, struct pt_regs *regs)
2459 +static irqreturn_t port_interrupt(int irq, void *data, struct pt_regs *regs)
2460  {
2461         struct port_list *port = data;
2462  
2463         port->has_connection = 1;
2464         schedule_work(&port_work);
2465 +       return(IRQ_HANDLED);
2466  } 
2467  
2468  void *port_data(int port_num)
2469 diff -Naur a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
2470 --- a/arch/um/drivers/ssl.c     Tue Sep  9 16:43:21 2003
2471 +++ b/arch/um/drivers/ssl.c     Tue Sep  9 16:48:57 2003
2472 @@ -53,8 +53,9 @@
2473  
2474  static struct line_driver driver = {
2475         .name                   = "UML serial line",
2476 -       .devfs_name             = "tts/%d",
2477 -       .major                  = TTYAUX_MAJOR,
2478 +       .device_name            = "ttS",
2479 +       .devfs_name             = "tts/",
2480 +       .major                  = TTY_MAJOR,
2481         .minor_start            = 64,
2482         .type                   = TTY_DRIVER_TYPE_SERIAL,
2483         .subtype                = 0,
2484 diff -Naur a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
2485 --- a/arch/um/drivers/stdio_console.c   Tue Sep  9 16:41:51 2003
2486 +++ b/arch/um/drivers/stdio_console.c   Tue Sep  9 16:47:57 2003
2487 @@ -83,7 +83,8 @@
2488  
2489  static struct line_driver driver = {
2490         .name                   = "UML console",
2491 -       .devfs_name             = "vc/%d",
2492 +       .device_name            = "tty",
2493 +       .devfs_name             = "vc/",
2494         .major                  = TTY_MAJOR,
2495         .minor_start            = 0,
2496         .type                   = TTY_DRIVER_TYPE_CONSOLE,
2497 @@ -159,6 +160,15 @@
2498  
2499  static int con_init_done = 0;
2500  
2501 +static struct tty_operations console_ops = {
2502 +       .open                   = con_open,
2503 +       .close                  = con_close,
2504 +       .write                  = con_write,
2505 +       .chars_in_buffer        = chars_in_buffer,
2506 +       .set_termios            = set_termios,
2507 +       .write_room             = line_write_room,
2508 +};
2509 +
2510  int stdio_init(void)
2511  {
2512         char *new_title;
2513 @@ -166,7 +176,8 @@
2514         printk(KERN_INFO "Initializing stdio console driver\n");
2515  
2516         console_driver = line_register_devfs(&console_lines, &driver,
2517 -                               &console_ops, vts, sizeof(vts)/sizeof(vts[0]));
2518 +                                            &console_ops, vts,
2519 +                                            sizeof(vts)/sizeof(vts[0]));
2520  
2521         lines_init(vts, sizeof(vts)/sizeof(vts[0]));
2522  
2523 @@ -188,15 +199,6 @@
2524         if(con_init_done) up(&vts[console->index].sem);
2525  }
2526  
2527 -static struct tty_operations console_ops = {
2528 -       .open                   = con_open,
2529 -       .close                  = con_close,
2530 -       .write                  = con_write,
2531 -       .chars_in_buffer        = chars_in_buffer,
2532 -       .set_termios            = set_termios,
2533 -       .write_room             = line_write_room,
2534 -};
2535 -
2536  static struct tty_driver *console_device(struct console *c, int *index)
2537  {
2538         *index = c->index;
2539 @@ -212,12 +214,14 @@
2540                                                console_device, console_setup,
2541                                                CON_PRINTBUFFER);
2542  
2543 -static void __init stdio_console_init(void)
2544 +static int __init stdio_console_init(void)
2545  {
2546         INIT_LIST_HEAD(&vts[0].chan_list);
2547         list_add(&init_console_chan.list, &vts[0].chan_list);
2548         register_console(&stdiocons);
2549 +       return(0);
2550  }
2551 +
2552  console_initcall(stdio_console_init);
2553  
2554  static int console_chan_setup(char *str)
2555 diff -Naur a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
2556 --- a/arch/um/drivers/ubd_kern.c        Tue Sep  9 16:43:08 2003
2557 +++ b/arch/um/drivers/ubd_kern.c        Tue Sep  9 16:48:54 2003
2558 @@ -8,6 +8,13 @@
2559   * old style ubd by setting UBD_SHIFT to 0
2560   * 2002-09-27...2002-10-18 massive tinkering for 2.5
2561   * partitions have changed in 2.5
2562 + * 2003-01-29 more tinkering for 2.5.59-1
2563 + * This should now address the sysfs problems and has
2564 + * the symlink for devfs to allow for booting with
2565 + * the common /dev/ubd/discX/... names rather than
2566 + * only /dev/ubdN/discN this version also has lots of
2567 + * clean ups preparing for ubd-many.
2568 + * James McMechan
2569   */
2570  
2571  #define MAJOR_NR UBD_MAJOR
2572 @@ -40,6 +47,7 @@
2573  #include "mconsole_kern.h"
2574  #include "init.h"
2575  #include "irq_user.h"
2576 +#include "irq_kern.h"
2577  #include "ubd_user.h"
2578  #include "2_5compat.h"
2579  #include "os.h"
2580 @@ -67,7 +75,7 @@
2581  static request_queue_t *ubd_queue;
2582  
2583  /* Protected by ubd_lock */
2584 -static int fake_major = 0;
2585 +static int fake_major = MAJOR_NR;
2586  
2587  static struct gendisk *ubd_gendisk[MAX_DEV];
2588  static struct gendisk *fake_gendisk[MAX_DEV];
2589 @@ -96,12 +104,12 @@
2590  
2591  struct ubd {
2592         char *file;
2593 -       int is_dir;
2594         int count;
2595         int fd;
2596         __u64 size;
2597         struct openflags boot_openflags;
2598         struct openflags openflags;
2599 +       int no_cow;
2600         struct cow cow;
2601  };
2602  
2603 @@ -115,12 +123,12 @@
2604  
2605  #define DEFAULT_UBD { \
2606         .file =                 NULL, \
2607 -       .is_dir =               0, \
2608         .count =                0, \
2609         .fd =                   -1, \
2610         .size =                 -1, \
2611         .boot_openflags =       OPEN_FLAGS, \
2612         .openflags =            OPEN_FLAGS, \
2613 +        .no_cow =               0, \
2614          .cow =                 DEFAULT_COW, \
2615  }
2616  
2617 @@ -128,8 +136,10 @@
2618  
2619  static int ubd0_init(void)
2620  {
2621 -       if(ubd_dev[0].file == NULL)
2622 -               ubd_dev[0].file = "root_fs";
2623 +       struct ubd *dev = &ubd_dev[0];
2624 +
2625 +       if(dev->file == NULL)
2626 +               dev->file = "root_fs";
2627         return(0);
2628  }
2629  
2630 @@ -196,19 +206,39 @@
2631  "    Create ide0 entries that map onto ubd devices.\n\n"
2632  );
2633  
2634 +static int parse_unit(char **ptr)
2635 +{
2636 +       char *str = *ptr, *end;
2637 +       int n = -1;
2638 +
2639 +       if(isdigit(*str)) {
2640 +               n = simple_strtoul(str, &end, 0);
2641 +               if(end == str)
2642 +                       return(-1);
2643 +               *ptr = end;
2644 +       }
2645 +       else if (('a' <= *str) && (*str <= 'h')) {
2646 +               n = *str - 'a';
2647 +               str++;
2648 +               *ptr = str;
2649 +       }
2650 +       return(n);
2651 +}
2652 +
2653  static int ubd_setup_common(char *str, int *index_out)
2654  {
2655 +       struct ubd *dev;
2656         struct openflags flags = global_openflags;
2657         char *backing_file;
2658         int n, err;
2659  
2660         if(index_out) *index_out = -1;
2661 -       n = *str++;
2662 +       n = *str;
2663         if(n == '='){
2664 -               static int fake_major_allowed = 1;
2665                 char *end;
2666                 int major;
2667  
2668 +               str++;
2669                 if(!strcmp(str, "sync")){
2670                         global_openflags.s = 1;
2671                         return(0);
2672 @@ -220,20 +250,14 @@
2673                         return(1);
2674                 }
2675  
2676 -               if(!fake_major_allowed){
2677 -                       printk(KERN_ERR "Can't assign a fake major twice\n");
2678 -                       return(1);
2679 -               }
2680 -
2681                 err = 1;
2682                 spin_lock(&ubd_lock);
2683 -               if(!fake_major_allowed){
2684 +               if(fake_major != MAJOR_NR){
2685                         printk(KERN_ERR "Can't assign a fake major twice\n");
2686                         goto out1;
2687                 }
2688   
2689                 fake_major = major;
2690 -               fake_major_allowed = 0;
2691  
2692                 printk(KERN_INFO "Setting extra ubd major number to %d\n",
2693                        major);
2694 @@ -243,25 +267,23 @@
2695                 return(err);
2696         }
2697  
2698 -       if(n < '0'){
2699 -               printk(KERN_ERR "ubd_setup : index out of range\n"); }
2700 -
2701 -       if((n >= '0') && (n <= '9')) n -= '0';
2702 -       else if((n >= 'a') && (n <= 'z')) n -= 'a';
2703 -       else {
2704 -               printk(KERN_ERR "ubd_setup : device syntax invalid\n");
2705 +       n = parse_unit(&str);
2706 +       if(n < 0){
2707 +               printk(KERN_ERR "ubd_setup : couldn't parse unit number "
2708 +                      "'%s'\n", str);
2709                 return(1);
2710         }
2711         if(n >= MAX_DEV){
2712 -               printk(KERN_ERR "ubd_setup : index out of range "
2713 -                      "(%d devices)\n", MAX_DEV);      
2714 +               printk(KERN_ERR "ubd_setup : index %d out of range "
2715 +                      "(%d devices)\n", n, MAX_DEV);
2716                 return(1);
2717         }
2718  
2719         err = 1;
2720         spin_lock(&ubd_lock);
2721  
2722 -       if(ubd_dev[n].file != NULL){
2723 +       dev = &ubd_dev[n];
2724 +       if(dev->file != NULL){
2725                 printk(KERN_ERR "ubd_setup : device already configured\n");
2726                 goto out2;
2727         }
2728 @@ -276,6 +298,11 @@
2729                 flags.s = 1;
2730                 str++;
2731         }
2732 +       if (*str == 'd'){
2733 +               dev->no_cow = 1;
2734 +               str++;
2735 +       }
2736 +
2737         if(*str++ != '='){
2738                 printk(KERN_ERR "ubd_setup : Expected '='\n");
2739                 goto out2;
2740 @@ -284,14 +311,17 @@
2741         err = 0;
2742         backing_file = strchr(str, ',');
2743         if(backing_file){
2744 -               *backing_file = '\0';
2745 -               backing_file++;
2746 +               if(dev->no_cow)
2747 +                       printk(KERN_ERR "Can't specify both 'd' and a "
2748 +                              "cow file\n");
2749 +               else {
2750 +                       *backing_file = '\0';
2751 +                       backing_file++;
2752 +               }
2753         }
2754 -       ubd_dev[n].file = str;
2755 -       if(ubd_is_dir(ubd_dev[n].file))
2756 -               ubd_dev[n].is_dir = 1;
2757 -       ubd_dev[n].cow.file = backing_file;
2758 -       ubd_dev[n].boot_openflags = flags;
2759 +       dev->file = str;
2760 +       dev->cow.file = backing_file;
2761 +       dev->boot_openflags = flags;
2762   out2:
2763         spin_unlock(&ubd_lock);
2764         return(err);
2765 @@ -321,8 +351,7 @@
2766  static int fakehd_set = 0;
2767  static int fakehd(char *str)
2768  {
2769 -       printk(KERN_INFO 
2770 -              "fakehd : Changing ubd name to \"hd\".\n");
2771 +       printk(KERN_INFO "fakehd : Changing ubd name to \"hd\".\n");
2772         fakehd_set = 1;
2773         return 1;
2774  }
2775 @@ -391,9 +420,10 @@
2776         do_ubd_request(ubd_queue);
2777  }
2778  
2779 -static void ubd_intr(int irq, void *dev, struct pt_regs *unused)
2780 +static irqreturn_t ubd_intr(int irq, void *dev, struct pt_regs *unused)
2781  {
2782         ubd_handler();
2783 +       return(IRQ_HANDLED);
2784  }
2785  
2786  /* Only changed by ubd_init, which is an initcall. */
2787 @@ -429,16 +459,18 @@
2788  static int ubd_open_dev(struct ubd *dev)
2789  {
2790         struct openflags flags;
2791 -       int err, n, create_cow, *create_ptr;
2792 +       char **back_ptr;
2793 +       int err, create_cow, *create_ptr;
2794  
2795 +       dev->openflags = dev->boot_openflags;
2796         create_cow = 0;
2797         create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL;
2798 -       dev->fd = open_ubd_file(dev->file, &dev->openflags, &dev->cow.file,
2799 +       back_ptr = dev->no_cow ? NULL : &dev->cow.file;
2800 +       dev->fd = open_ubd_file(dev->file, &dev->openflags, back_ptr,
2801                                 &dev->cow.bitmap_offset, &dev->cow.bitmap_len, 
2802                                 &dev->cow.data_offset, create_ptr);
2803  
2804         if((dev->fd == -ENOENT) && create_cow){
2805 -               n = dev - ubd_dev;
2806                 dev->fd = create_cow_file(dev->file, dev->cow.file, 
2807                                           dev->openflags, 1 << 9,
2808                                           &dev->cow.bitmap_offset, 
2809 @@ -455,7 +487,10 @@
2810         if(dev->cow.file != NULL){
2811                 err = -ENOMEM;
2812                 dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len);
2813 -               if(dev->cow.bitmap == NULL) goto error;
2814 +               if(dev->cow.bitmap == NULL){
2815 +                       printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
2816 +                       goto error;
2817 +               }
2818                 flush_tlb_kernel_vm();
2819  
2820                 err = read_cow_bitmap(dev->fd, dev->cow.bitmap, 
2821 @@ -481,17 +516,31 @@
2822                         
2823  {
2824         struct gendisk *disk;
2825 +       char from[sizeof("ubd/nnnnn\0")], to[sizeof("discnnnnn/disc\0")];
2826 +       int err;
2827  
2828         disk = alloc_disk(1 << UBD_SHIFT);
2829 -       if (!disk)
2830 -               return -ENOMEM;
2831 +       if(disk == NULL)
2832 +               return(-ENOMEM);
2833  
2834         disk->major = major;
2835         disk->first_minor = unit << UBD_SHIFT;
2836         disk->fops = &ubd_blops;
2837         set_capacity(disk, size / 512);
2838 -       sprintf(disk->disk_name, "ubd");
2839 -       sprintf(disk->devfs_name, "ubd/disc%d", unit);
2840 +       if(major == MAJOR_NR){
2841 +               sprintf(disk->disk_name, "ubd%d", unit);
2842 +               sprintf(disk->devfs_name, "ubd/disc%d", unit);
2843 +               sprintf(from, "ubd/%d", unit);
2844 +               sprintf(to, "disc%d/disc", unit);
2845 +               err = devfs_mk_symlink(from, to);
2846 +               if(err)
2847 +                       printk("ubd_new_disk failed to make link from %s to "
2848 +                              "%s, error = %d\n", from, to, err);
2849 +       }
2850 +       else {
2851 +               sprintf(disk->disk_name, "ubd_fake%d", unit);
2852 +               sprintf(disk->devfs_name, "ubd_fake/disc%d", unit);
2853 +       }
2854  
2855         disk->private_data = &ubd_dev[unit];
2856         disk->queue = ubd_queue;
2857 @@ -506,10 +555,7 @@
2858         struct ubd *dev = &ubd_dev[n];
2859         int err;
2860  
2861 -       if(dev->is_dir)
2862 -               return(-EISDIR);
2863 -
2864 -       if (!dev->file)
2865 +       if(dev->file == NULL)
2866                 return(-ENODEV);
2867  
2868         if (ubd_open_dev(dev))
2869 @@ -523,7 +569,7 @@
2870         if(err) 
2871                 return(err);
2872   
2873 -       if(fake_major)
2874 +       if(fake_major != MAJOR_NR)
2875                 ubd_new_disk(fake_major, dev->size, n, 
2876                              &fake_gendisk[n]);
2877  
2878 @@ -561,42 +607,42 @@
2879         return(err);
2880  }
2881  
2882 -static int ubd_get_config(char *dev, char *str, int size, char **error_out)
2883 +static int ubd_get_config(char *name, char *str, int size, char **error_out)
2884  {
2885 -       struct ubd *ubd;
2886 +       struct ubd *dev;
2887         char *end;
2888 -       int major, n = 0;
2889 +       int n, len = 0;
2890  
2891 -       major = simple_strtoul(dev, &end, 0);
2892 -       if((*end != '\0') || (end == dev)){
2893 -               *error_out = "ubd_get_config : didn't parse major number";
2894 +       n = simple_strtoul(name, &end, 0);
2895 +       if((*end != '\0') || (end == name)){
2896 +               *error_out = "ubd_get_config : didn't parse device number";
2897                 return(-1);
2898         }
2899  
2900 -       if((major >= MAX_DEV) || (major < 0)){
2901 -               *error_out = "ubd_get_config : major number out of range";
2902 +       if((n >= MAX_DEV) || (n < 0)){
2903 +               *error_out = "ubd_get_config : device number out of range";
2904                 return(-1);
2905         }
2906  
2907 -       ubd = &ubd_dev[major];
2908 +       dev = &ubd_dev[n];
2909         spin_lock(&ubd_lock);
2910  
2911 -       if(ubd->file == NULL){
2912 -               CONFIG_CHUNK(str, size, n, "", 1);
2913 +       if(dev->file == NULL){
2914 +               CONFIG_CHUNK(str, size, len, "", 1);
2915                 goto out;
2916         }
2917  
2918 -       CONFIG_CHUNK(str, size, n, ubd->file, 0);
2919 +       CONFIG_CHUNK(str, size, len, dev->file, 0);
2920  
2921 -       if(ubd->cow.file != NULL){
2922 -               CONFIG_CHUNK(str, size, n, ",", 0);
2923 -               CONFIG_CHUNK(str, size, n, ubd->cow.file, 1);
2924 +       if(dev->cow.file != NULL){
2925 +               CONFIG_CHUNK(str, size, len, ",", 0);
2926 +               CONFIG_CHUNK(str, size, len, dev->cow.file, 1);
2927         }
2928 -       else CONFIG_CHUNK(str, size, n, "", 1);
2929 +       else CONFIG_CHUNK(str, size, len, "", 1);
2930  
2931   out:
2932         spin_unlock(&ubd_lock);
2933 -       return(n);
2934 +       return(len);
2935  }
2936  
2937  static int ubd_remove(char *str)
2938 @@ -604,11 +650,9 @@
2939         struct ubd *dev;
2940         int n, err = -ENODEV;
2941  
2942 -       if(!isdigit(*str))
2943 -               return(err);    /* it should be a number 0-7/a-h */
2944 +       n = parse_unit(&str);
2945  
2946 -       n = *str - '0';
2947 -       if(n >= MAX_DEV) 
2948 +       if((n < 0) || (n >= MAX_DEV))
2949                 return(err);
2950  
2951         dev = &ubd_dev[n];
2952 @@ -669,7 +713,7 @@
2953                 
2954         elevator_init(ubd_queue, &elevator_noop);
2955  
2956 -       if (fake_major != 0) {
2957 +       if (fake_major != MAJOR_NR) {
2958                 char name[sizeof("ubd_nnn\0")];
2959  
2960                 snprintf(name, sizeof(name), "ubd_%d", fake_major);
2961 @@ -714,15 +758,9 @@
2962  {
2963         struct gendisk *disk = inode->i_bdev->bd_disk;
2964         struct ubd *dev = disk->private_data;
2965 -       int err = -EISDIR;
2966 -
2967 -       if(dev->is_dir == 1)
2968 -               goto out;
2969 +       int err = 0;
2970  
2971 -       err = 0;
2972         if(dev->count == 0){
2973 -               dev->openflags = dev->boot_openflags;
2974 -
2975                 err = ubd_open_dev(dev);
2976                 if(err){
2977                         printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
2978 @@ -796,15 +834,6 @@
2979  
2980         if(req->rq_status == RQ_INACTIVE) return(1);
2981  
2982 -       if(dev->is_dir){
2983 -               strcpy(req->buffer, "HOSTFS:");
2984 -               strcat(req->buffer, dev->file);
2985 -               spin_lock(&ubd_io_lock);
2986 -               end_request(req, 1);
2987 -               spin_unlock(&ubd_io_lock);
2988 -               return(1);
2989 -       }
2990 -
2991         if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
2992                 printk("Write attempted on readonly ubd device %s\n", 
2993                        disk->disk_name);
2994 diff -Naur a/arch/um/drivers/ubd_user.c b/arch/um/drivers/ubd_user.c
2995 --- a/arch/um/drivers/ubd_user.c        Tue Sep  9 16:41:52 2003
2996 +++ b/arch/um/drivers/ubd_user.c        Tue Sep  9 16:47:57 2003
2997 @@ -24,142 +24,24 @@
2998  #include "user.h"
2999  #include "ubd_user.h"
3000  #include "os.h"
3001 +#include "cow.h"
3002  
3003  #include <endian.h>
3004  #include <byteswap.h>
3005 -#if __BYTE_ORDER == __BIG_ENDIAN
3006 -# define ntohll(x) (x)
3007 -# define htonll(x) (x)
3008 -#elif __BYTE_ORDER == __LITTLE_ENDIAN
3009 -# define ntohll(x)  bswap_64(x)
3010 -# define htonll(x)  bswap_64(x)
3011 -#else
3012 -#error "__BYTE_ORDER not defined"
3013 -#endif
3014 -
3015 -#define PATH_LEN_V1 256
3016 -
3017 -struct cow_header_v1 {
3018 -       int magic;
3019 -       int version;
3020 -       char backing_file[PATH_LEN_V1];
3021 -       time_t mtime;
3022 -       __u64 size;
3023 -       int sectorsize;
3024 -};
3025 -
3026 -#define PATH_LEN_V2 MAXPATHLEN
3027 -
3028 -struct cow_header_v2 {
3029 -       unsigned long magic;
3030 -       unsigned long version;
3031 -       char backing_file[PATH_LEN_V2];
3032 -       time_t mtime;
3033 -       __u64 size;
3034 -       int sectorsize;
3035 -};
3036 -
3037 -union cow_header {
3038 -       struct cow_header_v1 v1;
3039 -       struct cow_header_v2 v2;
3040 -};
3041 -
3042 -#define COW_MAGIC 0x4f4f4f4d  /* MOOO */
3043 -#define COW_VERSION 2
3044 -
3045 -static void sizes(__u64 size, int sectorsize, int bitmap_offset, 
3046 -                 unsigned long *bitmap_len_out, int *data_offset_out)
3047 -{
3048 -       *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
3049 -
3050 -       *data_offset_out = bitmap_offset + *bitmap_len_out;
3051 -       *data_offset_out = (*data_offset_out + sectorsize - 1) / sectorsize;
3052 -       *data_offset_out *= sectorsize;
3053 -}
3054 -
3055 -static int read_cow_header(int fd, int *magic_out, char **backing_file_out, 
3056 -                          time_t *mtime_out, __u64 *size_out, 
3057 -                          int *sectorsize_out, int *bitmap_offset_out)
3058 -{
3059 -       union cow_header *header;
3060 -       char *file;
3061 -       int err, n;
3062 -       unsigned long version, magic;
3063 -
3064 -       header = um_kmalloc(sizeof(*header));
3065 -       if(header == NULL){
3066 -               printk("read_cow_header - Failed to allocate header\n");
3067 -               return(-ENOMEM);
3068 -       }
3069 -       err = -EINVAL;
3070 -       n = read(fd, header, sizeof(*header));
3071 -       if(n < offsetof(typeof(header->v1), backing_file)){
3072 -               printk("read_cow_header - short header\n");
3073 -               goto out;
3074 -       }
3075 -
3076 -       magic = header->v1.magic;
3077 -       if(magic == COW_MAGIC) {
3078 -               version = header->v1.version;
3079 -       }
3080 -       else if(magic == ntohl(COW_MAGIC)){
3081 -               version = ntohl(header->v1.version);
3082 -       }
3083 -       else goto out;
3084 -
3085 -       *magic_out = COW_MAGIC;
3086 -
3087 -       if(version == 1){
3088 -               if(n < sizeof(header->v1)){
3089 -                       printk("read_cow_header - failed to read V1 header\n");
3090 -                       goto out;
3091 -               }
3092 -               *mtime_out = header->v1.mtime;
3093 -               *size_out = header->v1.size;
3094 -               *sectorsize_out = header->v1.sectorsize;
3095 -               *bitmap_offset_out = sizeof(header->v1);
3096 -               file = header->v1.backing_file;
3097 -       }
3098 -       else if(version == 2){
3099 -               if(n < sizeof(header->v2)){
3100 -                       printk("read_cow_header - failed to read V2 header\n");
3101 -                       goto out;
3102 -               }
3103 -               *mtime_out = ntohl(header->v2.mtime);
3104 -               *size_out = ntohll(header->v2.size);
3105 -               *sectorsize_out = ntohl(header->v2.sectorsize);
3106 -               *bitmap_offset_out = sizeof(header->v2);
3107 -               file = header->v2.backing_file;
3108 -       }
3109 -       else {
3110 -               printk("read_cow_header - invalid COW version\n");
3111 -               goto out;
3112 -       }
3113 -       err = -ENOMEM;
3114 -       *backing_file_out = uml_strdup(file);
3115 -       if(*backing_file_out == NULL){
3116 -               printk("read_cow_header - failed to allocate backing file\n");
3117 -               goto out;
3118 -       }
3119 -       err = 0;
3120 - out:
3121 -       kfree(header);
3122 -       return(err);
3123 -}
3124  
3125  static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
3126  {
3127 -       struct stat buf1, buf2;
3128 +       struct stat64 buf1, buf2;
3129  
3130         if(from_cmdline == NULL) return(1);
3131         if(!strcmp(from_cmdline, from_cow)) return(1);
3132  
3133 -       if(stat(from_cmdline, &buf1) < 0){
3134 +       if(stat64(from_cmdline, &buf1) < 0){
3135                 printk("Couldn't stat '%s', errno = %d\n", from_cmdline, 
3136                        errno);
3137                 return(1);
3138         }
3139 -       if(stat(from_cow, &buf2) < 0){
3140 +       if(stat64(from_cow, &buf2) < 0){
3141                 printk("Couldn't stat '%s', errno = %d\n", from_cow, errno);
3142                 return(1);
3143         }
3144 @@ -215,118 +97,6 @@
3145         return(0);
3146  }
3147  
3148 -static int absolutize(char *to, int size, char *from)
3149 -{
3150 -       char save_cwd[256], *slash;
3151 -       int remaining;
3152 -
3153 -       if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
3154 -               printk("absolutize : unable to get cwd - errno = %d\n", errno);
3155 -               return(-1);
3156 -       }
3157 -       slash = strrchr(from, '/');
3158 -       if(slash != NULL){
3159 -               *slash = '\0';
3160 -               if(chdir(from)){
3161 -                       *slash = '/';
3162 -                       printk("absolutize : Can't cd to '%s' - errno = %d\n",
3163 -                              from, errno);
3164 -                       return(-1);
3165 -               }
3166 -               *slash = '/';
3167 -               if(getcwd(to, size) == NULL){
3168 -                       printk("absolutize : unable to get cwd of '%s' - "
3169 -                              "errno = %d\n", from, errno);
3170 -                       return(-1);
3171 -               }
3172 -               remaining = size - strlen(to);
3173 -               if(strlen(slash) + 1 > remaining){
3174 -                       printk("absolutize : unable to fit '%s' into %d "
3175 -                              "chars\n", from, size);
3176 -                       return(-1);
3177 -               }
3178 -               strcat(to, slash);
3179 -       }
3180 -       else {
3181 -               if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
3182 -                       printk("absolutize : unable to fit '%s' into %d "
3183 -                              "chars\n", from, size);
3184 -                       return(-1);
3185 -               }
3186 -               strcpy(to, save_cwd);
3187 -               strcat(to, "/");
3188 -               strcat(to, from);
3189 -       }
3190 -       chdir(save_cwd);
3191 -       return(0);
3192 -}
3193 -
3194 -static int write_cow_header(char *cow_file, int fd, char *backing_file, 
3195 -                           int sectorsize, long long *size)
3196 -{
3197 -        struct cow_header_v2 *header;
3198 -       struct stat64 buf;
3199 -       int err;
3200 -
3201 -       err = os_seek_file(fd, 0);
3202 -       if(err != 0){
3203 -               printk("write_cow_header - lseek failed, errno = %d\n", errno);
3204 -               return(-errno);
3205 -       }
3206 -
3207 -       err = -ENOMEM;
3208 -       header = um_kmalloc(sizeof(*header));
3209 -       if(header == NULL){
3210 -               printk("Failed to allocate COW V2 header\n");
3211 -               goto out;
3212 -       }
3213 -       header->magic = htonl(COW_MAGIC);
3214 -       header->version = htonl(COW_VERSION);
3215 -
3216 -       err = -EINVAL;
3217 -       if(strlen(backing_file) > sizeof(header->backing_file) - 1){
3218 -               printk("Backing file name \"%s\" is too long - names are "
3219 -                      "limited to %d characters\n", backing_file, 
3220 -                      sizeof(header->backing_file) - 1);
3221 -               goto out_free;
3222 -       }
3223 -
3224 -       if(absolutize(header->backing_file, sizeof(header->backing_file), 
3225 -                     backing_file))
3226 -               goto out_free;
3227 -
3228 -       err = stat64(header->backing_file, &buf);
3229 -       if(err < 0){
3230 -               printk("Stat of backing file '%s' failed, errno = %d\n",
3231 -                      header->backing_file, errno);
3232 -               err = -errno;
3233 -               goto out_free;
3234 -       }
3235 -
3236 -       err = os_file_size(header->backing_file, size);
3237 -       if(err){
3238 -               printk("Couldn't get size of backing file '%s', errno = %d\n",
3239 -                      header->backing_file, -*size);
3240 -               goto out_free;
3241 -       }
3242 -
3243 -       header->mtime = htonl(buf.st_mtime);
3244 -       header->size = htonll(*size);
3245 -       header->sectorsize = htonl(sectorsize);
3246 -
3247 -       err = write(fd, header, sizeof(*header));
3248 -       if(err != sizeof(*header)){
3249 -               printk("Write of header to new COW file '%s' failed, "
3250 -                      "errno = %d\n", cow_file, errno);
3251 -               goto out_free;
3252 -       }
3253 -       err = 0;
3254 - out_free:
3255 -       kfree(header);
3256 - out:
3257 -       return(err);
3258 -}
3259 -
3260  int open_ubd_file(char *file, struct openflags *openflags, 
3261                   char **backing_file_out, int *bitmap_offset_out, 
3262                   unsigned long *bitmap_len_out, int *data_offset_out, 
3263 @@ -346,10 +116,17 @@
3264                  if((fd = os_open_file(file, *openflags, mode)) < 0) 
3265                         return(fd);
3266          }
3267 +
3268 +       err = os_lock_file(fd, openflags->w);
3269 +       if(err){
3270 +               printk("Failed to lock '%s', errno = %d\n", file, -err);
3271 +               goto error;
3272 +       }
3273 +       
3274         if(backing_file_out == NULL) return(fd);
3275  
3276 -       err = read_cow_header(fd, &magic, &backing_file, &mtime, &size, 
3277 -                             &sectorsize, bitmap_offset_out);
3278 +       err = read_cow_header(file_reader, &fd, &magic, &backing_file, &mtime, 
3279 +                             &size, &sectorsize, bitmap_offset_out);
3280         if(err && (*backing_file_out != NULL)){
3281                 printk("Failed to read COW header from COW file \"%s\", "
3282                        "errno = %d\n", file, err);
3283 @@ -376,12 +153,12 @@
3284                 if(err) goto error;
3285         }
3286  
3287 -       sizes(size, sectorsize, *bitmap_offset_out, bitmap_len_out, 
3288 -             data_offset_out);
3289 +       cow_sizes(size, sectorsize, *bitmap_offset_out, bitmap_len_out, 
3290 +                 data_offset_out);
3291  
3292          return(fd);
3293   error:
3294 -       close(fd);
3295 +       os_close_file(fd);
3296         return(err);
3297  }
3298  
3299 @@ -389,10 +166,7 @@
3300                     int sectorsize, int *bitmap_offset_out, 
3301                     unsigned long *bitmap_len_out, int *data_offset_out)
3302  {
3303 -       __u64 blocks;
3304 -       long zero;
3305 -       int err, fd, i;
3306 -       long long size;
3307 +       int err, fd;
3308  
3309         flags.c = 1;
3310         fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
3311 @@ -403,29 +177,12 @@
3312                 goto out;
3313         }
3314  
3315 -       err = write_cow_header(cow_file, fd, backing_file, sectorsize, &size);
3316 -       if(err) goto out_close;
3317 -
3318 -       blocks = (size + sectorsize - 1) / sectorsize;
3319 -       blocks = (blocks + sizeof(long) * 8 - 1) / (sizeof(long) * 8);
3320 -       zero = 0;
3321 -       for(i = 0; i < blocks; i++){
3322 -               err = write(fd, &zero, sizeof(zero));
3323 -               if(err != sizeof(zero)){
3324 -                       printk("Write of bitmap to new COW file '%s' failed, "
3325 -                              "errno = %d\n", cow_file, errno);
3326 -                       goto out_close;
3327 -               }
3328 -       }
3329 -
3330 -       sizes(size, sectorsize, sizeof(struct cow_header_v2), 
3331 -             bitmap_len_out, data_offset_out);
3332 -       *bitmap_offset_out = sizeof(struct cow_header_v2);
3333 -
3334 -       return(fd);
3335 -
3336 - out_close:
3337 -       close(fd);
3338 +       err = init_cow_file(fd, cow_file, backing_file, sectorsize, 
3339 +                           bitmap_offset_out, bitmap_len_out, 
3340 +                           data_offset_out);
3341 +       if(!err)
3342 +               return(fd);
3343 +       os_close_file(fd);
3344   out:
3345         return(err);
3346  }
3347 @@ -448,14 +205,6 @@
3348         else return(n);
3349  }
3350  
3351 -int ubd_is_dir(char *file)
3352 -{
3353 -       struct stat64 buf;
3354 -
3355 -       if(stat64(file, &buf) < 0) return(0);
3356 -       return(S_ISDIR(buf.st_mode));
3357 -}
3358 -
3359  void do_io(struct io_thread_req *req)
3360  {
3361         char *buf;
3362 diff -Naur a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
3363 --- a/arch/um/drivers/xterm.c   Tue Sep  9 16:41:17 2003
3364 +++ b/arch/um/drivers/xterm.c   Tue Sep  9 16:47:27 2003
3365 @@ -108,7 +108,7 @@
3366         }
3367         close(fd);
3368  
3369 -       fd = create_unix_socket(file, sizeof(file));
3370 +       fd = create_unix_socket(file, sizeof(file), 1);
3371         if(fd < 0){
3372                 printk("xterm_open : create_unix_socket failed, errno = %d\n", 
3373                        -fd);
3374 diff -Naur a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c
3375 --- a/arch/um/drivers/xterm_kern.c      Tue Sep  9 16:45:16 2003
3376 +++ b/arch/um/drivers/xterm_kern.c      Tue Sep  9 16:50:00 2003
3377 @@ -5,9 +5,12 @@
3378  
3379  #include "linux/errno.h"
3380  #include "linux/slab.h"
3381 +#include "linux/signal.h"
3382 +#include "linux/interrupt.h"
3383  #include "asm/semaphore.h"
3384  #include "asm/irq.h"
3385  #include "irq_user.h"
3386 +#include "irq_kern.h"
3387  #include "kern_util.h"
3388  #include "os.h"
3389  #include "xterm.h"
3390 @@ -19,17 +22,18 @@
3391         int new_fd;
3392  };
3393  
3394 -static void xterm_interrupt(int irq, void *data, struct pt_regs *regs)
3395 +static irqreturn_t xterm_interrupt(int irq, void *data, struct pt_regs *regs)
3396  {
3397         struct xterm_wait *xterm = data;
3398         int fd;
3399  
3400         fd = os_rcv_fd(xterm->fd, &xterm->pid);
3401         if(fd == -EAGAIN)
3402 -               return;
3403 +               return(IRQ_NONE);
3404  
3405         xterm->new_fd = fd;
3406         up(&xterm->sem);
3407 +       return(IRQ_HANDLED);
3408  }
3409  
3410  int xterm_fd(int socket, int *pid_out)
3411 diff -Naur a/arch/um/dyn.lds.S b/arch/um/dyn.lds.S
3412 --- a/arch/um/dyn.lds.S Tue Sep  9 16:43:23 2003
3413 +++ b/arch/um/dyn.lds.S Tue Sep  9 16:49:04 2003
3414 @@ -15,7 +15,11 @@
3415    . = ALIGN(4096);             /* Init code and data */
3416    _stext = .;
3417    __init_begin = .;
3418 -  .text.init : { *(.text.init) }
3419 +  .init.text : { 
3420 +       _sinittext = .;
3421 +       *(.init.text)
3422 +       _einittext = .;
3423 +  }
3424  
3425    . = ALIGN(4096);
3426  
3427 @@ -67,7 +71,7 @@
3428  
3429    #include "asm/common.lds.S"
3430  
3431 -  .data.init : { *(.data.init) }
3432 +  init.data : { *(.init.data) }
3433  
3434    /* Ensure the __preinit_array_start label is properly aligned.  We
3435       could instead move the label definition inside the section, but
3436 diff -Naur a/arch/um/include/irq_kern.h b/arch/um/include/irq_kern.h
3437 --- a/arch/um/include/irq_kern.h        Wed Dec 31 19:00:00 1969
3438 +++ b/arch/um/include/irq_kern.h        Tue Sep  9 16:48:56 2003
3439 @@ -0,0 +1,28 @@
3440 +/* 
3441 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
3442 + * Licensed under the GPL
3443 + */
3444 +
3445 +#ifndef __IRQ_KERN_H__
3446 +#define __IRQ_KERN_H__
3447 +
3448 +#include "linux/interrupt.h"
3449 +
3450 +extern int um_request_irq(unsigned int irq, int fd, int type,
3451 +                         irqreturn_t (*handler)(int, void *, 
3452 +                                                struct pt_regs *),
3453 +                         unsigned long irqflags,  const char * devname,
3454 +                         void *dev_id);
3455 +
3456 +#endif
3457 +
3458 +/*
3459 + * Overrides for Emacs so that we follow Linus's tabbing style.
3460 + * Emacs will notice this stuff at the end of the file and automatically
3461 + * adjust the settings for this buffer only.  This must remain at the end
3462 + * of the file.
3463 + * ---------------------------------------------------------------------------
3464 + * Local variables:
3465 + * c-file-style: "linux"
3466 + * End:
3467 + */
3468 diff -Naur a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
3469 --- a/arch/um/include/kern_util.h       Tue Sep  9 16:42:24 2003
3470 +++ b/arch/um/include/kern_util.h       Tue Sep  9 16:48:18 2003
3471 @@ -63,10 +63,9 @@
3472  extern void *syscall_sp(void *t);
3473  extern void syscall_trace(void);
3474  extern int hz(void);
3475 -extern void idle_timer(void);
3476 +extern void uml_idle_timer(void);
3477  extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs);
3478  extern int external_pid(void *t);
3479 -extern int pid_to_processor_id(int pid);
3480  extern void boot_timer_handler(int sig);
3481  extern void interrupt_end(void);
3482  extern void initial_thread_cb(void (*proc)(void *), void *arg);
3483 @@ -90,9 +89,7 @@
3484  extern char *uml_strdup(char *string);
3485  extern void unprotect_kernel_mem(void);
3486  extern void protect_kernel_mem(void);
3487 -extern void set_kmem_end(unsigned long);
3488  extern void uml_cleanup(void);
3489 -extern int pid_to_processor_id(int pid);
3490  extern void set_current(void *t);
3491  extern void lock_signalled_task(void *t);
3492  extern void IPI_handler(int cpu);
3493 @@ -101,7 +98,9 @@
3494  extern int clear_user_proc(void *buf, int size);
3495  extern int copy_to_user_proc(void *to, void *from, int size);
3496  extern int copy_from_user_proc(void *to, void *from, int size);
3497 +extern int strlen_user_proc(char *str);
3498  extern void bus_handler(int sig, union uml_pt_regs *regs);
3499 +extern void winch(int sig, union uml_pt_regs *regs);
3500  extern long execute_syscall(void *r);
3501  extern int smp_sigio_handler(void);
3502  extern void *get_current(void);
3503 diff -Naur a/arch/um/include/line.h b/arch/um/include/line.h
3504 --- a/arch/um/include/line.h    Tue Sep  9 16:45:29 2003
3505 +++ b/arch/um/include/line.h    Tue Sep  9 16:50:05 2003
3506 @@ -9,12 +9,14 @@
3507  #include "linux/list.h"
3508  #include "linux/workqueue.h"
3509  #include "linux/tty.h"
3510 +#include "linux/interrupt.h"
3511  #include "asm/semaphore.h"
3512  #include "chan_user.h"
3513  #include "mconsole_kern.h"
3514  
3515  struct line_driver {
3516         char *name;
3517 +       char *device_name;
3518         char *devfs_name;
3519         short major;
3520         short minor_start;
3521 @@ -67,8 +69,9 @@
3522  
3523  #define LINES_INIT(n) {  num :         n }
3524  
3525 -extern void line_interrupt(int irq, void *data, struct pt_regs *unused);
3526 -extern void line_write_interrupt(int irq, void *data, struct pt_regs *unused);
3527 +extern irqreturn_t line_interrupt(int irq, void *data, struct pt_regs *unused);
3528 +extern irqreturn_t line_write_interrupt(int irq, void *data, 
3529 +                                       struct pt_regs *unused);
3530  extern void line_close(struct line *lines, struct tty_struct *tty);
3531  extern int line_open(struct line *lines, struct tty_struct *tty, 
3532                      struct chan_opts *opts);
3533 diff -Naur a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h
3534 --- a/arch/um/include/mconsole.h        Tue Sep  9 16:42:56 2003
3535 +++ b/arch/um/include/mconsole.h        Tue Sep  9 16:48:27 2003
3536 @@ -77,6 +77,7 @@
3537  extern void mconsole_cad(struct mc_request *req);
3538  extern void mconsole_stop(struct mc_request *req);
3539  extern void mconsole_go(struct mc_request *req);
3540 +extern void mconsole_log(struct mc_request *req);
3541  
3542  extern int mconsole_get_request(int fd, struct mc_request *req);
3543  extern int mconsole_notify(char *sock_name, int type, const void *data, 
3544 diff -Naur a/arch/um/include/mem.h b/arch/um/include/mem.h
3545 --- a/arch/um/include/mem.h     Tue Sep  9 16:46:13 2003
3546 +++ b/arch/um/include/mem.h     Tue Sep  9 16:51:14 2003
3547 @@ -13,7 +13,6 @@
3548  };
3549  
3550  extern void set_usable_vm(unsigned long start, unsigned long end);
3551 -extern void set_kmem_end(unsigned long new);
3552  
3553  #endif
3554  
3555 diff -Naur a/arch/um/include/mem_user.h b/arch/um/include/mem_user.h
3556 --- a/arch/um/include/mem_user.h        Tue Sep  9 16:43:56 2003
3557 +++ b/arch/um/include/mem_user.h        Tue Sep  9 16:49:29 2003
3558 @@ -51,9 +51,6 @@
3559  
3560  extern int init_mem_user(void);
3561  extern int create_mem_file(unsigned long len);
3562 -extern void setup_range(int fd, char *driver, unsigned long start,
3563 -                       unsigned long pfn, unsigned long total, int need_vm, 
3564 -                       struct mem_region *region, void *reserved);
3565  extern void setup_memory(void *entry);
3566  extern unsigned long find_iomem(char *driver, unsigned long *len_out);
3567  extern int init_maps(struct mem_region *region);
3568 diff -Naur a/arch/um/include/os.h b/arch/um/include/os.h
3569 --- a/arch/um/include/os.h      Tue Sep  9 16:41:47 2003
3570 +++ b/arch/um/include/os.h      Tue Sep  9 16:47:55 2003
3571 @@ -103,10 +103,11 @@
3572  extern int os_shutdown_socket(int fd, int r, int w);
3573  extern void os_close_file(int fd);
3574  extern int os_rcv_fd(int fd, int *helper_pid_out);
3575 -extern int create_unix_socket(char *file, int len);
3576 +extern int create_unix_socket(char *file, int len, int close_on_exec);
3577  extern int os_connect_socket(char *name);
3578  extern int os_file_type(char *file);
3579  extern int os_file_mode(char *file, struct openflags *mode_out);
3580 +extern int os_lock_file(int fd, int excl);
3581  
3582  extern unsigned long os_process_pc(int pid);
3583  extern int os_process_parent(int pid);
3584 @@ -120,6 +121,7 @@
3585  extern int os_protect_memory(void *addr, unsigned long len, 
3586                              int r, int w, int x);
3587  extern int os_unmap_memory(void *addr, int len);
3588 +extern void os_flush_stdout(void);
3589  
3590  #endif
3591  
3592 diff -Naur a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h
3593 --- a/arch/um/include/sysdep-i386/sigcontext.h  Tue Sep  9 16:45:13 2003
3594 +++ b/arch/um/include/sysdep-i386/sigcontext.h  Tue Sep  9 16:49:58 2003
3595 @@ -28,8 +28,8 @@
3596   */
3597  #define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
3598  
3599 -/* These are General Protection and Page Fault */
3600 -#define SEGV_IS_FIXABLE(trap) ((trap == 13) || (trap == 14))
3601 +/* This is Page Fault */
3602 +#define SEGV_IS_FIXABLE(trap) (trap == 14)
3603  
3604  #define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc)))
3605  
3606 diff -Naur a/arch/um/include/ubd_user.h b/arch/um/include/ubd_user.h
3607 --- a/arch/um/include/ubd_user.h        Tue Sep  9 16:43:28 2003
3608 +++ b/arch/um/include/ubd_user.h        Tue Sep  9 16:49:08 2003
3609 @@ -39,7 +39,6 @@
3610  extern int write_ubd_fs(int fd, char *buffer, int len);
3611  extern int start_io_thread(unsigned long sp, int *fds_out);
3612  extern void do_io(struct io_thread_req *req);
3613 -extern int ubd_is_dir(char *file);
3614  
3615  static inline int ubd_test_bit(__u64 bit, unsigned char *data)
3616  {
3617 diff -Naur a/arch/um/include/user.h b/arch/um/include/user.h
3618 --- a/arch/um/include/user.h    Tue Sep  9 16:41:16 2003
3619 +++ b/arch/um/include/user.h    Tue Sep  9 16:47:26 2003
3620 @@ -14,7 +14,7 @@
3621  extern void kfree(void *ptr);
3622  extern int in_aton(char *str);
3623  extern int open_gdb_chan(void);
3624 -
3625 +extern int strlcpy(char *, const char *, int);
3626  #endif
3627  
3628  /*
3629 diff -Naur a/arch/um/include/user_util.h b/arch/um/include/user_util.h
3630 --- a/arch/um/include/user_util.h       Tue Sep  9 16:41:34 2003
3631 +++ b/arch/um/include/user_util.h       Tue Sep  9 16:47:39 2003
3632 @@ -59,7 +59,6 @@
3633  extern void *add_signal_handler(int sig, void (*handler)(int));
3634  extern int start_fork_tramp(void *arg, unsigned long temp_stack, 
3635                             int clone_flags, int (*tramp)(void *));
3636 -extern int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags);
3637  extern int linux_main(int argc, char **argv);
3638  extern void set_cmdline(char *cmd);
3639  extern void input_cb(void (*proc)(void *), void *arg, int arg_len);
3640 @@ -90,7 +89,8 @@
3641  extern int arch_fixup(unsigned long address, void *sc_ptr);
3642  extern void forward_pending_sigio(int target);
3643  extern int can_do_skas(void);
3644
3645 +extern void arch_init_thread(void);
3646 +
3647  #endif
3648  
3649  /*
3650 diff -Naur a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
3651 --- a/arch/um/kernel/Makefile   Tue Sep  9 16:44:02 2003
3652 +++ b/arch/um/kernel/Makefile   Tue Sep  9 16:49:30 2003
3653 @@ -21,6 +21,8 @@
3654  obj-$(CONFIG_MODE_TT) += tt/
3655  obj-$(CONFIG_MODE_SKAS) += skas/
3656  
3657 +clean-files    := config.c
3658 +
3659  user-objs-$(CONFIG_TTY_LOG) += tty_log.o
3660  
3661  USER_OBJS := $(filter %_user.o,$(obj-y))  $(user-objs-y) config.o helper.o \
3662 @@ -45,17 +47,13 @@
3663  $(obj)/frame.o: $(src)/frame.c
3664         $(CC) $(CFLAGS_$(notdir $@)) -c -o $@ $<
3665  
3666 -QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
3667 +QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; $$config =~ s/\n/\\n"\n"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }'
3668  
3669  $(obj)/config.c : $(src)/config.c.in $(TOPDIR)/.config
3670         $(PERL) -e $(QUOTE) < $(src)/config.c.in > $@
3671  
3672  $(obj)/config.o : $(obj)/config.c
3673  
3674 -clean:
3675 -       rm -f config.c
3676 -       for dir in $(subdir-y) ; do $(MAKE) -C $$dir clean; done
3677 -
3678  modules:
3679  
3680  fastdep:
3681 diff -Naur a/arch/um/kernel/config.c.in b/arch/um/kernel/config.c.in
3682 --- a/arch/um/kernel/config.c.in        Tue Sep  9 16:45:16 2003
3683 +++ b/arch/um/kernel/config.c.in        Tue Sep  9 16:50:00 2003
3684 @@ -7,9 +7,7 @@
3685  #include <stdlib.h>
3686  #include "init.h"
3687  
3688 -static __initdata char *config = "
3689 -CONFIG
3690 -";
3691 +static __initdata char *config = "CONFIG";
3692  
3693  static int __init print_config(char *line, int *add)
3694  {
3695 diff -Naur a/arch/um/kernel/exec_kern.c b/arch/um/kernel/exec_kern.c
3696 --- a/arch/um/kernel/exec_kern.c        Tue Sep  9 16:41:55 2003
3697 +++ b/arch/um/kernel/exec_kern.c        Tue Sep  9 16:48:00 2003
3698 @@ -32,10 +32,15 @@
3699         CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp);
3700  }
3701  
3702 +extern void log_exec(char **argv, void *tty);
3703 +
3704  static int execve1(char *file, char **argv, char **env)
3705  {
3706          int error;
3707  
3708 +#ifdef CONFIG_TTY_LOG
3709 +       log_exec(argv, current->tty);
3710 +#endif
3711          error = do_execve(file, argv, env, &current->thread.regs);
3712          if (error == 0){
3713                  current->ptrace &= ~PT_DTRACE;
3714 diff -Naur a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c
3715 --- a/arch/um/kernel/init_task.c        Tue Sep  9 16:46:17 2003
3716 +++ b/arch/um/kernel/init_task.c        Tue Sep  9 16:51:23 2003
3717 @@ -17,6 +17,7 @@
3718  struct mm_struct init_mm = INIT_MM(init_mm);
3719  static struct files_struct init_files = INIT_FILES;
3720  static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
3721 +static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
3722  
3723  /*
3724   * Initial task structure.
3725 @@ -38,26 +39,12 @@
3726  __attribute__((__section__(".data.init_task"))) = 
3727  { INIT_THREAD_INFO(init_task) };
3728  
3729 -struct task_struct *alloc_task_struct(void)
3730 -{
3731 -       return((struct task_struct *) 
3732 -              __get_free_pages(GFP_KERNEL, CONFIG_KERNEL_STACK_ORDER));
3733 -}
3734 -
3735  void unprotect_stack(unsigned long stack)
3736  {
3737         protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE, 
3738                        1, 1, 0, 1);
3739  }
3740  
3741 -void free_task_struct(struct task_struct *task)
3742 -{
3743 -       /* free_pages decrements the page counter and only actually frees
3744 -        * the pages if they are now not accessed by anything.
3745 -        */
3746 -       free_pages((unsigned long) task, CONFIG_KERNEL_STACK_ORDER);
3747 -}
3748 -
3749  /*
3750   * Overrides for Emacs so that we follow Linus's tabbing style.
3751   * Emacs will notice this stuff at the end of the file and automatically
3752 diff -Naur a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
3753 --- a/arch/um/kernel/irq.c      Tue Sep  9 16:45:47 2003
3754 +++ b/arch/um/kernel/irq.c      Tue Sep  9 16:50:14 2003
3755 @@ -28,6 +28,7 @@
3756  #include "user_util.h"
3757  #include "kern_util.h"
3758  #include "irq_user.h"
3759 +#include "irq_kern.h"
3760  
3761  static void register_irq_proc (unsigned int irq);
3762  
3763 @@ -82,65 +83,52 @@
3764         end_none
3765  };
3766  
3767 -/* Not changed */
3768 -volatile unsigned long irq_err_count;
3769 -
3770  /*
3771   * Generic, controller-independent functions:
3772   */
3773  
3774 -int get_irq_list(char *buf)
3775 +int show_interrupts(struct seq_file *p, void *v)
3776  {
3777         int i, j;
3778 -       unsigned long flags;
3779         struct irqaction * action;
3780 -       char *p = buf;
3781 +       unsigned long flags;
3782  
3783 -       p += sprintf(p, "           ");
3784 -       for (j=0; j<num_online_cpus(); j++)
3785 -               p += sprintf(p, "CPU%d       ",j);
3786 -       *p++ = '\n';
3787 +       seq_printf(p, "           ");
3788 +       for (j=0; j<NR_CPUS; j++)
3789 +               if (cpu_online(j))
3790 +                       seq_printf(p, "CPU%d       ",j);
3791 +       seq_putc(p, '\n');
3792  
3793         for (i = 0 ; i < NR_IRQS ; i++) {
3794                 spin_lock_irqsave(&irq_desc[i].lock, flags);
3795                 action = irq_desc[i].action;
3796                 if (!action) 
3797 -                       goto end;
3798 -               p += sprintf(p, "%3d: ",i);
3799 +                       goto skip;
3800 +               seq_printf(p, "%3d: ",i);
3801  #ifndef CONFIG_SMP
3802 -               p += sprintf(p, "%10u ", kstat_irqs(i));
3803 +               seq_printf(p, "%10u ", kstat_irqs(i));
3804  #else
3805 -               for (j = 0; j < num_online_cpus(); j++)
3806 -                       p += sprintf(p, "%10u ",
3807 -                               kstat_cpu(cpu_logical_map(j)).irqs[i]);
3808 +               for (j = 0; j < NR_CPUS; j++)
3809 +                       if (cpu_online(j))
3810 +                               seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
3811  #endif
3812 -               p += sprintf(p, " %14s", irq_desc[i].handler->typename);
3813 -               p += sprintf(p, "  %s", action->name);
3814 +               seq_printf(p, " %14s", irq_desc[i].handler->typename);
3815 +               seq_printf(p, "  %s", action->name);
3816  
3817                 for (action=action->next; action; action = action->next)
3818 -                       p += sprintf(p, ", %s", action->name);
3819 -               *p++ = '\n';
3820 -       end:
3821 +                       seq_printf(p, ", %s", action->name);
3822 +
3823 +               seq_putc(p, '\n');
3824 +skip:
3825                 spin_unlock_irqrestore(&irq_desc[i].lock, flags);
3826         }
3827 -       p += sprintf(p, "\n");
3828 -#ifdef notdef
3829 -#ifdef CONFIG_SMP
3830 -       p += sprintf(p, "LOC: ");
3831 -       for (j = 0; j < num_online_cpus(); j++)
3832 -               p += sprintf(p, "%10u ",
3833 -                       apic_timer_irqs[cpu_logical_map(j)]);
3834 -       p += sprintf(p, "\n");
3835 -#endif
3836 -#endif
3837 -       p += sprintf(p, "ERR: %10lu\n", irq_err_count);
3838 -       return p - buf;
3839 -}
3840 +       seq_printf(p, "NMI: ");
3841 +       for (j = 0; j < NR_CPUS; j++)
3842 +               if (cpu_online(j))
3843 +                       seq_printf(p, "%10u ", nmi_count(j));
3844 +       seq_putc(p, '\n');
3845  
3846 -
3847 -int show_interrupts(struct seq_file *p, void *v)
3848 -{
3849 -       return(0);
3850 +       return 0;
3851  }
3852  
3853  /*
3854 @@ -281,13 +269,12 @@
3855          * 0 return value means that this irq is already being
3856          * handled by some other CPU. (or is disabled)
3857          */
3858 -       int cpu = smp_processor_id();
3859         irq_desc_t *desc = irq_desc + irq;
3860         struct irqaction * action;
3861         unsigned int status;
3862  
3863         irq_enter();
3864 -       kstat_cpu(cpu).irqs[irq]++;
3865 +       kstat_this_cpu.irqs[irq]++;
3866         spin_lock(&desc->lock);
3867         desc->handler->ack(irq);
3868         /*
3869 @@ -384,7 +371,7 @@
3870   */
3871   
3872  int request_irq(unsigned int irq,
3873 -               void (*handler)(int, void *, struct pt_regs *),
3874 +               irqreturn_t (*handler)(int, void *, struct pt_regs *),
3875                 unsigned long irqflags, 
3876                 const char * devname,
3877                 void *dev_id)
3878 @@ -430,15 +417,19 @@
3879  }
3880  
3881  int um_request_irq(unsigned int irq, int fd, int type,
3882 -                  void (*handler)(int, void *, struct pt_regs *),
3883 +                  irqreturn_t (*handler)(int, void *, struct pt_regs *),
3884                    unsigned long irqflags, const char * devname,
3885                    void *dev_id)
3886  {
3887 -       int retval;
3888 +       int err;
3889  
3890 -       retval = request_irq(irq, handler, irqflags, devname, dev_id);
3891 -       if(retval) return(retval);
3892 -       return(activate_fd(irq, fd, type, dev_id));
3893 +       err = request_irq(irq, handler, irqflags, devname, dev_id);
3894 +       if(err) 
3895 +               return(err);
3896 +
3897 +       if(fd != -1)
3898 +               err = activate_fd(irq, fd, type, dev_id);
3899 +       return(err);
3900  }
3901  
3902  /* this was setup_x86_irq but it seems pretty generic */
3903 @@ -654,7 +645,7 @@
3904                 return -EINVAL;
3905         tmp = *mask;
3906         for (k = 0; k < sizeof(cpumask_t)/sizeof(u16); ++k) {
3907 -               int j = sprintf(page, "%04hx", cpus_coerce(tmp));
3908 +               int j = sprintf(page, "%04hx", (short) cpus_coerce(tmp));
3909                 len += j;
3910                 page += j;
3911                 cpus_shift_right(tmp, tmp, 16);
3912 diff -Naur a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
3913 --- a/arch/um/kernel/mem.c      Tue Sep  9 16:42:54 2003
3914 +++ b/arch/um/kernel/mem.c      Tue Sep  9 16:48:27 2003
3915 @@ -119,11 +119,6 @@
3916         return(kmem_top);
3917  }
3918  
3919 -void set_kmem_end(unsigned long new)
3920 -{
3921 -       kmem_top = new;
3922 -}
3923 -
3924  #ifdef CONFIG_HIGHMEM
3925  /* Changed during early boot */
3926  pte_t *kmap_pte;
3927 @@ -218,7 +213,7 @@
3928                 if(regions[i] == NULL) break;           
3929         }
3930         if(i == NREGIONS){
3931 -               printk("setup_range : no free regions\n");
3932 +               printk("setup_one_range : no free regions\n");
3933                 i = -1;
3934                 goto out;
3935         }
3936 @@ -227,7 +222,9 @@
3937                 fd = create_mem_file(len);
3938  
3939         if(region == NULL){
3940 -               region = alloc_bootmem_low_pages(sizeof(*region));
3941 +               if(kmalloc_ok)
3942 +                       region = kmalloc(sizeof(*region), GFP_KERNEL);
3943 +               else region = alloc_bootmem_low_pages(sizeof(*region));
3944                 if(region == NULL)
3945                         panic("Failed to allocating mem_region");
3946         }
3947 @@ -528,9 +525,9 @@
3948         return(NREGIONS);
3949  }
3950  
3951 -void setup_range(int fd, char *driver, unsigned long start, unsigned long pfn,
3952 -                unsigned long len, int need_vm, struct mem_region *region, 
3953 -                void *reserved)
3954 +static void setup_range(int fd, char *driver, unsigned long start, 
3955 +                       unsigned long pfn, unsigned long len, int need_vm, 
3956 +                       struct mem_region *region, void *reserved)
3957  {
3958         int i, cur;
3959  
3960 diff -Naur a/arch/um/kernel/mem_user.c b/arch/um/kernel/mem_user.c
3961 --- a/arch/um/kernel/mem_user.c Tue Sep  9 16:43:27 2003
3962 +++ b/arch/um/kernel/mem_user.c Tue Sep  9 16:49:07 2003
3963 @@ -111,6 +111,11 @@
3964                 offset = 0;
3965         }
3966  
3967 +       if(offset >= region->len){
3968 +               printf("%ld bytes of physical memory is insufficient\n",
3969 +                      region->len);
3970 +               exit(1);
3971 +       }
3972         loc = mmap(start, region->len - offset, PROT_READ | PROT_WRITE, 
3973                    MAP_SHARED | MAP_FIXED, region->fd, offset);
3974         if(loc != start){
3975 @@ -122,26 +127,26 @@
3976  
3977  static int __init parse_iomem(char *str, int *add)
3978  {
3979 -       struct stat buf;
3980 +       struct stat64 buf;
3981         char *file, *driver;
3982         int fd;
3983  
3984         driver = str;
3985         file = strchr(str,',');
3986         if(file == NULL){
3987 -               printk("parse_iomem : failed to parse iomem\n");
3988 +               printf("parse_iomem : failed to parse iomem\n");
3989                 return(1);
3990         }
3991         *file = '\0';
3992         file++;
3993         fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0);
3994         if(fd < 0){
3995 -               printk("parse_iomem - Couldn't open io file, errno = %d\n", 
3996 +               printf("parse_iomem - Couldn't open io file, errno = %d\n", 
3997                        errno);
3998                 return(1);
3999         }
4000 -       if(fstat(fd, &buf) < 0) {
4001 -               printk("parse_iomem - cannot fstat file, errno = %d\n", errno);
4002 +       if(fstat64(fd, &buf) < 0) {
4003 +               printf("parse_iomem - cannot fstat file, errno = %d\n", errno);
4004                 return(1);
4005         }
4006         add_iomem(driver, fd, buf.st_size);
4007 diff -Naur a/arch/um/kernel/process.c b/arch/um/kernel/process.c
4008 --- a/arch/um/kernel/process.c  Tue Sep  9 16:45:56 2003
4009 +++ b/arch/um/kernel/process.c  Tue Sep  9 16:50:22 2003
4010 @@ -72,7 +72,6 @@
4011                     SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1);
4012         set_handler(SIGUSR2, (__sighandler_t) sig_handler, 
4013                     SA_NOMASK | flags, -1);
4014 -       (void) CHOOSE_MODE(signal(SIGCHLD, SIG_IGN), (void *) 0);
4015         signal(SIGHUP, SIG_IGN);
4016  
4017         init_irq_signals(altstack);
4018 @@ -127,7 +126,8 @@
4019         if(err < 0) panic("Waiting for outer trampoline failed - errno = %d", 
4020                           errno);
4021         if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL))
4022 -               panic("outer trampoline didn't exit with SIGKILL");
4023 +               panic("outer trampoline didn't exit with SIGKILL, "
4024 +                     "status = %d", status);
4025  
4026         return(arg.pid);
4027  }
4028 diff -Naur a/arch/um/kernel/process_kern.c b/arch/um/kernel/process_kern.c
4029 --- a/arch/um/kernel/process_kern.c     Tue Sep  9 16:43:24 2003
4030 +++ b/arch/um/kernel/process_kern.c     Tue Sep  9 16:49:06 2003
4031 @@ -52,17 +52,12 @@
4032  
4033  struct task_struct *get_task(int pid, int require)
4034  {
4035 -        struct task_struct *task, *ret;
4036 +        struct task_struct *ret;
4037  
4038 -        ret = NULL;
4039          read_lock(&tasklist_lock);
4040 -        for_each_process(task){
4041 -                if(task->pid == pid){
4042 -                        ret = task;
4043 -                        break;
4044 -                }
4045 -        }
4046 +       ret = find_task_by_pid(pid);
4047          read_unlock(&tasklist_lock);
4048 +
4049          if(require && (ret == NULL)) panic("get_task couldn't find a task\n");
4050          return(ret);
4051  }
4052 @@ -103,13 +98,14 @@
4053  
4054  int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
4055  {
4056 -       struct task_struct *p;
4057 +       int pid;
4058  
4059         current->thread.request.u.thread.proc = fn;
4060         current->thread.request.u.thread.arg = arg;
4061 -       p = do_fork(CLONE_VM | flags, 0, NULL, 0, NULL, NULL);
4062 -       if(IS_ERR(p)) panic("do_fork failed in kernel_thread");
4063 -       return(p->pid);
4064 +       pid = do_fork(CLONE_VM | flags, 0, NULL, 0, NULL, NULL);
4065 +       if(pid < 0)
4066 +               panic("do_fork failed in kernel_thread, errno = %d", pid);
4067 +       return(pid);
4068  }
4069  
4070  void switch_mm(struct mm_struct *prev, struct mm_struct *next, 
4071 @@ -129,7 +125,7 @@
4072                 { external_pid(task), task });
4073  }
4074  
4075 -void *switch_to(void *prev, void *next, void *last)
4076 +void *_switch_to(void *prev, void *next, void *last)
4077  {
4078         return(CHOOSE_MODE(switch_to_tt(prev, next), 
4079                            switch_to_skas(prev, next)));
4080 @@ -149,7 +145,7 @@
4081  void exit_thread(void)
4082  {
4083         CHOOSE_MODE(exit_thread_tt(), exit_thread_skas());
4084 -       unprotect_stack((unsigned long) current->thread_info);
4085 +       unprotect_stack((unsigned long) current_thread);
4086  }
4087   
4088  void *get_current(void)
4089 @@ -157,6 +153,10 @@
4090         return(current);
4091  }
4092  
4093 +void prepare_to_copy(struct task_struct *tsk)
4094 +{
4095 +}
4096 +
4097  int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
4098                 unsigned long stack_top, struct task_struct * p, 
4099                 struct pt_regs *regs)
4100 @@ -190,7 +190,7 @@
4101  
4102  void default_idle(void)
4103  {
4104 -       idle_timer();
4105 +       uml_idle_timer();
4106  
4107         atomic_inc(&init_mm.mm_count);
4108         current->mm = &init_mm;
4109 @@ -363,10 +363,15 @@
4110         return(clear_user(buf, size));
4111  }
4112  
4113 +int strlen_user_proc(char *str)
4114 +{
4115 +       return(strlen_user(str));
4116 +}
4117 +
4118  int smp_sigio_handler(void)
4119  {
4120  #ifdef CONFIG_SMP
4121 -       int cpu = current->thread_info->cpu;
4122 +       int cpu = current_thread->cpu;
4123         IPI_handler(cpu);
4124         if(cpu != 0)
4125                 return(1);
4126 @@ -381,7 +386,7 @@
4127  
4128  int cpu(void)
4129  {
4130 -       return(current->thread_info->cpu);
4131 +       return(current_thread->cpu);
4132  }
4133  
4134  /*
4135 diff -Naur a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
4136 --- a/arch/um/kernel/ptrace.c   Tue Sep  9 16:41:35 2003
4137 +++ b/arch/um/kernel/ptrace.c   Tue Sep  9 16:47:40 2003
4138 @@ -311,11 +311,8 @@
4139  
4140         /* the 0x80 provides a way for the tracing parent to distinguish
4141            between a syscall stop and SIGTRAP delivery */
4142 -       current->exit_code = SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
4143 -                                       ? 0x80 : 0);
4144 -       current->state = TASK_STOPPED;
4145 -       notify_parent(current, SIGCHLD);
4146 -       schedule();
4147 +       ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
4148 +                                ? 0x80 : 0));
4149  
4150         /*
4151          * this isn't the same as continuing with a signal, but it will do
4152 diff -Naur a/arch/um/kernel/sigio_kern.c b/arch/um/kernel/sigio_kern.c
4153 --- a/arch/um/kernel/sigio_kern.c       Tue Sep  9 16:41:54 2003
4154 +++ b/arch/um/kernel/sigio_kern.c       Tue Sep  9 16:47:58 2003
4155 @@ -6,18 +6,21 @@
4156  #include "linux/kernel.h"
4157  #include "linux/list.h"
4158  #include "linux/slab.h"
4159 -#include "asm/irq.h"
4160 +#include "linux/signal.h"
4161 +#include "linux/interrupt.h"
4162  #include "init.h"
4163  #include "sigio.h"
4164  #include "irq_user.h"
4165 +#include "irq_kern.h"
4166  
4167  /* Protected by sigio_lock() called from write_sigio_workaround */
4168  static int sigio_irq_fd = -1;
4169  
4170 -void sigio_interrupt(int irq, void *data, struct pt_regs *unused)
4171 +irqreturn_t sigio_interrupt(int irq, void *data, struct pt_regs *unused)
4172  {
4173         read_sigio_fd(sigio_irq_fd);
4174         reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ);
4175 +       return(IRQ_HANDLED);
4176  }
4177  
4178  int write_sigio_irq(int fd)
4179 diff -Naur a/arch/um/kernel/signal_kern.c b/arch/um/kernel/signal_kern.c
4180 --- a/arch/um/kernel/signal_kern.c      Tue Sep  9 16:43:31 2003
4181 +++ b/arch/um/kernel/signal_kern.c      Tue Sep  9 16:49:19 2003
4182 @@ -36,7 +36,7 @@
4183         if(sig == SIGSEGV){
4184                 struct k_sigaction *ka;
4185  
4186 -               ka = &current->sig->action[SIGSEGV - 1];
4187 +               ka = &current->sighand->action[SIGSEGV - 1];
4188                 ka->sa.sa_handler = SIG_DFL;
4189         }
4190         force_sig(SIGSEGV, current);
4191 @@ -142,7 +142,7 @@
4192                 return(0);
4193  
4194         /* Whee!  Actually deliver the signal.  */
4195 -       ka = &current->sig->action[sig -1 ];
4196 +       ka = &current->sighand->action[sig -1 ];
4197         err = handle_signal(regs, sig, ka, &info, oldset, error);
4198         if(!err) return(1);
4199  
4200 @@ -201,7 +201,7 @@
4201         }
4202  }
4203  
4204 -int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
4205 +int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
4206  {
4207         sigset_t saveset, newset;
4208  
4209 @@ -227,6 +227,42 @@
4210         }
4211  }
4212  
4213 +int sys_sigaction(int sig, const struct old_sigaction __user *act,
4214 +                        struct old_sigaction __user *oact)
4215 +{
4216 +       struct k_sigaction new_ka, old_ka;
4217 +       int ret;
4218 +
4219 +       if (act) {
4220 +               old_sigset_t mask;
4221 +               if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
4222 +                   __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
4223 +                   __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
4224 +                       return -EFAULT;
4225 +               __get_user(new_ka.sa.sa_flags, &act->sa_flags);
4226 +               __get_user(mask, &act->sa_mask);
4227 +               siginitset(&new_ka.sa.sa_mask, mask);
4228 +       }
4229 +
4230 +       ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
4231 +
4232 +       if (!ret && oact) {
4233 +               if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
4234 +                   __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
4235 +                   __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
4236 +                       return -EFAULT;
4237 +               __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
4238 +               __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
4239 +       }
4240 +
4241 +       return ret;
4242 +}
4243 +
4244 +int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
4245 +{
4246 +       return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
4247 +}
4248 +
4249  static int copy_sc_from_user(struct pt_regs *to, void *from, 
4250                              struct arch_frame_data *arch)
4251  {
4252 @@ -239,8 +275,8 @@
4253  
4254  int sys_sigreturn(struct pt_regs regs)
4255  {
4256 -       void *sc = sp_to_sc(PT_REGS_SP(&current->thread.regs));
4257 -       void *mask = sp_to_mask(PT_REGS_SP(&current->thread.regs));
4258 +       void __user *sc = sp_to_sc(PT_REGS_SP(&current->thread.regs));
4259 +       void __user *mask = sp_to_mask(PT_REGS_SP(&current->thread.regs));
4260         int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
4261  
4262         spin_lock_irq(&current->sighand->siglock);
4263 @@ -257,7 +293,8 @@
4264  
4265  int sys_rt_sigreturn(struct pt_regs regs)
4266  {
4267 -       struct ucontext *uc = sp_to_uc(PT_REGS_SP(&current->thread.regs));
4268 +       unsigned long sp = PT_REGS_SP(&current->thread.regs);
4269 +       struct ucontext __user *uc = sp_to_uc(sp);
4270         void *fp;
4271         int sig_size = _NSIG_WORDS * sizeof(unsigned long);
4272  
4273 diff -Naur a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile
4274 --- a/arch/um/kernel/skas/Makefile      Tue Sep  9 16:42:00 2003
4275 +++ b/arch/um/kernel/skas/Makefile      Tue Sep  9 16:48:10 2003
4276 @@ -7,18 +7,22 @@
4277         process_kern.o syscall_kern.o syscall_user.o time.o tlb.o trap_user.o \
4278         sys-$(SUBARCH)/
4279  
4280 +host-progs     := util/mk_ptregs
4281 +clean-files    := include/skas_ptregs.h
4282 +
4283  USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o
4284  USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
4285  
4286 -include/skas_ptregs.h : util/mk_ptregs
4287 -       util/mk_ptregs > $@
4288 -
4289 -util/mk_ptregs :
4290 -       $(MAKE) -C util
4291 +$(TOPDIR)/arch/um/include/skas_ptregs.h : $(src)/util/mk_ptregs
4292 +       @echo -n '  Generating $@'
4293 +       @$< > $@.tmp
4294 +       @if [ -r $@ ] && cmp -s $@ $@.tmp; then \
4295 +               echo ' (unchanged)'; \
4296 +               rm -f $@.tmp; \
4297 +       else \
4298 +               echo ' (updated)'; \
4299 +               mv -f $@.tmp $@; \
4300 +       fi
4301  
4302  $(USER_OBJS) : %.o: %.c
4303         $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
4304 -
4305 -clean :
4306 -       $(MAKE) -C util clean
4307 -       $(RM) -f include/skas_ptregs.h
4308 diff -Naur a/arch/um/kernel/skas/include/mode.h b/arch/um/kernel/skas/include/mode.h
4309 --- a/arch/um/kernel/skas/include/mode.h        Tue Sep  9 16:43:28 2003
4310 +++ b/arch/um/kernel/skas/include/mode.h        Tue Sep  9 16:49:08 2003
4311 @@ -20,6 +20,7 @@
4312  extern void halt_skas(void);
4313  extern void reboot_skas(void);
4314  extern void kill_off_processes_skas(void);
4315 +extern int is_skas_winch(int pid, int fd, void *data);
4316  
4317  #endif
4318  
4319 diff -Naur a/arch/um/kernel/skas/include/uaccess.h b/arch/um/kernel/skas/include/uaccess.h
4320 --- a/arch/um/kernel/skas/include/uaccess.h     Tue Sep  9 16:42:57 2003
4321 +++ b/arch/um/kernel/skas/include/uaccess.h     Tue Sep  9 16:48:51 2003
4322 @@ -19,7 +19,7 @@
4323  #define access_ok_skas(type, addr, size) \
4324         ((segment_eq(get_fs(), KERNEL_DS)) || \
4325          (((unsigned long) (addr) < TASK_SIZE) && \
4326 -         ((unsigned long) (addr) + (size) < TASK_SIZE)))
4327 +         ((unsigned long) (addr) + (size) <= TASK_SIZE)))
4328  
4329  static inline int verify_area_skas(int type, const void * addr, 
4330                                    unsigned long size)
4331 diff -Naur a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
4332 --- a/arch/um/kernel/skas/process.c     Tue Sep  9 16:46:01 2003
4333 +++ b/arch/um/kernel/skas/process.c     Tue Sep  9 16:51:06 2003
4334 @@ -4,6 +4,7 @@
4335   */
4336  
4337  #include <stdlib.h>
4338 +#include <unistd.h>
4339  #include <errno.h>
4340  #include <signal.h>
4341  #include <setjmp.h>
4342 @@ -24,6 +25,16 @@
4343  #include "os.h"
4344  #include "proc_mm.h"
4345  #include "skas_ptrace.h"
4346 +#include "chan_user.h"
4347 +
4348 +int is_skas_winch(int pid, int fd, void *data)
4349 +{
4350 +       if(pid != getpid())
4351 +               return(0);
4352 +
4353 +       register_winch_irq(-1, fd, -1, data);
4354 +       return(1);
4355 +}
4356  
4357  unsigned long exec_regs[FRAME_SIZE];
4358  unsigned long exec_fp_regs[HOST_FP_SIZE];
4359 @@ -48,11 +59,11 @@
4360         int err, syscall_nr, status;
4361  
4362         syscall_nr = PT_SYSCALL_NR(regs->skas.regs);
4363 +       UPT_SYSCALL_NR(regs) = syscall_nr;
4364         if(syscall_nr < 1){
4365                 relay_signal(SIGTRAP, regs);
4366                 return;
4367         }
4368 -       UPT_SYSCALL_NR(regs) = syscall_nr;
4369  
4370         err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);
4371         if(err < 0)
4372 @@ -72,8 +83,6 @@
4373         handle_syscall(regs);
4374  }
4375  
4376 -int userspace_pid;
4377 -
4378  static int userspace_tramp(void *arg)
4379  {
4380         init_new_thread_signals(0);
4381 @@ -83,6 +92,8 @@
4382         return(0);
4383  }
4384  
4385 +int userspace_pid;
4386 +
4387  void start_userspace(void)
4388  {
4389         void *stack;
4390 @@ -149,6 +160,7 @@
4391                         case SIGILL:
4392                         case SIGBUS:
4393                         case SIGFPE:
4394 +                       case SIGWINCH:
4395                                 user_signal(WSTOPSIG(status), regs);
4396                                 break;
4397                         default:
4398 @@ -328,7 +340,8 @@
4399  int new_mm(int from)
4400  {
4401         struct proc_mm_op copy;
4402 -       int n, fd = os_open_file("/proc/mm", of_write(OPENFLAGS()), 0);
4403 +       int n, fd = os_open_file("/proc/mm", 
4404 +                                of_cloexec(of_write(OPENFLAGS())), 0);
4405  
4406         if(fd < 0)
4407                 return(-errno);
4408 @@ -342,6 +355,7 @@
4409                         printk("new_mm : /proc/mm copy_segments failed, "
4410                                "errno = %d\n", errno);
4411         }
4412 +
4413         return(fd);
4414  }
4415  
4416 diff -Naur a/arch/um/kernel/skas/process_kern.c b/arch/um/kernel/skas/process_kern.c
4417 --- a/arch/um/kernel/skas/process_kern.c        Tue Sep  9 16:41:52 2003
4418 +++ b/arch/um/kernel/skas/process_kern.c        Tue Sep  9 16:47:57 2003
4419 @@ -61,9 +61,8 @@
4420         thread_wait(&current->thread.mode.skas.switch_buf, 
4421                     current->thread.mode.skas.fork_buf);
4422  
4423 -#ifdef CONFIG_SMP
4424 -       schedule_tail(NULL);
4425 -#endif
4426 +       if(current->thread.prev_sched != NULL)
4427 +               schedule_tail(current->thread.prev_sched);
4428         current->thread.prev_sched = NULL;
4429  
4430         n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
4431 @@ -93,9 +92,8 @@
4432                     current->thread.mode.skas.fork_buf);
4433         
4434         force_flush_all();
4435 -#ifdef CONFIG_SMP
4436 -       schedule_tail(current->thread.prev_sched);
4437 -#endif
4438 +       if(current->thread.prev_sched != NULL)
4439 +               schedule_tail(current->thread.prev_sched);
4440         current->thread.prev_sched = NULL;
4441         unblock_signals();
4442  
4443 @@ -136,7 +134,7 @@
4444  
4445  void init_idle_skas(void)
4446  {
4447 -       cpu_tasks[current->thread_info->cpu].pid = os_getpid();
4448 +       cpu_tasks[current_thread->cpu].pid = os_getpid();
4449         default_idle();
4450  }
4451  
4452 @@ -164,7 +162,7 @@
4453         capture_signal_stack();
4454  
4455         init_new_thread_signals(1);
4456 -       idle_timer();
4457 +       uml_idle_timer();
4458  
4459         init_task.thread.request.u.thread.proc = start_kernel_proc;
4460         init_task.thread.request.u.thread.arg = NULL;
4461 diff -Naur a/arch/um/kernel/skas/util/mk_ptregs.c b/arch/um/kernel/skas/util/mk_ptregs.c
4462 --- a/arch/um/kernel/skas/util/mk_ptregs.c      Tue Sep  9 16:42:54 2003
4463 +++ b/arch/um/kernel/skas/util/mk_ptregs.c      Tue Sep  9 16:48:27 2003
4464 @@ -1,3 +1,4 @@
4465 +#include <stdio.h>
4466  #include <asm/ptrace.h>
4467  #include <asm/user.h>
4468  
4469 diff -Naur a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c
4470 --- a/arch/um/kernel/smp.c      Tue Sep  9 16:41:48 2003
4471 +++ b/arch/um/kernel/smp.c      Tue Sep  9 16:47:56 2003
4472 @@ -22,7 +22,7 @@
4473  #include "os.h"
4474  
4475  /* CPU online map, set by smp_boot_cpus */
4476 -unsigned long cpu_online_map = cpumask_of_cpu(0);
4477 +unsigned long cpu_online_map = CPU_MASK_NONE;
4478  
4479  /* Per CPU bogomips and other parameters
4480   * The only piece used here is the ipi pipe, which is set before SMP is
4481 @@ -97,15 +97,15 @@
4482  
4483         printk(KERN_INFO "Stopping all CPUs...");
4484         for(i = 0; i < num_online_cpus(); i++){
4485 -               if(i == current->thread_info->cpu)
4486 +               if(i == current_thread->cpu)
4487                         continue;
4488                 write(cpu_data[i].ipi_pipe[1], "S", 1);
4489         }
4490         printk("done\n");
4491  }
4492  
4493 -static cpumask_t smp_commenced_mask;
4494 -static cpumask_t smp_callin_map = CPU_MASK_NONE;
4495 +static cpumask_t smp_commenced_mask = CPU_MASK_NONE;
4496 +static cpumask_t cpu_callin_map = CPU_MASK_NONE;
4497  
4498  static int idle_proc(void *cpup)
4499  {
4500 @@ -120,12 +120,12 @@
4501                      current->thread.mode.tt.extern_pid);
4502   
4503         wmb();
4504 -       if (cpu_test_and_set(cpu, &smp_callin_map)) {
4505 +       if (cpu_test_and_set(cpu, cpu_callin_map)) {
4506                 printk("huh, CPU#%d already present??\n", cpu);
4507                 BUG();
4508         }
4509  
4510 -       while (!cpu_isset(cpu, &smp_commenced_mask))
4511 +       while (!cpu_isset(cpu, smp_commenced_mask))
4512                 cpu_relax();
4513  
4514         cpu_set(cpu, cpu_online_map);
4515 @@ -140,8 +140,11 @@
4516  
4517          current->thread.request.u.thread.proc = idle_proc;
4518          current->thread.request.u.thread.arg = (void *) cpu;
4519 -       new_task = do_fork(CLONE_VM | CLONE_IDLETASK, 0, NULL, 0, NULL, NULL);
4520 -       if(IS_ERR(new_task)) panic("do_fork failed in idle_thread");
4521 +       new_task = copy_process(CLONE_VM | CLONE_IDLETASK, 0, NULL, 0, NULL, 
4522 +                               NULL);
4523 +       if(IS_ERR(new_task)) 
4524 +               panic("copy_process failed in idle_thread, error = %ld",
4525 +                     PTR_ERR(new_task));
4526  
4527         cpu_tasks[cpu] = ((struct cpu_task) 
4528                           { .pid =      new_task->thread.mode.tt.extern_pid,
4529 @@ -150,6 +153,7 @@
4530         CHOOSE_MODE(write(new_task->thread.mode.tt.switch_pipe[1], &c, 
4531                           sizeof(c)),
4532                     ({ panic("skas mode doesn't support SMP"); }));
4533 +       wake_up_forked_process(new_task);
4534         return(new_task);
4535  }
4536  
4537 @@ -157,15 +161,16 @@
4538  {
4539         struct task_struct *idle;
4540         unsigned long waittime;
4541 -       int err, cpu;
4542 +       int err, cpu, me = smp_processor_id();
4543  
4544 -       cpu_set(0, cpu_online_map);
4545 -       cpu_set(0, smp_callin_map);
4546 +       cpu_clear(me, cpu_online_map);
4547 +       cpu_set(me, cpu_online_map);
4548 +       cpu_set(me, cpu_callin_map);
4549  
4550 -       err = os_pipe(cpu_data[0].ipi_pipe, 1, 1);
4551 +       err = os_pipe(cpu_data[me].ipi_pipe, 1, 1);
4552         if(err) panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
4553  
4554 -       activate_ipi(cpu_data[0].ipi_pipe[0], 
4555 +       activate_ipi(cpu_data[me].ipi_pipe[0], 
4556                      current->thread.mode.tt.extern_pid);
4557  
4558         for(cpu = 1; cpu < ncpus; cpu++){
4559 @@ -177,10 +182,10 @@
4560                 unhash_process(idle);
4561  
4562                 waittime = 200000000;
4563 -               while (waittime-- && !cpu_isset(cpu, smp_callin_map))
4564 +               while (waittime-- && !cpu_isset(cpu, cpu_callin_map))
4565                         cpu_relax();
4566  
4567 -               if (cpu_isset(cpu, smp_callin_map))
4568 +               if (cpu_isset(cpu, cpu_callin_map))
4569                         printk("done\n");
4570                 else printk("failed\n");
4571         }
4572 @@ -270,7 +275,7 @@
4573         info = _info;
4574  
4575         for (i=0;i<NR_CPUS;i++)
4576 -               if((i != current->thread_info->cpu) && 
4577 +               if((i != current_thread->cpu) && 
4578                    cpu_isset(i, cpu_online_map))
4579                         write(cpu_data[i].ipi_pipe[1], "C", 1);
4580  
4581 diff -Naur a/arch/um/kernel/sys_call_table.c b/arch/um/kernel/sys_call_table.c
4582 --- a/arch/um/kernel/sys_call_table.c   Tue Sep  9 16:45:55 2003
4583 +++ b/arch/um/kernel/sys_call_table.c   Tue Sep  9 16:50:22 2003
4584 @@ -219,15 +219,30 @@
4585  extern syscall_handler_t sys_gettid;
4586  extern syscall_handler_t sys_readahead;
4587  extern syscall_handler_t sys_tkill;
4588 +extern syscall_handler_t sys_setxattr;
4589 +extern syscall_handler_t sys_lsetxattr;
4590 +extern syscall_handler_t sys_fsetxattr;
4591 +extern syscall_handler_t sys_getxattr;
4592 +extern syscall_handler_t sys_lgetxattr;
4593 +extern syscall_handler_t sys_fgetxattr;
4594 +extern syscall_handler_t sys_listxattr;
4595 +extern syscall_handler_t sys_llistxattr;
4596 +extern syscall_handler_t sys_flistxattr;
4597 +extern syscall_handler_t sys_removexattr;
4598 +extern syscall_handler_t sys_lremovexattr;
4599 +extern syscall_handler_t sys_fremovexattr;
4600  extern syscall_handler_t sys_sendfile64;
4601  extern syscall_handler_t sys_futex;
4602  extern syscall_handler_t sys_sched_setaffinity;
4603  extern syscall_handler_t sys_sched_getaffinity;
4604 +extern syscall_handler_t sys_set_thread_area;
4605 +extern syscall_handler_t sys_get_thread_area;
4606  extern syscall_handler_t sys_io_setup;
4607  extern syscall_handler_t sys_io_destroy;
4608  extern syscall_handler_t sys_io_getevents;
4609  extern syscall_handler_t sys_io_submit;
4610  extern syscall_handler_t sys_io_cancel;
4611 +extern syscall_handler_t sys_fadvise64;
4612  extern syscall_handler_t sys_exit_group;
4613  extern syscall_handler_t sys_lookup_dcookie;
4614  extern syscall_handler_t sys_epoll_create;
4615 @@ -235,6 +250,20 @@
4616  extern syscall_handler_t sys_epoll_wait;
4617  extern syscall_handler_t sys_remap_file_pages;
4618  extern syscall_handler_t sys_set_tid_address;
4619 +extern syscall_handler_t sys_timer_create;
4620 +extern syscall_handler_t sys_timer_settime;
4621 +extern syscall_handler_t sys_timer_gettime;
4622 +extern syscall_handler_t sys_timer_getoverrun;
4623 +extern syscall_handler_t sys_timer_delete;
4624 +extern syscall_handler_t sys_clock_settime;
4625 +extern syscall_handler_t sys_clock_gettime;
4626 +extern syscall_handler_t sys_clock_getres;
4627 +extern syscall_handler_t sys_clock_nanosleep;
4628 +extern syscall_handler_t sys_statfs64;
4629 +extern syscall_handler_t sys_fstatfs64;
4630 +extern syscall_handler_t sys_tgkill;
4631 +extern syscall_handler_t sys_utimes;
4632 +extern syscall_handler_t sys_fadvise64_64;
4633  
4634  #ifdef CONFIG_NFSD
4635  #define NFSSERVCTL sys_nfsservctl
4636 @@ -246,7 +275,7 @@
4637  extern syscall_handler_t um_time;
4638  extern syscall_handler_t um_stime;
4639  
4640 -#define LAST_GENERIC_SYSCALL __NR_set_tid_address
4641 +#define LAST_GENERIC_SYSCALL __NR_fadvise64_64
4642  
4643  #if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL
4644  #define LAST_SYSCALL LAST_GENERIC_SYSCALL
4645 @@ -455,32 +484,37 @@
4646         [ __NR_stat64 ] = sys_stat64,
4647         [ __NR_lstat64 ] = sys_lstat64,
4648         [ __NR_fstat64 ] = sys_fstat64,
4649 -       [ __NR_fcntl64 ] = sys_fcntl64,
4650         [ __NR_getdents64 ] = sys_getdents64,
4651 +       [ __NR_fcntl64 ] = sys_fcntl64,
4652 +       [ 223 ] = sys_ni_syscall,
4653         [ __NR_gettid ] = sys_gettid,
4654         [ __NR_readahead ] = sys_readahead,
4655 -       [ __NR_setxattr ] = sys_ni_syscall,
4656 -       [ __NR_lsetxattr ] = sys_ni_syscall,
4657 -       [ __NR_fsetxattr ] = sys_ni_syscall,
4658 -       [ __NR_getxattr ] = sys_ni_syscall,
4659 -       [ __NR_lgetxattr ] = sys_ni_syscall,
4660 -       [ __NR_fgetxattr ] = sys_ni_syscall,
4661 -       [ __NR_listxattr ] = sys_ni_syscall,
4662 -       [ __NR_llistxattr ] = sys_ni_syscall,
4663 -       [ __NR_flistxattr ] = sys_ni_syscall,
4664 -       [ __NR_removexattr ] = sys_ni_syscall,
4665 -       [ __NR_lremovexattr ] = sys_ni_syscall,
4666 -       [ __NR_fremovexattr ] = sys_ni_syscall,
4667 +       [ __NR_setxattr ] = sys_setxattr,
4668 +       [ __NR_lsetxattr ] = sys_lsetxattr,
4669 +       [ __NR_fsetxattr ] = sys_fsetxattr,
4670 +       [ __NR_getxattr ] = sys_getxattr,
4671 +       [ __NR_lgetxattr ] = sys_lgetxattr,
4672 +       [ __NR_fgetxattr ] = sys_fgetxattr,
4673 +       [ __NR_listxattr ] = sys_listxattr,
4674 +       [ __NR_llistxattr ] = sys_llistxattr,
4675 +       [ __NR_flistxattr ] = sys_flistxattr,
4676 +       [ __NR_removexattr ] = sys_removexattr,
4677 +       [ __NR_lremovexattr ] = sys_lremovexattr,
4678 +       [ __NR_fremovexattr ] = sys_fremovexattr,
4679         [ __NR_tkill ] = sys_tkill,
4680         [ __NR_sendfile64 ] = sys_sendfile64,
4681         [ __NR_futex ] = sys_futex,
4682         [ __NR_sched_setaffinity ] = sys_sched_setaffinity,
4683         [ __NR_sched_getaffinity ] = sys_sched_getaffinity,
4684 +       [ __NR_set_thread_area ] = sys_ni_syscall,
4685 +       [ __NR_get_thread_area ] = sys_ni_syscall,
4686         [ __NR_io_setup ] = sys_io_setup,
4687         [ __NR_io_destroy ] = sys_io_destroy,
4688         [ __NR_io_getevents ] = sys_io_getevents,
4689         [ __NR_io_submit ] = sys_io_submit,
4690         [ __NR_io_cancel ] = sys_io_cancel,
4691 +       [ __NR_fadvise64 ] = sys_fadvise64,
4692 +       [ 251 ] = sys_ni_syscall,
4693         [ __NR_exit_group ] = sys_exit_group,
4694         [ __NR_lookup_dcookie ] = sys_lookup_dcookie,
4695         [ __NR_epoll_create ] = sys_epoll_create,
4696 @@ -488,6 +522,20 @@
4697         [ __NR_epoll_wait ] = sys_epoll_wait,
4698          [ __NR_remap_file_pages ] = sys_remap_file_pages,
4699          [ __NR_set_tid_address ] = sys_set_tid_address,
4700 +       [ __NR_timer_create ] = sys_timer_create,
4701 +       [ __NR_timer_settime ] = sys_timer_settime,
4702 +       [ __NR_timer_gettime ] = sys_timer_gettime,
4703 +       [ __NR_timer_getoverrun ] = sys_timer_getoverrun,
4704 +       [ __NR_timer_delete ] = sys_timer_delete,
4705 +       [ __NR_clock_settime ] = sys_clock_settime,
4706 +       [ __NR_clock_gettime ] = sys_clock_gettime,
4707 +       [ __NR_clock_getres ] = sys_clock_getres,
4708 +       [ __NR_clock_nanosleep ] = sys_clock_nanosleep,
4709 +       [ __NR_statfs64 ] = sys_statfs64,
4710 +       [ __NR_fstatfs64 ] = sys_fstatfs64,
4711 +       [ __NR_tgkill ] = sys_tgkill,
4712 +       [ __NR_utimes ] = sys_utimes,
4713 +       [ __NR_fadvise64_64 ] = sys_fadvise64_64,
4714  
4715         ARCH_SYSCALLS
4716         [ LAST_SYSCALL + 1 ... NR_syscalls ] = 
4717 diff -Naur a/arch/um/kernel/syscall_kern.c b/arch/um/kernel/syscall_kern.c
4718 --- a/arch/um/kernel/syscall_kern.c     Tue Sep  9 16:45:13 2003
4719 +++ b/arch/um/kernel/syscall_kern.c     Tue Sep  9 16:49:58 2003
4720 @@ -35,39 +35,40 @@
4721  
4722  long sys_fork(void)
4723  {
4724 -       struct task_struct *p;
4725 +       long ret;
4726  
4727         current->thread.forking = 1;
4728 -        p = do_fork(SIGCHLD, 0, NULL, 0, NULL, NULL);
4729 +        ret = do_fork(SIGCHLD, 0, NULL, 0, NULL, NULL);
4730         current->thread.forking = 0;
4731 -       return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
4732 +       return(ret);
4733  }
4734  
4735 -long sys_clone(unsigned long clone_flags, unsigned long newsp)
4736 +long sys_clone(unsigned long clone_flags, unsigned long newsp, 
4737 +              int *parent_tid, int *child_tid)
4738  {
4739 -       struct task_struct *p;
4740 +       long ret;
4741  
4742         current->thread.forking = 1;
4743 -       p = do_fork(clone_flags, newsp, NULL, 0, NULL, NULL);
4744 +       ret = do_fork(clone_flags, newsp, NULL, 0, parent_tid, child_tid);
4745         current->thread.forking = 0;
4746 -       return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
4747 +       return(ret);
4748  }
4749  
4750  long sys_vfork(void)
4751  {
4752 -       struct task_struct *p;
4753 +       long ret;
4754  
4755         current->thread.forking = 1;
4756 -       p = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0, NULL, NULL);
4757 +       ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0, NULL, 
4758 +                     NULL);
4759         current->thread.forking = 0;
4760 -       return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
4761 +       return(ret);
4762  }
4763  
4764  /* common code for old and new mmaps */
4765 -static inline long do_mmap2(
4766 -       unsigned long addr, unsigned long len,
4767 -       unsigned long prot, unsigned long flags,
4768 -       unsigned long fd, unsigned long pgoff)
4769 +long do_mmap2(struct mm_struct *mm, unsigned long addr, unsigned long len,
4770 +             unsigned long prot, unsigned long flags, unsigned long fd,
4771 +             unsigned long pgoff)
4772  {
4773         int error = -EBADF;
4774         struct file * file = NULL;
4775 @@ -79,9 +80,9 @@
4776                         goto out;
4777         }
4778  
4779 -       down_write(&current->mm->mmap_sem);
4780 -       error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
4781 -       up_write(&current->mm->mmap_sem);
4782 +       down_write(&mm->mmap_sem);
4783 +       error = do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff);
4784 +       up_write(&mm->mmap_sem);
4785  
4786         if (file)
4787                 fput(file);
4788 @@ -93,7 +94,7 @@
4789                unsigned long prot, unsigned long flags,
4790                unsigned long fd, unsigned long pgoff)
4791  {
4792 -       return do_mmap2(addr, len, prot, flags, fd, pgoff);
4793 +       return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
4794  }
4795  
4796  /*
4797 @@ -120,7 +121,8 @@
4798         if (offset & ~PAGE_MASK)
4799                 goto out;
4800  
4801 -       err = do_mmap2(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
4802 +       err = do_mmap2(current->mm, addr, len, prot, flags, fd, 
4803 +                      offset >> PAGE_SHIFT);
4804   out:
4805         return err;
4806  }
4807 @@ -141,37 +143,6 @@
4808          return error;
4809  }
4810  
4811 -int sys_sigaction(int sig, const struct old_sigaction *act,
4812 -                        struct old_sigaction *oact)
4813 -{
4814 -       struct k_sigaction new_ka, old_ka;
4815 -       int ret;
4816 -
4817 -       if (act) {
4818 -               old_sigset_t mask;
4819 -               if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
4820 -                   __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
4821 -                   __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
4822 -                       return -EFAULT;
4823 -               __get_user(new_ka.sa.sa_flags, &act->sa_flags);
4824 -               __get_user(mask, &act->sa_mask);
4825 -               siginitset(&new_ka.sa.sa_mask, mask);
4826 -       }
4827 -
4828 -       ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
4829 -
4830 -       if (!ret && oact) {
4831 -               if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
4832 -                   __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
4833 -                   __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
4834 -                       return -EFAULT;
4835 -               __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
4836 -               __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
4837 -       }
4838 -
4839 -       return ret;
4840 -}
4841 -
4842  /*
4843   * sys_ipc() is the de-multiplexer for the SysV IPC calls..
4844   *
4845 @@ -253,7 +224,7 @@
4846                 return sys_shmctl (first, second,
4847                                    (struct shmid_ds *) ptr);
4848         default:
4849 -               return -EINVAL;
4850 +               return -ENOSYS;
4851         }
4852  }
4853  
4854 @@ -302,11 +273,6 @@
4855         return error;
4856  }
4857  
4858 -int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
4859 -{
4860 -       return(do_sigaltstack(uss, uoss, PT_REGS_SP(&current->thread.regs)));
4861 -}
4862 -
4863  long execute_syscall(void *r)
4864  {
4865         return(CHOOSE_MODE_PROC(execute_syscall_tt, execute_syscall_skas, r));
4866 diff -Naur a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c
4867 --- a/arch/um/kernel/sysrq.c    Tue Sep  9 16:42:22 2003
4868 +++ b/arch/um/kernel/sysrq.c    Tue Sep  9 16:48:13 2003
4869 @@ -53,6 +53,14 @@
4870         show_trace((unsigned long *)esp);
4871  }
4872  
4873 +void show_stack(struct task_struct *task, unsigned long *sp)
4874 +{
4875 +       if(task)
4876 +               show_trace_task(task);
4877 +       else
4878 +               show_trace(sp);
4879 +}
4880 +
4881  /*
4882   * Overrides for Emacs so that we follow Linus's tabbing style.
4883   * Emacs will notice this stuff at the end of the file and automatically
4884 diff -Naur a/arch/um/kernel/time.c b/arch/um/kernel/time.c
4885 --- a/arch/um/kernel/time.c     Tue Sep  9 16:41:45 2003
4886 +++ b/arch/um/kernel/time.c     Tue Sep  9 16:47:55 2003
4887 @@ -15,12 +15,16 @@
4888  #include "process.h"
4889  #include "signal_user.h"
4890  #include "time_user.h"
4891 +#include "kern_constants.h"
4892  
4893  extern struct timeval xtime;
4894  
4895 +struct timeval local_offset = { 0, 0 };
4896 +
4897  void timer(void)
4898  {
4899         gettimeofday(&xtime, NULL);
4900 +       timeradd(&xtime, &local_offset, &xtime);
4901  }
4902  
4903  void set_interval(int timer_type)
4904 @@ -65,7 +69,7 @@
4905                        errno);
4906  }
4907  
4908 -void idle_timer(void)
4909 +void uml_idle_timer(void)
4910  {
4911         if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
4912                 panic("Couldn't unset SIGVTALRM handler");
4913 @@ -82,8 +86,6 @@
4914         set_interval(ITIMER_VIRTUAL);
4915  }
4916  
4917 -struct timeval local_offset = { 0, 0 };
4918 -
4919  void do_gettimeofday(struct timeval *tv)
4920  {
4921         unsigned long flags;
4922 @@ -100,7 +102,7 @@
4923         unsigned long flags;
4924         struct timeval tv_in;
4925  
4926 -       if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
4927 +       if ((unsigned long) tv->tv_nsec >= UM_NSEC_PER_SEC)
4928                 return -EINVAL;
4929  
4930         tv_in.tv_sec = tv->tv_sec;
4931 @@ -110,6 +112,8 @@
4932         gettimeofday(&now, NULL);
4933         timersub(&tv_in, &now, &local_offset);
4934         time_unlock(flags);
4935 +
4936 +       return(0);
4937  }
4938  
4939  void idle_sleep(int secs)
4940 diff -Naur a/arch/um/kernel/time_kern.c b/arch/um/kernel/time_kern.c
4941 --- a/arch/um/kernel/time_kern.c        Tue Sep  9 16:43:50 2003
4942 +++ b/arch/um/kernel/time_kern.c        Tue Sep  9 16:49:26 2003
4943 @@ -38,7 +38,7 @@
4944  
4945  void timer_irq(union uml_pt_regs *regs)
4946  {
4947 -       int cpu = current->thread_info->cpu, ticks = missed_ticks[cpu];
4948 +       int cpu = current_thread->cpu, ticks = missed_ticks[cpu];
4949  
4950          if(!timer_irq_inited) return;
4951         missed_ticks[cpu] = 0;
4952 @@ -55,12 +55,13 @@
4953         do_timer(&regs);
4954  }
4955  
4956 -void um_timer(int irq, void *dev, struct pt_regs *regs)
4957 +irqreturn_t um_timer(int irq, void *dev, struct pt_regs *regs)
4958  {
4959         do_timer(regs);
4960 -       write_seqlock(&xtime_lock);
4961 +       write_seqlock_irq(&xtime_lock);
4962         timer();
4963 -       write_sequnlock(&xtime_lock);
4964 +       write_sequnlock_irq(&xtime_lock);
4965 +       return(IRQ_HANDLED);
4966  }
4967  
4968  long um_time(int * tloc)
4969 @@ -78,12 +79,12 @@
4970  long um_stime(int * tptr)
4971  {
4972         int value;
4973 -       struct timeval new;
4974 +       struct timespec new;
4975  
4976         if (get_user(value, tptr))
4977                  return -EFAULT;
4978         new.tv_sec = value;
4979 -       new.tv_usec = 0;
4980 +       new.tv_nsec = 0;
4981         do_settimeofday(&new);
4982         return 0;
4983  }
4984 @@ -122,9 +123,11 @@
4985  void timer_handler(int sig, union uml_pt_regs *regs)
4986  {
4987  #ifdef CONFIG_SMP
4988 +       local_irq_disable();
4989         update_process_times(user_context(UPT_SP(regs)));
4990 +       local_irq_enable();
4991  #endif
4992 -       if(current->thread_info->cpu == 0)
4993 +       if(current_thread->cpu == 0)
4994                 timer_irq(regs);
4995  }
4996  
4997 diff -Naur a/arch/um/kernel/trap_kern.c b/arch/um/kernel/trap_kern.c
4998 --- a/arch/um/kernel/trap_kern.c        Tue Sep  9 16:41:19 2003
4999 +++ b/arch/um/kernel/trap_kern.c        Tue Sep  9 16:47:27 2003
5000 @@ -16,6 +16,7 @@
5001  #include "asm/tlbflush.h"
5002  #include "asm/a.out.h"
5003  #include "asm/current.h"
5004 +#include "asm/irq.h"
5005  #include "user_util.h"
5006  #include "kern_util.h"
5007  #include "kern.h"
5008 @@ -51,7 +52,7 @@
5009         if(is_write && !(vma->vm_flags & VM_WRITE)) 
5010                 goto out;
5011         page = address & PAGE_MASK;
5012 -       if(page == (unsigned long) current->thread_info + PAGE_SIZE)
5013 +       if(page == (unsigned long) current_thread + PAGE_SIZE)
5014                 panic("Kernel stack overflow");
5015         pgd = pgd_offset(mm, page);
5016         pmd = pmd_offset(pgd, page);
5017 @@ -180,6 +181,11 @@
5018         else relay_signal(sig, regs);
5019  }
5020  
5021 +void winch(int sig, union uml_pt_regs *regs)
5022 +{
5023 +       do_IRQ(WINCH_IRQ, regs);
5024 +}
5025 +
5026  void trap_init(void)
5027  {
5028  }
5029 diff -Naur a/arch/um/kernel/trap_user.c b/arch/um/kernel/trap_user.c
5030 --- a/arch/um/kernel/trap_user.c        Tue Sep  9 16:43:06 2003
5031 +++ b/arch/um/kernel/trap_user.c        Tue Sep  9 16:48:52 2003
5032 @@ -82,6 +82,8 @@
5033                      .is_irq            = 0 },
5034         [ SIGILL ] { .handler           = relay_signal,
5035                      .is_irq            = 0 },
5036 +       [ SIGWINCH ] { .handler         = winch,
5037 +                      .is_irq          = 1 },
5038         [ SIGBUS ] { .handler           = bus_handler,
5039                      .is_irq            = 0 },
5040         [ SIGSEGV] { .handler           = segv_handler,
5041 diff -Naur a/arch/um/kernel/tt/exec_kern.c b/arch/um/kernel/tt/exec_kern.c
5042 --- a/arch/um/kernel/tt/exec_kern.c     Tue Sep  9 16:41:43 2003
5043 +++ b/arch/um/kernel/tt/exec_kern.c     Tue Sep  9 16:47:53 2003
5044 @@ -47,17 +47,17 @@
5045                 do_exit(SIGKILL);
5046         }
5047  
5048 -       if(current->thread_info->cpu == 0)
5049 +       if(current_thread->cpu == 0)
5050                 forward_interrupts(new_pid);
5051         current->thread.request.op = OP_EXEC;
5052         current->thread.request.u.exec.pid = new_pid;
5053 -       unprotect_stack((unsigned long) current->thread_info);
5054 +       unprotect_stack((unsigned long) current_thread);
5055         os_usr1_process(os_getpid());
5056  
5057         enable_timer();
5058         free_page(stack);
5059         protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1);
5060 -       task_protections((unsigned long) current->thread_info);
5061 +       task_protections((unsigned long) current_thread);
5062         force_flush_all();
5063         unblock_signals();
5064  }
5065 diff -Naur a/arch/um/kernel/tt/include/uaccess.h b/arch/um/kernel/tt/include/uaccess.h
5066 --- a/arch/um/kernel/tt/include/uaccess.h       Tue Sep  9 16:43:54 2003
5067 +++ b/arch/um/kernel/tt/include/uaccess.h       Tue Sep  9 16:49:28 2003
5068 @@ -46,18 +46,20 @@
5069  
5070  static inline int copy_from_user_tt(void *to, const void *from, int n)
5071  {
5072 -       return(access_ok_tt(VERIFY_READ, from, n) ?
5073 -              __do_copy_from_user(to, from, n, 
5074 -                                  &current->thread.fault_addr,
5075 -                                  &current->thread.fault_catcher) : n);
5076 +       if(!access_ok_tt(VERIFY_READ, from, n)) 
5077 +               return(n);
5078 +
5079 +       return(__do_copy_from_user(to, from, n, &current->thread.fault_addr,
5080 +                                  &current->thread.fault_catcher));
5081  }
5082  
5083  static inline int copy_to_user_tt(void *to, const void *from, int n)
5084  {
5085 -       return(access_ok_tt(VERIFY_WRITE, to, n) ?
5086 -              __do_copy_to_user(to, from, n, 
5087 -                                  &current->thread.fault_addr,
5088 -                                  &current->thread.fault_catcher) : n);
5089 +       if(!access_ok_tt(VERIFY_WRITE, to, n))
5090 +               return(n);
5091 +               
5092 +       return(__do_copy_to_user(to, from, n, &current->thread.fault_addr,
5093 +                                &current->thread.fault_catcher));
5094  }
5095  
5096  extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
5097 @@ -67,7 +69,9 @@
5098  {
5099         int n;
5100  
5101 -       if(!access_ok_tt(VERIFY_READ, src, 1)) return(-EFAULT);
5102 +       if(!access_ok_tt(VERIFY_READ, src, 1)) 
5103 +               return(-EFAULT);
5104 +
5105         n = __do_strncpy_from_user(dst, src, count, 
5106                                    &current->thread.fault_addr,
5107                                    &current->thread.fault_catcher);
5108 @@ -87,10 +91,11 @@
5109  
5110  static inline int clear_user_tt(void *mem, int len)
5111  {
5112 -       return(access_ok_tt(VERIFY_WRITE, mem, len) ? 
5113 -              __do_clear_user(mem, len, 
5114 -                              &current->thread.fault_addr,
5115 -                              &current->thread.fault_catcher) : len);
5116 +       if(!access_ok_tt(VERIFY_WRITE, mem, len))
5117 +               return(len);
5118 +
5119 +       return(__do_clear_user(mem, len, &current->thread.fault_addr,
5120 +                              &current->thread.fault_catcher));
5121  }
5122  
5123  extern int __do_strnlen_user(const char *str, unsigned long n,
5124 diff -Naur a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
5125 --- a/arch/um/kernel/tt/process_kern.c  Tue Sep  9 16:45:54 2003
5126 +++ b/arch/um/kernel/tt/process_kern.c  Tue Sep  9 16:50:21 2003
5127 @@ -104,7 +104,10 @@
5128  
5129  void release_thread_tt(struct task_struct *task)
5130  {
5131 -       os_kill_process(task->thread.mode.tt.extern_pid, 0);
5132 +       int pid = task->thread.mode.tt.extern_pid;
5133 +
5134 +       if(os_getpid() != pid)
5135 +               os_kill_process(pid, 0);
5136  }
5137  
5138  void exit_thread_tt(void)
5139 @@ -125,27 +128,27 @@
5140         UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
5141         suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
5142  
5143 -       block_signals();
5144 +       force_flush_all();
5145 +       if(current->thread.prev_sched != NULL)
5146 +               schedule_tail(current->thread.prev_sched);
5147 +       current->thread.prev_sched = NULL;
5148 +
5149         init_new_thread_signals(1);
5150 -#ifdef CONFIG_SMP
5151 -       schedule_tail(current->thread.prev_sched);
5152 -#endif
5153         enable_timer();
5154         free_page(current->thread.temp_stack);
5155         set_cmdline("(kernel thread)");
5156 -       force_flush_all();
5157  
5158 -       current->thread.prev_sched = NULL;
5159         change_sig(SIGUSR1, 1);
5160         change_sig(SIGVTALRM, 1);
5161         change_sig(SIGPROF, 1);
5162 -       unblock_signals();
5163 +       local_irq_enable();
5164         if(!run_kernel_thread(fn, arg, &current->thread.exec_buf))
5165                 do_exit(0);
5166  }
5167  
5168  static int new_thread_proc(void *stack)
5169  {
5170 +       local_irq_disable();
5171         init_new_thread_stack(stack, new_thread_handler);
5172         os_usr1_process(os_getpid());
5173         return(0);
5174 @@ -165,35 +168,32 @@
5175         UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
5176         suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
5177  
5178 -#ifdef CONFIG_SMP      
5179 -       schedule_tail(NULL);
5180 -#endif
5181 +       force_flush_all();
5182 +       if(current->thread.prev_sched != NULL)
5183 +               schedule_tail(current->thread.prev_sched);
5184 +       current->thread.prev_sched = NULL;
5185 +
5186         enable_timer();
5187         change_sig(SIGVTALRM, 1);
5188         local_irq_enable();
5189 -       force_flush_all();
5190         if(current->mm != current->parent->mm)
5191                 protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 
5192                                1, 0, 1);
5193 -       task_protections((unsigned long) current->thread_info);
5194 -
5195 -       current->thread.prev_sched = NULL;
5196 +       task_protections((unsigned long) current_thread);
5197  
5198         free_page(current->thread.temp_stack);
5199 +       local_irq_disable();
5200         change_sig(SIGUSR1, 0);
5201         set_user_mode(current);
5202  }
5203  
5204 -static int sigusr1 = SIGUSR1;
5205 -
5206  int fork_tramp(void *stack)
5207  {
5208 -       int sig = sigusr1;
5209 -
5210         local_irq_disable();
5211 +       arch_init_thread();
5212         init_new_thread_stack(stack, finish_fork_handler);
5213  
5214 -       kill(os_getpid(), sig);
5215 +       os_usr1_process(os_getpid());
5216         return(0);
5217  }
5218  
5219 @@ -377,8 +377,8 @@
5220  
5221         pages = (1 << CONFIG_KERNEL_STACK_ORDER);
5222  
5223 -       start = (unsigned long) current->thread_info + PAGE_SIZE;
5224 -       end = (unsigned long) current + PAGE_SIZE * pages;
5225 +       start = (unsigned long) current_thread + PAGE_SIZE;
5226 +       end = (unsigned long) current_thread + PAGE_SIZE * pages;
5227         protect_memory(uml_reserved, start - uml_reserved, 1, w, 1, 1);
5228         protect_memory(end, high_physmem - end, 1, w, 1, 1);
5229  
5230 diff -Naur a/arch/um/kernel/tt/ptproxy/proxy.c b/arch/um/kernel/tt/ptproxy/proxy.c
5231 --- a/arch/um/kernel/tt/ptproxy/proxy.c Tue Sep  9 16:43:48 2003
5232 +++ b/arch/um/kernel/tt/ptproxy/proxy.c Tue Sep  9 16:49:22 2003
5233 @@ -293,10 +293,10 @@
5234  }
5235  
5236  char gdb_init_string[] = 
5237 -"att 1
5238 -b panic
5239 -b stop
5240 -handle SIGWINCH nostop noprint pass
5241 +"att 1 \n\
5242 +b panic \n\
5243 +b stop \n\
5244 +handle SIGWINCH nostop noprint pass \n\
5245  ";
5246  
5247  int start_debugger(char *prog, int startup, int stop, int *fd_out)
5248 diff -Naur a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c
5249 --- a/arch/um/kernel/tt/tracer.c        Tue Sep  9 16:41:14 2003
5250 +++ b/arch/um/kernel/tt/tracer.c        Tue Sep  9 16:47:25 2003
5251 @@ -39,7 +39,7 @@
5252                 return(0);
5253  
5254         register_winch_irq(tracer_winch[0], fd, -1, data);
5255 -       return(0);
5256 +       return(1);
5257  }
5258  
5259  static void tracer_winch_handler(int sig)
5260 @@ -401,7 +401,7 @@
5261                 
5262                 if(!strcmp(line, "go")) debug_stop = 0;
5263                 else if(!strcmp(line, "parent")) debug_parent = 1;
5264 -               else printk("Unknown debug option : '%s'\n", line);
5265 +               else printf("Unknown debug option : '%s'\n", line);
5266  
5267                 line = next;
5268         }
5269 diff -Naur a/arch/um/kernel/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c
5270 --- a/arch/um/kernel/tt/uaccess_user.c  Tue Sep  9 16:42:02 2003
5271 +++ b/arch/um/kernel/tt/uaccess_user.c  Tue Sep  9 16:48:11 2003
5272 @@ -8,15 +8,20 @@
5273  #include <string.h>
5274  #include "user_util.h"
5275  #include "uml_uaccess.h"
5276 +#include "task.h"
5277 +#include "kern_util.h"
5278  
5279  int __do_copy_from_user(void *to, const void *from, int n,
5280                         void **fault_addr, void **fault_catcher)
5281  {
5282 +       struct tt_regs save = TASK_REGS(get_current())->tt;
5283         unsigned long fault;
5284         int faulted;
5285  
5286         fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
5287                                __do_copy, &faulted);
5288 +       TASK_REGS(get_current())->tt = save;
5289 +
5290         if(!faulted) return(0);
5291         else return(n - (fault - (unsigned long) from));
5292  }
5293 @@ -29,11 +34,14 @@
5294  int __do_strncpy_from_user(char *dst, const char *src, unsigned long count,
5295                            void **fault_addr, void **fault_catcher)
5296  {
5297 +       struct tt_regs save = TASK_REGS(get_current())->tt;
5298         unsigned long fault;
5299         int faulted;
5300  
5301         fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher,
5302                                __do_strncpy, &faulted);
5303 +       TASK_REGS(get_current())->tt = save;
5304 +
5305         if(!faulted) return(strlen(dst));
5306         else return(-1);
5307  }
5308 @@ -46,11 +54,14 @@
5309  int __do_clear_user(void *mem, unsigned long len,
5310                     void **fault_addr, void **fault_catcher)
5311  {
5312 +       struct tt_regs save = TASK_REGS(get_current())->tt;
5313         unsigned long fault;
5314         int faulted;
5315  
5316         fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher,
5317                                __do_clear, &faulted);
5318 +       TASK_REGS(get_current())->tt = save;
5319 +
5320         if(!faulted) return(0);
5321         else return(len - (fault - (unsigned long) mem));
5322  }
5323 @@ -58,6 +69,7 @@
5324  int __do_strnlen_user(const char *str, unsigned long n,
5325                       void **fault_addr, void **fault_catcher)
5326  {
5327 +       struct tt_regs save = TASK_REGS(get_current())->tt;
5328         int ret;
5329         unsigned long *faddrp = (unsigned long *)fault_addr;
5330         jmp_buf jbuf;
5331 @@ -71,6 +83,8 @@
5332         }
5333         *fault_addr = NULL;
5334         *fault_catcher = NULL;
5335 +
5336 +       TASK_REGS(get_current())->tt = save;
5337         return ret;
5338  }
5339  
5340 diff -Naur a/arch/um/kernel/tty_log.c b/arch/um/kernel/tty_log.c
5341 --- a/arch/um/kernel/tty_log.c  Tue Sep  9 16:43:49 2003
5342 +++ b/arch/um/kernel/tty_log.c  Tue Sep  9 16:49:22 2003
5343 @@ -13,6 +13,7 @@
5344  #include <sys/time.h>
5345  #include "init.h"
5346  #include "user.h"
5347 +#include "kern_util.h"
5348  #include "os.h"
5349  
5350  #define TTY_LOG_DIR "./"
5351 @@ -24,29 +25,40 @@
5352  #define TTY_LOG_OPEN 1
5353  #define TTY_LOG_CLOSE 2
5354  #define TTY_LOG_WRITE 3
5355 +#define TTY_LOG_EXEC 4
5356 +
5357 +#define TTY_READ 1
5358 +#define TTY_WRITE 2
5359  
5360  struct tty_log_buf {
5361         int what;
5362         unsigned long tty;
5363         int len;
5364 +       int direction;
5365 +       unsigned long sec;
5366 +       unsigned long usec;
5367  };
5368  
5369 -int open_tty_log(void *tty)
5370 +int open_tty_log(void *tty, void *current_tty)
5371  {
5372         struct timeval tv;
5373         struct tty_log_buf data;
5374         char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")];
5375         int fd;
5376  
5377 +       gettimeofday(&tv, NULL);
5378         if(tty_log_fd != -1){
5379 -               data = ((struct tty_log_buf) { what :   TTY_LOG_OPEN,
5380 -                                              tty : (unsigned long) tty,
5381 -                                              len : 0 });
5382 +               data = ((struct tty_log_buf) { .what    = TTY_LOG_OPEN,
5383 +                                              .tty  = (unsigned long) tty,
5384 +                                              .len  = sizeof(current_tty),
5385 +                                              .direction = 0,
5386 +                                              .sec = tv.tv_sec,
5387 +                                              .usec = tv.tv_usec } );
5388                 write(tty_log_fd, &data, sizeof(data));
5389 +               write(tty_log_fd, &current_tty, data.len);
5390                 return(tty_log_fd);
5391         }
5392  
5393 -       gettimeofday(&tv, NULL);
5394         sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec, 
5395                 (unsigned int) tv.tv_usec);
5396  
5397 @@ -62,30 +74,114 @@
5398  void close_tty_log(int fd, void *tty)
5399  {
5400         struct tty_log_buf data;
5401 +       struct timeval tv;
5402  
5403         if(tty_log_fd != -1){
5404 -               data = ((struct tty_log_buf) { what :   TTY_LOG_CLOSE,
5405 -                                              tty : (unsigned long) tty,
5406 -                                              len : 0 });
5407 +               gettimeofday(&tv, NULL);
5408 +               data = ((struct tty_log_buf) { .what    = TTY_LOG_CLOSE,
5409 +                                              .tty  = (unsigned long) tty,
5410 +                                              .len  = 0,
5411 +                                              .direction = 0,
5412 +                                              .sec = tv.tv_sec,
5413 +                                              .usec = tv.tv_usec } );
5414                 write(tty_log_fd, &data, sizeof(data));
5415                 return;
5416         }
5417         close(fd);
5418  }
5419  
5420 -int write_tty_log(int fd, char *buf, int len, void *tty)
5421 +static int log_chunk(int fd, const char *buf, int len)
5422  {
5423 +       int total = 0, try, missed, n;
5424 +       char chunk[64];
5425 +
5426 +       while(len > 0){
5427 +               try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
5428 +               missed = copy_from_user_proc(chunk, (char *) buf, try);
5429 +               try -= missed;
5430 +               n = write(fd, chunk, try);
5431 +               if(n != try)
5432 +                       return(-errno);
5433 +               if(missed != 0)
5434 +                       return(-EFAULT);
5435 +
5436 +               len -= try;
5437 +               total += try;
5438 +               buf += try;
5439 +       }
5440 +
5441 +       return(total);
5442 +}
5443 +
5444 +int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
5445 +{
5446 +       struct timeval tv;
5447         struct tty_log_buf data;
5448 +       int direction;
5449  
5450         if(fd == tty_log_fd){
5451 -               data = ((struct tty_log_buf) { what :   TTY_LOG_WRITE,
5452 -                                              tty : (unsigned long) tty,
5453 -                                              len : len });
5454 +               gettimeofday(&tv, NULL);
5455 +               direction = is_read ? TTY_READ : TTY_WRITE;
5456 +               data = ((struct tty_log_buf) { .what    = TTY_LOG_WRITE,
5457 +                                              .tty  = (unsigned long) tty,
5458 +                                              .len  = len,
5459 +                                              .direction = direction,
5460 +                                              .sec = tv.tv_sec,
5461 +                                              .usec = tv.tv_usec } );
5462                 write(tty_log_fd, &data, sizeof(data));
5463         }
5464 -       return(write(fd, buf, len));
5465 +
5466 +       return(log_chunk(fd, buf, len));
5467  }
5468  
5469 +void log_exec(char **argv, void *tty)
5470 +{
5471 +       struct timeval tv;
5472 +       struct tty_log_buf data;
5473 +       char **ptr,*arg;
5474 +       int len;
5475 +       
5476 +       if(tty_log_fd == -1) return;
5477 +
5478 +       gettimeofday(&tv, NULL);
5479 +
5480 +       len = 0;
5481 +       for(ptr = argv; ; ptr++){
5482 +               if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
5483 +                       return;
5484 +               if(arg == NULL) break;
5485 +               len += strlen_user_proc(arg);
5486 +       }
5487 +
5488 +       data = ((struct tty_log_buf) { .what    = TTY_LOG_EXEC,
5489 +                                      .tty  = (unsigned long) tty,
5490 +                                      .len  = len,
5491 +                                      .direction = 0,
5492 +                                      .sec = tv.tv_sec,
5493 +                                      .usec = tv.tv_usec } );
5494 +       write(tty_log_fd, &data, sizeof(data));
5495 +
5496 +       for(ptr = argv; ; ptr++){
5497 +               if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
5498 +                       return;
5499 +               if(arg == NULL) break;
5500 +               log_chunk(tty_log_fd, arg, strlen_user_proc(arg));
5501 +       }
5502 +}
5503 +
5504 +extern void register_tty_logger(int (*opener)(void *, void *),
5505 +                               int (*writer)(int, const char *, int, 
5506 +                                             void *, int),
5507 +                               void (*closer)(int, void *));
5508 +
5509 +static int register_logger(void)
5510 +{
5511 +       register_tty_logger(open_tty_log, write_tty_log, close_tty_log);
5512 +       return(0);
5513 +}
5514 +
5515 +__uml_initcall(register_logger);
5516 +
5517  static int __init set_tty_log_dir(char *name, int *add)
5518  {
5519         tty_log_dir = name;
5520 @@ -104,7 +200,7 @@
5521  
5522         tty_log_fd = strtoul(name, &end, 0);
5523         if((*end != '\0') || (end == name)){
5524 -               printk("set_tty_log_fd - strtoul failed on '%s'\n", name);
5525 +               printf("set_tty_log_fd - strtoul failed on '%s'\n", name);
5526                 tty_log_fd = -1;
5527         }
5528         return 0;
5529 diff -Naur a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
5530 --- a/arch/um/kernel/um_arch.c  Tue Sep  9 16:45:38 2003
5531 +++ b/arch/um/kernel/um_arch.c  Tue Sep  9 16:50:11 2003
5532 @@ -38,13 +38,18 @@
5533  #include "mode_kern.h"
5534  #include "mode.h"
5535  
5536 -#define DEFAULT_COMMAND_LINE "root=6200"
5537 +#define DEFAULT_COMMAND_LINE "root=ubd0"
5538  
5539  struct cpuinfo_um boot_cpu_data = { 
5540         .loops_per_jiffy        = 0,
5541         .ipi_pipe               = { -1, -1 }
5542  };
5543  
5544 +/* Placeholder to make UML link until the vsyscall stuff is actually 
5545 + * implemented
5546 + */
5547 +void *__kernel_vsyscall;
5548 +
5549  unsigned long thread_saved_pc(struct task_struct *task)
5550  {
5551         return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
5552 @@ -61,10 +66,14 @@
5553                 return 0;
5554  #endif
5555  
5556 -       seq_printf(m, "bogomips\t: %lu.%02lu\n",
5557 +       seq_printf(m, "processor\t: %d\n", index);
5558 +       seq_printf(m, "vendor_id\t: User Mode Linux\n");
5559 +       seq_printf(m, "model name\t: UML\n");
5560 +       seq_printf(m, "mode\t\t: %s\n", CHOOSE_MODE("tt", "skas"));
5561 +       seq_printf(m, "host\t\t: %s\n", host_info);
5562 +       seq_printf(m, "bogomips\t: %lu.%02lu\n\n",
5563                    loops_per_jiffy/(500000/HZ),
5564                    (loops_per_jiffy/(5000/HZ)) % 100);
5565 -       seq_printf(m, "host\t\t: %s\n", host_info);
5566  
5567         return(0);
5568  }
5569 @@ -134,12 +143,12 @@
5570         if(umid != NULL){
5571                 snprintf(argv1_begin, 
5572                          (argv1_end - argv1_begin) * sizeof(*ptr), 
5573 -                        "(%s)", umid);
5574 +                        "(%s) ", umid);
5575                 ptr = &argv1_begin[strlen(argv1_begin)];
5576         }
5577         else ptr = argv1_begin;
5578  
5579 -       snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), " [%s]", cmd);
5580 +       snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd);
5581         memset(argv1_begin + strlen(argv1_begin), '\0', 
5582                argv1_end - argv1_begin - strlen(argv1_begin));
5583  #endif
5584 @@ -179,7 +188,7 @@
5585  static int __init uml_ncpus_setup(char *line, int *add)
5586  {
5587         if (!sscanf(line, "%d", &ncpus)) {
5588 -               printk("Couldn't parse [%s]\n", line);
5589 +               printf("Couldn't parse [%s]\n", line);
5590                 return -1;
5591         }
5592  
5593 @@ -210,7 +219,7 @@
5594  
5595  static int __init mode_tt_setup(char *line, int *add)
5596  {
5597 -       printk("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
5598 +       printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
5599         return(0);
5600  }
5601  
5602 @@ -221,7 +230,7 @@
5603  
5604  static int __init mode_tt_setup(char *line, int *add)
5605  {
5606 -       printk("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
5607 +       printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
5608         return(0);
5609  }
5610  
5611 @@ -369,6 +378,7 @@
5612                 2 * PAGE_SIZE;
5613  
5614         task_protections((unsigned long) &init_thread_info);
5615 +       os_flush_stdout();
5616  
5617         return(CHOOSE_MODE(start_uml_tt(), start_uml_skas()));
5618  }
5619 diff -Naur a/arch/um/kernel/umid.c b/arch/um/kernel/umid.c
5620 --- a/arch/um/kernel/umid.c     Tue Sep  9 16:46:00 2003
5621 +++ b/arch/um/kernel/umid.c     Tue Sep  9 16:51:03 2003
5622 @@ -33,18 +33,19 @@
5623  static int umid_is_random = 1;
5624  static int umid_inited = 0;
5625  
5626 -static int make_umid(void);
5627 +static int make_umid(int (*printer)(const char *fmt, ...));
5628  
5629 -static int __init set_umid(char *name, int is_random)
5630 +static int __init set_umid(char *name, int is_random, 
5631 +                          int (*printer)(const char *fmt, ...))
5632  {
5633         if(umid_inited){
5634 -               printk("Unique machine name can't be set twice\n");
5635 +               (*printer)("Unique machine name can't be set twice\n");
5636                 return(-1);
5637         }
5638  
5639         if(strlen(name) > UMID_LEN - 1)
5640 -               printk("Unique machine name is being truncated to %s "
5641 -                      "characters\n", UMID_LEN);
5642 +               (*printer)("Unique machine name is being truncated to %s "
5643 +                          "characters\n", UMID_LEN);
5644         strlcpy(umid, name, sizeof(umid));
5645  
5646         umid_is_random = is_random;
5647 @@ -54,7 +55,7 @@
5648  
5649  static int __init set_umid_arg(char *name, int *add)
5650  {
5651 -       return(set_umid(name, 0));
5652 +       return(set_umid(name, 0, printf));
5653  }
5654  
5655  __uml_setup("umid=", set_umid_arg,
5656 @@ -67,7 +68,7 @@
5657  {
5658         int n;
5659  
5660 -       if(!umid_inited && make_umid()) return(-1);
5661 +       if(!umid_inited && make_umid(printk)) return(-1);
5662  
5663         n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1;
5664         if(n > len){
5665 @@ -92,14 +93,14 @@
5666         fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), 
5667                           0644);
5668         if(fd < 0){
5669 -               printk("Open of machine pid file \"%s\" failed - "
5670 +               printf("Open of machine pid file \"%s\" failed - "
5671                        "errno = %d\n", file, -fd);
5672                 return 0;
5673         }
5674  
5675         sprintf(pid, "%d\n", os_getpid());
5676         if(write(fd, pid, strlen(pid)) != strlen(pid))
5677 -               printk("Write of pid file failed - errno = %d\n", errno);
5678 +               printf("Write of pid file failed - errno = %d\n", errno);
5679         close(fd);
5680         return 0;
5681  }
5682 @@ -197,7 +198,7 @@
5683         if((strlen(name) > 0) && (name[strlen(name) - 1] != '/')){
5684                 uml_dir = malloc(strlen(name) + 1);
5685                 if(uml_dir == NULL){
5686 -                       printk("Failed to malloc uml_dir - error = %d\n",
5687 +                       printf("Failed to malloc uml_dir - error = %d\n",
5688                                errno);
5689                         uml_dir = name;
5690                         return(0);
5691 @@ -217,7 +218,7 @@
5692                 char *home = getenv("HOME");
5693  
5694                 if(home == NULL){
5695 -                       printk("make_uml_dir : no value in environment for "
5696 +                       printf("make_uml_dir : no value in environment for "
5697                                "$HOME\n");
5698                         exit(1);
5699                 }
5700 @@ -239,25 +240,25 @@
5701         strcpy(uml_dir, dir);
5702         
5703         if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){
5704 -               printk("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
5705 +               printf("Failed to mkdir %s - errno = %i\n", uml_dir, errno);
5706                 return(-1);
5707         }
5708         return 0;
5709  }
5710  
5711 -static int __init make_umid(void)
5712 +static int __init make_umid(int (*printer)(const char *fmt, ...))
5713  {
5714         int fd, err;
5715         char tmp[strlen(uml_dir) + UMID_LEN + 1];
5716  
5717         strlcpy(tmp, uml_dir, sizeof(tmp));
5718  
5719 -       if(*umid == 0){
5720 +       if(!umid_inited){
5721                 strcat(tmp, "XXXXXX");
5722                 fd = mkstemp(tmp);
5723                 if(fd < 0){
5724 -                       printk("make_umid - mkstemp failed, errno = %d\n",
5725 -                              errno);
5726 +                       (*printer)("make_umid - mkstemp failed, errno = %d\n",
5727 +                                  errno);
5728                         return(1);
5729                 }
5730  
5731 @@ -267,7 +268,7 @@
5732                  * for directories.
5733                  */
5734                 unlink(tmp);
5735 -               set_umid(&tmp[strlen(uml_dir)], 1);
5736 +               set_umid(&tmp[strlen(uml_dir)], 1, printer);
5737         }
5738         
5739         sprintf(tmp, "%s%s", uml_dir, umid);
5740 @@ -275,14 +276,14 @@
5741         if((err = mkdir(tmp, 0777)) < 0){
5742                 if(errno == EEXIST){
5743                         if(not_dead_yet(tmp)){
5744 -                               printk("umid '%s' is in use\n", umid);
5745 +                               (*printer)("umid '%s' is in use\n", umid);
5746                                 return(-1);
5747                         }
5748                         err = mkdir(tmp, 0777);
5749                 }
5750         }
5751         if(err < 0){
5752 -               printk("Failed to create %s - errno = %d\n", umid, errno);
5753 +               (*printer)("Failed to create %s - errno = %d\n", umid, errno);
5754                 return(-1);
5755         }
5756  
5757 @@ -295,7 +296,13 @@
5758  );
5759  
5760  __uml_postsetup(make_uml_dir);
5761 -__uml_postsetup(make_umid);
5762 +
5763 +static int __init make_umid_setup(void)
5764 +{
5765 +       return(make_umid(printf));
5766 +}
5767 +
5768 +__uml_postsetup(make_umid_setup);
5769  __uml_postsetup(create_pid_file);
5770  
5771  /*
5772 diff -Naur a/arch/um/kernel/user_util.c b/arch/um/kernel/user_util.c
5773 --- a/arch/um/kernel/user_util.c        Tue Sep  9 16:41:41 2003
5774 +++ b/arch/um/kernel/user_util.c        Tue Sep  9 16:47:43 2003
5775 @@ -119,17 +119,6 @@
5776         }
5777  }
5778  
5779 -int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags)
5780 -{
5781 -       int pid;
5782 -
5783 -       pid = clone(fn, sp, flags, arg);
5784 -       if(pid < 0) return(-1);
5785 -       wait_for_stop(pid, SIGSTOP, PTRACE_CONT, NULL);
5786 -       ptrace(PTRACE_CONT, pid, 0, 0);
5787 -       return(pid);
5788 -}
5789 -
5790  int raw(int fd, int complain)
5791  {
5792         struct termios tt;
5793 diff -Naur a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
5794 --- a/arch/um/os-Linux/drivers/tuntap_user.c    Tue Sep  9 16:46:16 2003
5795 +++ b/arch/um/os-Linux/drivers/tuntap_user.c    Tue Sep  9 16:51:17 2003
5796 @@ -142,7 +142,7 @@
5797                         return(-errno);
5798                 }
5799                 memset(&ifr, 0, sizeof(ifr));
5800 -               ifr.ifr_flags = IFF_TAP;
5801 +               ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
5802                 strlcpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name));
5803                 if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){
5804                         printk("TUNSETIFF failed, errno = %d", errno);
5805 diff -Naur a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
5806 --- a/arch/um/os-Linux/file.c   Tue Sep  9 16:46:10 2003
5807 +++ b/arch/um/os-Linux/file.c   Tue Sep  9 16:51:13 2003
5808 @@ -315,7 +315,7 @@
5809         return(new);
5810  }
5811  
5812 -int create_unix_socket(char *file, int len)
5813 +int create_unix_socket(char *file, int len, int close_on_exec)
5814  {
5815         struct sockaddr_un addr;
5816         int sock, err;
5817 @@ -327,6 +327,10 @@
5818                 return(-errno);
5819         }
5820  
5821 +       if(close_on_exec && fcntl(sock, F_SETFD, 1) < 0)
5822 +               printk("create_unix_socket : Setting FD_CLOEXEC failed, "
5823 +                      "errno = %d", errno);
5824 +
5825         addr.sun_family = AF_UNIX;
5826  
5827         /* XXX Be more careful about overflow */
5828 @@ -342,6 +346,37 @@
5829         return(sock);
5830  }
5831  
5832 +void os_flush_stdout(void)
5833 +{
5834 +       fflush(stdout);
5835 +}
5836 +
5837 +int os_lock_file(int fd, int excl)
5838 +{
5839 +       int type = excl ? F_WRLCK : F_RDLCK;
5840 +       struct flock lock = ((struct flock) { .l_type   = type,
5841 +                                             .l_whence = SEEK_SET,
5842 +                                             .l_start  = 0,
5843 +                                             .l_len    = 0 } );
5844 +       int err, save;
5845 +
5846 +       err = fcntl(fd, F_SETLK, &lock);
5847 +       if(!err)
5848 +               goto out;
5849 +
5850 +       save = -errno;
5851 +       err = fcntl(fd, F_GETLK, &lock);
5852 +       if(err){
5853 +               err = -errno;
5854 +               goto out;
5855 +       }
5856 +       
5857 +       printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid);
5858 +       err = save;
5859 + out:
5860 +       return(err);
5861 +}
5862 +
5863  /*
5864   * Overrides for Emacs so that we follow Linus's tabbing style.
5865   * Emacs will notice this stuff at the end of the file and automatically
5866 diff -Naur a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
5867 --- a/arch/um/sys-i386/Makefile Tue Sep  9 16:41:38 2003
5868 +++ b/arch/um/sys-i386/Makefile Tue Sep  9 16:47:42 2003
5869 @@ -1,7 +1,8 @@
5870 -obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o module.o \
5871 -       ptrace.o ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o
5872 +obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o ptrace.o \
5873 +       ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o
5874  
5875  obj-$(CONFIG_HIGHMEM) += highmem.o
5876 +obj-$(CONFIG_MODULES) += module.o
5877  
5878  USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o
5879  USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
5880 @@ -9,6 +10,8 @@
5881  SYMLINKS = semaphore.c highmem.c module.c
5882  SYMLINKS := $(foreach f,$(SYMLINKS),$(src)/$f)
5883  
5884 +clean-files := $(SYMLINKS)
5885 +
5886  semaphore.c-dir = kernel
5887  highmem.c-dir = mm
5888  module.c-dir = kernel
5889 @@ -24,8 +27,7 @@
5890  $(SYMLINKS): 
5891         $(call make_link,$@)
5892  
5893 -clean:
5894 -       $(MAKE) -C util clean
5895 +subdir- := util
5896  
5897  fastdep:
5898  
5899 diff -Naur a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c
5900 --- a/arch/um/sys-i386/bugs.c   Tue Sep  9 16:45:37 2003
5901 +++ b/arch/um/sys-i386/bugs.c   Tue Sep  9 16:50:09 2003
5902 @@ -8,6 +8,7 @@
5903  #include <errno.h>
5904  #include <string.h>
5905  #include <sys/signal.h>
5906 +#include <asm/ldt.h>
5907  #include "kern_util.h"
5908  #include "user.h"
5909  #include "sysdep/ptrace.h"
5910 @@ -16,8 +17,8 @@
5911  #define MAXTOKEN 64
5912  
5913  /* Set during early boot */
5914 -int cpu_has_cmov = 1;
5915 -int cpu_has_xmm = 0;
5916 +int host_has_cmov = 1;
5917 +int host_has_xmm = 0;
5918  
5919  static char token(int fd, char *buf, int len, char stop)
5920  {
5921 @@ -104,6 +105,25 @@
5922         return(1);
5923  }
5924  
5925 +static void disable_lcall(void)
5926 +{
5927 +       struct modify_ldt_ldt_s ldt;
5928 +       int err;
5929 +
5930 +       bzero(&ldt, sizeof(ldt));
5931 +       ldt.entry_number = 7;
5932 +       ldt.base_addr = 0;
5933 +       ldt.limit = 0;
5934 +       err = modify_ldt(1, &ldt, sizeof(ldt));
5935 +       if(err)
5936 +               printk("Failed to disable lcall7 - errno = %d\n", errno);
5937 +}
5938 +
5939 +void arch_init_thread(void)
5940 +{
5941 +       disable_lcall();
5942 +}
5943 +
5944  void arch_check_bugs(void)
5945  {
5946         int have_it;
5947 @@ -113,8 +133,8 @@
5948                        "checks\n");
5949                 return;
5950         }
5951 -       if(check_cpu_feature("cmov", &have_it)) cpu_has_cmov = have_it;
5952 -       if(check_cpu_feature("xmm", &have_it)) cpu_has_xmm = have_it;
5953 +       if(check_cpu_feature("cmov", &have_it)) host_has_cmov = have_it;
5954 +       if(check_cpu_feature("xmm", &have_it)) host_has_xmm = have_it;
5955  }
5956  
5957  int arch_handle_signal(int sig, union uml_pt_regs *regs)
5958 @@ -130,18 +150,18 @@
5959         if((*((char *) ip) != 0x0f) || ((*((char *) (ip + 1)) & 0xf0) != 0x40))
5960                 return(0);
5961  
5962 -       if(cpu_has_cmov == 0)
5963 +       if(host_has_cmov == 0)
5964                 panic("SIGILL caused by cmov, which this processor doesn't "
5965                       "implement, boot a filesystem compiled for older "
5966                       "processors");
5967 -       else if(cpu_has_cmov == 1)
5968 +       else if(host_has_cmov == 1)
5969                 panic("SIGILL caused by cmov, which this processor claims to "
5970                       "implement");
5971 -       else if(cpu_has_cmov == -1)
5972 +       else if(host_has_cmov == -1)
5973                 panic("SIGILL caused by cmov, couldn't tell if this processor "
5974                       "implements it, boot a filesystem compiled for older "
5975                       "processors");
5976 -       else panic("Bad value for cpu_has_cmov (%d)", cpu_has_cmov);
5977 +       else panic("Bad value for host_has_cmov (%d)", host_has_cmov);
5978         return(0);
5979  }
5980  
5981 diff -Naur a/arch/um/uml.lds.S b/arch/um/uml.lds.S
5982 --- a/arch/um/uml.lds.S Tue Sep  9 16:43:03 2003
5983 +++ b/arch/um/uml.lds.S Tue Sep  9 16:48:52 2003
5984 @@ -26,7 +26,11 @@
5985    . = ALIGN(4096);             /* Init code and data */
5986    _stext = .;
5987    __init_begin = .;
5988 -  .text.init : { *(.text.init) }
5989 +  .init.text : { 
5990 +       _sinittext = .;
5991 +       *(.init.text)
5992 +       _einittext = .;
5993 +  }
5994    . = ALIGN(4096);
5995    .text      :
5996    {
5997 @@ -38,7 +42,7 @@
5998  
5999    #include "asm/common.lds.S"
6000  
6001 -  .data.init : { *(.data.init) }
6002 +  init.data : { *(init.data) }
6003    .data    :
6004    {
6005      . = ALIGN(KERNEL_STACK_SIZE);              /* init_task */
6006 diff -Naur a/arch/um/util/mk_constants_kern.c b/arch/um/util/mk_constants_kern.c
6007 --- a/arch/um/util/mk_constants_kern.c  Tue Sep  9 16:41:24 2003
6008 +++ b/arch/um/util/mk_constants_kern.c  Tue Sep  9 16:47:30 2003
6009 @@ -1,5 +1,6 @@
6010  #include "linux/kernel.h"
6011  #include "linux/stringify.h"
6012 +#include "linux/time.h"
6013  #include "asm/page.h"
6014  
6015  extern void print_head(void);
6016 @@ -11,6 +12,7 @@
6017  {
6018    print_head();
6019    print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE);
6020 +
6021    print_constant_str("UM_KERN_EMERG", KERN_EMERG);
6022    print_constant_str("UM_KERN_ALERT", KERN_ALERT);
6023    print_constant_str("UM_KERN_CRIT", KERN_CRIT);
6024 @@ -19,6 +21,8 @@
6025    print_constant_str("UM_KERN_NOTICE", KERN_NOTICE);
6026    print_constant_str("UM_KERN_INFO", KERN_INFO);
6027    print_constant_str("UM_KERN_DEBUG", KERN_DEBUG);
6028 +
6029 +  print_constant_int("UM_NSEC_PER_SEC", NSEC_PER_SEC);
6030    print_tail();
6031    return(0);
6032  }
6033 diff -Naur a/fs/Makefile b/fs/Makefile
6034 --- a/fs/Makefile       Tue Sep  9 16:43:32 2003
6035 +++ b/fs/Makefile       Tue Sep  9 16:49:19 2003
6036 @@ -91,3 +91,5 @@
6037  obj-$(CONFIG_XFS_FS)           += xfs/
6038  obj-$(CONFIG_AFS_FS)           += afs/
6039  obj-$(CONFIG_BEFS_FS)          += befs/
6040 +obj-$(CONFIG_HOSTFS)           += hostfs/
6041 +obj-$(CONFIG_HPPFS)            += hppfs/
6042 diff -Naur a/fs/hostfs/Makefile b/fs/hostfs/Makefile
6043 --- a/fs/hostfs/Makefile        Wed Dec 31 19:00:00 1969
6044 +++ b/fs/hostfs/Makefile        Tue Sep  9 16:47:22 2003
6045 @@ -0,0 +1,36 @@
6046 +# 
6047 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
6048 +# Licensed under the GPL
6049 +#
6050 +
6051 +# struct stat64 changed the inode field name between 2.2 and 2.4 from st_ino
6052 +# to __st_ino.  It stayed in the same place, so as long as the correct name
6053 +# is used, hostfs compiled on 2.2 should work on 2.4 and vice versa.
6054 +
6055 +STAT64_INO_FIELD := $(shell grep -q __st_ino /usr/include/bits/stat.h && \
6056 +                               echo __)st_ino
6057 +
6058 +hostfs-objs := hostfs_kern.o hostfs_user.o
6059 +
6060 +obj-y = 
6061 +obj-$(CONFIG_HOSTFS) += hostfs.o
6062 +
6063 +SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
6064 +
6065 +USER_OBJS := $(filter %_user.o,$(obj-y) $(obj-m) $(SINGLE_OBJS))
6066 +USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
6067 +
6068 +USER_CFLAGS += -DSTAT64_INO_FIELD=$(STAT64_INO_FIELD)
6069 +
6070 +$(USER_OBJS) : %.o: %.c
6071 +       $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
6072 +
6073 +clean:
6074 +
6075 +modules:
6076 +
6077 +fastdep:
6078 +
6079 +dep:
6080 +
6081 +archmrproper: clean
6082 diff -Naur a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h
6083 --- a/fs/hostfs/hostfs.h        Wed Dec 31 19:00:00 1969
6084 +++ b/fs/hostfs/hostfs.h        Tue Sep  9 16:47:21 2003
6085 @@ -0,0 +1,79 @@
6086 +#ifndef __UM_FS_HOSTFS
6087 +#define __UM_FS_HOSTFS
6088 +
6089 +#include "os.h"
6090 +
6091 +/* These are exactly the same definitions as in fs.h, but the names are 
6092 + * changed so that this file can be included in both kernel and user files.
6093 + */
6094 +
6095 +#define HOSTFS_ATTR_MODE       1
6096 +#define HOSTFS_ATTR_UID        2
6097 +#define HOSTFS_ATTR_GID        4
6098 +#define HOSTFS_ATTR_SIZE       8
6099 +#define HOSTFS_ATTR_ATIME      16
6100 +#define HOSTFS_ATTR_MTIME      32
6101 +#define HOSTFS_ATTR_CTIME      64
6102 +#define HOSTFS_ATTR_ATIME_SET  128
6103 +#define HOSTFS_ATTR_MTIME_SET  256
6104 +#define HOSTFS_ATTR_FORCE      512     /* Not a change, but a change it */
6105 +#define HOSTFS_ATTR_ATTR_FLAG  1024
6106 +
6107 +struct hostfs_iattr {
6108 +       unsigned int    ia_valid;
6109 +       mode_t          ia_mode;
6110 +       uid_t           ia_uid;
6111 +       gid_t           ia_gid;
6112 +       loff_t          ia_size;
6113 +       struct timespec ia_atime;
6114 +       struct timespec ia_mtime;
6115 +       struct timespec ia_ctime;
6116 +       unsigned int    ia_attr_flags;
6117 +};
6118 +
6119 +extern int stat_file(const char *path, unsigned long long *inode_out, 
6120 +                    int *mode_out, int *nlink_out, int *uid_out, int *gid_out,
6121 +                    unsigned long long *size_out, struct timespec *atime_out, 
6122 +                    struct timespec *mtime_out, struct timespec *ctime_out, 
6123 +                    int *blksize_out, unsigned long long *blocks_out);
6124 +extern int access_file(char *path, int r, int w, int x);
6125 +extern int open_file(char *path, int r, int w, int append);
6126 +extern int file_type(const char *path, int *rdev);
6127 +extern void *open_dir(char *path, int *err_out);
6128 +extern char *read_dir(void *stream, unsigned long long *pos, 
6129 +                     unsigned long long *ino_out, int *len_out);
6130 +extern void close_file(void *stream);
6131 +extern void close_dir(void *stream);
6132 +extern int read_file(int fd, unsigned long long *offset, char *buf, int len);
6133 +extern int write_file(int fd, unsigned long long *offset, const char *buf,
6134 +                     int len);
6135 +extern int lseek_file(int fd, long long offset, int whence);
6136 +extern int file_create(char *name, int ur, int uw, int ux, int gr, 
6137 +                      int gw, int gx, int or, int ow, int ox);
6138 +extern int set_attr(const char *file, struct hostfs_iattr *attrs);
6139 +extern int make_symlink(const char *from, const char *to);
6140 +extern int unlink_file(const char *file);
6141 +extern int do_mkdir(const char *file, int mode);
6142 +extern int do_rmdir(const char *file);
6143 +extern int do_mknod(const char *file, int mode, int dev);
6144 +extern int link_file(const char *from, const char *to);
6145 +extern int do_readlink(char *file, char *buf, int size);
6146 +extern int rename_file(char *from, char *to);
6147 +extern int do_statfs(char *root, long *bsize_out, long long *blocks_out, 
6148 +                    long long *bfree_out, long long *bavail_out, 
6149 +                    long long *files_out, long long *ffree_out, 
6150 +                    void *fsid_out, int fsid_size, long *namelen_out, 
6151 +                    long *spare_out);
6152 +
6153 +#endif
6154 +
6155 +/*
6156 + * Overrides for Emacs so that we follow Linus's tabbing style.
6157 + * Emacs will notice this stuff at the end of the file and automatically
6158 + * adjust the settings for this buffer only.  This must remain at the end
6159 + * of the file.
6160 + * ---------------------------------------------------------------------------
6161 + * Local variables:
6162 + * c-file-style: "linux"
6163 + * End:
6164 + */
6165 diff -Naur a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
6166 --- a/fs/hostfs/hostfs_kern.c   Wed Dec 31 19:00:00 1969
6167 +++ b/fs/hostfs/hostfs_kern.c   Tue Sep  9 16:47:25 2003
6168 @@ -0,0 +1,1008 @@
6169 +/* 
6170 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
6171 + * Licensed under the GPL
6172 + *
6173 + * Ported the filesystem routines to 2.5.
6174 + * 2003-02-10 Petr Baudis <pasky@ucw.cz>
6175 + */
6176 +
6177 +#include <linux/stddef.h>
6178 +#include <linux/fs.h>
6179 +#include <linux/version.h>
6180 +#include <linux/module.h>
6181 +#include <linux/init.h>
6182 +#include <linux/slab.h>
6183 +#include <linux/pagemap.h>
6184 +#include <linux/blkdev.h>
6185 +#include <linux/list.h>
6186 +#include <linux/buffer_head.h>
6187 +#include <linux/root_dev.h>
6188 +#include <linux/statfs.h>
6189 +#include <asm/uaccess.h>
6190 +#include "hostfs.h"
6191 +#include "kern_util.h"
6192 +#include "kern.h"
6193 +#include "user_util.h"
6194 +#include "2_5compat.h"
6195 +#include "init.h"
6196 +
6197 +struct hostfs_inode_info {
6198 +       char *host_filename;
6199 +       int fd;
6200 +       int mode;
6201 +       struct inode vfs_inode;
6202 +};
6203 +
6204 +static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode)
6205 +{
6206 +       return(list_entry(inode, struct hostfs_inode_info, vfs_inode));
6207 +}
6208 +
6209 +#define FILE_HOSTFS_I(file) HOSTFS_I((file)->f_dentry->d_inode)
6210 +
6211 +int hostfs_d_delete(struct dentry *dentry)
6212 +{
6213 +       return(1);
6214 +}
6215 +
6216 +struct dentry_operations hostfs_dentry_ops = {
6217 +       .d_delete               = hostfs_d_delete,
6218 +};
6219 +
6220 +/* Changed in hostfs_args before the kernel starts running */
6221 +static char *root_ino = "/";
6222 +static int append = 0;
6223 +
6224 +#define HOSTFS_SUPER_MAGIC 0x00c0ffee
6225 +
6226 +static struct inode_operations hostfs_iops;
6227 +static struct inode_operations hostfs_dir_iops;
6228 +static struct address_space_operations hostfs_link_aops;
6229 +
6230 +static int __init hostfs_args(char *options, int *add)
6231 +{
6232 +       char *ptr;
6233 +
6234 +       ptr = strchr(options, ',');
6235 +       if(ptr != NULL)
6236 +               *ptr++ = '\0';
6237 +       if(*options != '\0')
6238 +               root_ino = options;
6239 +
6240 +       options = ptr;
6241 +       while(options){
6242 +               ptr = strchr(options, ',');
6243 +               if(ptr != NULL)
6244 +                       *ptr++ = '\0';
6245 +               if(*options != '\0'){
6246 +                       if(!strcmp(options, "append"))
6247 +                               append = 1;
6248 +                       else printf("hostfs_args - unsupported option - %s\n",
6249 +                                   options);
6250 +               }
6251 +               options = ptr;
6252 +       }
6253 +       return(0);
6254 +}
6255 +
6256 +__uml_setup("hostfs=", hostfs_args,
6257 +"hostfs=<root dir>,<flags>,...\n"
6258 +"    This is used to set hostfs parameters.  The root directory argument\n"
6259 +"    is used to confine all hostfs mounts to within the specified directory\n"
6260 +"    tree on the host.  If this isn't specified, then a user inside UML can\n"
6261 +"    mount anything on the host that's accessible to the user that's running\n"
6262 +"    it.\n"
6263 +"    The only flag currently supported is 'append', which specifies that all\n"
6264 +"    files opened by hostfs will be opened in append mode.\n\n"
6265 +);
6266 +
6267 +static char *dentry_name(struct dentry *dentry, int extra)
6268 +{
6269 +       struct dentry *parent;
6270 +       char *root, *name;
6271 +       int len;
6272 +
6273 +       len = 0;
6274 +       parent = dentry;
6275 +       while(parent->d_parent != parent){
6276 +               len += parent->d_name.len + 1;
6277 +               parent = parent->d_parent;
6278 +       }
6279 +       
6280 +       root = HOSTFS_I(parent->d_inode)->host_filename;
6281 +       len += strlen(root);
6282 +       name = kmalloc(len + extra + 1, GFP_KERNEL);
6283 +       if(name == NULL) return(NULL);
6284 +
6285 +       name[len] = '\0';
6286 +       parent = dentry;
6287 +       while(parent->d_parent != parent){
6288 +               len -= parent->d_name.len + 1;
6289 +               name[len] = '/';
6290 +               strncpy(&name[len + 1], parent->d_name.name, 
6291 +                       parent->d_name.len);
6292 +               parent = parent->d_parent;
6293 +       }
6294 +       strncpy(name, root, strlen(root));
6295 +       return(name);
6296 +}
6297 +
6298 +static char *inode_name(struct inode *ino, int extra)
6299 +{
6300 +       struct dentry *dentry;
6301 +
6302 +       dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias);
6303 +       return(dentry_name(dentry, extra));
6304 +}
6305 +
6306 +static int read_name(struct inode *ino, char *name)
6307 +{
6308 +       /* The non-int inode fields are copied into ints by stat_file and
6309 +        * then copied into the inode because passing the actual pointers
6310 +        * in and having them treated as int * breaks on big-endian machines
6311 +        */
6312 +       int err;
6313 +       int i_mode, i_nlink, i_blksize;
6314 +       unsigned long long i_size;
6315 +       unsigned long long i_ino;
6316 +       unsigned long long i_blocks;
6317 +
6318 +       err = stat_file(name, &i_ino, &i_mode, &i_nlink, &ino->i_uid, 
6319 +                       &ino->i_gid, &i_size, &ino->i_atime, &ino->i_mtime, 
6320 +                       &ino->i_ctime, &i_blksize, &i_blocks);
6321 +       if(err) 
6322 +               return(err);
6323 +
6324 +       ino->i_ino = i_ino;
6325 +       ino->i_mode = i_mode;
6326 +       ino->i_nlink = i_nlink;
6327 +       ino->i_size = i_size;
6328 +       ino->i_blksize = i_blksize;
6329 +       ino->i_blocks = i_blocks;
6330 +       if((ino->i_sb->s_dev == ROOT_DEV) && (ino->i_uid == getuid()))
6331 +               ino->i_uid = 0;
6332 +       return(0);
6333 +}
6334 +
6335 +static char *follow_link(char *link)
6336 +{
6337 +       int len, n;
6338 +       char *name, *resolved, *end;
6339 +
6340 +       len = 64;
6341 +       while(1){
6342 +               n = -ENOMEM;
6343 +               name = kmalloc(len, GFP_KERNEL);
6344 +               if(name == NULL)
6345 +                       goto out;
6346 +
6347 +               n = do_readlink(link, name, len);
6348 +               if(n < len)
6349 +                       break;
6350 +               len *= 2;
6351 +               kfree(name);
6352 +       }
6353 +       if(n < 0)
6354 +               goto out_free;
6355 +
6356 +       if(*name == '/')
6357 +               return(name);
6358 +
6359 +       end = strrchr(link, '/');
6360 +       if(end == NULL)
6361 +               return(name);
6362 +
6363 +       *(end + 1) = '\0';
6364 +       len = strlen(link) + strlen(name) + 1;
6365 +
6366 +       resolved = kmalloc(len, GFP_KERNEL);
6367 +       if(resolved == NULL){
6368 +               n = -ENOMEM;
6369 +               goto out_free;
6370 +       }
6371 +
6372 +       sprintf(resolved, "%s%s", link, name);
6373 +       kfree(name);
6374 +       kfree(link);
6375 +       return(resolved);
6376 +
6377 + out_free:
6378 +       kfree(name);
6379 + out:
6380 +       return(ERR_PTR(n));
6381 +}
6382 +
6383 +static int read_inode(struct inode *ino)
6384 +{
6385 +       char *name;
6386 +       int err = 0;
6387 +
6388 +       /* Unfortunately, we are called from iget() when we don't have a dentry
6389 +        * allocated yet.
6390 +        */
6391 +       if(list_empty(&ino->i_dentry))
6392 +               goto out;
6393
6394 +       err = -ENOMEM;
6395 +       name = inode_name(ino, 0);
6396 +       if(name == NULL) 
6397 +               goto out;
6398 +
6399 +       if(file_type(name, NULL) == OS_TYPE_SYMLINK){
6400 +               name = follow_link(name);
6401 +               if(IS_ERR(name)){
6402 +                       err = PTR_ERR(name);
6403 +                       goto out;
6404 +               }
6405 +       }
6406 +       
6407 +       err = read_name(ino, name);
6408 +       kfree(name);
6409 + out:
6410 +       return(err);
6411 +}
6412 +
6413 +int hostfs_statfs(struct super_block *sb, struct kstatfs *sf)
6414 +{
6415 +       /* do_statfs uses struct statfs64 internally, but the linux kernel
6416 +        * struct statfs still has 32-bit versions for most of these fields,
6417 +        * so we convert them here
6418 +        */
6419 +       int err;
6420 +       long long f_blocks;
6421 +       long long f_bfree;
6422 +       long long f_bavail;
6423 +       long long f_files;
6424 +       long long f_ffree;
6425 +
6426 +       err = do_statfs(HOSTFS_I(sb->s_root->d_inode)->host_filename,
6427 +                       &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files,
6428 +                       &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid), 
6429 +                       &sf->f_namelen, sf->f_spare);
6430 +       if(err) return(err);
6431 +       sf->f_blocks = f_blocks;
6432 +       sf->f_bfree = f_bfree;
6433 +       sf->f_bavail = f_bavail;
6434 +       sf->f_files = f_files;
6435 +       sf->f_ffree = f_ffree;
6436 +       sf->f_type = HOSTFS_SUPER_MAGIC;
6437 +       return(0);
6438 +}
6439 +
6440 +static struct inode *hostfs_alloc_inode(struct super_block *sb)
6441 +{
6442 +       struct hostfs_inode_info *hi;
6443 +
6444 +       hi = kmalloc(sizeof(*hi), GFP_KERNEL);
6445 +       if(hi == NULL) 
6446 +               return(NULL);
6447 +
6448 +       *hi = ((struct hostfs_inode_info) { .host_filename      = NULL,
6449 +                                           .fd                 = -1,
6450 +                                           .mode               = 0 });
6451 +       inode_init_once(&hi->vfs_inode);
6452 +       return(&hi->vfs_inode);
6453 +}
6454 +
6455 +static void hostfs_destroy_inode(struct inode *inode)
6456 +{
6457 +       if(HOSTFS_I(inode)->host_filename) 
6458 +               kfree(HOSTFS_I(inode)->host_filename);
6459 +
6460 +       if(HOSTFS_I(inode)->fd != -1) 
6461 +               close_file(&HOSTFS_I(inode)->fd);
6462 +
6463 +       kfree(HOSTFS_I(inode));
6464 +}
6465 +
6466 +static void hostfs_read_inode(struct inode *inode)
6467 +{
6468 +       read_inode(inode);
6469 +}
6470 +
6471 +static struct super_operations hostfs_sbops = { 
6472 +       .alloc_inode    = hostfs_alloc_inode,
6473 +       .destroy_inode  = hostfs_destroy_inode,
6474 +       .read_inode     = hostfs_read_inode,
6475 +       .statfs         = hostfs_statfs,
6476 +};
6477 +
6478 +int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
6479 +{
6480 +       void *dir;
6481 +       char *name;
6482 +       unsigned long long next, ino;
6483 +       int error, len;
6484 +
6485 +       name = dentry_name(file->f_dentry, 0);
6486 +       if(name == NULL) return(-ENOMEM);
6487 +       dir = open_dir(name, &error);
6488 +       kfree(name);
6489 +       if(dir == NULL) return(-error);
6490 +       next = file->f_pos;
6491 +       while((name = read_dir(dir, &next, &ino, &len)) != NULL){
6492 +               error = (*filldir)(ent, name, len, file->f_pos, 
6493 +                                  ino, DT_UNKNOWN);
6494 +               if(error) break;
6495 +               file->f_pos = next;
6496 +       }
6497 +       close_dir(dir);
6498 +       return(0);
6499 +}
6500 +
6501 +int hostfs_file_open(struct inode *ino, struct file *file)
6502 +{
6503 +       char *name;
6504 +       int mode = 0, r = 0, w = 0, fd;
6505 +
6506 +       mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
6507 +       if((mode & HOSTFS_I(ino)->mode) == mode)
6508 +               return(0);
6509 +
6510 +       /* The file may already have been opened, but with the wrong access,
6511 +        * so this resets things and reopens the file with the new access.
6512 +        */
6513 +       if(HOSTFS_I(ino)->fd != -1){
6514 +               close_file(&HOSTFS_I(ino)->fd);
6515 +               HOSTFS_I(ino)->fd = -1;
6516 +       }
6517 +
6518 +       HOSTFS_I(ino)->mode |= mode;
6519 +       if(HOSTFS_I(ino)->mode & FMODE_READ) 
6520 +               r = 1;
6521 +       if(HOSTFS_I(ino)->mode & FMODE_WRITE) 
6522 +               w = 1;
6523 +       if(w) 
6524 +               r = 1;
6525 +
6526 +       name = dentry_name(file->f_dentry, 0);
6527 +       if(name == NULL) 
6528 +               return(-ENOMEM);
6529 +
6530 +       fd = open_file(name, r, w, append);
6531 +       kfree(name);
6532 +       if(fd < 0) return(fd);
6533 +       FILE_HOSTFS_I(file)->fd = fd;
6534 +
6535 +       return(0);
6536 +}
6537 +
6538 +int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
6539 +{
6540 +       return(0);
6541 +}
6542 +
6543 +static struct file_operations hostfs_file_fops = {
6544 +       .llseek         = generic_file_llseek,
6545 +       .read           = generic_file_read,
6546 +       .write          = generic_file_write,
6547 +       .mmap           = generic_file_mmap,
6548 +       .open           = hostfs_file_open,
6549 +       .release        = NULL,
6550 +       .fsync          = hostfs_fsync,
6551 +};
6552 +
6553 +static struct file_operations hostfs_dir_fops = {
6554 +       .readdir        = hostfs_readdir,
6555 +       .read           = generic_read_dir,
6556 +};
6557 +
6558 +int hostfs_writepage(struct page *page, struct writeback_control *wbc)
6559 +{
6560 +       struct address_space *mapping = page->mapping;
6561 +       struct inode *inode = mapping->host;
6562 +       char *buffer;
6563 +       unsigned long long base;
6564 +       int count = PAGE_CACHE_SIZE;
6565 +       int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
6566 +       int err;
6567 +
6568 +       if (page->index >= end_index)
6569 +               count = inode->i_size & (PAGE_CACHE_SIZE-1);
6570 +
6571 +       buffer = kmap(page);
6572 +       base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
6573 +
6574 +       err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count);
6575 +       if(err != count){
6576 +               ClearPageUptodate(page);
6577 +               goto out;
6578 +       }
6579 +
6580 +       if (base > inode->i_size)
6581 +               inode->i_size = base;
6582 +
6583 +       if (PageError(page))
6584 +               ClearPageError(page);   
6585 +       err = 0;
6586 +
6587 + out:  
6588 +       kunmap(page);
6589 +
6590 +       unlock_page(page);
6591 +       return err; 
6592 +}
6593 +
6594 +int hostfs_readpage(struct file *file, struct page *page)
6595 +{
6596 +       char *buffer;
6597 +       long long start;
6598 +       int err = 0;
6599 +
6600 +       start = (long long) page->index << PAGE_CACHE_SHIFT;
6601 +       buffer = kmap(page);
6602 +       err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer,
6603 +                       PAGE_CACHE_SIZE);
6604 +       if(err < 0) goto out;
6605 +
6606 +       memset(&buffer[err], 0, PAGE_CACHE_SIZE - err);
6607 +
6608 +       flush_dcache_page(page);
6609 +       SetPageUptodate(page);
6610 +       if (PageError(page)) ClearPageError(page);
6611 +       err = 0;
6612 + out:
6613 +       kunmap(page);
6614 +       unlock_page(page);
6615 +       return(err);
6616 +}
6617 +
6618 +int hostfs_prepare_write(struct file *file, struct page *page, 
6619 +                        unsigned int from, unsigned int to)
6620 +{
6621 +       char *buffer;
6622 +       long long start, tmp;
6623 +       int err;
6624 +
6625 +       start = (long long) page->index << PAGE_CACHE_SHIFT;
6626 +       buffer = kmap(page);
6627 +       if(from != 0){
6628 +               tmp = start;
6629 +               err = read_file(FILE_HOSTFS_I(file)->fd, &tmp, buffer,
6630 +                               from);
6631 +               if(err < 0) goto out;
6632 +       }
6633 +       if(to != PAGE_CACHE_SIZE){
6634 +               start += to;
6635 +               err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer + to,
6636 +                               PAGE_CACHE_SIZE - to);
6637 +               if(err < 0) goto out;           
6638 +       }
6639 +       err = 0;
6640 + out:
6641 +       kunmap(page);
6642 +       return(err);
6643 +}
6644 +
6645 +int hostfs_commit_write(struct file *file, struct page *page, unsigned from,
6646 +                unsigned to)
6647 +{
6648 +       struct address_space *mapping = page->mapping;
6649 +       struct inode *inode = mapping->host;
6650 +       char *buffer;
6651 +       long long start;
6652 +       int err = 0;
6653 +
6654 +       start = (long long) (page->index << PAGE_CACHE_SHIFT) + from;
6655 +       buffer = kmap(page);
6656 +       err = write_file(FILE_HOSTFS_I(file)->fd, &start, buffer + from, 
6657 +                        to - from);
6658 +       if(err > 0) err = 0;
6659 +       if(!err && (start > inode->i_size))
6660 +               inode->i_size = start;
6661 +
6662 +       kunmap(page);
6663 +       return(err);
6664 +}
6665 +
6666 +static struct address_space_operations hostfs_aops = {
6667 +       .writepage      = hostfs_writepage,
6668 +       .readpage       = hostfs_readpage,
6669 +/*     .set_page_dirty = __set_page_dirty_nobuffers, */
6670 +       .prepare_write  = hostfs_prepare_write,
6671 +       .commit_write   = hostfs_commit_write
6672 +};
6673 +
6674 +static int init_inode(struct inode *inode, struct dentry *dentry)
6675 +{
6676 +       char *name;
6677 +       int type, err = -ENOMEM, rdev;
6678 +
6679 +       if(dentry){
6680 +               name = dentry_name(dentry, 0);
6681 +               if(name == NULL)
6682 +                       goto out;
6683 +               type = file_type(name, &rdev);
6684 +               kfree(name);
6685 +       }
6686 +       else type = OS_TYPE_DIR;
6687 +
6688 +       err = 0;
6689 +       if(type == OS_TYPE_SYMLINK)
6690 +               inode->i_op = &page_symlink_inode_operations;
6691 +       else if(type == OS_TYPE_DIR)
6692 +               inode->i_op = &hostfs_dir_iops;
6693 +       else inode->i_op = &hostfs_iops;
6694 +
6695 +       if(type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops;
6696 +       else inode->i_fop = &hostfs_file_fops;
6697 +
6698 +       if(type == OS_TYPE_SYMLINK) 
6699 +               inode->i_mapping->a_ops = &hostfs_link_aops;
6700 +       else inode->i_mapping->a_ops = &hostfs_aops;
6701 +
6702 +       switch (type) {
6703 +       case OS_TYPE_CHARDEV:
6704 +               init_special_inode(inode, S_IFCHR, rdev);
6705 +               break;
6706 +       case OS_TYPE_BLOCKDEV:
6707 +               init_special_inode(inode, S_IFBLK, rdev);
6708 +               break;
6709 +       case OS_TYPE_FIFO:
6710 +               init_special_inode(inode, S_IFIFO, 0);
6711 +               break;
6712 +       case OS_TYPE_SOCK:
6713 +               init_special_inode(inode, S_IFSOCK, 0);
6714 +               break;
6715 +       }
6716 + out:
6717 +       return(err);
6718 +}
6719 +
6720 +int hostfs_create(struct inode *dir, struct dentry *dentry, int mode, 
6721 +                 struct nameidata *nd)
6722 +{
6723 +       struct inode *inode;
6724 +       char *name;
6725 +       int error, fd;
6726 +
6727 +       error = -ENOMEM;
6728 +       inode = iget(dir->i_sb, 0);
6729 +       if(inode == NULL) goto out;
6730 +
6731 +       error = init_inode(inode, dentry);
6732 +       if(error) 
6733 +               goto out_put;
6734 +       
6735 +       error = -ENOMEM;
6736 +       name = dentry_name(dentry, 0);
6737 +       if(name == NULL)
6738 +               goto out_put;
6739 +
6740 +       fd = file_create(name, 
6741 +                        mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR, 
6742 +                        mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP, 
6743 +                        mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH);
6744 +       if(fd < 0) 
6745 +               error = fd;
6746 +       else error = read_name(inode, name);
6747 +
6748 +       kfree(name);
6749 +       if(error)
6750 +               goto out_put;
6751 +
6752 +       HOSTFS_I(inode)->fd = fd;
6753 +       HOSTFS_I(inode)->mode = FMODE_READ | FMODE_WRITE;
6754 +       d_instantiate(dentry, inode);
6755 +       return(0);
6756 +
6757 + out_put:
6758 +       iput(inode);
6759 + out:
6760 +       return(error);
6761 +}
6762 +
6763 +struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry, 
6764 +                            struct nameidata *nd)
6765 +{
6766 +       struct inode *inode;
6767 +       char *name;
6768 +       int err;
6769 +
6770 +       err = -ENOMEM;
6771 +       inode = iget(ino->i_sb, 0);
6772 +       if(inode == NULL) 
6773 +               goto out;
6774
6775 +       err = init_inode(inode, dentry);
6776 +       if(err) 
6777 +               goto out_put;
6778 +
6779 +       err = -ENOMEM;
6780 +       name = dentry_name(dentry, 0);
6781 +       if(name == NULL)
6782 +               goto out_put;
6783 +
6784 +       err = read_name(inode, name);
6785 +       kfree(name);
6786 +       if(err == -ENOENT){
6787 +               iput(inode);
6788 +               inode = NULL;
6789 +       }
6790 +       else if(err)
6791 +               goto out_put;
6792 +
6793 +       d_add(dentry, inode);
6794 +       dentry->d_op = &hostfs_dentry_ops;
6795 +       return(NULL);
6796 +
6797 + out_put:
6798 +       iput(inode);
6799 + out:
6800 +       return(ERR_PTR(err));
6801 +}
6802 +
6803 +static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
6804 +{
6805 +        char *file;
6806 +       int len;
6807 +
6808 +       file = inode_name(ino, dentry->d_name.len + 1);
6809 +       if(file == NULL) return(NULL);
6810 +        strcat(file, "/");
6811 +       len = strlen(file);
6812 +        strncat(file, dentry->d_name.name, dentry->d_name.len);
6813 +       file[len + dentry->d_name.len] = '\0';
6814 +        return(file);
6815 +}
6816 +
6817 +int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
6818 +{
6819 +        char *from_name, *to_name;
6820 +        int err;
6821 +
6822 +        if((from_name = inode_dentry_name(ino, from)) == NULL) 
6823 +                return(-ENOMEM);
6824 +        to_name = dentry_name(to, 0);
6825 +       if(to_name == NULL){
6826 +               kfree(from_name);
6827 +               return(-ENOMEM);
6828 +       }
6829 +        err = link_file(to_name, from_name);
6830 +        kfree(from_name);
6831 +        kfree(to_name);
6832 +        return(err);
6833 +}
6834 +
6835 +int hostfs_unlink(struct inode *ino, struct dentry *dentry)
6836 +{
6837 +       char *file;
6838 +       int err;
6839 +
6840 +       if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
6841 +       if(append)
6842 +               return(-EPERM);
6843 +
6844 +       err = unlink_file(file);
6845 +       kfree(file);
6846 +       return(err);
6847 +}
6848 +
6849 +int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
6850 +{
6851 +       char *file;
6852 +       int err;
6853 +
6854 +       if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
6855 +       err = make_symlink(file, to);
6856 +       kfree(file);
6857 +       return(err);
6858 +}
6859 +
6860 +int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode)
6861 +{
6862 +       char *file;
6863 +       int err;
6864 +
6865 +       if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
6866 +       err = do_mkdir(file, mode);
6867 +       kfree(file);
6868 +       return(err);
6869 +}
6870 +
6871 +int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
6872 +{
6873 +       char *file;
6874 +       int err;
6875 +
6876 +       if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
6877 +       err = do_rmdir(file);
6878 +       kfree(file);
6879 +       return(err);
6880 +}
6881 +
6882 +int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
6883 +{
6884 +       struct inode *inode;
6885 +       char *name;
6886 +       int err = -ENOMEM;
6887
6888 +       inode = iget(dir->i_sb, 0);
6889 +       if(inode == NULL) 
6890 +               goto out;
6891 +
6892 +       err = init_inode(inode, dentry);
6893 +       if(err) 
6894 +               goto out_put;
6895 +
6896 +       err = -ENOMEM;
6897 +       name = dentry_name(dentry, 0);
6898 +       if(name == NULL)
6899 +               goto out_put;
6900 +
6901 +       init_special_inode(inode, mode, dev);
6902 +       err = do_mknod(name, mode, dev);
6903 +       if(err)
6904 +               goto out_free;
6905 +
6906 +       err = read_name(inode, name);
6907 +       kfree(name);
6908 +       if(err)
6909 +               goto out_put;
6910 +
6911 +       d_instantiate(dentry, inode);
6912 +       return(0);
6913 +
6914 + out_free:
6915 +       kfree(name);
6916 + out_put:
6917 +       iput(inode);
6918 + out:
6919 +       return(err);
6920 +}
6921 +
6922 +int hostfs_rename(struct inode *from_ino, struct dentry *from,
6923 +                 struct inode *to_ino, struct dentry *to)
6924 +{
6925 +       char *from_name, *to_name;
6926 +       int err;
6927 +
6928 +       if((from_name = inode_dentry_name(from_ino, from)) == NULL)
6929 +               return(-ENOMEM);
6930 +       if((to_name = inode_dentry_name(to_ino, to)) == NULL){
6931 +               kfree(from_name);
6932 +               return(-ENOMEM);
6933 +       }
6934 +       err = rename_file(from_name, to_name);
6935 +       kfree(from_name);
6936 +       kfree(to_name);
6937 +       return(err);
6938 +}
6939 +
6940 +void hostfs_truncate(struct inode *ino)
6941 +{
6942 +       not_implemented();
6943 +}
6944 +
6945 +int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd)
6946 +{
6947 +       char *name;
6948 +       int r = 0, w = 0, x = 0, err;
6949 +
6950 +       if(desired & MAY_READ) r = 1;
6951 +       if(desired & MAY_WRITE) w = 1;
6952 +       if(desired & MAY_EXEC) x = 1;
6953 +       name = inode_name(ino, 0);
6954 +       if(name == NULL) return(-ENOMEM);
6955 +       err = access_file(name, r, w, x);
6956 +       kfree(name);
6957 +       if(!err) err = vfs_permission(ino, desired);
6958 +       return(err);
6959 +}
6960 +
6961 +int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
6962 +{
6963 +       struct hostfs_iattr attrs;
6964 +       char *name;
6965 +       int err;
6966 +       
6967 +       if(append) 
6968 +               attr->ia_valid &= ~ATTR_SIZE;
6969 +
6970 +       attrs.ia_valid = 0;
6971 +       if(attr->ia_valid & ATTR_MODE){
6972 +               attrs.ia_valid |= HOSTFS_ATTR_MODE;
6973 +               attrs.ia_mode = attr->ia_mode;
6974 +       }
6975 +       if(attr->ia_valid & ATTR_UID){
6976 +               if((dentry->d_inode->i_sb->s_dev == ROOT_DEV) && 
6977 +                  (attr->ia_uid == 0))
6978 +                       attr->ia_uid = getuid();
6979 +               attrs.ia_valid |= HOSTFS_ATTR_UID;
6980 +               attrs.ia_uid = attr->ia_uid;
6981 +       }
6982 +       if(attr->ia_valid & ATTR_GID){
6983 +               if((dentry->d_inode->i_sb->s_dev == ROOT_DEV) && 
6984 +                  (attr->ia_gid == 0))
6985 +                       attr->ia_gid = getuid();
6986 +               attrs.ia_valid |= HOSTFS_ATTR_GID;
6987 +               attrs.ia_gid = attr->ia_gid;
6988 +       }
6989 +       if(attr->ia_valid & ATTR_SIZE){
6990 +               attrs.ia_valid |= HOSTFS_ATTR_SIZE;
6991 +               attrs.ia_size = attr->ia_size;
6992 +       }
6993 +       if(attr->ia_valid & ATTR_ATIME){
6994 +               attrs.ia_valid |= HOSTFS_ATTR_ATIME;
6995 +               attrs.ia_atime = attr->ia_atime;
6996 +       }
6997 +       if(attr->ia_valid & ATTR_MTIME){
6998 +               attrs.ia_valid |= HOSTFS_ATTR_MTIME;
6999 +               attrs.ia_mtime = attr->ia_mtime;
7000 +       }
7001 +       if(attr->ia_valid & ATTR_CTIME){
7002 +               attrs.ia_valid |= HOSTFS_ATTR_CTIME;
7003 +               attrs.ia_ctime = attr->ia_ctime;
7004 +       }
7005 +       if(attr->ia_valid & ATTR_ATIME_SET){
7006 +               attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
7007 +       }
7008 +       if(attr->ia_valid & ATTR_MTIME_SET){
7009 +               attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
7010 +       }
7011 +       name = dentry_name(dentry, 0);
7012 +       if(name == NULL) return(-ENOMEM);
7013 +       err = set_attr(name, &attrs);
7014 +       kfree(name);
7015 +       if(err)
7016 +               return(err);
7017 +
7018 +       return(inode_setattr(dentry->d_inode, attr));
7019 +}
7020 +
7021 +int hostfs_getattr(struct vfsmount *mnt, struct dentry *dentry, 
7022 +          struct kstat *stat)
7023 +{
7024 +       generic_fillattr(dentry->d_inode, stat);
7025 +       return(0);
7026 +}
7027 +
7028 +static struct inode_operations hostfs_iops = {
7029 +       .create         = hostfs_create,
7030 +       .link           = hostfs_link,
7031 +       .unlink         = hostfs_unlink,
7032 +       .symlink        = hostfs_symlink,
7033 +       .mkdir          = hostfs_mkdir,
7034 +       .rmdir          = hostfs_rmdir,
7035 +       .mknod          = hostfs_mknod,
7036 +       .rename         = hostfs_rename,
7037 +       .truncate       = hostfs_truncate,
7038 +       .permission     = hostfs_permission,
7039 +       .setattr        = hostfs_setattr,
7040 +       .getattr        = hostfs_getattr,
7041 +};
7042 +
7043 +static struct inode_operations hostfs_dir_iops = {
7044 +       .create         = hostfs_create,
7045 +       .lookup         = hostfs_lookup,
7046 +       .link           = hostfs_link,
7047 +       .unlink         = hostfs_unlink,
7048 +       .symlink        = hostfs_symlink,
7049 +       .mkdir          = hostfs_mkdir,
7050 +       .rmdir          = hostfs_rmdir,
7051 +       .mknod          = hostfs_mknod,
7052 +       .rename         = hostfs_rename,
7053 +       .truncate       = hostfs_truncate,
7054 +       .permission     = hostfs_permission,
7055 +       .setattr        = hostfs_setattr,
7056 +       .getattr        = hostfs_getattr,
7057 +};
7058 +
7059 +int hostfs_link_readpage(struct file *file, struct page *page)
7060 +{
7061 +       char *buffer, *name;
7062 +       long long start;
7063 +       int err;
7064 +
7065 +       start = page->index << PAGE_CACHE_SHIFT;
7066 +       buffer = kmap(page);
7067 +       name = inode_name(page->mapping->host, 0);
7068 +       if(name == NULL) return(-ENOMEM);
7069 +       err = do_readlink(name, buffer, PAGE_CACHE_SIZE);
7070 +       kfree(name);
7071 +       if(err == PAGE_CACHE_SIZE)
7072 +               err = -E2BIG;
7073 +       else if(err > 0){
7074 +               flush_dcache_page(page);
7075 +               SetPageUptodate(page);
7076 +               if (PageError(page)) ClearPageError(page);
7077 +               err = 0;
7078 +       }
7079 +       kunmap(page);
7080 +       unlock_page(page);
7081 +       return(err);
7082 +}
7083 +
7084 +static struct address_space_operations hostfs_link_aops = {
7085 +       .readpage       = hostfs_link_readpage,
7086 +};
7087 +
7088 +static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
7089 +{
7090 +       struct inode *root_inode;
7091 +       char *name, *data = d;
7092 +       int err;
7093 +
7094 +       sb->s_blocksize = 1024;
7095 +       sb->s_blocksize_bits = 10;
7096 +       sb->s_magic = HOSTFS_SUPER_MAGIC;
7097 +       sb->s_op = &hostfs_sbops;
7098 +
7099 +       if((data == NULL) || (*data == '\0')) 
7100 +               data = root_ino;
7101 +
7102 +       err = -ENOMEM;
7103 +       name = kmalloc(strlen(data) + 1, GFP_KERNEL);
7104 +       if(name == NULL) 
7105 +               goto out;
7106 +
7107 +       strcpy(name, data);
7108 +
7109 +       root_inode = iget(sb, 0);
7110 +       if(root_inode == NULL)
7111 +               goto out_free;
7112 +
7113 +       err = init_inode(root_inode, NULL);
7114 +       if(err)
7115 +               goto out_put;
7116 +
7117 +       HOSTFS_I(root_inode)->host_filename = name;
7118 +
7119 +       err = -ENOMEM;
7120 +       sb->s_root = d_alloc_root(root_inode);
7121 +       if(sb->s_root == NULL)
7122 +               goto out_put;
7123 +
7124 +       err = read_inode(root_inode);
7125 +       if(err)
7126 +               goto out_put;
7127 +
7128 +       return(0);
7129 +
7130 + out_put:
7131 +       iput(root_inode);
7132 + out_free:
7133 +       kfree(name);
7134 + out:
7135 +       return(err);
7136 +}
7137 +
7138 +static struct super_block *hostfs_read_sb(struct file_system_type *type,
7139 +                                            int flags, const char *dev_name,
7140 +                                            void *data)
7141 +{
7142 +       return(get_sb_nodev(type, flags, data, hostfs_fill_sb_common));
7143 +}
7144 +
7145 +static struct file_system_type hostfs_type = {
7146 +       .owner          = THIS_MODULE,
7147 +       .name           = "hostfs",
7148 +       .get_sb         = hostfs_read_sb,
7149 +       .kill_sb        = kill_anon_super,
7150 +       .fs_flags       = 0,
7151 +};
7152 +
7153 +static int __init init_hostfs(void)
7154 +{
7155 +       return(register_filesystem(&hostfs_type));
7156 +}
7157 +
7158 +static void __exit exit_hostfs(void)
7159 +{
7160 +       unregister_filesystem(&hostfs_type);
7161 +}
7162 +
7163 +module_init(init_hostfs)
7164 +module_exit(exit_hostfs)
7165 +MODULE_LICENSE("GPL");
7166 +
7167 +/*
7168 + * Overrides for Emacs so that we follow Linus's tabbing style.
7169 + * Emacs will notice this stuff at the end of the file and automatically
7170 + * adjust the settings for this buffer only.  This must remain at the end
7171 + * of the file.
7172 + * ---------------------------------------------------------------------------
7173 + * Local variables:
7174 + * c-file-style: "linux"
7175 + * End:
7176 + */
7177 diff -Naur a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c
7178 --- a/fs/hostfs/hostfs_user.c   Wed Dec 31 19:00:00 1969
7179 +++ b/fs/hostfs/hostfs_user.c   Tue Sep  9 16:47:43 2003
7180 @@ -0,0 +1,361 @@
7181 +/* 
7182 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
7183 + * Licensed under the GPL
7184 + */
7185 +
7186 +#include <unistd.h>
7187 +#include <stdio.h>
7188 +#include <fcntl.h>
7189 +#include <dirent.h>
7190 +#include <errno.h>
7191 +#include <utime.h>
7192 +#include <string.h>
7193 +#include <sys/stat.h>
7194 +#include <sys/time.h>
7195 +#include <sys/vfs.h>
7196 +#include "hostfs.h"
7197 +#include "kern_util.h"
7198 +#include "user.h"
7199 +
7200 +int stat_file(const char *path, unsigned long long *inode_out, int *mode_out,
7201 +             int *nlink_out, int *uid_out, int *gid_out, 
7202 +             unsigned long long *size_out, struct timespec *atime_out,
7203 +             struct timespec *mtime_out, struct timespec *ctime_out,
7204 +             int *blksize_out, unsigned long long *blocks_out)
7205 +{
7206 +       struct stat64 buf;
7207 +
7208 +       if(lstat64(path, &buf) < 0) 
7209 +               return(-errno);
7210 +
7211 +       /* See the Makefile for why STAT64_INO_FIELD is passed in
7212 +        * by the build
7213 +        */
7214 +       if(inode_out != NULL) *inode_out = buf.STAT64_INO_FIELD;
7215 +       if(mode_out != NULL) *mode_out = buf.st_mode;
7216 +       if(nlink_out != NULL) *nlink_out = buf.st_nlink;
7217 +       if(uid_out != NULL) *uid_out = buf.st_uid;
7218 +       if(gid_out != NULL) *gid_out = buf.st_gid;
7219 +       if(size_out != NULL) *size_out = buf.st_size;
7220 +       if(atime_out != NULL) {
7221 +               atime_out->tv_sec = buf.st_atime;
7222 +               atime_out->tv_nsec = 0;
7223 +       }
7224 +       if(mtime_out != NULL) {
7225 +               mtime_out->tv_sec = buf.st_mtime;
7226 +               mtime_out->tv_nsec = 0;
7227 +       }
7228 +       if(ctime_out != NULL) {
7229 +               ctime_out->tv_sec = buf.st_ctime;
7230 +               ctime_out->tv_nsec = 0;
7231 +       }
7232 +       if(blksize_out != NULL) *blksize_out = buf.st_blksize;
7233 +       if(blocks_out != NULL) *blocks_out = buf.st_blocks;
7234 +       return(0);
7235 +}
7236 +
7237 +int file_type(const char *path, int *rdev)
7238 +{
7239 +       struct stat64 buf;
7240 +
7241 +       if(lstat64(path, &buf) < 0) 
7242 +               return(-errno);
7243 +       if(rdev != NULL) 
7244 +               *rdev = buf.st_rdev;
7245 +
7246 +       if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR);
7247 +       else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK);
7248 +       else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV);
7249 +       else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV);
7250 +       else if(S_ISFIFO(buf.st_mode))return(OS_TYPE_FIFO);
7251 +       else if(S_ISSOCK(buf.st_mode))return(OS_TYPE_SOCK);
7252 +       else return(OS_TYPE_FILE);
7253 +}
7254 +
7255 +int access_file(char *path, int r, int w, int x)
7256 +{
7257 +       int mode = 0;
7258 +
7259 +       if(r) mode = R_OK;
7260 +       if(w) mode |= W_OK;
7261 +       if(x) mode |= X_OK;
7262 +       if(access(path, mode) != 0) return(-errno);
7263 +       else return(0);
7264 +}
7265 +
7266 +int open_file(char *path, int r, int w, int append)
7267 +{
7268 +       int mode = 0, fd;
7269 +
7270 +       if(r && !w) 
7271 +               mode = O_RDONLY;
7272 +       else if(!r && w) 
7273 +               mode = O_WRONLY;
7274 +       else if(r && w) 
7275 +               mode = O_RDWR;
7276 +       else panic("Impossible mode in open_file");
7277 +
7278 +       if(append)
7279 +               mode |= O_APPEND;
7280 +       fd = open64(path, mode);
7281 +       if(fd < 0) return(-errno);
7282 +       else return(fd);
7283 +}
7284 +
7285 +void *open_dir(char *path, int *err_out)
7286 +{
7287 +       DIR *dir;
7288 +
7289 +       dir = opendir(path);
7290 +       *err_out = errno;
7291 +       if(dir == NULL) return(NULL);
7292 +       return(dir);
7293 +}
7294 +
7295 +char *read_dir(void *stream, unsigned long long *pos, 
7296 +              unsigned long long *ino_out, int *len_out)
7297 +{
7298 +       DIR *dir = stream;
7299 +       struct dirent *ent;
7300 +
7301 +       seekdir(dir, *pos);
7302 +       ent = readdir(dir);
7303 +       if(ent == NULL) return(NULL);
7304 +       *len_out = strlen(ent->d_name);
7305 +       *ino_out = ent->d_ino;
7306 +       *pos = telldir(dir);
7307 +       return(ent->d_name);
7308 +}
7309 +
7310 +int read_file(int fd, unsigned long long *offset, char *buf, int len)
7311 +{
7312 +       int n;
7313 +
7314 +       n = pread64(fd, buf, len, *offset);
7315 +       if(n < 0) return(-errno);
7316 +       *offset += n;
7317 +       return(n);
7318 +}
7319 +
7320 +int write_file(int fd, unsigned long long *offset, const char *buf, int len)
7321 +{
7322 +       int n;
7323 +
7324 +       n = pwrite64(fd, buf, len, *offset);
7325 +       if(n < 0) return(-errno);
7326 +       *offset += n;
7327 +       return(n);
7328 +}
7329 +
7330 +int lseek_file(int fd, long long offset, int whence)
7331 +{
7332 +       int ret;
7333 +
7334 +       ret = lseek64(fd, offset, whence);
7335 +       if(ret < 0) return(-errno);
7336 +       return(0);
7337 +}
7338 +
7339 +void close_file(void *stream)
7340 +{
7341 +       close(*((int *) stream));
7342 +}
7343 +
7344 +void close_dir(void *stream)
7345 +{
7346 +       closedir(stream);
7347 +}
7348 +
7349 +int file_create(char *name, int ur, int uw, int ux, int gr, 
7350 +               int gw, int gx, int or, int ow, int ox)
7351 +{
7352 +       int mode, fd;
7353 +
7354 +       mode = 0;
7355 +       mode |= ur ? S_IRUSR : 0;
7356 +       mode |= uw ? S_IWUSR : 0;
7357 +       mode |= ux ? S_IXUSR : 0;
7358 +       mode |= gr ? S_IRGRP : 0;
7359 +       mode |= gw ? S_IWGRP : 0;
7360 +       mode |= gx ? S_IXGRP : 0;
7361 +       mode |= or ? S_IROTH : 0;
7362 +       mode |= ow ? S_IWOTH : 0;
7363 +       mode |= ox ? S_IXOTH : 0;
7364 +       fd = open64(name, O_CREAT | O_RDWR, mode);
7365 +       if(fd < 0) 
7366 +               return(-errno);
7367 +       return(fd);
7368 +}
7369 +
7370 +int set_attr(const char *file, struct hostfs_iattr *attrs)
7371 +{
7372 +       struct utimbuf buf;
7373 +       int err, ma;
7374 +
7375 +       if(attrs->ia_valid & HOSTFS_ATTR_MODE){
7376 +               if(chmod(file, attrs->ia_mode) != 0) return(-errno);
7377 +       }
7378 +       if(attrs->ia_valid & HOSTFS_ATTR_UID){
7379 +               if(chown(file, attrs->ia_uid, -1)) return(-errno);
7380 +       }
7381 +       if(attrs->ia_valid & HOSTFS_ATTR_GID){
7382 +               if(chown(file, -1, attrs->ia_gid)) return(-errno);
7383 +       }
7384 +       if(attrs->ia_valid & HOSTFS_ATTR_SIZE){
7385 +               if(truncate(file, attrs->ia_size)) return(-errno);
7386 +       }
7387 +       ma = HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET;
7388 +       if((attrs->ia_valid & ma) == ma){
7389 +               buf.actime = attrs->ia_atime.tv_sec;
7390 +               buf.modtime = attrs->ia_mtime.tv_sec;
7391 +               if(utime(file, &buf) != 0) return(-errno);
7392 +       }
7393 +       else {
7394 +               struct timespec ts;
7395 +
7396 +               if(attrs->ia_valid & HOSTFS_ATTR_ATIME_SET){
7397 +                       err = stat_file(file, NULL, NULL, NULL, NULL, NULL, 
7398 +                                       NULL, NULL, &ts, NULL, NULL, NULL);
7399 +                       if(err != 0) 
7400 +                               return(err);
7401 +                       buf.actime = attrs->ia_atime.tv_sec;
7402 +                       buf.modtime = ts.tv_sec;
7403 +                       if(utime(file, &buf) != 0) 
7404 +                               return(-errno);
7405 +               }
7406 +               if(attrs->ia_valid & HOSTFS_ATTR_MTIME_SET){
7407 +                       err = stat_file(file, NULL, NULL, NULL, NULL, NULL, 
7408 +                                       NULL, &ts, NULL, NULL, NULL, NULL);
7409 +                       if(err != 0) 
7410 +                               return(err);
7411 +                       buf.actime = ts.tv_sec;
7412 +                       buf.modtime = attrs->ia_mtime.tv_sec;
7413 +                       if(utime(file, &buf) != 0) 
7414 +                               return(-errno);
7415 +               }
7416 +       }
7417 +       if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ;
7418 +       if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){
7419 +               err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL, 
7420 +                               &attrs->ia_atime, &attrs->ia_mtime, NULL, 
7421 +                               NULL, NULL);
7422 +               if(err != 0) return(err);
7423 +       }
7424 +       return(0);
7425 +}
7426 +
7427 +int make_symlink(const char *from, const char *to)
7428 +{
7429 +       int err;
7430 +
7431 +       err = symlink(to, from);
7432 +       if(err) return(-errno);
7433 +       return(0);
7434 +}
7435 +
7436 +int unlink_file(const char *file)
7437 +{
7438 +       int err;
7439 +
7440 +       err = unlink(file);
7441 +       if(err) return(-errno);
7442 +       return(0);
7443 +}
7444 +
7445 +int do_mkdir(const char *file, int mode)
7446 +{
7447 +       int err;
7448 +
7449 +       err = mkdir(file, mode);
7450 +       if(err) return(-errno);
7451 +       return(0);
7452 +}
7453 +
7454 +int do_rmdir(const char *file)
7455 +{
7456 +       int err;
7457 +
7458 +       err = rmdir(file);
7459 +       if(err) return(-errno);
7460 +       return(0);
7461 +}
7462 +
7463 +int do_mknod(const char *file, int mode, int dev)
7464 +{
7465 +       int err;
7466 +
7467 +       err = mknod(file, mode, dev);
7468 +       if(err) return(-errno);
7469 +       return(0);
7470 +}
7471 +
7472 +int link_file(const char *to, const char *from)
7473 +{
7474 +       int err;
7475 +
7476 +       err = link(to, from);
7477 +       if(err) return(-errno);
7478 +       return(0);
7479 +}
7480 +
7481 +int do_readlink(char *file, char *buf, int size)
7482 +{
7483 +       int n;
7484 +
7485 +       n = readlink(file, buf, size);
7486 +       if(n < 0) 
7487 +               return(-errno);
7488 +       if(n < size) 
7489 +               buf[n] = '\0';
7490 +       return(n);
7491 +}
7492 +
7493 +int rename_file(char *from, char *to)
7494 +{
7495 +       int err;
7496 +
7497 +       err = rename(from, to);
7498 +       if(err < 0) return(-errno);
7499 +       return(0);      
7500 +}
7501 +
7502 +int do_statfs(char *root, long *bsize_out, long long *blocks_out, 
7503 +             long long *bfree_out, long long *bavail_out, 
7504 +             long long *files_out, long long *ffree_out,
7505 +             void *fsid_out, int fsid_size, long *namelen_out, 
7506 +             long *spare_out)
7507 +{
7508 +       struct statfs64 buf;
7509 +       int err;
7510 +
7511 +       err = statfs64(root, &buf);
7512 +       if(err < 0) return(-errno);
7513 +       *bsize_out = buf.f_bsize;
7514 +       *blocks_out = buf.f_blocks;
7515 +       *bfree_out = buf.f_bfree;
7516 +       *bavail_out = buf.f_bavail;
7517 +       *files_out = buf.f_files;
7518 +       *ffree_out = buf.f_ffree;
7519 +       memcpy(fsid_out, &buf.f_fsid, 
7520 +              sizeof(buf.f_fsid) > fsid_size ? fsid_size : 
7521 +              sizeof(buf.f_fsid));
7522 +       *namelen_out = buf.f_namelen;
7523 +       spare_out[0] = buf.f_spare[0];
7524 +       spare_out[1] = buf.f_spare[1];
7525 +       spare_out[2] = buf.f_spare[2];
7526 +       spare_out[3] = buf.f_spare[3];
7527 +       spare_out[4] = buf.f_spare[4];
7528 +       spare_out[5] = buf.f_spare[5];
7529 +       return(0);
7530 +}
7531 +
7532 +/*
7533 + * Overrides for Emacs so that we follow Linus's tabbing style.
7534 + * Emacs will notice this stuff at the end of the file and automatically
7535 + * adjust the settings for this buffer only.  This must remain at the end
7536 + * of the file.
7537 + * ---------------------------------------------------------------------------
7538 + * Local variables:
7539 + * c-file-style: "linux"
7540 + * End:
7541 + */
7542 diff -Naur a/fs/hppfs/Makefile b/fs/hppfs/Makefile
7543 --- a/fs/hppfs/Makefile Wed Dec 31 19:00:00 1969
7544 +++ b/fs/hppfs/Makefile Tue Sep  9 16:49:04 2003
7545 @@ -0,0 +1,19 @@
7546 +# 
7547 +# Copyright (C) 2002, 2003 Jeff Dike (jdike@karaya.com)
7548 +# Licensed under the GPL
7549 +#
7550 +
7551 +hppfs-objs := hppfs_kern.o
7552 +
7553 +obj-y = 
7554 +obj-$(CONFIG_HPPFS) += hppfs.o
7555 +
7556 +clean:
7557 +
7558 +modules:
7559 +
7560 +fastdep:
7561 +
7562 +dep:
7563 +
7564 +archmrproper: clean
7565 diff -Naur a/fs/hppfs/hppfs_kern.c b/fs/hppfs/hppfs_kern.c
7566 --- a/fs/hppfs/hppfs_kern.c     Wed Dec 31 19:00:00 1969
7567 +++ b/fs/hppfs/hppfs_kern.c     Tue Sep  9 16:48:52 2003
7568 @@ -0,0 +1,811 @@
7569 +/* 
7570 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
7571 + * Licensed under the GPL
7572 + */
7573 +
7574 +#include <linux/fs.h>
7575 +#include <linux/module.h>
7576 +#include <linux/init.h>
7577 +#include <linux/slab.h>
7578 +#include <linux/list.h>
7579 +#include <linux/kernel.h>
7580 +#include <linux/ctype.h>
7581 +#include <linux/dcache.h>
7582 +#include <linux/statfs.h>
7583 +#include <asm/uaccess.h>
7584 +#include <asm/fcntl.h>
7585 +#include "os.h"
7586 +
7587 +static int init_inode(struct inode *inode, struct dentry *dentry);
7588 +
7589 +struct hppfs_data {
7590 +       struct list_head list;
7591 +       char contents[PAGE_SIZE - sizeof(struct list_head)];
7592 +};
7593 +
7594 +struct hppfs_private {
7595 +       struct file proc_file;
7596 +       int host_fd;
7597 +       loff_t len;
7598 +       struct hppfs_data *contents;
7599 +};
7600 +
7601 +struct hppfs_inode_info {
7602 +        struct dentry *proc_dentry;
7603 +       struct inode vfs_inode;
7604 +};
7605 +
7606 +static inline struct hppfs_inode_info *HPPFS_I(struct inode *inode)
7607 +{
7608 +       return(list_entry(inode, struct hppfs_inode_info, vfs_inode));
7609 +}
7610 +
7611 +#define HPPFS_SUPER_MAGIC 0xb00000ee
7612 +
7613 +static struct super_operations hppfs_sbops;
7614 +
7615 +static int is_pid(struct dentry *dentry)
7616 +{
7617 +       struct super_block *sb;
7618 +       int i;
7619 +
7620 +       sb = dentry->d_sb;
7621 +       if((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root))
7622 +               return(0);
7623 +
7624 +       for(i = 0; i < dentry->d_name.len; i++){
7625 +               if(!isdigit(dentry->d_name.name[i]))
7626 +                       return(0);
7627 +       }
7628 +       return(1);
7629 +}
7630 +
7631 +static char *dentry_name(struct dentry *dentry, int extra)
7632 +{
7633 +       struct dentry *parent;
7634 +       char *root, *name;
7635 +       const char *seg_name;
7636 +       int len, seg_len;
7637 +
7638 +       len = 0;
7639 +       parent = dentry;
7640 +       while(parent->d_parent != parent){
7641 +               if(is_pid(parent))
7642 +                       len += strlen("pid") + 1;
7643 +               else len += parent->d_name.len + 1;
7644 +               parent = parent->d_parent;
7645 +       }
7646 +       
7647 +       root = "proc";
7648 +       len += strlen(root);
7649 +       name = kmalloc(len + extra + 1, GFP_KERNEL);
7650 +       if(name == NULL) return(NULL);
7651 +
7652 +       name[len] = '\0';
7653 +       parent = dentry;
7654 +       while(parent->d_parent != parent){
7655 +               if(is_pid(parent)){
7656 +                       seg_name = "pid";
7657 +                       seg_len = strlen("pid");
7658 +               }
7659 +               else {
7660 +                       seg_name = parent->d_name.name;
7661 +                       seg_len = parent->d_name.len;
7662 +               }
7663 +
7664 +               len -= seg_len + 1;
7665 +               name[len] = '/';
7666 +               strncpy(&name[len + 1], seg_name, seg_len);
7667 +               parent = parent->d_parent;
7668 +       }
7669 +       strncpy(name, root, strlen(root));
7670 +       return(name);
7671 +}
7672 +
7673 +struct dentry_operations hppfs_dentry_ops = {
7674 +};
7675 +
7676 +static int file_removed(struct dentry *dentry, const char *file)
7677 +{
7678 +       char *host_file;
7679 +       int extra, fd;
7680 +
7681 +       extra = 0;
7682 +       if(file != NULL) extra += strlen(file) + 1;
7683 +
7684 +       host_file = dentry_name(dentry, extra + strlen("/remove"));
7685 +       if(host_file == NULL){
7686 +               printk("file_removed : allocation failed\n");
7687 +               return(-ENOMEM);
7688 +       }
7689 +
7690 +       if(file != NULL){
7691 +               strcat(host_file, "/");
7692 +               strcat(host_file, file);
7693 +       }
7694 +       strcat(host_file, "/remove");
7695 +
7696 +       fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
7697 +       kfree(host_file);
7698 +       if(fd > 0){
7699 +               os_close_file(fd);
7700 +               return(1);
7701 +       }
7702 +       return(0);
7703 +}
7704 +
7705 +static void hppfs_read_inode(struct inode *ino)
7706 +{
7707 +       struct inode *proc_ino;
7708 +
7709 +       if(HPPFS_I(ino)->proc_dentry == NULL)
7710 +               return;
7711 +
7712 +       proc_ino = HPPFS_I(ino)->proc_dentry->d_inode;
7713 +       ino->i_uid = proc_ino->i_uid;
7714 +       ino->i_gid = proc_ino->i_gid;
7715 +       ino->i_atime = proc_ino->i_atime;
7716 +       ino->i_mtime = proc_ino->i_mtime;
7717 +       ino->i_ctime = proc_ino->i_ctime;
7718 +       ino->i_ino = proc_ino->i_ino;
7719 +       ino->i_mode = proc_ino->i_mode;
7720 +       ino->i_nlink = proc_ino->i_nlink;
7721 +       ino->i_size = proc_ino->i_size;
7722 +       ino->i_blksize = proc_ino->i_blksize;
7723 +       ino->i_blocks = proc_ino->i_blocks;
7724 +}
7725 +
7726 +static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry, 
7727 +                                  struct nameidata *nd)
7728 +{
7729 +       struct dentry *proc_dentry, *new, *parent;
7730 +       struct inode *inode;
7731 +       int err, deleted;
7732 +
7733 +       deleted = file_removed(dentry, NULL);
7734 +       if(deleted < 0)
7735 +               return(ERR_PTR(deleted));
7736 +       else if(deleted)
7737 +               return(ERR_PTR(-ENOENT));
7738 +
7739 +       err = -ENOMEM;
7740 +       parent = HPPFS_I(ino)->proc_dentry;
7741 +       down(&parent->d_inode->i_sem);
7742 +       proc_dentry = d_lookup(parent, &dentry->d_name);
7743 +       if(proc_dentry == NULL){
7744 +               proc_dentry = d_alloc(parent, &dentry->d_name);
7745 +               if(proc_dentry == NULL){
7746 +                       up(&parent->d_inode->i_sem);
7747 +                       goto out;
7748 +               }
7749 +               new = (*parent->d_inode->i_op->lookup)(parent->d_inode, 
7750 +                                                      proc_dentry, NULL);
7751 +               if(new){
7752 +                       dput(proc_dentry);
7753 +                       proc_dentry = new;
7754 +               }
7755 +       }
7756 +       up(&parent->d_inode->i_sem);
7757 +
7758 +       if(IS_ERR(proc_dentry))
7759 +               return(proc_dentry);
7760 +
7761 +       inode = iget(ino->i_sb, 0);
7762 +       if(inode == NULL) 
7763 +               goto out_dput;
7764 +
7765 +       err = init_inode(inode, proc_dentry);
7766 +       if(err) 
7767 +               goto out_put;
7768 +       
7769 +       hppfs_read_inode(inode);
7770 +
7771 +       d_add(dentry, inode);
7772 +       dentry->d_op = &hppfs_dentry_ops;
7773 +       return(NULL);
7774 +
7775 + out_put:
7776 +       iput(inode);
7777 + out_dput:
7778 +       dput(proc_dentry);
7779 + out:
7780 +       return(ERR_PTR(err));
7781 +}
7782 +
7783 +static struct inode_operations hppfs_file_iops = {
7784 +};
7785 +
7786 +static ssize_t read_proc(struct file *file, char *buf, ssize_t count, 
7787 +                        loff_t *ppos, int is_user)
7788 +{
7789 +       ssize_t (*read)(struct file *, char *, size_t, loff_t *);
7790 +       ssize_t n;
7791 +
7792 +       read = file->f_dentry->d_inode->i_fop->read;
7793 +
7794 +       if(!is_user)
7795 +               set_fs(KERNEL_DS);
7796 +               
7797 +       n = (*read)(file, buf, count, &file->f_pos);
7798 +
7799 +       if(!is_user)
7800 +               set_fs(USER_DS);
7801 +
7802 +       if(ppos) *ppos = file->f_pos;
7803 +       return(n);
7804 +}
7805 +
7806 +static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
7807 +{
7808 +       ssize_t n;
7809 +       int cur, err;
7810 +       char *new_buf;
7811 +
7812 +       n = -ENOMEM;
7813 +       new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
7814 +       if(new_buf == NULL){
7815 +               printk("hppfs_read_file : kmalloc failed\n");
7816 +               goto out;
7817 +       }
7818 +       n = 0;
7819 +       while(count > 0){
7820 +               cur = min_t(ssize_t, count, PAGE_SIZE);
7821 +               err = os_read_file(fd, new_buf, cur);
7822 +               if(err < 0){
7823 +                       printk("hppfs_read : read failed, errno = %d\n",
7824 +                              count);
7825 +                       n = err;
7826 +                       goto out_free;
7827 +               }
7828 +               else if(err == 0)
7829 +                       break;
7830 +
7831 +               if(copy_to_user(buf, new_buf, err)){
7832 +                       n = -EFAULT;
7833 +                       goto out_free;
7834 +               }
7835 +               n += err;
7836 +               count -= err;
7837 +       }
7838 + out_free:
7839 +       kfree(new_buf);
7840 + out:
7841 +       return(n);
7842 +}
7843 +
7844 +static ssize_t hppfs_read(struct file *file, char *buf, size_t count, 
7845 +                         loff_t *ppos)
7846 +{
7847 +       struct hppfs_private *hppfs = file->private_data;
7848 +       struct hppfs_data *data;
7849 +       loff_t off;
7850 +       int err;
7851 +
7852 +       if(hppfs->contents != NULL){
7853 +               if(*ppos >= hppfs->len) return(0);
7854 +
7855 +               data = hppfs->contents;
7856 +               off = *ppos;
7857 +               while(off >= sizeof(data->contents)){
7858 +                       data = list_entry(data->list.next, struct hppfs_data,
7859 +                                         list);
7860 +                       off -= sizeof(data->contents);
7861 +               }
7862 +
7863 +               if(off + count > hppfs->len)
7864 +                       count = hppfs->len - off;
7865 +               copy_to_user(buf, &data->contents[off], count);
7866 +               *ppos += count;
7867 +       }
7868 +       else if(hppfs->host_fd != -1){
7869 +               err = os_seek_file(hppfs->host_fd, *ppos);
7870 +               if(err){
7871 +                       printk("hppfs_read : seek failed, errno = %d\n", err);
7872 +                       return(err);
7873 +               }
7874 +               count = hppfs_read_file(hppfs->host_fd, buf, count);
7875 +               if(count > 0)
7876 +                       *ppos += count;
7877 +       }
7878 +       else count = read_proc(&hppfs->proc_file, buf, count, ppos, 1);
7879 +
7880 +       return(count);
7881 +}
7882 +
7883 +static ssize_t hppfs_write(struct file *file, const char *buf, size_t len, 
7884 +                          loff_t *ppos)
7885 +{
7886 +       struct hppfs_private *data = file->private_data;
7887 +       struct file *proc_file = &data->proc_file;
7888 +       ssize_t (*write)(struct file *, const char *, size_t, loff_t *);
7889 +       int err;
7890 +
7891 +       write = proc_file->f_dentry->d_inode->i_fop->write;
7892 +
7893 +       proc_file->f_pos = file->f_pos;
7894 +       err = (*write)(proc_file, buf, len, &proc_file->f_pos);
7895 +       file->f_pos = proc_file->f_pos;
7896 +
7897 +       return(err);
7898 +}
7899 +
7900 +static int open_host_sock(char *host_file, int *filter_out)
7901 +{
7902 +       char *end;
7903 +       int fd;
7904 +
7905 +       end = &host_file[strlen(host_file)];
7906 +       strcpy(end, "/rw");
7907 +       *filter_out = 1;
7908 +       fd = os_connect_socket(host_file);
7909 +       if(fd > 0)
7910 +               return(fd);
7911 +
7912 +       strcpy(end, "/r");
7913 +       *filter_out = 0;
7914 +       fd = os_connect_socket(host_file);
7915 +       return(fd);
7916 +}
7917 +
7918 +static void free_contents(struct hppfs_data *head)
7919 +{
7920 +       struct hppfs_data *data;
7921 +       struct list_head *ele, *next;
7922 +
7923 +       if(head == NULL) return;
7924 +
7925 +       list_for_each_safe(ele, next, &head->list){
7926 +               data = list_entry(ele, struct hppfs_data, list);
7927 +               kfree(data);
7928 +       }
7929 +       kfree(head);
7930 +}
7931 +
7932 +static struct hppfs_data *hppfs_get_data(int fd, int filter, 
7933 +                                        struct file *proc_file, 
7934 +                                        struct file *hppfs_file, 
7935 +                                        loff_t *size_out)
7936 +{
7937 +       struct hppfs_data *data, *new, *head;
7938 +       int n, err;
7939 +
7940 +       err = -ENOMEM;
7941 +       data = kmalloc(sizeof(*data), GFP_KERNEL);
7942 +       if(data == NULL){
7943 +               printk("hppfs_get_data : head allocation failed\n");
7944 +               goto failed;
7945 +       }
7946 +
7947 +       INIT_LIST_HEAD(&data->list);
7948 +
7949 +       head = data;
7950 +       *size_out = 0;
7951 +
7952 +       if(filter){
7953 +               while((n = read_proc(proc_file, data->contents,
7954 +                                    sizeof(data->contents), NULL, 0)) > 0)
7955 +                       os_write_file(fd, data->contents, n);
7956 +               err = os_shutdown_socket(fd, 0, 1);
7957 +               if(err){
7958 +                       printk("hppfs_get_data : failed to shut down "
7959 +                              "socket\n");
7960 +                       goto failed_free;
7961 +               }
7962 +       }
7963 +       while(1){
7964 +               n = os_read_file(fd, data->contents, sizeof(data->contents));
7965 +               if(n < 0){
7966 +                       err = n;
7967 +                       printk("hppfs_get_data : read failed, errno = %d\n",
7968 +                              err);
7969 +                       goto failed_free;
7970 +               }
7971 +               else if(n == 0)
7972 +                       break;
7973 +
7974 +               *size_out += n;
7975 +
7976 +               if(n < sizeof(data->contents))
7977 +                       break;
7978 +
7979 +               new = kmalloc(sizeof(*data), GFP_KERNEL);
7980 +               if(new == 0){
7981 +                       printk("hppfs_get_data : data allocation failed\n");
7982 +                       err = -ENOMEM;
7983 +                       goto failed_free;
7984 +               }
7985 +       
7986 +               INIT_LIST_HEAD(&new->list);
7987 +               list_add(&new->list, &data->list);
7988 +               data = new;
7989 +       }
7990 +       return(head);
7991 +
7992 + failed_free:
7993 +       free_contents(head);
7994 + failed:               
7995 +       return(ERR_PTR(err));
7996 +}
7997 +
7998 +static struct hppfs_private *hppfs_data(void)
7999 +{
8000 +       struct hppfs_private *data;
8001 +
8002 +       data = kmalloc(sizeof(*data), GFP_KERNEL);
8003 +       if(data == NULL)
8004 +               return(data);
8005 +
8006 +       *data = ((struct hppfs_private ) { .host_fd             = -1,
8007 +                                          .len                 = -1,
8008 +                                          .contents            = NULL } );
8009 +       return(data);
8010 +}
8011 +
8012 +static int file_mode(int fmode)
8013 +{
8014 +       if(fmode == (FMODE_READ | FMODE_WRITE))
8015 +               return(O_RDWR);
8016 +       if(fmode == FMODE_READ)
8017 +               return(O_RDONLY);
8018 +       if(fmode == FMODE_WRITE)
8019 +               return(O_WRONLY);
8020 +       return(0);
8021 +}
8022 +
8023 +static int hppfs_open(struct inode *inode, struct file *file)
8024 +{
8025 +       struct hppfs_private *data;
8026 +       struct dentry *proc_dentry;
8027 +       char *host_file;
8028 +       int err, fd, type, filter;
8029 +
8030 +       err = -ENOMEM;
8031 +       data = hppfs_data();
8032 +       if(data == NULL)
8033 +               goto out;
8034 +
8035 +       host_file = dentry_name(file->f_dentry, strlen("/rw"));
8036 +       if(host_file == NULL)
8037 +               goto out_free2;
8038 +
8039 +       proc_dentry = HPPFS_I(inode)->proc_dentry;
8040 +
8041 +       /* XXX This isn't closed anywhere */
8042 +       err = open_private_file(&data->proc_file, proc_dentry, 
8043 +                               file_mode(file->f_mode));
8044 +       if(err)
8045 +               goto out_free1;
8046 +
8047 +       type = os_file_type(host_file);
8048 +       if(type == OS_TYPE_FILE){
8049 +               fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
8050 +               if(fd >= 0) 
8051 +                       data->host_fd = fd;
8052 +               else printk("hppfs_open : failed to open '%s', errno = %d\n",
8053 +                           host_file, -fd);
8054 +
8055 +               data->contents = NULL;
8056 +       }
8057 +       else if(type == OS_TYPE_DIR){
8058 +               fd = open_host_sock(host_file, &filter);
8059 +               if(fd > 0){
8060 +                       data->contents = hppfs_get_data(fd, filter, 
8061 +                                                       &data->proc_file, 
8062 +                                                       file, &data->len);
8063 +                       if(!IS_ERR(data->contents))
8064 +                               data->host_fd = fd;
8065 +               }
8066 +               else printk("hppfs_open : failed to open a socket in "
8067 +                           "'%s', errno = %d\n", host_file, -fd);
8068 +       }
8069 +       kfree(host_file);
8070 +
8071 +       file->private_data = data;
8072 +       return(0);
8073 +
8074 + out_free1:
8075 +       kfree(host_file);
8076 + out_free2:
8077 +       free_contents(data->contents);
8078 +       kfree(data);
8079 + out:
8080 +       return(err);
8081 +}
8082 +
8083 +static int hppfs_dir_open(struct inode *inode, struct file *file)
8084 +{
8085 +       struct hppfs_private *data;
8086 +       struct dentry *proc_dentry;
8087 +       int err;
8088 +
8089 +       err = -ENOMEM;
8090 +       data = hppfs_data();
8091 +       if(data == NULL)
8092 +               goto out;
8093 +
8094 +       proc_dentry = HPPFS_I(inode)->proc_dentry;
8095 +       err = open_private_file(&data->proc_file, proc_dentry, 
8096 +                               file_mode(file->f_mode));
8097 +       if(err)
8098 +               goto out_free;
8099 +
8100 +       file->private_data = data;
8101 +       return(0);
8102 +
8103 + out_free:
8104 +       kfree(data);
8105 + out:
8106 +       return(err);
8107 +}
8108 +
8109 +static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
8110 +{
8111 +       struct hppfs_private *data = file->private_data;
8112 +       struct file *proc_file = &data->proc_file;
8113 +       loff_t (*llseek)(struct file *, loff_t, int);
8114 +       loff_t ret;
8115 +
8116 +       llseek = proc_file->f_dentry->d_inode->i_fop->llseek;
8117 +       if(llseek != NULL){
8118 +               ret = (*llseek)(proc_file, off, where);
8119 +               if(ret < 0)
8120 +                       return(ret);
8121 +       }
8122 +
8123 +       return(default_llseek(file, off, where));
8124 +}
8125 +
8126 +static struct file_operations hppfs_file_fops = {
8127 +       .owner          = NULL,
8128 +       .llseek         = hppfs_llseek,
8129 +       .read           = hppfs_read,
8130 +       .write          = hppfs_write,
8131 +       .open           = hppfs_open,
8132 +};
8133 +
8134 +struct hppfs_dirent {
8135 +       void *vfs_dirent;
8136 +       filldir_t filldir;
8137 +       struct dentry *dentry;
8138 +};
8139 +
8140 +static int hppfs_filldir(void *d, const char *name, int size, 
8141 +                        loff_t offset, ino_t inode, unsigned int type)
8142 +{
8143 +       struct hppfs_dirent *dirent = d;
8144 +
8145 +       if(file_removed(dirent->dentry, name))
8146 +               return(0);
8147 +
8148 +       return((*dirent->filldir)(dirent->vfs_dirent, name, size, offset, 
8149 +                                 inode, type));
8150 +}
8151 +
8152 +static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
8153 +{
8154 +       struct hppfs_private *data = file->private_data;
8155 +       struct file *proc_file = &data->proc_file;
8156 +       int (*readdir)(struct file *, void *, filldir_t);
8157 +       struct hppfs_dirent dirent = ((struct hppfs_dirent)
8158 +                                     { .vfs_dirent     = ent,
8159 +                                       .filldir        = filldir,
8160 +                                       .dentry         = file->f_dentry } );
8161 +       int err;
8162 +
8163 +       readdir = proc_file->f_dentry->d_inode->i_fop->readdir;
8164 +
8165 +       proc_file->f_pos = file->f_pos;
8166 +       err = (*readdir)(proc_file, &dirent, hppfs_filldir);
8167 +       file->f_pos = proc_file->f_pos;
8168 +
8169 +       return(err);
8170 +}
8171 +
8172 +static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync)
8173 +{
8174 +       return(0);
8175 +}
8176 +
8177 +static struct file_operations hppfs_dir_fops = {
8178 +       .owner          = NULL,
8179 +       .readdir        = hppfs_readdir,
8180 +       .open           = hppfs_dir_open,
8181 +       .fsync          = hppfs_fsync,
8182 +};
8183 +
8184 +static int hppfs_statfs(struct super_block *sb, struct kstatfs *sf)
8185 +{
8186 +       sf->f_blocks = 0;
8187 +       sf->f_bfree = 0;
8188 +       sf->f_bavail = 0;
8189 +       sf->f_files = 0;
8190 +       sf->f_ffree = 0;
8191 +       sf->f_type = HPPFS_SUPER_MAGIC;
8192 +       return(0);
8193 +}
8194 +
8195 +static struct inode *hppfs_alloc_inode(struct super_block *sb)
8196 +{
8197 +       struct hppfs_inode_info *hi;
8198 +
8199 +       hi = kmalloc(sizeof(*hi), GFP_KERNEL);
8200 +       if(hi == NULL) 
8201 +               return(NULL);
8202 +
8203 +       *hi = ((struct hppfs_inode_info) { .proc_dentry = NULL });
8204 +       inode_init_once(&hi->vfs_inode);
8205 +       return(&hi->vfs_inode);
8206 +}
8207 +
8208 +void hppfs_delete_inode(struct inode *ino)
8209 +{
8210 +       clear_inode(ino);
8211 +}
8212 +
8213 +static void hppfs_destroy_inode(struct inode *inode)
8214 +{
8215 +       kfree(HPPFS_I(inode));
8216 +}
8217 +
8218 +static struct super_operations hppfs_sbops = { 
8219 +       .alloc_inode    = hppfs_alloc_inode,
8220 +       .destroy_inode  = hppfs_destroy_inode,
8221 +       .read_inode     = hppfs_read_inode,
8222 +       .delete_inode   = hppfs_delete_inode,
8223 +       .statfs         = hppfs_statfs,
8224 +};
8225 +
8226 +static int hppfs_readlink(struct dentry *dentry, char *buffer, int buflen)
8227 +{
8228 +       struct file proc_file;
8229 +       struct dentry *proc_dentry;
8230 +       int (*readlink)(struct dentry *, char *, int);
8231 +       int err, n;
8232 +
8233 +       proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
8234 +       err = open_private_file(&proc_file, proc_dentry, O_RDONLY);
8235 +       if(err) 
8236 +               return(err);
8237 +
8238 +       readlink = proc_dentry->d_inode->i_op->readlink;
8239 +       n = (*readlink)(proc_dentry, buffer, buflen);
8240 +
8241 +       close_private_file(&proc_file);
8242 +       
8243 +       return(n);
8244 +}
8245 +
8246 +static int hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
8247 +{
8248 +       struct file proc_file;
8249 +       struct dentry *proc_dentry;
8250 +       int (*follow_link)(struct dentry *, struct nameidata *);
8251 +       int err, n;
8252 +
8253 +       proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
8254 +       err = open_private_file(&proc_file, proc_dentry, O_RDONLY);
8255 +       if(err) 
8256 +               return(err);
8257 +
8258 +       follow_link = proc_dentry->d_inode->i_op->follow_link;
8259 +       n = (*follow_link)(proc_dentry, nd);
8260 +
8261 +       close_private_file(&proc_file);
8262 +       
8263 +       return(n);
8264 +}
8265 +
8266 +static struct inode_operations hppfs_dir_iops = {
8267 +       .lookup         = hppfs_lookup,
8268 +};
8269 +
8270 +static struct inode_operations hppfs_link_iops = {
8271 +       .readlink       = hppfs_readlink,
8272 +       .follow_link    = hppfs_follow_link,
8273 +};
8274 +
8275 +static int init_inode(struct inode *inode, struct dentry *dentry)
8276 +{
8277 +       if(S_ISDIR(dentry->d_inode->i_mode)){
8278 +               inode->i_op = &hppfs_dir_iops;
8279 +               inode->i_fop = &hppfs_dir_fops;
8280 +       }
8281 +       else if(S_ISLNK(dentry->d_inode->i_mode)){
8282 +               inode->i_op = &hppfs_link_iops;
8283 +               inode->i_fop = &hppfs_file_fops;
8284 +       }
8285 +       else {
8286 +               inode->i_op = &hppfs_file_iops;
8287 +               inode->i_fop = &hppfs_file_fops;
8288 +       }
8289 +
8290 +       HPPFS_I(inode)->proc_dentry = dentry;
8291 +
8292 +       return(0);
8293 +}
8294 +
8295 +static int hppfs_fill_super(struct super_block *sb, void *d, int silent)
8296 +{
8297 +       struct inode *root_inode;
8298 +       struct file_system_type *procfs;
8299 +       struct super_block *proc_sb;
8300 +       int err;
8301 +
8302 +       err = -ENOENT;
8303 +       procfs = get_fs_type("proc");
8304 +       if(procfs == NULL) 
8305 +               goto out;
8306 +
8307 +       if(list_empty(&procfs->fs_supers))
8308 +               goto out;
8309 +
8310 +       proc_sb = list_entry(procfs->fs_supers.next, struct super_block,
8311 +                            s_instances);
8312 +       
8313 +       sb->s_blocksize = 1024;
8314 +       sb->s_blocksize_bits = 10;
8315 +       sb->s_magic = HPPFS_SUPER_MAGIC;
8316 +       sb->s_op = &hppfs_sbops;
8317 +
8318 +       root_inode = iget(sb, 0);
8319 +       if(root_inode == NULL)
8320 +               goto out;
8321 +
8322 +       err = init_inode(root_inode, proc_sb->s_root);
8323 +       if(err)
8324 +               goto out_put;
8325 +
8326 +       err = -ENOMEM;
8327 +       sb->s_root = d_alloc_root(root_inode);
8328 +       if(sb->s_root == NULL)
8329 +               goto out_put;
8330 +
8331 +       hppfs_read_inode(root_inode);
8332 +
8333 +       return(0);
8334 +
8335 + out_put:
8336 +       iput(root_inode);
8337 + out:
8338 +       return(err);
8339 +}
8340 +
8341 +static struct super_block *hppfs_read_super(struct file_system_type *type,
8342 +                                            int flags, const char *dev_name,
8343 +                                            void *data)
8344 +{
8345 +       return(get_sb_nodev(type, flags, data, hppfs_fill_super));
8346 +}
8347 +
8348 +static struct file_system_type hppfs_type = {
8349 +       .owner          = THIS_MODULE,
8350 +       .name           = "hppfs",
8351 +       .get_sb         = hppfs_read_super,
8352 +       .kill_sb        = kill_anon_super,
8353 +       .fs_flags       = 0,
8354 +};
8355 +
8356 +static int __init init_hppfs(void)
8357 +{
8358 +       return(register_filesystem(&hppfs_type));
8359 +}
8360 +
8361 +static void __exit exit_hppfs(void)
8362 +{
8363 +       unregister_filesystem(&hppfs_type);
8364 +}
8365 +
8366 +module_init(init_hppfs)
8367 +module_exit(exit_hppfs)
8368 +MODULE_LICENSE("GPL");
8369 +
8370 +/*
8371 + * Overrides for Emacs so that we follow Linus's tabbing style.
8372 + * Emacs will notice this stuff at the end of the file and automatically
8373 + * adjust the settings for this buffer only.  This must remain at the end
8374 + * of the file.
8375 + * ---------------------------------------------------------------------------
8376 + * Local variables:
8377 + * c-file-style: "linux"
8378 + * End:
8379 + */
8380 diff -Naur a/include/asm-um/archparam-i386.h b/include/asm-um/archparam-i386.h
8381 --- a/include/asm-um/archparam-i386.h   Tue Sep  9 16:45:45 2003
8382 +++ b/include/asm-um/archparam-i386.h   Tue Sep  9 16:50:12 2003
8383 @@ -56,6 +56,65 @@
8384         pr_reg[16] = PT_REGS_SS(regs);          \
8385  } while(0);
8386  
8387 +#define VSYSCALL_BASE  (__fix_to_virt(FIX_VSYSCALL))
8388 +#define VSYSCALL_EHDR  ((const struct elfhdr *) VSYSCALL_BASE)
8389 +#define VSYSCALL_ENTRY ((unsigned long) &__kernel_vsyscall)
8390 +extern void *__kernel_vsyscall;
8391 +
8392 +/*
8393 + * Architecture-neutral AT_ values in 0-17, leave some room
8394 + * for more of them, start the x86-specific ones at 32.
8395 + */
8396 +#define AT_SYSINFO             32
8397 +#define AT_SYSINFO_EHDR                33
8398 +
8399 +#define ARCH_DLINFO                                            \
8400 +do {                                                           \
8401 +               NEW_AUX_ENT(AT_SYSINFO, VSYSCALL_ENTRY);        \
8402 +               NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE);    \
8403 +} while (0)
8404 +
8405 +/*
8406 + * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out
8407 + * extra segments containing the vsyscall DSO contents.  Dumping its
8408 + * contents makes post-mortem fully interpretable later without matching up
8409 + * the same kernel and hardware config to see what PC values meant.
8410 + * Dumping its extra ELF program headers includes all the other information
8411 + * a debugger needs to easily find how the vsyscall DSO was being used.
8412 + */
8413 +#define ELF_CORE_EXTRA_PHDRS           (VSYSCALL_EHDR->e_phnum)
8414 +#define ELF_CORE_WRITE_EXTRA_PHDRS                                           \
8415 +do {                                                                         \
8416 +       const struct elf_phdr *const vsyscall_phdrs =                         \
8417 +               (const struct elf_phdr *) (VSYSCALL_BASE                      \
8418 +                                          + VSYSCALL_EHDR->e_phoff);         \
8419 +       int i;                                                                \
8420 +       Elf32_Off ofs = 0;                                                    \
8421 +       for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {                        \
8422 +               struct elf_phdr phdr = vsyscall_phdrs[i];                     \
8423 +               if (phdr.p_type == PT_LOAD) {                                 \
8424 +                       ofs = phdr.p_offset = offset;                         \
8425 +                       offset += phdr.p_filesz;                              \
8426 +               }                                                             \
8427 +               else                                                          \
8428 +                       phdr.p_offset += ofs;                                 \
8429 +               phdr.p_paddr = 0; /* match other core phdrs */                \
8430 +               DUMP_WRITE(&phdr, sizeof(phdr));                              \
8431 +       }                                                                     \
8432 +} while (0)
8433 +#define ELF_CORE_WRITE_EXTRA_DATA                                            \
8434 +do {                                                                         \
8435 +       const struct elf_phdr *const vsyscall_phdrs =                         \
8436 +               (const struct elf_phdr *) (VSYSCALL_BASE                      \
8437 +                                          + VSYSCALL_EHDR->e_phoff);         \
8438 +       int i;                                                                \
8439 +       for (i = 0; i < VSYSCALL_EHDR->e_phnum; ++i) {                        \
8440 +               if (vsyscall_phdrs[i].p_type == PT_LOAD)                      \
8441 +                       DUMP_WRITE((void *) vsyscall_phdrs[i].p_vaddr,        \
8442 +                                  vsyscall_phdrs[i].p_filesz);               \
8443 +       }                                                                     \
8444 +} while (0)
8445 +
8446  /********* Bits for asm-um/delay.h **********/
8447  
8448  typedef unsigned long um_udelay_t;
8449 diff -Naur a/include/asm-um/common.lds.S b/include/asm-um/common.lds.S
8450 --- a/include/asm-um/common.lds.S       Tue Sep  9 16:41:45 2003
8451 +++ b/include/asm-um/common.lds.S       Tue Sep  9 16:47:55 2003
8452 @@ -1,3 +1,5 @@
8453 +#include <asm-generic/vmlinux.lds.h>
8454 +
8455    .fini      : { *(.fini)    } =0x9090
8456    _etext = .;
8457    PROVIDE (etext = .);
8458 @@ -67,6 +69,10 @@
8459    }
8460    __initcall_end = .;
8461  
8462 +  __con_initcall_start = .;
8463 +  .con_initcall.init : { *(.con_initcall.init) }
8464 +  __con_initcall_end = .;
8465 +
8466    __uml_initcall_start = .;
8467    .uml.initcall.init : { *(.uml.initcall.init) }
8468    __uml_initcall_end = .;
8469 @@ -80,7 +86,33 @@
8470    .uml.exitcall : { *(.uml.exitcall.exit) }
8471    __uml_exitcall_end = .;
8472  
8473 -  . = ALIGN(4096);
8474 +  . = ALIGN(4);
8475 +  __alt_instructions = .;
8476 +  .altinstructions : { *(.altinstructions) } 
8477 +  __alt_instructions_end = .; 
8478 +  .altinstr_replacement : { *(.altinstr_replacement) } 
8479 +  /* .exit.text is discard at runtime, not link time, to deal with references
8480 +     from .altinstructions and .eh_frame */
8481 +  .exit.text : { *(.exit.text) }
8482 +  .exit.data : { *(.exit.data) }
8483
8484 +  __preinit_array_start = .;
8485 +  .preinit_array : { *(.preinit_array) }
8486 +  __preinit_array_end = .;
8487 +  __init_array_start = .;
8488 +  .init_array : { *(.init_array) }
8489 +  __init_array_end = .;
8490 +  __fini_array_start = .;
8491 +  .fini_array : { *(.fini_array) }
8492 +  __fini_array_end = .;
8493 +
8494 +   . = ALIGN(4096);
8495    __initramfs_start = .;
8496    .init.ramfs : { *(.init.ramfs) }
8497    __initramfs_end = .;
8498 +
8499 +  /* Sections to be discarded */
8500 +  /DISCARD/ : {
8501 +       *(.exitcall.exit)
8502 +  }
8503
8504 diff -Naur a/include/asm-um/cpufeature.h b/include/asm-um/cpufeature.h
8505 --- a/include/asm-um/cpufeature.h       Wed Dec 31 19:00:00 1969
8506 +++ b/include/asm-um/cpufeature.h       Tue Sep  9 16:47:22 2003
8507 @@ -0,0 +1,6 @@
8508 +#ifndef __UM_CPUFEATURE_H
8509 +#define __UM_CPUFEATURE_H
8510 +
8511 +#include "asm/arch/cpufeature.h"
8512 +
8513 +#endif
8514 diff -Naur a/include/asm-um/current.h b/include/asm-um/current.h
8515 --- a/include/asm-um/current.h  Tue Sep  9 16:41:22 2003
8516 +++ b/include/asm-um/current.h  Tue Sep  9 16:47:29 2003
8517 @@ -16,8 +16,10 @@
8518  #define CURRENT_THREAD(dummy) (((unsigned long) &dummy) & \
8519                                 (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER))
8520  
8521 -#define current ({ int dummy; \
8522 -                   ((struct thread_info *) CURRENT_THREAD(dummy))->task; })
8523 +#define current_thread \
8524 +       ({ int dummy; ((struct thread_info *) CURRENT_THREAD(dummy)); })
8525 +
8526 +#define current (current_thread->task)
8527  
8528  #endif /* __ASSEMBLY__ */
8529  
8530 diff -Naur a/include/asm-um/fixmap.h b/include/asm-um/fixmap.h
8531 --- a/include/asm-um/fixmap.h   Tue Sep  9 16:46:00 2003
8532 +++ b/include/asm-um/fixmap.h   Tue Sep  9 16:51:02 2003
8533 @@ -34,6 +34,7 @@
8534         FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
8535         FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
8536  #endif
8537 +       FIX_VSYSCALL,
8538         __end_of_fixed_addresses
8539  };
8540  
8541 @@ -63,6 +64,13 @@
8542  #define __fix_to_virt(x)       (FIXADDR_TOP - ((x) << PAGE_SHIFT))
8543  #define __virt_to_fix(x)      ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
8544  
8545 +/*
8546 + * This is the range that is readable by user mode, and things
8547 + * acting like user mode such as get_user_pages.
8548 + */
8549 +#define FIXADDR_USER_START     (__fix_to_virt(FIX_VSYSCALL))
8550 +#define FIXADDR_USER_END       (FIXADDR_USER_START + PAGE_SIZE)
8551 +
8552  extern void __this_fixmap_does_not_exist(void);
8553  
8554  /*
8555 diff -Naur a/include/asm-um/irq.h b/include/asm-um/irq.h
8556 --- a/include/asm-um/irq.h      Tue Sep  9 16:46:09 2003
8557 +++ b/include/asm-um/irq.h      Tue Sep  9 16:51:12 2003
8558 @@ -1,15 +1,6 @@
8559  #ifndef __UM_IRQ_H
8560  #define __UM_IRQ_H
8561  
8562 -/* The i386 irq.h has a struct task_struct in a prototype without including
8563 - * sched.h.  This forward declaration kills the resulting warning.
8564 - */
8565 -struct task_struct;
8566 -
8567 -#include "asm/ptrace.h"
8568 -
8569 -#undef NR_IRQS
8570 -
8571  #define TIMER_IRQ              0
8572  #define UMN_IRQ                        1
8573  #define CONSOLE_IRQ            2
8574 @@ -28,8 +19,4 @@
8575  #define LAST_IRQ XTERM_IRQ
8576  #define NR_IRQS (LAST_IRQ + 1)
8577  
8578 -extern int um_request_irq(unsigned int irq, int fd, int type,
8579 -                         void (*handler)(int, void *, struct pt_regs *),
8580 -                         unsigned long irqflags,  const char * devname,
8581 -                         void *dev_id);
8582  #endif
8583 diff -Naur a/include/asm-um/local.h b/include/asm-um/local.h
8584 --- a/include/asm-um/local.h    Wed Dec 31 19:00:00 1969
8585 +++ b/include/asm-um/local.h    Tue Sep  9 16:49:26 2003
8586 @@ -0,0 +1,6 @@
8587 +#ifndef __UM_LOCAL_H
8588 +#define __UM_LOCAL_H
8589 +
8590 +#include "asm/arch/local.h"
8591 +
8592 +#endif
8593 diff -Naur a/include/asm-um/module-generic.h b/include/asm-um/module-generic.h
8594 --- a/include/asm-um/module-generic.h   Wed Dec 31 19:00:00 1969
8595 +++ b/include/asm-um/module-generic.h   Tue Sep  9 16:49:17 2003
8596 @@ -0,0 +1,6 @@
8597 +#ifndef __UM_MODULE_GENERIC_H
8598 +#define __UM_MODULE_GENERIC_H
8599 +
8600 +#include "asm/arch/module.h"
8601 +
8602 +#endif
8603 diff -Naur a/include/asm-um/module-i386.h b/include/asm-um/module-i386.h
8604 --- a/include/asm-um/module-i386.h      Wed Dec 31 19:00:00 1969
8605 +++ b/include/asm-um/module-i386.h      Tue Sep  9 16:49:10 2003
8606 @@ -0,0 +1,13 @@
8607 +#ifndef __UM_MODULE_I386_H
8608 +#define __UM_MODULE_I386_H
8609 +
8610 +/* UML is simple */
8611 +struct mod_arch_specific
8612 +{
8613 +};
8614 +
8615 +#define Elf_Shdr Elf32_Shdr
8616 +#define Elf_Sym Elf32_Sym
8617 +#define Elf_Ehdr Elf32_Ehdr
8618 +
8619 +#endif
8620 diff -Naur a/include/asm-um/page.h b/include/asm-um/page.h
8621 --- a/include/asm-um/page.h     Tue Sep  9 16:43:32 2003
8622 +++ b/include/asm-um/page.h     Tue Sep  9 16:49:19 2003
8623 @@ -4,7 +4,6 @@
8624  struct page;
8625  
8626  #include "asm/arch/page.h"
8627 -#include "asm/bug.h"
8628  
8629  #undef __pa
8630  #undef __va
8631 diff -Naur a/include/asm-um/pgtable.h b/include/asm-um/pgtable.h
8632 --- a/include/asm-um/pgtable.h  Tue Sep  9 16:46:25 2003
8633 +++ b/include/asm-um/pgtable.h  Tue Sep  9 16:51:24 2003
8634 @@ -79,12 +79,13 @@
8635  
8636  #define _PAGE_PRESENT  0x001
8637  #define _PAGE_NEWPAGE  0x002
8638 -#define _PAGE_PROTNONE 0x004   /* If not present */
8639 -#define _PAGE_RW       0x008
8640 -#define _PAGE_USER     0x010
8641 -#define _PAGE_ACCESSED 0x020
8642 -#define _PAGE_DIRTY    0x040
8643 -#define _PAGE_NEWPROT   0x080
8644 +#define _PAGE_NEWPROT   0x004
8645 +#define _PAGE_FILE     0x008   /* set:pagecache unset:swap */
8646 +#define _PAGE_PROTNONE 0x010   /* If not present */
8647 +#define _PAGE_RW       0x020
8648 +#define _PAGE_USER     0x040
8649 +#define _PAGE_ACCESSED 0x080
8650 +#define _PAGE_DIRTY    0x100
8651  
8652  #define REGION_MASK    0xf0000000
8653  #define REGION_SHIFT   28
8654 @@ -203,6 +204,16 @@
8655  #define pfn_pte(pfn, prot) __pte(pfn_to_phys(pfn) | pgprot_val(prot))
8656  #define pfn_pmd(pfn, prot) __pmd(pfn_to_phys(pfn) | pgprot_val(prot))
8657  
8658 +/*
8659 + * Bits 0 through 3 are taken
8660 + */
8661 +#define PTE_FILE_MAX_BITS      28
8662 +
8663 +#define pte_to_pgoff(pte) ((pte).pte_low >> 4)
8664 +
8665 +#define pgoff_to_pte(off) \
8666 +       ((pte_t) { ((off) << 4) + _PAGE_FILE })
8667 +
8668  static inline pte_t pte_mknewprot(pte_t pte)
8669  {
8670         pte_val(pte) |= _PAGE_NEWPROT;
8671 @@ -236,6 +247,12 @@
8672   * The following only work if pte_present() is true.
8673   * Undefined behaviour if not..
8674   */
8675 +static inline int pte_user(pte_t pte)
8676 +{ 
8677 +       return((pte_val(pte) & _PAGE_USER) && 
8678 +              !(pte_val(pte) & _PAGE_PROTNONE));
8679 +}
8680 +
8681  static inline int pte_read(pte_t pte)
8682  { 
8683         return((pte_val(pte) & _PAGE_USER) && 
8684 @@ -253,6 +270,14 @@
8685                !(pte_val(pte) & _PAGE_PROTNONE));
8686  }
8687  
8688 +/*
8689 + * The following only works if pte_present() is not true.
8690 + */
8691 +static inline int pte_file(pte_t pte)
8692 +{ 
8693 +       return (pte).pte_low & _PAGE_FILE; 
8694 +}
8695 +
8696  static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; }
8697  static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; }
8698  static inline int pte_newpage(pte_t pte) { return pte_val(pte) & _PAGE_NEWPAGE; }
8699 @@ -355,14 +380,26 @@
8700  #define pmd_page(pmd) (phys_mem_map(pmd_val(pmd) & PAGE_MASK) + \
8701                        ((phys_addr(pmd_val(pmd)) >> PAGE_SHIFT)))
8702  
8703 -/* to find an entry in a page-table-directory. */
8704 +/*
8705 + * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
8706 + *
8707 + * this macro returns the index of the entry in the pgd page which would
8708 + * control the given virtual address
8709 + */
8710  #define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
8711  
8712 -/* to find an entry in a page-table-directory */
8713 +/*
8714 + * pgd_offset() returns a (pgd_t *)
8715 + * pgd_index() is used get the offset into the pgd page's array of pgd_t's;
8716 + */
8717  #define pgd_offset(mm, address) \
8718  ((mm)->pgd + ((address) >> PGDIR_SHIFT))
8719  
8720 -/* to find an entry in a kernel page-table-directory */
8721 +
8722 +/*
8723 + * a shortcut which implies the use of the kernel's pgd, instead
8724 + * of a process's
8725 + */
8726  #define pgd_offset_k(address) pgd_offset(&init_mm, address)
8727  
8728  #define pmd_index(address) \
8729 @@ -374,7 +411,12 @@
8730         return (pmd_t *) dir;
8731  }
8732  
8733 -/* Find an entry in the third-level page table.. */ 
8734 +/*
8735 + * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
8736 + *
8737 + * this macro returns the index of the entry in the pte page which would
8738 + * control the given virtual address
8739 + */
8740  #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
8741  #define pte_offset_kernel(dir, address) \
8742         ((pte_t *) pmd_page_kernel(*(dir)) +  pte_index(address))
8743 @@ -400,11 +442,11 @@
8744  #define update_mmu_cache(vma,address,pte) do ; while (0)
8745  
8746  /* Encode and de-code a swap entry */
8747 -#define __swp_type(x)                  (((x).val >> 3) & 0x7f)
8748 -#define __swp_offset(x)                        ((x).val >> 10)
8749 +#define __swp_type(x)                  (((x).val >> 4) & 0x3f)
8750 +#define __swp_offset(x)                        ((x).val >> 11)
8751  
8752  #define __swp_entry(type, offset) \
8753 -       ((swp_entry_t) { ((type) << 3) | ((offset) << 10) })
8754 +       ((swp_entry_t) { ((type) << 4) | ((offset) << 11) })
8755  #define __pte_to_swp_entry(pte) \
8756         ((swp_entry_t) { pte_val(pte_mkuptodate(pte)) })
8757  #define __swp_entry_to_pte(x)          ((pte_t) { (x).val })
8758 diff -Naur a/include/asm-um/processor-generic.h b/include/asm-um/processor-generic.h
8759 --- a/include/asm-um/processor-generic.h        Tue Sep  9 16:41:42 2003
8760 +++ b/include/asm-um/processor-generic.h        Tue Sep  9 16:47:43 2003
8761 @@ -11,9 +11,7 @@
8762  struct task_struct;
8763  
8764  #include "linux/config.h"
8765 -#include "linux/signal.h"
8766  #include "asm/ptrace.h"
8767 -#include "asm/siginfo.h"
8768  #include "choose-mode.h"
8769  
8770  struct mm_struct;
8771 @@ -101,14 +99,19 @@
8772  } mm_segment_t;
8773  
8774  extern struct task_struct *alloc_task_struct(void);
8775 -extern void free_task_struct(struct task_struct *task);
8776  
8777  extern void release_thread(struct task_struct *);
8778  extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
8779  extern void dump_thread(struct pt_regs *regs, struct user *u);
8780 +extern void prepare_to_copy(struct task_struct *tsk);
8781  
8782  extern unsigned long thread_saved_pc(struct task_struct *t);
8783  
8784 +static inline void mm_copy_segments(struct mm_struct *from_mm, 
8785 +                                   struct mm_struct *new_mm)
8786 +{
8787 +}
8788 +
8789  #define init_stack     (init_thread_union.stack)
8790  
8791  /*
8792 diff -Naur a/include/asm-um/processor-i386.h b/include/asm-um/processor-i386.h
8793 --- a/include/asm-um/processor-i386.h   Tue Sep  9 16:41:17 2003
8794 +++ b/include/asm-um/processor-i386.h   Tue Sep  9 16:47:27 2003
8795 @@ -6,8 +6,8 @@
8796  #ifndef __UM_PROCESSOR_I386_H
8797  #define __UM_PROCESSOR_I386_H
8798  
8799 -extern int cpu_has_xmm;
8800 -extern int cpu_has_cmov;
8801 +extern int host_has_xmm;
8802 +extern int host_has_cmov;
8803  
8804  struct arch_thread {
8805         unsigned long debugregs[8];
8806 diff -Naur a/include/asm-um/sections.h b/include/asm-um/sections.h
8807 --- a/include/asm-um/sections.h Wed Dec 31 19:00:00 1969
8808 +++ b/include/asm-um/sections.h Tue Sep  9 16:49:28 2003
8809 @@ -0,0 +1,7 @@
8810 +#ifndef _UM_SECTIONS_H
8811 +#define _UM_SECTIONS_H
8812 +
8813 +/* nothing to see, move along */
8814 +#include <asm-generic/sections.h>
8815 +
8816 +#endif
8817 diff -Naur a/include/asm-um/smp.h b/include/asm-um/smp.h
8818 --- a/include/asm-um/smp.h      Tue Sep  9 16:41:04 2003
8819 +++ b/include/asm-um/smp.h      Tue Sep  9 16:47:18 2003
8820 @@ -10,7 +10,7 @@
8821  
8822  extern cpumask_t cpu_online_map;
8823  
8824 -#define smp_processor_id() (current->thread_info->cpu)
8825 +#define smp_processor_id() (current_thread->cpu)
8826  #define cpu_logical_map(n) (n)
8827  #define cpu_number_map(n) (n)
8828  #define PROC_CHANGE_PENALTY    15 /* Pick a number, any number */
8829 diff -Naur a/include/asm-um/system-generic.h b/include/asm-um/system-generic.h
8830 --- a/include/asm-um/system-generic.h   Tue Sep  9 16:46:13 2003
8831 +++ b/include/asm-um/system-generic.h   Tue Sep  9 16:51:14 2003
8832 @@ -23,8 +23,10 @@
8833  extern void block_signals(void);
8834  extern void unblock_signals(void);
8835  
8836 -#define local_save_flags(flags) do { (flags) = get_signals(); } while(0)
8837 -#define local_irq_restore(flags) do { set_signals(flags); } while(0)
8838 +#define local_save_flags(flags) do { typecheck(unsigned long, flags); \
8839 +                                    (flags) = get_signals(); } while(0)
8840 +#define local_irq_restore(flags) do { typecheck(unsigned long, flags); \
8841 +                                     set_signals(flags); } while(0)
8842  
8843  #define local_irq_save(flags) do { local_save_flags(flags); \
8844                                     local_irq_disable(); } while(0)
8845 @@ -39,4 +41,7 @@
8846          (flags == 0);                   \
8847  })
8848  
8849 +extern void *_switch_to(void *prev, void *next, void *last);
8850 +#define switch_to(prev, next, last) prev = _switch_to(prev, next, last)
8851 +
8852  #endif
8853 diff -Naur a/include/asm-um/thread_info.h b/include/asm-um/thread_info.h
8854 --- a/include/asm-um/thread_info.h      Tue Sep  9 16:42:02 2003
8855 +++ b/include/asm-um/thread_info.h      Tue Sep  9 16:48:12 2003
8856 @@ -9,6 +9,7 @@
8857  #ifndef __ASSEMBLY__
8858  
8859  #include <asm/processor.h>
8860 +#include <asm/types.h>
8861  
8862  struct thread_info {
8863         struct task_struct      *task;          /* main task structure */
8864 @@ -43,15 +44,18 @@
8865  static inline struct thread_info *current_thread_info(void)
8866  {
8867         struct thread_info *ti;
8868 -       __asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~16383UL));
8869 +       unsigned long mask = PAGE_SIZE * 
8870 +               (1 << CONFIG_KERNEL_STACK_ORDER) - 1;
8871 +       __asm__("andl %%esp,%0; ":"=r" (ti) : "0" (~mask));
8872         return ti;
8873  }
8874  
8875  /* thread information allocation */
8876 -#define THREAD_SIZE (4*PAGE_SIZE)
8877 -#define alloc_thread_info(tsk) ((struct thread_info *) \
8878 -       __get_free_pages(GFP_KERNEL,2))
8879 -#define free_thread_info(ti) free_pages((unsigned long) (ti), 2)
8880 +#define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE)
8881 +#define alloc_thread_info(tsk) \
8882 +       ((struct thread_info *) kmalloc(THREAD_SIZE, GFP_KERNEL))
8883 +#define free_thread_info(ti) kfree(ti)
8884 +       
8885  #define get_thread_info(ti) get_task_struct((ti)->task)
8886  #define put_thread_info(ti) put_task_struct((ti)->task)
8887  
8888 @@ -65,11 +69,13 @@
8889  #define TIF_POLLING_NRFLAG      3       /* true if poll_idle() is polling 
8890                                          * TIF_NEED_RESCHED 
8891                                          */
8892 +#define TIF_RESTART_BLOCK      4
8893  
8894  #define _TIF_SYSCALL_TRACE     (1 << TIF_SYSCALL_TRACE)
8895  #define _TIF_SIGPENDING                (1 << TIF_SIGPENDING)
8896  #define _TIF_NEED_RESCHED      (1 << TIF_NEED_RESCHED)
8897  #define _TIF_POLLING_NRFLAG     (1 << TIF_POLLING_NRFLAG)
8898 +#define _TIF_RESTART_BLOCK     (1 << TIF_RESTART_BLOCK)
8899  
8900  #endif
8901  
8902 diff -Naur a/include/asm-um/timex.h b/include/asm-um/timex.h
8903 --- a/include/asm-um/timex.h    Tue Sep  9 16:43:51 2003
8904 +++ b/include/asm-um/timex.h    Tue Sep  9 16:49:27 2003
8905 @@ -1,8 +1,6 @@
8906  #ifndef __UM_TIMEX_H
8907  #define __UM_TIMEX_H
8908  
8909 -#include "linux/time.h"
8910 -
8911  typedef unsigned long cycles_t;
8912  
8913  #define cacheflush_time (0)
8914 diff -Naur a/include/linux/mm.h b/include/linux/mm.h
8915 --- a/include/linux/mm.h        Tue Sep  9 16:41:15 2003
8916 +++ b/include/linux/mm.h        Tue Sep  9 16:47:26 2003
8917 @@ -487,6 +487,9 @@
8918         return __set_page_dirty_buffers(page);
8919  }
8920  
8921 +extern long do_mprotect(struct mm_struct *mm, unsigned long start, 
8922 +                       size_t len, unsigned long prot);
8923 +
8924  /*
8925   * On a two-level page table, this ends up being trivial. Thus the
8926   * inlining and the symmetry break with pte_alloc_map() that does all
8927 @@ -517,9 +520,10 @@
8928  
8929  extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
8930  
8931 -extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr,
8932 -       unsigned long len, unsigned long prot,
8933 -       unsigned long flag, unsigned long pgoff);
8934 +extern unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file *file, 
8935 +                                  unsigned long addr, unsigned long len,
8936 +                                  unsigned long prot, unsigned long flag,
8937 +                                  unsigned long pgoff);
8938  
8939  static inline unsigned long do_mmap(struct file *file, unsigned long addr,
8940         unsigned long len, unsigned long prot,
8941 @@ -529,7 +533,8 @@
8942         if ((offset + PAGE_ALIGN(len)) < offset)
8943                 goto out;
8944         if (!(offset & ~PAGE_MASK))
8945 -               ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
8946 +               ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flag, 
8947 +                                   offset >> PAGE_SHIFT);
8948  out:
8949         return ret;
8950  }
8951 diff -Naur a/include/linux/proc_mm.h b/include/linux/proc_mm.h
8952 --- a/include/linux/proc_mm.h   Wed Dec 31 19:00:00 1969
8953 +++ b/include/linux/proc_mm.h   Tue Sep  9 16:47:15 2003
8954 @@ -0,0 +1,48 @@
8955 +/* 
8956 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
8957 + * Licensed under the GPL
8958 + */
8959 +
8960 +#ifndef __PROC_MM_H
8961 +#define __PROC_MM_H
8962 +
8963 +#include "linux/sched.h"
8964 +
8965 +#define MM_MMAP 54
8966 +#define MM_MUNMAP 55
8967 +#define MM_MPROTECT 56
8968 +#define MM_COPY_SEGMENTS 57
8969 +
8970 +struct mm_mmap {
8971 +       unsigned long addr;
8972 +       unsigned long len;
8973 +       unsigned long prot;
8974 +       unsigned long flags;
8975 +       unsigned long fd;
8976 +       unsigned long offset;
8977 +};
8978 +
8979 +struct mm_munmap {
8980 +       unsigned long addr;
8981 +       unsigned long len;      
8982 +};
8983 +
8984 +struct mm_mprotect {
8985 +       unsigned long addr;
8986 +       unsigned long len;
8987 +        unsigned int prot;
8988 +};
8989 +
8990 +struct proc_mm_op {
8991 +       int op;
8992 +       union {
8993 +               struct mm_mmap mmap;
8994 +               struct mm_munmap munmap;
8995 +               struct mm_mprotect mprotect;
8996 +               int copy_segments;
8997 +       } u;
8998 +};
8999 +
9000 +extern struct mm_struct *proc_mm_get_mm(int fd);
9001 +
9002 +#endif
9003 diff -Naur a/mm/Makefile b/mm/Makefile
9004 --- a/mm/Makefile       Tue Sep  9 16:43:50 2003
9005 +++ b/mm/Makefile       Tue Sep  9 16:49:26 2003
9006 @@ -12,3 +12,5 @@
9007                            slab.o swap.o truncate.o vmscan.o $(mmu-y)
9008  
9009  obj-$(CONFIG_SWAP)     += page_io.o swap_state.o swapfile.o
9010 +obj-$(CONFIG_PROC_MM)  += proc_mm.o
9011 +
9012 diff -Naur a/mm/memory.c b/mm/memory.c
9013 --- a/mm/memory.c       Tue Sep  9 16:43:03 2003
9014 +++ b/mm/memory.c       Tue Sep  9 16:48:52 2003
9015 @@ -44,6 +44,7 @@
9016  #include <linux/highmem.h>
9017  #include <linux/pagemap.h>
9018  #include <linux/rmap-locking.h>
9019 +#include <linux/init.h>
9020  #include <linux/module.h>
9021  
9022  #include <asm/pgalloc.h>
9023 @@ -673,6 +674,24 @@
9024  }
9025  
9026  
9027 +static struct vm_area_struct fixmap_vma = {
9028 +       /* Catch users - if there are any valid
9029 +          ones, we can make this be "&init_mm" or
9030 +          something.  */
9031 +       .vm_mm = NULL,
9032 +       .vm_page_prot = PAGE_READONLY,
9033 +       .vm_flags = VM_READ | VM_EXEC,
9034 +};
9035 +
9036 +static int init_fixmap_vma(void)
9037 +{
9038 +       fixmap_vma.vm_start = FIXADDR_START;
9039 +       fixmap_vma.vm_end = FIXADDR_TOP;
9040 +       return(0);
9041 +}
9042 +
9043 +__initcall(init_fixmap_vma);
9044 +
9045  int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
9046                 unsigned long start, int len, int write, int force,
9047                 struct page **pages, struct vm_area_struct **vmas)
9048 @@ -693,19 +712,8 @@
9049  
9050                 vma = find_extend_vma(mm, start);
9051  
9052 -#ifdef FIXADDR_USER_START
9053 -               if (!vma &&
9054 -                   start >= FIXADDR_USER_START && start < FIXADDR_USER_END) {
9055 -                       static struct vm_area_struct fixmap_vma = {
9056 -                               /* Catch users - if there are any valid
9057 -                                  ones, we can make this be "&init_mm" or
9058 -                                  something.  */
9059 -                               .vm_mm = NULL,
9060 -                               .vm_start = FIXADDR_USER_START,
9061 -                               .vm_end = FIXADDR_USER_END,
9062 -                               .vm_page_prot = PAGE_READONLY,
9063 -                               .vm_flags = VM_READ | VM_EXEC,
9064 -                       };
9065 +#ifdef FIXADDR_START
9066 +               if (!vma && start >= FIXADDR_START && start < FIXADDR_TOP) {
9067                         unsigned long pg = start & PAGE_MASK;
9068                         pgd_t *pgd;
9069                         pmd_t *pmd;
9070 diff -Naur a/mm/mmap.c b/mm/mmap.c
9071 --- a/mm/mmap.c Tue Sep  9 16:43:49 2003
9072 +++ b/mm/mmap.c Tue Sep  9 16:49:24 2003
9073 @@ -434,11 +434,11 @@
9074   * The caller must hold down_write(current->mm->mmap_sem).
9075   */
9076  
9077 -unsigned long do_mmap_pgoff(struct file * file, unsigned long addr,
9078 -                       unsigned long len, unsigned long prot,
9079 -                       unsigned long flags, unsigned long pgoff)
9080 +unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file * file, 
9081 +                           unsigned long addr, unsigned long len,
9082 +                           unsigned long prot, unsigned long flags,
9083 +                           unsigned long pgoff)
9084  {
9085 -       struct mm_struct * mm = current->mm;
9086         struct vm_area_struct * vma, * prev;
9087         struct inode *inode;
9088         unsigned int vm_flags;
9089 diff -Naur a/mm/mprotect.c b/mm/mprotect.c
9090 --- a/mm/mprotect.c     Tue Sep  9 16:42:54 2003
9091 +++ b/mm/mprotect.c     Tue Sep  9 16:48:27 2003
9092 @@ -222,7 +222,8 @@
9093  }
9094  
9095  asmlinkage long
9096 -sys_mprotect(unsigned long start, size_t len, unsigned long prot)
9097 +do_mprotect(struct mm_struct *mm, unsigned long start, size_t len, 
9098 +            unsigned long prot)
9099  {
9100         unsigned long vm_flags, nstart, end, tmp;
9101         struct vm_area_struct * vma, * next, * prev;
9102 @@ -241,9 +242,9 @@
9103  
9104         vm_flags = calc_vm_prot_bits(prot);
9105  
9106 -       down_write(&current->mm->mmap_sem);
9107 +       down_write(&mm->mmap_sem);
9108  
9109 -       vma = find_vma_prev(current->mm, start, &prev);
9110 +       vma = find_vma_prev(mm, start, &prev);
9111         error = -ENOMEM;
9112         if (!vma || vma->vm_start > start)
9113                 goto out;
9114 @@ -304,6 +305,11 @@
9115                 prev->vm_mm->map_count--;
9116         }
9117  out:
9118 -       up_write(&current->mm->mmap_sem);
9119 +       up_write(&mm->mmap_sem);
9120         return error;
9121  }
9122 +
9123 +asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
9124 +{
9125 +        return(do_mprotect(current->mm, start, len, prot));
9126 +}
9127 diff -Naur a/mm/proc_mm.c b/mm/proc_mm.c
9128 --- a/mm/proc_mm.c      Wed Dec 31 19:00:00 1969
9129 +++ b/mm/proc_mm.c      Tue Sep  9 16:48:51 2003
9130 @@ -0,0 +1,174 @@
9131 +/* 
9132 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
9133 + * Licensed under the GPL
9134 + */
9135 +
9136 +#include "linux/mm.h"
9137 +#include "linux/init.h"
9138 +#include "linux/proc_fs.h"
9139 +#include "linux/proc_mm.h"
9140 +#include "linux/file.h"
9141 +#include "asm/uaccess.h"
9142 +#include "asm/mmu_context.h"
9143 +
9144 +static struct file_operations proc_mm_fops;
9145 +
9146 +struct mm_struct *proc_mm_get_mm(int fd)
9147 +{
9148 +       struct mm_struct *ret = ERR_PTR(-EBADF);
9149 +       struct file *file;
9150 +
9151 +       file = fget(fd);
9152 +       if (!file)
9153 +               goto out;
9154 +
9155 +       ret = ERR_PTR(-EINVAL);
9156 +       if(file->f_op != &proc_mm_fops)
9157 +               goto out_fput;
9158 +
9159 +       ret = file->private_data;
9160 + out_fput:
9161 +       fput(file);
9162 + out:
9163 +       return(ret);
9164 +}
9165 +
9166 +extern long do_mmap2(struct mm_struct *mm, unsigned long addr, 
9167 +                    unsigned long len, unsigned long prot, 
9168 +                    unsigned long flags, unsigned long fd,
9169 +                    unsigned long pgoff);
9170 +
9171 +static ssize_t write_proc_mm(struct file *file, const char *buffer,
9172 +                            size_t count, loff_t *ppos)
9173 +{
9174 +       struct mm_struct *mm = file->private_data;
9175 +       struct proc_mm_op req;
9176 +       int n, ret;
9177 +
9178 +       if(count > sizeof(req))
9179 +               return(-EINVAL);
9180 +
9181 +       n = copy_from_user(&req, buffer, count);
9182 +       if(n != 0)
9183 +               return(-EFAULT);
9184 +
9185 +       ret = count;
9186 +       switch(req.op){
9187 +       case MM_MMAP: {
9188 +               struct mm_mmap *map = &req.u.mmap;
9189 +
9190 +               ret = do_mmap2(mm, map->addr, map->len, map->prot, 
9191 +                              map->flags, map->fd, map->offset >> PAGE_SHIFT);
9192 +               if((ret & ~PAGE_MASK) == 0)
9193 +                       ret = count;
9194 +       
9195 +               break;
9196 +       }
9197 +       case MM_MUNMAP: {
9198 +               struct mm_munmap *unmap = &req.u.munmap;
9199 +
9200 +               down_write(&mm->mmap_sem);
9201 +               ret = do_munmap(mm, unmap->addr, unmap->len);
9202 +               up_write(&mm->mmap_sem);
9203 +
9204 +               if(ret == 0)
9205 +                       ret = count;
9206 +               break;
9207 +       }
9208 +       case MM_MPROTECT: {
9209 +               struct mm_mprotect *protect = &req.u.mprotect;
9210 +
9211 +               ret = do_mprotect(mm, protect->addr, protect->len, 
9212 +                                 protect->prot);
9213 +               if(ret == 0)
9214 +                       ret = count;
9215 +               break;
9216 +       }
9217 +
9218 +       case MM_COPY_SEGMENTS: {
9219 +               struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
9220 +
9221 +               if(IS_ERR(from)){
9222 +                       ret = PTR_ERR(from);
9223 +                       break;
9224 +               }
9225 +
9226 +               mm_copy_segments(from, mm);
9227 +               break;
9228 +       }
9229 +       default:
9230 +               ret = -EINVAL;
9231 +               break;
9232 +       }
9233 +
9234 +       return(ret);
9235 +}
9236 +
9237 +static int open_proc_mm(struct inode *inode, struct file *file)
9238 +{
9239 +       struct mm_struct *mm = mm_alloc();
9240 +       int ret;
9241 +
9242 +       ret = -ENOMEM;
9243 +       if(mm == NULL)
9244 +               goto out_mem;
9245 +
9246 +       ret = init_new_context(current, mm);
9247 +       if(ret)
9248 +               goto out_free;
9249 +
9250 +       spin_lock(&mmlist_lock);
9251 +       list_add(&mm->mmlist, &current->mm->mmlist);
9252 +       mmlist_nr++;
9253 +       spin_unlock(&mmlist_lock);
9254 +
9255 +       file->private_data = mm;
9256 +
9257 +       return(0);
9258 +
9259 + out_free:
9260 +       mmput(mm);
9261 + out_mem:
9262 +       return(ret);
9263 +}
9264 +
9265 +static int release_proc_mm(struct inode *inode, struct file *file)
9266 +{
9267 +       struct mm_struct *mm = file->private_data;
9268 +
9269 +       mmput(mm);
9270 +       return(0);
9271 +}
9272 +
9273 +static struct file_operations proc_mm_fops = {
9274 +       .open           = open_proc_mm,
9275 +       .release        = release_proc_mm,
9276 +       .write          = write_proc_mm,
9277 +};
9278 +
9279 +static int make_proc_mm(void)
9280 +{
9281 +       struct proc_dir_entry *ent;
9282 +
9283 +       ent = create_proc_entry("mm", 0222, &proc_root);
9284 +       if(ent == NULL){
9285 +               printk("make_proc_mm : Failed to register /proc/mm\n");
9286 +               return(0);
9287 +       }
9288 +       ent->proc_fops = &proc_mm_fops;
9289 +
9290 +       return(0);
9291 +}
9292 +
9293 +__initcall(make_proc_mm);
9294 +
9295 +/*
9296 + * Overrides for Emacs so that we follow Linus's tabbing style.
9297 + * Emacs will notice this stuff at the end of the file and automatically
9298 + * adjust the settings for this buffer only.  This must remain at the end
9299 + * of the file.
9300 + * ---------------------------------------------------------------------------
9301 + * Local variables:
9302 + * c-file-style: "linux"
9303 + * End:
9304 + */