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
7 bool "Networking support"
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.
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>.
23 source "fs/Kconfig.binfmt"
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.
30 + tristate "HoneyPot ProcFS"
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
38 + See http://user-mode-linux.sf.net/hppfs.html for more information.
40 + You only need this if you are setting up a UML honeypot. Otherwise,
41 + it is safe to say 'N' here.
44 bool "Management console"
47 bool "Magic SysRq key"
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.
61 bool "2G/2G host address space split"
64 bool "Highmem support"
67 + bool "/proc/mm support"
69 config KERNEL_STACK_ORDER
70 int "Kernel stack size order"
74 bool "Enable ptrace proxy"
75 depends on XTERM_CHAN && DEBUG_INFO
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.
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
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.
90 +# Turn this back on when the driver actually works
93 +# tristate "COW block device"
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.
100 +config BLK_DEV_COW_COMMON
102 + default BLK_DEV_COW || BLK_DEV_UBD
105 tristate "Loopback device support"
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
112 -menu "Network Devices"
113 +menu "UML Network Devices"
119 Startup example: "eth0=slirp,FE:FD:01:02:03:04,/usr/local/bin/slirp"
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
128 - tristate "Dummy net driver support"
131 - tristate "Bonding driver support"
134 - tristate "EQL (serial line load balancing) support"
137 - tristate "Universal TUN/TAP device driver support"
140 - tristate "Ethertap network tap (OBSOLETE)"
141 - depends on EXPERIMENTAL && NETLINK
144 - tristate "PPP (point-to-point protocol) support"
146 -config PPP_MULTILINK
147 - bool "PPP multilink support (EXPERIMENTAL)"
148 - depends on PPP && EXPERIMENTAL
151 - bool "PPP filtering"
152 - depends on PPP && FILTER
155 - tristate "PPP support for async serial ports"
159 - tristate "PPP support for sync tty ports"
163 - tristate "PPP Deflate compression"
167 - tristate "PPP BSD-Compress compression"
171 - tristate "PPP over Ethernet (EXPERIMENTAL)"
172 - depends on PPP && EXPERIMENTAL
175 - tristate "SLIP (serial line) support"
177 -config SLIP_COMPRESSED
178 - bool "CSLIP compressed headers"
182 - bool "Keepalive and linefill"
185 -config SLIP_MODE_SLIP6
186 - bool "Six bit SLIP encapsulation"
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
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
202 ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \
203 $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
205 GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h
207 -include $(ARCH_DIR)/Makefile-$(SUBARCH)
208 -include $(ARCH_DIR)/Makefile-os-$(OS)
213 MAKEFILE-$(CONFIG_MODE_TT) += Makefile-tt
214 MAKEFILE-$(CONFIG_MODE_SKAS) += Makefile-skas
216 include $(addprefix $(ARCH_DIR)/,$(MAKEFILE-y))
219 +include $(ARCH_DIR)/Makefile-$(SUBARCH)
220 +include $(ARCH_DIR)/Makefile-os-$(OS)
222 EXTRAVERSION := $(EXTRAVERSION)-1um
224 ARCH_INCLUDE = -I$(ARCH_DIR)/include
227 CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
228 -D_LARGEFILE64_SOURCE $(ARCH_INCLUDE) -Derrno=kernel_errno \
230 + -Dsigprocmask=kernel_sigprocmask $(MODE_INCLUDE)
232 LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
234 SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000)
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
241 include/linux/version.h: arch/$(ARCH)/Makefile
243 CONFIG_KERNEL_STACK_ORDER ?= 2
244 STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
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))
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
256 LD_SCRIPT-y := $(ARCH_DIR)/$(LD_SCRIPT-y)
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)
263 linux: vmlinux $(LD_SCRIPT-y)
264 $(CC) -Wl,-T,$(LD_SCRIPT-y) $(LINK-y) $(LINK_WRAPS) \
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) \
274 USER_CFLAGS += -D_GNU_SOURCE
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 \
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 $@ $<
286 @@ -161,19 +168,23 @@
288 cd $(ARCH_DIR) && ln -sf os-$(OS) os
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 > $@
294 +filechk_$(ARCH_DIR)/include/task.h := $(ARCH_DIR)/util/mk_task
296 $(ARCH_DIR)/include/task.h : $(ARCH_DIR)/util/mk_task
300 +filechk_$(ARCH_DIR)/include/kern_constants.h := $(ARCH_DIR)/util/mk_constants
302 $(ARCH_DIR)/include/kern_constants.h : $(ARCH_DIR)/util/mk_constants
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 ;
311 $(ARCH_DIR)/util: FORCE
312 - @$(call descend,$@,)
313 + $(MAKE) -f scripts/Makefile.build obj=$@
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
322 SYS_HEADERS = $(SYS_DIR)/sc.h $(SYS_DIR)/thread.h
324 +sys_prepare: $(SYS_DIR)/sc.h
326 prepare: $(SYS_HEADERS)
328 +filechk_$(SYS_DIR)/sc.h := $(SYS_UTIL_DIR)/mk_sc
330 $(SYS_DIR)/sc.h: $(SYS_UTIL_DIR)/mk_sc
334 +filechk_$(SYS_DIR)/thread.h := $(SYS_UTIL_DIR)/mk_thread
336 $(SYS_DIR)/thread.h: $(SYS_UTIL_DIR)/mk_thread
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),$@)
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),$@)
350 $(SYS_UTIL_DIR): include/asm FORCE
351 - @$(call descend,$@,)
352 + +@$(call descend,$@,)
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
360 LINK_SKAS = -Wl,-rpath,/lib
361 LD_SCRIPT_SKAS = dyn.lds.s
363 -GEN_HEADERS += $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h
364 +GEN_HEADERS += $(TOPDIR)/$(ARCH_DIR)/include/skas_ptregs.h
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
377 -# CONFIG_UDF_RW is not set
379 # CONFIG_UFS_FS_WRITE is not set
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
390 CONFIG_RWSEM_GENERIC_SPINLOCK=y
391 -CONFIG_CONFIG_LOG_BUF_SHIFT=14
394 -# Code maturity level options
396 -CONFIG_EXPERIMENTAL=y
400 +# UML-specific options
406 -CONFIG_BSD_PROCESS_ACCT=y
408 -CONFIG_BINFMT_AOUT=y
415 # CONFIG_HOST_2G_2G is not set
417 CONFIG_KERNEL_STACK_ORDER=2
420 +# Code maturity level options
422 +CONFIG_EXPERIMENTAL=y
423 +CONFIG_CLEAN_COMPILE=y
425 +CONFIG_BROKEN_ON_SMP=y
432 +CONFIG_BSD_PROCESS_ACCT=y
434 +CONFIG_LOG_BUF_SHIFT=14
435 +# CONFIG_IKCONFIG is not set
436 +# CONFIG_EMBEDDED is not set
440 +CONFIG_IOSCHED_NOOP=y
442 +CONFIG_IOSCHED_DEADLINE=y
445 # Loadable module support
448 -# CONFIG_KMOD is not set
449 +# CONFIG_MODULES is not set
452 +# Generic Driver Options
460 # CONFIG_BLK_DEV_UBD_SYNC is not set
461 +CONFIG_BLK_DEV_COW_COMMON=y
462 CONFIG_BLK_DEV_LOOP=y
470 +# UML Network Devices
473 CONFIG_UML_NET_ETHERTAP=y
475 CONFIG_UML_NET_MCAST=y
476 # CONFIG_UML_NET_PCAP is not set
477 CONFIG_UML_NET_SLIRP=y
479 -# CONFIG_BONDING is not set
480 -# CONFIG_EQUALIZER is not set
482 -# CONFIG_ETHERTAP is not set
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
491 -# CONFIG_SLIP_COMPRESSED is not set
492 -# CONFIG_SLIP_SMART is not set
493 -# CONFIG_SLIP_MODE_SLIP6 is not set
500 # CONFIG_NETLINK_DEV is not set
501 -# CONFIG_NETFILTER is not set
502 -# CONFIG_FILTER is not set
504 # CONFIG_NET_KEY is not set
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
518 # SCTP Configuration (EXPERIMENTAL)
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
531 # CONFIG_NET_PKTGEN is not set
533 +# CONFIG_BONDING is not set
534 +# CONFIG_EQUALIZER is not set
538 # Ethernet (10 or 100Mbit)
543 +# Ethernet (10000 Mbit)
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
554 +# CONFIG_SLIP_COMPRESSED is not set
555 +# CONFIG_SLIP_SMART is not set
556 +# CONFIG_SLIP_MODE_SLIP6 is not set
559 # Wireless LAN (non-hamradio)
561 # CONFIG_NET_RADIO is not set
562 @@ -188,66 +210,82 @@
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
576 +# CONFIG_ROMFS_FS is not set
578 # CONFIG_QFMT_V1 is not set
579 # CONFIG_QFMT_V2 is not set
583 -CONFIG_REISERFS_FS=m
584 -# CONFIG_REISERFS_CHECK is not set
585 -# CONFIG_REISERFS_PROC_INFO is not set
590 +# CD-ROM/DVD Filesystems
593 +# CONFIG_JOLIET is not set
594 +# CONFIG_ZISOFS is not set
595 +# CONFIG_UDF_FS is not set
598 +# DOS/FAT/NT Filesystems
603 +# CONFIG_NTFS_FS is not set
606 +# Pseudo filesystems
610 +CONFIG_DEVFS_MOUNT=y
611 +# CONFIG_DEVFS_DEBUG is not set
613 +# CONFIG_DEVPTS_FS_XATTR is not set
614 +# CONFIG_TMPFS is not set
618 +# Miscellaneous filesystems
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
630 # CONFIG_EFS_FS is not set
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
639 -# CONFIG_JOLIET is not set
640 -# CONFIG_ZISOFS is not set
641 -# CONFIG_JFS_FS is not set
643 # CONFIG_VXFS_FS is not set
644 -# CONFIG_NTFS_FS is not set
645 # CONFIG_HPFS_FS is not set
648 -CONFIG_DEVFS_MOUNT=y
649 -# CONFIG_DEVFS_DEBUG is not set
651 # CONFIG_QNX4FS_FS is not set
652 -# CONFIG_ROMFS_FS is not set
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
661 # Network File Systems
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
682 -CONFIG_GENERIC_ISA_DMA=y
685 -# SCSI support type (disk, tape, CD-ROM)
688 -CONFIG_SD_EXTRA_DEVS=40
691 -CONFIG_BLK_DEV_SR_VENDOR=y
692 -CONFIG_SR_EXTRA_DEVS=2
696 -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
698 -CONFIG_SCSI_DEBUG_QUEUES=y
699 -CONFIG_SCSI_MULTI_LUN=y
700 -CONFIG_SCSI_CONSTANTS=y
701 -CONFIG_SCSI_LOGGING=y
703 +# CONFIG_SCSI is not set
706 # Multi-device support (RAID and LVM)
709 # CONFIG_FTL is not set
710 # CONFIG_NFTL is not set
711 +# CONFIG_INFTL is not set
714 # RAM/ROM/Flash chip drivers
715 @@ -374,20 +392,21 @@
717 # Mapping drivers for chip access
719 +# CONFIG_MTD_COMPLEX_MAPPINGS is not set
722 # Self-contained MTD device drivers
724 # CONFIG_MTD_SLRAM is not set
725 # CONFIG_MTD_MTDRAM is not set
730 # Disk-On-Chip Device Drivers
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
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
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
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
756 obj-y += stdio_console.o $(CHAN_OBJS)
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))
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
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>
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
782 if(!isatty(fd)) return;
785 - if(!CHOOSE_MODE(is_tracer_winch(pid, fd, device_data), 0) &&
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);
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
799 +#include <asm/types.h>
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)
808 +#error "__BYTE_ORDER not defined"
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);
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);
822 +extern int write_cow_header(char *cow_file, int fd, char *backing_file,
823 + int sectorsize, long long *size);
825 +extern void cow_sizes(__u64 size, int sectorsize, int bitmap_offset,
826 + unsigned long *bitmap_len_out, int *data_offset_out);
831 + * ---------------------------------------------------------------------------
833 + * c-file-style: "linux"
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
840 +#define COW_MAJOR 60
841 +#define MAJOR_NR COW_MAJOR
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"
856 +#include "ubd_user.h"
864 + struct block_device *cow_bdev;
865 + char *backing_path;
867 + struct block_device *backing_bdev;
869 + unsigned long *bitmap;
870 + unsigned long bitmap_len;
873 + devfs_handle_t devfs;
874 + struct semaphore sem;
875 + struct semaphore io_sem;
877 + spinlock_t io_lock;
878 + struct buffer_head *bh;
879 + struct buffer_head *bhtail;
883 +#define DEFAULT_COW { \
885 + .cow_path = NULL, \
887 + .backing_path = NULL, \
888 + .backing_dev = 0, \
891 + .bitmap_offset = 0, \
892 + .data_offset = 0, \
894 + .working = ATOMIC_INIT(0), \
895 + .io_lock = SPIN_LOCK_UNLOCKED, \
899 +#define MAX_MINOR (MAX_DEV << COW_SHIFT)
901 +struct cow cow_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_COW };
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 };
907 +/* Protected by cow_lock */
908 +static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 };
910 +static struct hd_struct cow_part[MAX_MINOR] =
911 + { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } };
913 +/* Protected by io_request_lock */
914 +static request_queue_t *cow_queue;
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);
922 +static struct block_device_operations cow_blops = {
924 + .release = cow_release,
925 + .ioctl = cow_ioctl,
926 + .revalidate = cow_revalidate,
929 +/* Initialized in an initcall, and unchanged thereafter */
930 +devfs_handle_t cow_dir_handle;
932 +#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \
935 + .major_name = name, \
936 + .minor_shift = shift, \
937 + .max_p = 1 << shift, \
941 + .real_devices = NULL, \
948 +static spinlock_t cow_lock = SPIN_LOCK_UNLOCKED;
950 +static struct gendisk cow_gendisk = INIT_GENDISK(MAJOR_NR, "cow", cow_part,
951 + COW_SHIFT, sizes, MAX_DEV,
954 +static int cow_add(int n)
956 + struct cow *dev = &cow_dev[n];
957 + char name[sizeof("nnnnnn\0")];
960 + if(dev->cow_path == NULL)
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,
969 + init_MUTEX_LOCKED(&dev->sem);
970 + init_MUTEX(&dev->io_sem);
979 +* Add buffer_head to back of pending list
981 +static void cow_add_bh(struct cow *cow, struct buffer_head *bh)
983 + unsigned long flags;
985 + spin_lock_irqsave(&cow->io_lock, flags);
986 + if(cow->bhtail != NULL){
987 + cow->bhtail->b_reqnext = bh;
994 + spin_unlock_irqrestore(&cow->io_lock, flags);
998 +* Grab first pending buffer
1000 +static struct buffer_head *cow_get_bh(struct cow *cow)
1002 + struct buffer_head *bh;
1004 + spin_lock_irq(&cow->io_lock);
1007 + if(bh == cow->bhtail)
1008 + cow->bhtail = NULL;
1009 + cow->bh = bh->b_reqnext;
1010 + bh->b_reqnext = NULL;
1012 + spin_unlock_irq(&cow->io_lock);
1017 +static void cow_handle_bh(struct cow *cow, struct buffer_head *bh,
1018 + struct buffer_head **cow_bh, int ncow_bh)
1023 + ll_rw_block(WRITE, ncow_bh, cow_bh);
1025 + for(i = 0; i < ncow_bh ; i++){
1026 + wait_on_buffer(cow_bh[i]);
1027 + brelse(cow_bh[i]);
1030 + ll_rw_block(WRITE, 1, &bh);
1034 +static struct buffer_head *cow_new_bh(struct cow *dev, int sector)
1036 + struct buffer_head *bh;
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])),
1045 +/* Copied from loop.c, needed to avoid deadlocking in make_request. */
1047 +static int cow_thread(void *data)
1049 + struct cow *dev = data;
1050 + struct buffer_head *bh;
1053 + exit_files(current);
1055 + sprintf(current->comm, "cow%d", dev - cow_dev);
1057 + spin_lock_irq(¤t->sigmask_lock);
1058 + sigfillset(¤t->blocked);
1059 + flush_signals(current);
1060 + spin_unlock_irq(¤t->sigmask_lock);
1062 + atomic_inc(&dev->working);
1064 + current->policy = SCHED_OTHER;
1065 + current->nice = -20;
1067 + current->flags |= PF_NOIO;
1070 + * up sem, we are running
1075 + int start, len, nbh, i, update_bitmap = 0;
1076 + struct buffer_head *cow_bh[2];
1078 + down_interruptible(&dev->io_sem);
1080 + * could be upped because of tear-down, not because of
1083 + if(!atomic_read(&dev->working))
1086 + bh = cow_get_bh(dev);
1088 + printk(KERN_ERR "cow: missing bh\n");
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))
1099 + update_bitmap = 1;
1100 + ubd_set_bit(start + i, (unsigned char *) dev->bitmap);
1106 + if(update_bitmap){
1107 + cow_bh[0] = cow_new_bh(dev, start);
1109 + if(start / dev->sectorsize !=
1110 + (start + len) / dev->sectorsize){
1111 + cow_bh[1] = cow_new_bh(dev, start + len);
1116 + bh->b_dev = dev->cow_dev;
1117 + bh->b_blocknr += dev->data_offset / dev->sectorsize;
1119 + cow_handle_bh(dev, bh, cow_bh, nbh);
1122 + * upped both for pending work and tear-down, lo_pending
1123 + * will hit zero then
1125 + if(atomic_dec_and_test(&dev->working))
1133 +static int cow_make_request(request_queue_t *q, int rw, struct buffer_head *bh)
1138 + minor = MINOR(bh->b_rdev);
1139 + n = minor >> COW_SHIFT;
1140 + dev = &cow_dev[n];
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;
1147 + else if(rw == WRITE){
1148 + bh->b_dev = dev->cow_dev;
1149 + bh->b_blocknr += dev->data_offset / dev->sectorsize;
1151 + cow_add_bh(dev, bh);
1156 + bh->b_rdev = dev->backing_dev;
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);
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);
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);
1181 + add_gendisk(&cow_gendisk);
1183 + for(i=0;i<MAX_DEV;i++)
1189 +__initcall(cow_init);
1191 +static int reader(__u64 start, char *buf, int count, void *arg)
1193 + dev_t dev = *((dev_t *) arg);
1194 + struct buffer_head *bh;
1196 + int cur, offset, left, n, blocksize = get_hardsect_size(dev);
1198 + if(blocksize == 0)
1199 + panic("Zero blocksize");
1201 + block = start / blocksize;
1202 + offset = start % blocksize;
1206 + n = (left > blocksize) ? blocksize : left;
1208 + bh = bread(dev, block, (n < 512) ? 512 : n);
1213 + memcpy(&buf[cur], bh->b_data + offset, n);
1224 +static int cow_open(struct inode *inode, struct file *filp)
1226 + int (*dev_ioctl)(struct inode *, struct file *, unsigned int,
1233 + char *backing_file;
1234 + int n, offset, err = 0;
1236 + n = DEVICE_NR(inode->i_rdev);
1239 + dev = &cow_dev[n];
1240 + offset = n << COW_SHIFT;
1242 + spin_lock(&cow_lock);
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);
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);
1262 + dev->cow_bdev = bdget(dev->cow_dev);
1263 + if(dev->cow_bdev == NULL){
1264 + printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n",
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);
1278 + err = blkdev_get(dev->cow_bdev, FMODE_READ|FMODE_WRITE, 0,
1281 + printk("cow_open - blkdev_get of COW device failed, "
1282 + "error = %d\n", err);
1286 + err = blkdev_get(dev->backing_bdev, FMODE_READ, 0, BDEV_RAW);
1288 + printk("cow_open - blkdev_get of backing device "
1289 + "failed, error = %d\n", err);
1293 + err = read_cow_header(reader, &dev->cow_dev, &magic,
1294 + &backing_file, &mtime, &size,
1295 + &dev->sectorsize, &dev->bitmap_offset);
1297 + printk(KERN_ERR "cow_open - read_cow_header failed, "
1298 + "err = %d\n", err);
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){
1307 + printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
1310 + flush_tlb_kernel_vm();
1312 + err = reader(dev->bitmap_offset, (char *) dev->bitmap,
1313 + dev->bitmap_len, &dev->cow_dev);
1315 + printk(KERN_ERR "Failed to read COW bitmap\n");
1316 + vfree(dev->bitmap);
1320 + dev_ioctl = dev->backing_bdev->bd_op->ioctl;
1322 + set_fs(KERNEL_DS);
1323 + err = (*dev_ioctl)(inode, filp, BLKGETSIZE,
1324 + (unsigned long) &sizes[offset]);
1327 + printk(KERN_ERR "cow_open - BLKGETSIZE failed, "
1328 + "error = %d\n", err);
1332 + kernel_thread(cow_thread, dev,
1333 + CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
1338 + spin_unlock(&cow_lock);
1342 +static int cow_release(struct inode * inode, struct file * file)
1347 + n = DEVICE_NR(inode->i_rdev);
1350 + dev = &cow_dev[n];
1352 + spin_lock(&cow_lock);
1354 + if(--dev->count > 0)
1357 + err = blkdev_put(dev->cow_bdev, BDEV_RAW);
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;
1364 + err = blkdev_put(dev->backing_bdev, BDEV_RAW);
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;
1372 + spin_unlock(&cow_lock);
1376 +static int cow_ioctl(struct inode * inode, struct file * file,
1377 + unsigned int cmd, unsigned long arg)
1380 + int (*dev_ioctl)(struct inode *, struct file *, unsigned int,
1384 + n = DEVICE_NR(inode->i_rdev);
1387 + dev = &cow_dev[n];
1389 + dev_ioctl = dev->backing_bdev->bd_op->ioctl;
1390 + return((*dev_ioctl)(inode, file, cmd, arg));
1393 +static int cow_revalidate(kdev_t rdev)
1395 + printk(KERN_ERR "Need to implement cow_revalidate\n");
1399 +static int parse_unit(char **ptr)
1401 + char *str = *ptr, *end;
1404 + if(isdigit(*str)) {
1405 + n = simple_strtoul(str, &end, 0);
1410 + else if (('a' <= *str) && (*str <= 'h')) {
1418 +static int cow_setup(char *str)
1421 + char *cow_name, *backing_name;
1424 + unit = parse_unit(&str);
1426 + printk(KERN_ERR "cow_setup - Couldn't parse unit number\n");
1431 + printk(KERN_ERR "cow_setup - Missing '=' after unit "
1438 + backing_name = strchr(str, ',');
1439 + if(backing_name == NULL){
1440 + printk(KERN_ERR "cow_setup - missing backing device name\n");
1443 + *backing_name = '\0';
1446 + spin_lock(&cow_lock);
1448 + dev = &cow_dev[unit];
1449 + dev->cow_path = cow_name;
1450 + dev->backing_path = backing_name;
1452 + spin_unlock(&cow_lock);
1456 +__setup("cow", cow_setup);
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
1463 + * ---------------------------------------------------------------------------
1464 + * Local variables:
1465 + * c-file-style: "linux"
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
1472 +#ifndef __COW_SYS_H__
1473 +#define __COW_SYS_H__
1475 +#include "kern_util.h"
1476 +#include "user_util.h"
1480 +static inline void *cow_malloc(int size)
1482 + return(um_kmalloc(size));
1485 +static inline void cow_free(void *ptr)
1490 +#define cow_printf printk
1492 +static inline char *cow_strdup(char *str)
1494 + return(uml_strdup(str));
1497 +static inline int cow_seek_file(int fd, __u64 offset)
1499 + return(os_seek_file(fd, offset));
1502 +static inline int cow_file_size(char *file, __u64 *size_out)
1504 + return(os_file_size(file, size_out));
1507 +static inline int cow_write_file(int fd, char *buf, int size)
1509 + return(os_write_file(fd, buf, size));
1515 + * ---------------------------------------------------------------------------
1516 + * Local variables:
1517 + * c-file-style: "linux"
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
1524 +#include <stddef.h>
1525 +#include <string.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>
1535 +#include "cow_sys.h"
1537 +#define PATH_LEN_V1 256
1539 +struct cow_header_v1 {
1542 + char backing_file[PATH_LEN_V1];
1548 +#define PATH_LEN_V2 MAXPATHLEN
1550 +struct cow_header_v2 {
1551 + unsigned long magic;
1552 + unsigned long version;
1553 + char backing_file[PATH_LEN_V2];
1560 + struct cow_header_v1 v1;
1561 + struct cow_header_v2 v2;
1564 +#define COW_MAGIC 0x4f4f4f4d /* MOOO */
1565 +#define COW_VERSION 2
1567 +void cow_sizes(__u64 size, int sectorsize, int bitmap_offset,
1568 + unsigned long *bitmap_len_out, int *data_offset_out)
1570 + *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
1572 + *data_offset_out = bitmap_offset + *bitmap_len_out;
1573 + *data_offset_out = (*data_offset_out + sectorsize - 1) / sectorsize;
1574 + *data_offset_out *= sectorsize;
1577 +static int absolutize(char *to, int size, char *from)
1579 + char save_cwd[256], *slash;
1582 + if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
1583 + cow_printf("absolutize : unable to get cwd - errno = %d\n",
1587 + slash = strrchr(from, '/');
1588 + if(slash != NULL){
1592 + cow_printf("absolutize : Can't cd to '%s' - "
1593 + "errno = %d\n", from, errno);
1597 + if(getcwd(to, size) == NULL){
1598 + cow_printf("absolutize : unable to get cwd of '%s' - "
1599 + "errno = %d\n", from, errno);
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);
1608 + strcat(to, slash);
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);
1616 + strcpy(to, save_cwd);
1624 +int write_cow_header(char *cow_file, int fd, char *backing_file,
1625 + int sectorsize, long long *size)
1627 + struct cow_header_v2 *header;
1628 + struct stat64 buf;
1631 + err = cow_seek_file(fd, 0);
1633 + cow_printf("write_cow_header - lseek failed, errno = %d\n",
1639 + header = cow_malloc(sizeof(*header));
1640 + if(header == NULL){
1641 + cow_printf("Failed to allocate COW V2 header\n");
1644 + header->magic = htonl(COW_MAGIC);
1645 + header->version = htonl(COW_VERSION);
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);
1655 + if(absolutize(header->backing_file, sizeof(header->backing_file),
1659 + err = stat64(header->backing_file, &buf);
1661 + cow_printf("Stat of backing file '%s' failed, errno = %d\n",
1662 + header->backing_file, errno);
1667 + err = cow_file_size(header->backing_file, size);
1669 + cow_printf("Couldn't get size of backing file '%s', "
1670 + "errno = %d\n", header->backing_file, -*size);
1674 + header->mtime = htonl(buf.st_mtime);
1675 + header->size = htonll(*size);
1676 + header->sectorsize = htonl(sectorsize);
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);
1691 +int file_reader(__u64 offset, char *buf, int len, void *arg)
1693 + int fd = *((int *) arg);
1695 + return(pread(fd, buf, len, offset));
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)
1703 + union cow_header *header;
1706 + unsigned long version, magic;
1708 + header = cow_malloc(sizeof(*header));
1709 + if(header == NULL){
1710 + cow_printf("read_cow_header - Failed to allocate header\n");
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");
1720 + magic = header->v1.magic;
1721 + if(magic == COW_MAGIC) {
1722 + version = header->v1.version;
1724 + else if(magic == ntohl(COW_MAGIC)){
1725 + version = ntohl(header->v1.version);
1727 + /* No error printed because the non-COW case comes through here */
1730 + *magic_out = COW_MAGIC;
1733 + if(n < sizeof(header->v1)){
1734 + cow_printf("read_cow_header - failed to read V1 "
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;
1744 + else if(version == 2){
1745 + if(n < sizeof(header->v2)){
1746 + cow_printf("read_cow_header - failed to read V2 "
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;
1757 + cow_printf("read_cow_header - invalid COW version\n");
1761 + *backing_file_out = cow_strdup(file);
1762 + if(*backing_file_out == NULL){
1763 + cow_printf("read_cow_header - failed to allocate backing "
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)
1777 + __u64 size, offset;
1781 + err = write_cow_header(cow_file, fd, backing_file, sectorsize, &size);
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);
1789 + offset = *data_offset_out + size - sizeof(zero);
1790 + err = cow_seek_file(fd, offset);
1792 + cow_printf("cow bitmap lseek failed : errno = %d\n", errno);
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
1800 + err = cow_write_file(fd, &zero, sizeof(zero));
1801 + if(err != sizeof(zero)){
1803 + cow_printf("Write of bitmap to new COW file '%s' failed, "
1804 + "errno = %d\n", cow_file, errno);
1815 + * ---------------------------------------------------------------------------
1816 + * Local variables:
1817 + * c-file-style: "linux"
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
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"
1830 #include "hostaudio.h"
1833 static int set_dsp(char *name, int *add)
1835 - dsp = uml_strdup(name);
1842 static int set_mixer(char *name, int *add)
1844 - mixer = uml_strdup(name);
1852 struct hostaudio_state *state = file->private_data;
1857 printk("hostaudio: read called, count = %d\n", count);
1860 - return(hostaudio_read_user(state, buffer, count, ppos));
1861 + kbuf = kmalloc(count, GFP_KERNEL);
1865 + err = hostaudio_read_user(state, kbuf, count, ppos);
1869 + if(copy_to_user(buffer, kbuf, err))
1877 static ssize_t hostaudio_write(struct file *file, const char *buffer,
1878 size_t count, loff_t *ppos)
1880 struct hostaudio_state *state = file->private_data;
1885 printk("hostaudio: write called, count = %d\n", count);
1887 - return(hostaudio_write_user(state, buffer, count, ppos));
1889 + kbuf = kmalloc(count, GFP_KERNEL);
1894 + if(copy_from_user(kbuf, buffer, count))
1897 + err = hostaudio_write_user(state, kbuf, count, ppos);
1906 static unsigned int hostaudio_poll(struct file *file,
1907 @@ -86,12 +119,43 @@
1908 unsigned int cmd, unsigned long arg)
1910 struct hostaudio_state *state = file->private_data;
1911 + unsigned long data = 0;
1915 printk("hostaudio: ioctl called, cmd = %u\n", 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))
1931 + err = hostaudio_ioctl_user(state, cmd, (unsigned long) &data);
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))
1947 - return(hostaudio_ioctl_user(state, cmd, arg));
1951 static int hostaudio_open(struct inode *inode, struct file *file)
1954 static int __init hostaudio_init_module(void)
1956 - printk(KERN_INFO "UML Audio Relay\n");
1957 + printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n",
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
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"
1976 #include "user_util.h"
1977 #include "kern_util.h"
1979 +#include "irq_kern.h"
1981 #define LINE_BUFSIZE 4096
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)
1986 struct line *dev = data;
1989 chan_interrupt(&dev->chan_list, &dev->task, dev->tty, irq,
1991 + return IRQ_HANDLED;
1994 void line_timer_cb(void *arg)
1995 @@ -136,20 +138,22 @@
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)
2002 struct line *dev = data;
2003 struct tty_struct *tty = dev->tty;
2006 err = flush_buffer(dev);
2007 - if(err == 0) return;
2011 dev->head = dev->buffer;
2012 dev->tail = dev->buffer;
2015 - if(tty == NULL) return;
2019 if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
2020 (tty->ldisc.write_wakeup != NULL))
2025 - if (waitqueue_active(&tty->write_wait))
2026 + if(waitqueue_active(&tty->write_wait))
2027 wake_up_interruptible(&tty->write_wait);
2029 + return(IRQ_HANDLED);
2032 int line_write_room(struct tty_struct *tty)
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";
2042 @@ -379,15 +383,15 @@
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);
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;
2072 for(i = 0; i < nlines; i++){
2074 - tty_unregister_devfs(driver, i);
2075 + tty_unregister_device(driver, i);
2078 mconsole_register_dev(&line_driver->mc);
2079 @@ -465,24 +470,25 @@
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)
2086 struct winch *winch = data;
2087 struct tty_struct *tty;
2091 - err = generic_read(winch->fd, &c, NULL);
2093 - if(err != -EAGAIN){
2094 - printk("winch_interrupt : read failed, errno = %d\n",
2096 - printk("fd %d is losing SIGWINCH support\n",
2098 - free_irq(irq, data);
2100 + if(winch->fd != -1){
2101 + err = generic_read(winch->fd, &c, NULL);
2103 + if(err != -EAGAIN){
2104 + printk("winch_interrupt : read failed, "
2105 + "errno = %d\n", -err);
2106 + printk("fd %d is losing SIGWINCH support\n",
2108 + return(IRQ_HANDLED);
2114 tty = winch->line->tty;
2117 kill_pg(tty->pgrp, SIGWINCH, 1);
2120 - reactivate_fd(winch->fd, WINCH_IRQ);
2121 + if(winch->fd != -1)
2122 + reactivate_fd(winch->fd, WINCH_IRQ);
2123 + return(IRQ_HANDLED);
2126 DECLARE_MUTEX(winch_handler_sem);
2127 @@ -529,7 +537,10 @@
2129 list_for_each(ele, &winch_handlers){
2130 winch = list_entry(ele, struct winch, list);
2132 + if(winch->fd != -1){
2133 + deactivate_fd(winch->fd, WINCH_IRQ);
2136 if(winch->pid != -1)
2137 os_kill_process(winch->pid, 1);
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
2146 +#include "irq_kern.h"
2148 static int do_unlink_socket(struct notifier_block *notifier,
2149 unsigned long what, void *data)
2152 DECLARE_WORK(mconsole_work, mc_work_proc, NULL);
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)
2158 struct mconsole_entry *new;
2161 if(!list_empty(&mc_requests)) schedule_work(&mconsole_work);
2162 reactivate_fd(fd, MCONSOLE_IRQ);
2163 + return(IRQ_HANDLED);
2166 void mconsole_version(struct mc_request *req)
2167 @@ -100,20 +102,34 @@
2168 mconsole_reply(req, version, 0, 0);
2171 +void mconsole_log(struct mc_request *req)
2174 + char *ptr = req->request.data;
2176 + ptr += strlen("log");
2177 + while(isspace(*ptr)) ptr++;
2179 + len = ptr - req->request.data;
2180 + printk("%.*s", len, ptr);
2181 + mconsole_reply(req, "", 0, 0);
2184 #define UML_MCONSOLE_HELPTEXT \
2186 - version - Get kernel version
2187 - help - Print this message
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'
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\
2214 void mconsole_help(struct mc_request *req)
2216 if(umid_file_name("mconsole", file, sizeof(file))) return(-1);
2217 snprintf(mconsole_socket_name, sizeof(file), "%s", file);
2219 - sock = create_unix_socket(file, sizeof(file));
2220 + sock = create_unix_socket(file, sizeof(file), 1);
2222 printk("Failed to initialize management console\n");
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
2228 { "cad", mconsole_cad, 1 },
2229 { "stop", mconsole_stop, 0 },
2230 { "go", mconsole_go, 1 },
2231 + { "log", mconsole_log, 1 },
2234 /* Initialized in mconsole_init, which is an initcall */
2236 memcpy(reply.data, str, len);
2237 reply.data[len] = '\0';
2240 reply.len = len + 1;
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");
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");
2256 p_buf = __pa(v_buf);
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
2262 #include "mconsole_kern.h"
2264 #include "irq_user.h"
2265 +#include "irq_kern.h"
2267 static spinlock_t opened_lock = SPIN_LOCK_UNLOCKED;
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)
2276 struct net_device *dev = dev_id;
2277 struct uml_net_private *lp = dev->priv;
2280 if(!netif_running(dev))
2284 spin_lock(&lp->lock);
2285 while((err = uml_net_rx(dev)) > 0) ;
2289 spin_unlock(&lp->lock);
2290 + return(IRQ_HANDLED);
2293 static int uml_net_open(struct net_device *dev)
2294 @@ -252,37 +254,6 @@
2299 - * default do nothing hard header packet routines for struct net_device init.
2300 - * real ethernet transports will overwrite with real routines.
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)
2305 - return(0); /* no change */
2308 -static int uml_net_rebuild_header(struct sk_buff *skb)
2310 - return(0); /* ignore */
2313 -static int uml_net_header_cache(struct neighbour *neigh, struct hh_cache *hh)
2315 - return(-1); /* fail */
2318 -static void uml_net_header_cache_update(struct hh_cache *hh,
2319 - struct net_device *dev, unsigned char * haddr)
2324 -static int uml_net_header_parse(struct sk_buff *skb, unsigned char *haddr)
2326 - return(0); /* nothing */
2329 static spinlock_t devices_lock = SPIN_LOCK_UNLOCKED;
2330 static struct list_head devices = LIST_HEAD_INIT(devices);
2333 struct uml_net *device;
2334 struct net_device *dev;
2335 struct uml_net_private *lp;
2337 + int save, err, size;
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);
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;
2351 (*transport->kern->init)(dev, init);
2353 dev->mtu = transport->user->max_packet;
2354 @@ -362,21 +327,29 @@
2358 - INIT_LIST_HEAD(&lp->list);
2359 - spin_lock_init(&lp->lock);
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.
2378 + save = lp->user[0];
2379 + *lp = ((struct uml_net_private)
2380 + { .list = LIST_HEAD_INIT(lp->list),
2381 + .lock = SPIN_LOCK_UNLOCKED,
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 } });
2397 init_timer(&lp->tl);
2398 lp->tl.function = uml_net_user_timer_expire;
2400 unregister_netdev(dev);
2402 list_del(&device->list);
2403 - free_netdev(device);
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
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"
2421 #include "kern_util.h"
2423 #include "irq_user.h"
2424 +#include "irq_kern.h"
2429 struct port_list *port;
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)
2435 struct connection *conn = data;
2438 fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
2444 printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n",
2447 list_add(&conn->list, &conn->port->connections);
2449 up(&conn->port->sem);
2450 + return(IRQ_HANDLED);
2453 static int port_accept(struct port_list *port)
2454 @@ -138,12 +141,13 @@
2456 DECLARE_WORK(port_work, port_work_proc, NULL);
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)
2461 struct port_list *port = data;
2463 port->has_connection = 1;
2464 schedule_work(&port_work);
2465 + return(IRQ_HANDLED);
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
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,
2482 .type = TTY_DRIVER_TYPE_SERIAL,
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
2489 static struct line_driver driver = {
2490 .name = "UML console",
2491 - .devfs_name = "vc/%d",
2492 + .device_name = "tty",
2493 + .devfs_name = "vc/",
2496 .type = TTY_DRIVER_TYPE_CONSOLE,
2497 @@ -159,6 +160,15 @@
2499 static int con_init_done = 0;
2501 +static struct tty_operations console_ops = {
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,
2510 int stdio_init(void)
2514 printk(KERN_INFO "Initializing stdio console driver\n");
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]));
2521 lines_init(vts, sizeof(vts)/sizeof(vts[0]));
2523 @@ -188,15 +199,6 @@
2524 if(con_init_done) up(&vts[console->index].sem);
2527 -static struct tty_operations console_ops = {
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,
2536 static struct tty_driver *console_device(struct console *c, int *index)
2539 @@ -212,12 +214,14 @@
2540 console_device, console_setup,
2543 -static void __init stdio_console_init(void)
2544 +static int __init stdio_console_init(void)
2546 INIT_LIST_HEAD(&vts[0].chan_list);
2547 list_add(&init_console_chan.list, &vts[0].chan_list);
2548 register_console(&stdiocons);
2552 console_initcall(stdio_console_init);
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
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.
2571 #define MAJOR_NR UBD_MAJOR
2573 #include "mconsole_kern.h"
2575 #include "irq_user.h"
2576 +#include "irq_kern.h"
2577 #include "ubd_user.h"
2578 #include "2_5compat.h"
2581 static request_queue_t *ubd_queue;
2583 /* Protected by ubd_lock */
2584 -static int fake_major = 0;
2585 +static int fake_major = MAJOR_NR;
2587 static struct gendisk *ubd_gendisk[MAX_DEV];
2588 static struct gendisk *fake_gendisk[MAX_DEV];
2589 @@ -96,12 +104,12 @@
2597 struct openflags boot_openflags;
2598 struct openflags openflags;
2603 @@ -115,12 +123,12 @@
2605 #define DEFAULT_UBD { \
2611 .boot_openflags = OPEN_FLAGS, \
2612 .openflags = OPEN_FLAGS, \
2614 .cow = DEFAULT_COW, \
2617 @@ -128,8 +136,10 @@
2619 static int ubd0_init(void)
2621 - if(ubd_dev[0].file == NULL)
2622 - ubd_dev[0].file = "root_fs";
2623 + struct ubd *dev = &ubd_dev[0];
2625 + if(dev->file == NULL)
2626 + dev->file = "root_fs";
2630 @@ -196,19 +206,39 @@
2631 " Create ide0 entries that map onto ubd devices.\n\n"
2634 +static int parse_unit(char **ptr)
2636 + char *str = *ptr, *end;
2639 + if(isdigit(*str)) {
2640 + n = simple_strtoul(str, &end, 0);
2645 + else if (('a' <= *str) && (*str <= 'h')) {
2653 static int ubd_setup_common(char *str, int *index_out)
2656 struct openflags flags = global_openflags;
2660 if(index_out) *index_out = -1;
2664 - static int fake_major_allowed = 1;
2669 if(!strcmp(str, "sync")){
2670 global_openflags.s = 1;
2672 @@ -220,20 +250,14 @@
2676 - if(!fake_major_allowed){
2677 - printk(KERN_ERR "Can't assign a fake major twice\n");
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");
2690 - fake_major_allowed = 0;
2692 printk(KERN_INFO "Setting extra ubd major number to %d\n",
2694 @@ -243,25 +267,23 @@
2699 - printk(KERN_ERR "ubd_setup : index out of range\n"); }
2701 - if((n >= '0') && (n <= '9')) n -= '0';
2702 - else if((n >= 'a') && (n <= 'z')) n -= 'a';
2704 - printk(KERN_ERR "ubd_setup : device syntax invalid\n");
2705 + n = parse_unit(&str);
2707 + printk(KERN_ERR "ubd_setup : couldn't parse unit number "
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);
2720 spin_lock(&ubd_lock);
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");
2728 @@ -276,6 +298,11 @@
2738 printk(KERN_ERR "ubd_setup : Expected '='\n");
2740 @@ -284,14 +311,17 @@
2742 backing_file = strchr(str, ',');
2744 - *backing_file = '\0';
2747 + printk(KERN_ERR "Can't specify both 'd' and a "
2750 + *backing_file = '\0';
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;
2760 + dev->cow.file = backing_file;
2761 + dev->boot_openflags = flags;
2763 spin_unlock(&ubd_lock);
2766 static int fakehd_set = 0;
2767 static int fakehd(char *str)
2770 - "fakehd : Changing ubd name to \"hd\".\n");
2771 + printk(KERN_INFO "fakehd : Changing ubd name to \"hd\".\n");
2775 @@ -391,9 +420,10 @@
2776 do_ubd_request(ubd_queue);
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)
2783 + return(IRQ_HANDLED);
2786 /* Only changed by ubd_init, which is an initcall. */
2787 @@ -429,16 +459,18 @@
2788 static int ubd_open_dev(struct ubd *dev)
2790 struct openflags flags;
2791 - int err, n, create_cow, *create_ptr;
2793 + int err, create_cow, *create_ptr;
2795 + dev->openflags = dev->boot_openflags;
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);
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){
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");
2818 flush_tlb_kernel_vm();
2820 err = read_cow_bitmap(dev->fd, dev->cow.bitmap,
2821 @@ -481,17 +516,31 @@
2824 struct gendisk *disk;
2825 + char from[sizeof("ubd/nnnnn\0")], to[sizeof("discnnnnn/disc\0")];
2828 disk = alloc_disk(1 << UBD_SHIFT);
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);
2847 + printk("ubd_new_disk failed to make link from %s to "
2848 + "%s, error = %d\n", from, to, err);
2851 + sprintf(disk->disk_name, "ubd_fake%d", unit);
2852 + sprintf(disk->devfs_name, "ubd_fake/disc%d", unit);
2855 disk->private_data = &ubd_dev[unit];
2856 disk->queue = ubd_queue;
2857 @@ -506,10 +555,7 @@
2858 struct ubd *dev = &ubd_dev[n];
2865 + if(dev->file == NULL)
2868 if (ubd_open_dev(dev))
2874 + if(fake_major != MAJOR_NR)
2875 ubd_new_disk(fake_major, dev->size, n,
2878 @@ -561,42 +607,42 @@
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)
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";
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";
2907 - ubd = &ubd_dev[major];
2908 + dev = &ubd_dev[n];
2909 spin_lock(&ubd_lock);
2911 - if(ubd->file == NULL){
2912 - CONFIG_CHUNK(str, size, n, "", 1);
2913 + if(dev->file == NULL){
2914 + CONFIG_CHUNK(str, size, len, "", 1);
2918 - CONFIG_CHUNK(str, size, n, ubd->file, 0);
2919 + CONFIG_CHUNK(str, size, len, dev->file, 0);
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);
2928 - else CONFIG_CHUNK(str, size, n, "", 1);
2929 + else CONFIG_CHUNK(str, size, len, "", 1);
2932 spin_unlock(&ubd_lock);
2937 static int ubd_remove(char *str)
2938 @@ -604,11 +650,9 @@
2940 int n, err = -ENODEV;
2942 - if(!isdigit(*str))
2943 - return(err); /* it should be a number 0-7/a-h */
2944 + n = parse_unit(&str);
2948 + if((n < 0) || (n >= MAX_DEV))
2954 elevator_init(ubd_queue, &elevator_noop);
2956 - if (fake_major != 0) {
2957 + if (fake_major != MAJOR_NR) {
2958 char name[sizeof("ubd_nnn\0")];
2960 snprintf(name, sizeof(name), "ubd_%d", fake_major);
2961 @@ -714,15 +758,9 @@
2963 struct gendisk *disk = inode->i_bdev->bd_disk;
2964 struct ubd *dev = disk->private_data;
2965 - int err = -EISDIR;
2967 - if(dev->is_dir == 1)
2972 if(dev->count == 0){
2973 - dev->openflags = dev->boot_openflags;
2975 err = ubd_open_dev(dev);
2977 printk(KERN_ERR "%s: Can't open \"%s\": errno = %d\n",
2978 @@ -796,15 +834,6 @@
2980 if(req->rq_status == RQ_INACTIVE) return(1);
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);
2991 if((rq_data_dir(req) == WRITE) && !dev->openflags.w){
2992 printk("Write attempted on readonly ubd device %s\n",
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 @@
2999 #include "ubd_user.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)
3012 -#error "__BYTE_ORDER not defined"
3015 -#define PATH_LEN_V1 256
3017 -struct cow_header_v1 {
3020 - char backing_file[PATH_LEN_V1];
3026 -#define PATH_LEN_V2 MAXPATHLEN
3028 -struct cow_header_v2 {
3029 - unsigned long magic;
3030 - unsigned long version;
3031 - char backing_file[PATH_LEN_V2];
3038 - struct cow_header_v1 v1;
3039 - struct cow_header_v2 v2;
3042 -#define COW_MAGIC 0x4f4f4f4d /* MOOO */
3043 -#define COW_VERSION 2
3045 -static void sizes(__u64 size, int sectorsize, int bitmap_offset,
3046 - unsigned long *bitmap_len_out, int *data_offset_out)
3048 - *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
3050 - *data_offset_out = bitmap_offset + *bitmap_len_out;
3051 - *data_offset_out = (*data_offset_out + sectorsize - 1) / sectorsize;
3052 - *data_offset_out *= sectorsize;
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)
3059 - union cow_header *header;
3062 - unsigned long version, magic;
3064 - header = um_kmalloc(sizeof(*header));
3065 - if(header == NULL){
3066 - printk("read_cow_header - Failed to allocate header\n");
3070 - n = read(fd, header, sizeof(*header));
3071 - if(n < offsetof(typeof(header->v1), backing_file)){
3072 - printk("read_cow_header - short header\n");
3076 - magic = header->v1.magic;
3077 - if(magic == COW_MAGIC) {
3078 - version = header->v1.version;
3080 - else if(magic == ntohl(COW_MAGIC)){
3081 - version = ntohl(header->v1.version);
3085 - *magic_out = COW_MAGIC;
3088 - if(n < sizeof(header->v1)){
3089 - printk("read_cow_header - failed to read V1 header\n");
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;
3098 - else if(version == 2){
3099 - if(n < sizeof(header->v2)){
3100 - printk("read_cow_header - failed to read V2 header\n");
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;
3110 - printk("read_cow_header - invalid COW version\n");
3114 - *backing_file_out = uml_strdup(file);
3115 - if(*backing_file_out == NULL){
3116 - printk("read_cow_header - failed to allocate backing file\n");
3125 static int same_backing_files(char *from_cmdline, char *from_cow, char *cow)
3127 - struct stat buf1, buf2;
3128 + struct stat64 buf1, buf2;
3130 if(from_cmdline == NULL) return(1);
3131 if(!strcmp(from_cmdline, from_cow)) return(1);
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,
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);
3144 @@ -215,118 +97,6 @@
3148 -static int absolutize(char *to, int size, char *from)
3150 - char save_cwd[256], *slash;
3153 - if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
3154 - printk("absolutize : unable to get cwd - errno = %d\n", errno);
3157 - slash = strrchr(from, '/');
3158 - if(slash != NULL){
3162 - printk("absolutize : Can't cd to '%s' - errno = %d\n",
3167 - if(getcwd(to, size) == NULL){
3168 - printk("absolutize : unable to get cwd of '%s' - "
3169 - "errno = %d\n", from, errno);
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);
3178 - strcat(to, slash);
3181 - if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){
3182 - printk("absolutize : unable to fit '%s' into %d "
3183 - "chars\n", from, size);
3186 - strcpy(to, save_cwd);
3194 -static int write_cow_header(char *cow_file, int fd, char *backing_file,
3195 - int sectorsize, long long *size)
3197 - struct cow_header_v2 *header;
3198 - struct stat64 buf;
3201 - err = os_seek_file(fd, 0);
3203 - printk("write_cow_header - lseek failed, errno = %d\n", errno);
3208 - header = um_kmalloc(sizeof(*header));
3209 - if(header == NULL){
3210 - printk("Failed to allocate COW V2 header\n");
3213 - header->magic = htonl(COW_MAGIC);
3214 - header->version = htonl(COW_VERSION);
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);
3224 - if(absolutize(header->backing_file, sizeof(header->backing_file),
3228 - err = stat64(header->backing_file, &buf);
3230 - printk("Stat of backing file '%s' failed, errno = %d\n",
3231 - header->backing_file, errno);
3236 - err = os_file_size(header->backing_file, size);
3238 - printk("Couldn't get size of backing file '%s', errno = %d\n",
3239 - header->backing_file, -*size);
3243 - header->mtime = htonl(buf.st_mtime);
3244 - header->size = htonll(*size);
3245 - header->sectorsize = htonl(sectorsize);
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);
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)
3268 + err = os_lock_file(fd, openflags->w);
3270 + printk("Failed to lock '%s', errno = %d\n", file, -err);
3274 if(backing_file_out == NULL) return(fd);
3276 - err = read_cow_header(fd, &magic, &backing_file, &mtime, &size,
3277 - §orsize, bitmap_offset_out);
3278 + err = read_cow_header(file_reader, &fd, &magic, &backing_file, &mtime,
3279 + &size, §orsize, 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 @@
3287 - sizes(size, sectorsize, *bitmap_offset_out, bitmap_len_out,
3289 + cow_sizes(size, sectorsize, *bitmap_offset_out, bitmap_len_out,
3295 + os_close_file(fd);
3299 @@ -389,10 +166,7 @@
3300 int sectorsize, int *bitmap_offset_out,
3301 unsigned long *bitmap_len_out, int *data_offset_out)
3310 fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL);
3311 @@ -403,29 +177,12 @@
3315 - err = write_cow_header(cow_file, fd, backing_file, sectorsize, &size);
3316 - if(err) goto out_close;
3318 - blocks = (size + sectorsize - 1) / sectorsize;
3319 - blocks = (blocks + sizeof(long) * 8 - 1) / (sizeof(long) * 8);
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);
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);
3338 + err = init_cow_file(fd, cow_file, backing_file, sectorsize,
3339 + bitmap_offset_out, bitmap_len_out,
3343 + os_close_file(fd);
3347 @@ -448,14 +205,6 @@
3351 -int ubd_is_dir(char *file)
3353 - struct stat64 buf;
3355 - if(stat64(file, &buf) < 0) return(0);
3356 - return(S_ISDIR(buf.st_mode));
3359 void do_io(struct io_thread_req *req)
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
3369 - fd = create_unix_socket(file, sizeof(file));
3370 + fd = create_unix_socket(file, sizeof(file), 1);
3372 printk("xterm_open : create_unix_socket failed, errno = %d\n",
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
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"
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)
3397 struct xterm_wait *xterm = data;
3400 fd = os_rcv_fd(xterm->fd, &xterm->pid);
3407 + return(IRQ_HANDLED);
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
3415 . = ALIGN(4096); /* Init code and data */
3418 - .text.init : { *(.text.init) }
3429 #include "asm/common.lds.S"
3431 - .data.init : { *(.data.init) }
3432 + init.data : { *(.init.data) }
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
3441 + * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
3442 + * Licensed under the GPL
3445 +#ifndef __IRQ_KERN_H__
3446 +#define __IRQ_KERN_H__
3448 +#include "linux/interrupt.h"
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,
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
3463 + * ---------------------------------------------------------------------------
3464 + * Local variables:
3465 + * c-file-style: "linux"
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
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);
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);
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
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"
3515 struct line_driver {
3517 + char *device_name;
3523 #define LINES_INIT(n) { num : n }
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
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);
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
3550 extern void set_usable_vm(unsigned long start, unsigned long end);
3551 -extern void set_kmem_end(unsigned long new);
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
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);
3582 extern unsigned long os_process_pc(int pid);
3583 extern int os_process_parent(int pid);
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);
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
3597 #define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
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)
3604 #define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc)))
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
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);
3615 static inline int ubd_test_bit(__u64 bit, unsigned char *data)
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
3621 extern void kfree(void *ptr);
3622 extern int in_aton(char *str);
3623 extern int open_gdb_chan(void);
3625 +extern int strlcpy(char *, const char *, int);
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
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);
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);
3645 +extern void arch_init_thread(void);
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
3654 obj-$(CONFIG_MODE_TT) += tt/
3655 obj-$(CONFIG_MODE_SKAS) += skas/
3657 +clean-files := config.c
3659 user-objs-$(CONFIG_TTY_LOG) += tty_log.o
3661 USER_OBJS := $(filter %_user.o,$(obj-y)) $(user-objs-y) config.o helper.o \
3663 $(obj)/frame.o: $(src)/frame.c
3664 $(CC) $(CFLAGS_$(notdir $@)) -c -o $@ $<
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 $$_ }'
3669 $(obj)/config.c : $(src)/config.c.in $(TOPDIR)/.config
3670 $(PERL) -e $(QUOTE) < $(src)/config.c.in > $@
3672 $(obj)/config.o : $(obj)/config.c
3676 - for dir in $(subdir-y) ; do $(MAKE) -C $$dir clean; done
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
3688 -static __initdata char *config = "
3691 +static __initdata char *config = "CONFIG";
3693 static int __init print_config(char *line, int *add)
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
3699 CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp);
3702 +extern void log_exec(char **argv, void *tty);
3704 static int execve1(char *file, char **argv, char **env)
3708 +#ifdef CONFIG_TTY_LOG
3709 + log_exec(argv, current->tty);
3711 error = do_execve(file, argv, env, ¤t->thread.regs);
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
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);
3724 * Initial task structure.
3726 __attribute__((__section__(".data.init_task"))) =
3727 { INIT_THREAD_INFO(init_task) };
3729 -struct task_struct *alloc_task_struct(void)
3731 - return((struct task_struct *)
3732 - __get_free_pages(GFP_KERNEL, CONFIG_KERNEL_STACK_ORDER));
3735 void unprotect_stack(unsigned long stack)
3737 protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE,
3741 -void free_task_struct(struct task_struct *task)
3743 - /* free_pages decrements the page counter and only actually frees
3744 - * the pages if they are now not accessed by anything.
3746 - free_pages((unsigned long) task, CONFIG_KERNEL_STACK_ORDER);
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
3756 #include "user_util.h"
3757 #include "kern_util.h"
3758 #include "irq_user.h"
3759 +#include "irq_kern.h"
3761 static void register_irq_proc (unsigned int irq);
3768 -volatile unsigned long irq_err_count;
3771 * Generic, controller-independent functions:
3774 -int get_irq_list(char *buf)
3775 +int show_interrupts(struct seq_file *p, void *v)
3778 - unsigned long flags;
3779 struct irqaction * action;
3781 + unsigned long flags;
3783 - p += sprintf(p, " ");
3784 - for (j=0; j<num_online_cpus(); j++)
3785 - p += sprintf(p, "CPU%d ",j);
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');
3793 for (i = 0 ; i < NR_IRQS ; i++) {
3794 spin_lock_irqsave(&irq_desc[i].lock, flags);
3795 action = irq_desc[i].action;
3798 - p += sprintf(p, "%3d: ",i);
3800 + seq_printf(p, "%3d: ",i);
3802 - p += sprintf(p, "%10u ", kstat_irqs(i));
3803 + seq_printf(p, "%10u ", kstat_irqs(i));
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]);
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);
3817 for (action=action->next; action; action = action->next)
3818 - p += sprintf(p, ", %s", action->name);
3821 + seq_printf(p, ", %s", action->name);
3823 + seq_putc(p, '\n');
3825 spin_unlock_irqrestore(&irq_desc[i].lock, flags);
3827 - p += sprintf(p, "\n");
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");
3837 - p += sprintf(p, "ERR: %10lu\n", irq_err_count);
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');
3847 -int show_interrupts(struct seq_file *p, void *v)
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)
3858 - int cpu = smp_processor_id();
3859 irq_desc_t *desc = irq_desc + irq;
3860 struct irqaction * action;
3861 unsigned int status;
3864 - kstat_cpu(cpu).irqs[irq]++;
3865 + kstat_this_cpu.irqs[irq]++;
3866 spin_lock(&desc->lock);
3867 desc->handler->ack(irq);
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,
3878 @@ -430,15 +417,19 @@
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,
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);
3898 + err = activate_fd(irq, fd, type, dev_id);
3902 /* this was setup_x86_irq but it seems pretty generic */
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));
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 @@
3919 -void set_kmem_end(unsigned long new)
3924 #ifdef CONFIG_HIGHMEM
3925 /* Changed during early boot */
3928 if(regions[i] == NULL) break;
3931 - printk("setup_range : no free regions\n");
3932 + printk("setup_one_range : no free regions\n");
3937 fd = create_mem_file(len);
3940 - region = alloc_bootmem_low_pages(sizeof(*region));
3942 + region = kmalloc(sizeof(*region), GFP_KERNEL);
3943 + else region = alloc_bootmem_low_pages(sizeof(*region));
3945 panic("Failed to allocating mem_region");
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,
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)
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 @@
3967 + if(offset >= region->len){
3968 + printf("%ld bytes of physical memory is insufficient\n",
3972 loc = mmap(start, region->len - offset, PROT_READ | PROT_WRITE,
3973 MAP_SHARED | MAP_FIXED, region->fd, offset);
3975 @@ -122,26 +127,26 @@
3977 static int __init parse_iomem(char *str, int *add)
3980 + struct stat64 buf;
3981 char *file, *driver;
3985 file = strchr(str,',');
3987 - printk("parse_iomem : failed to parse iomem\n");
3988 + printf("parse_iomem : failed to parse iomem\n");
3993 fd = os_open_file(file, of_rdwr(OPENFLAGS()), 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",
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);
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
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);
4017 init_irq_signals(altstack);
4019 if(err < 0) panic("Waiting for outer trampoline failed - errno = %d",
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);
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
4033 struct task_struct *get_task(int pid, int require)
4035 - struct task_struct *task, *ret;
4036 + struct task_struct *ret;
4039 read_lock(&tasklist_lock);
4040 - for_each_process(task){
4041 - if(task->pid == pid){
4046 + ret = find_task_by_pid(pid);
4047 read_unlock(&tasklist_lock);
4049 if(require && (ret == NULL)) panic("get_task couldn't find a task\n");
4052 @@ -103,13 +98,14 @@
4054 int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
4056 - struct task_struct *p;
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");
4064 + pid = do_fork(CLONE_VM | flags, 0, NULL, 0, NULL, NULL);
4066 + panic("do_fork failed in kernel_thread, errno = %d", pid);
4070 void switch_mm(struct mm_struct *prev, struct mm_struct *next,
4072 { external_pid(task), task });
4075 -void *switch_to(void *prev, void *next, void *last)
4076 +void *_switch_to(void *prev, void *next, void *last)
4078 return(CHOOSE_MODE(switch_to_tt(prev, next),
4079 switch_to_skas(prev, next)));
4081 void exit_thread(void)
4083 CHOOSE_MODE(exit_thread_tt(), exit_thread_skas());
4084 - unprotect_stack((unsigned long) current->thread_info);
4085 + unprotect_stack((unsigned long) current_thread);
4088 void *get_current(void)
4089 @@ -157,6 +153,10 @@
4093 +void prepare_to_copy(struct task_struct *tsk)
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)
4102 void default_idle(void)
4107 atomic_inc(&init_mm.mm_count);
4108 current->mm = &init_mm;
4109 @@ -363,10 +363,15 @@
4110 return(clear_user(buf, size));
4113 +int strlen_user_proc(char *str)
4115 + return(strlen_user(str));
4118 int smp_sigio_handler(void)
4121 - int cpu = current->thread_info->cpu;
4122 + int cpu = current_thread->cpu;
4130 - return(current->thread_info->cpu);
4131 + return(current_thread->cpu);
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 @@
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)
4144 - current->state = TASK_STOPPED;
4145 - notify_parent(current, SIGCHLD);
4147 + ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
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
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"
4164 #include "irq_user.h"
4165 +#include "irq_kern.h"
4167 /* Protected by sigio_lock() called from write_sigio_workaround */
4168 static int sigio_irq_fd = -1;
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)
4173 read_sigio_fd(sigio_irq_fd);
4174 reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ);
4175 + return(IRQ_HANDLED);
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
4184 struct k_sigaction *ka;
4186 - ka = ¤t->sig->action[SIGSEGV - 1];
4187 + ka = ¤t->sighand->action[SIGSEGV - 1];
4188 ka->sa.sa_handler = SIG_DFL;
4190 force_sig(SIGSEGV, current);
4194 /* Whee! Actually deliver the signal. */
4195 - ka = ¤t->sig->action[sig -1 ];
4196 + ka = ¤t->sighand->action[sig -1 ];
4197 err = handle_signal(regs, sig, ka, &info, oldset, error);
4204 -int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize)
4205 +int sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize)
4207 sigset_t saveset, newset;
4209 @@ -227,6 +227,42 @@
4213 +int sys_sigaction(int sig, const struct old_sigaction __user *act,
4214 + struct old_sigaction __user *oact)
4216 + struct k_sigaction new_ka, old_ka;
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))
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);
4230 + ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
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))
4237 + __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
4238 + __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
4244 +int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
4246 + return(do_sigaltstack(uss, uoss, PT_REGS_SP(¤t->thread.regs)));
4249 static int copy_sc_from_user(struct pt_regs *to, void *from,
4250 struct arch_frame_data *arch)
4254 int sys_sigreturn(struct pt_regs regs)
4256 - void *sc = sp_to_sc(PT_REGS_SP(¤t->thread.regs));
4257 - void *mask = sp_to_mask(PT_REGS_SP(¤t->thread.regs));
4258 + void __user *sc = sp_to_sc(PT_REGS_SP(¤t->thread.regs));
4259 + void __user *mask = sp_to_mask(PT_REGS_SP(¤t->thread.regs));
4260 int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
4262 spin_lock_irq(¤t->sighand->siglock);
4265 int sys_rt_sigreturn(struct pt_regs regs)
4267 - struct ucontext *uc = sp_to_uc(PT_REGS_SP(¤t->thread.regs));
4268 + unsigned long sp = PT_REGS_SP(¤t->thread.regs);
4269 + struct ucontext __user *uc = sp_to_uc(sp);
4271 int sig_size = _NSIG_WORDS * sizeof(unsigned long);
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
4277 process_kern.o syscall_kern.o syscall_user.o time.o tlb.o trap_user.o \
4280 +host-progs := util/mk_ptregs
4281 +clean-files := include/skas_ptregs.h
4283 USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o
4284 USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
4286 -include/skas_ptregs.h : util/mk_ptregs
4287 - util/mk_ptregs > $@
4291 +$(TOPDIR)/arch/um/include/skas_ptregs.h : $(src)/util/mk_ptregs
4292 + @echo -n ' Generating $@'
4294 + @if [ -r $@ ] && cmp -s $@ $@.tmp; then \
4295 + echo ' (unchanged)'; \
4298 + echo ' (updated)'; \
4299 + mv -f $@.tmp $@; \
4302 $(USER_OBJS) : %.o: %.c
4303 $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
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
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);
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
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)))
4329 static inline int verify_area_skas(int type, const void * addr,
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
4338 +#include <unistd.h>
4344 #include "proc_mm.h"
4345 #include "skas_ptrace.h"
4346 +#include "chan_user.h"
4348 +int is_skas_winch(int pid, int fd, void *data)
4350 + if(pid != getpid())
4353 + register_winch_irq(-1, fd, -1, data);
4357 unsigned long exec_regs[FRAME_SIZE];
4358 unsigned long exec_fp_regs[HOST_FP_SIZE];
4360 int err, syscall_nr, status;
4362 syscall_nr = PT_SYSCALL_NR(regs->skas.regs);
4363 + UPT_SYSCALL_NR(regs) = syscall_nr;
4365 relay_signal(SIGTRAP, regs);
4368 - UPT_SYSCALL_NR(regs) = syscall_nr;
4370 err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid);
4373 handle_syscall(regs);
4378 static int userspace_tramp(void *arg)
4380 init_new_thread_signals(0);
4387 void start_userspace(void)
4395 user_signal(WSTOPSIG(status), regs);
4399 int new_mm(int from)
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);
4409 printk("new_mm : /proc/mm copy_segments failed, "
4410 "errno = %d\n", errno);
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
4420 thread_wait(¤t->thread.mode.skas.switch_buf,
4421 current->thread.mode.skas.fork_buf);
4424 - schedule_tail(NULL);
4426 + if(current->thread.prev_sched != NULL)
4427 + schedule_tail(current->thread.prev_sched);
4428 current->thread.prev_sched = NULL;
4430 n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf);
4432 current->thread.mode.skas.fork_buf);
4436 - schedule_tail(current->thread.prev_sched);
4438 + if(current->thread.prev_sched != NULL)
4439 + schedule_tail(current->thread.prev_sched);
4440 current->thread.prev_sched = NULL;
4445 void init_idle_skas(void)
4447 - cpu_tasks[current->thread_info->cpu].pid = os_getpid();
4448 + cpu_tasks[current_thread->cpu].pid = os_getpid();
4453 capture_signal_stack();
4455 init_new_thread_signals(1);
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
4466 #include <asm/ptrace.h>
4467 #include <asm/user.h>
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
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;
4479 /* Per CPU bogomips and other parameters
4480 * The only piece used here is the ipi pipe, which is set before SMP is
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)
4488 write(cpu_data[i].ipi_pipe[1], "S", 1);
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;
4498 static int idle_proc(void *cpup)
4500 @@ -120,12 +120,12 @@
4501 current->thread.mode.tt.extern_pid);
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);
4510 - while (!cpu_isset(cpu, &smp_commenced_mask))
4511 + while (!cpu_isset(cpu, smp_commenced_mask))
4514 cpu_set(cpu, cpu_online_map);
4515 @@ -140,8 +140,11 @@
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,
4523 + if(IS_ERR(new_task))
4524 + panic("copy_process failed in idle_thread, error = %ld",
4525 + PTR_ERR(new_task));
4527 cpu_tasks[cpu] = ((struct cpu_task)
4528 { .pid = new_task->thread.mode.tt.extern_pid,
4530 CHOOSE_MODE(write(new_task->thread.mode.tt.switch_pipe[1], &c,
4532 ({ panic("skas mode doesn't support SMP"); }));
4533 + wake_up_forked_process(new_task);
4537 @@ -157,15 +161,16 @@
4539 struct task_struct *idle;
4540 unsigned long waittime;
4542 + int err, cpu, me = smp_processor_id();
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);
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);
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);
4558 for(cpu = 1; cpu < ncpus; cpu++){
4559 @@ -177,10 +182,10 @@
4560 unhash_process(idle);
4562 waittime = 200000000;
4563 - while (waittime-- && !cpu_isset(cpu, smp_callin_map))
4564 + while (waittime-- && !cpu_isset(cpu, cpu_callin_map))
4567 - if (cpu_isset(cpu, smp_callin_map))
4568 + if (cpu_isset(cpu, cpu_callin_map))
4570 else printk("failed\n");
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);
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;
4635 #define NFSSERVCTL sys_nfsservctl
4637 extern syscall_handler_t um_time;
4638 extern syscall_handler_t um_stime;
4640 -#define LAST_GENERIC_SYSCALL __NR_set_tid_address
4641 +#define LAST_GENERIC_SYSCALL __NR_fadvise64_64
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,
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
4724 - struct task_struct *p;
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);
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)
4739 - struct task_struct *p;
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);
4750 long sys_vfork(void)
4752 - struct task_struct *p;
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,
4759 current->thread.forking = 0;
4760 - return(IS_ERR(p) ? PTR_ERR(p) : p->pid);
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)
4774 struct file * file = NULL;
4779 - down_write(¤t->mm->mmap_sem);
4780 - error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff);
4781 - up_write(¤t->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);
4789 unsigned long prot, unsigned long flags,
4790 unsigned long fd, unsigned long pgoff)
4792 - return do_mmap2(addr, len, prot, flags, fd, pgoff);
4793 + return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff);
4798 if (offset & ~PAGE_MASK)
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);
4807 @@ -141,37 +143,6 @@
4811 -int sys_sigaction(int sig, const struct old_sigaction *act,
4812 - struct old_sigaction *oact)
4814 - struct k_sigaction new_ka, old_ka;
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))
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);
4828 - ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);
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))
4835 - __put_user(old_ka.sa.sa_flags, &oact->sa_flags);
4836 - __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
4843 * sys_ipc() is the de-multiplexer for the SysV IPC calls..
4846 return sys_shmctl (first, second,
4847 (struct shmid_ds *) ptr);
4854 @@ -302,11 +273,6 @@
4858 -int sys_sigaltstack(const stack_t *uss, stack_t *uoss)
4860 - return(do_sigaltstack(uss, uoss, PT_REGS_SP(¤t->thread.regs)));
4863 long execute_syscall(void *r)
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
4870 show_trace((unsigned long *)esp);
4873 +void show_stack(struct task_struct *task, unsigned long *sp)
4876 + show_trace_task(task);
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
4888 #include "process.h"
4889 #include "signal_user.h"
4890 #include "time_user.h"
4891 +#include "kern_constants.h"
4893 extern struct timeval xtime;
4895 +struct timeval local_offset = { 0, 0 };
4899 gettimeofday(&xtime, NULL);
4900 + timeradd(&xtime, &local_offset, &xtime);
4903 void set_interval(int timer_type)
4908 -void idle_timer(void)
4909 +void uml_idle_timer(void)
4911 if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR)
4912 panic("Couldn't unset SIGVTALRM handler");
4914 set_interval(ITIMER_VIRTUAL);
4917 -struct timeval local_offset = { 0, 0 };
4919 void do_gettimeofday(struct timeval *tv)
4921 unsigned long flags;
4923 unsigned long flags;
4924 struct timeval tv_in;
4926 - if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
4927 + if ((unsigned long) tv->tv_nsec >= UM_NSEC_PER_SEC)
4930 tv_in.tv_sec = tv->tv_sec;
4932 gettimeofday(&now, NULL);
4933 timersub(&tv_in, &now, &local_offset);
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
4945 void timer_irq(union uml_pt_regs *regs)
4947 - int cpu = current->thread_info->cpu, ticks = missed_ticks[cpu];
4948 + int cpu = current_thread->cpu, ticks = missed_ticks[cpu];
4950 if(!timer_irq_inited) return;
4951 missed_ticks[cpu] = 0;
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)
4960 - write_seqlock(&xtime_lock);
4961 + write_seqlock_irq(&xtime_lock);
4963 - write_sequnlock(&xtime_lock);
4964 + write_sequnlock_irq(&xtime_lock);
4965 + return(IRQ_HANDLED);
4968 long um_time(int * tloc)
4970 long um_stime(int * tptr)
4973 - struct timeval new;
4974 + struct timespec new;
4976 if (get_user(value, tptr))
4981 do_settimeofday(&new);
4984 @@ -122,9 +123,11 @@
4985 void timer_handler(int sig, union uml_pt_regs *regs)
4988 + local_irq_disable();
4989 update_process_times(user_context(UPT_SP(regs)));
4990 + local_irq_enable();
4992 - if(current->thread_info->cpu == 0)
4993 + if(current_thread->cpu == 0)
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
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"
5009 if(is_write && !(vma->vm_flags & VM_WRITE))
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);
5021 +void winch(int sig, union uml_pt_regs *regs)
5023 + do_IRQ(WINCH_IRQ, regs);
5026 void trap_init(void)
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
5034 [ SIGILL ] { .handler = relay_signal,
5036 + [ SIGWINCH ] { .handler = winch,
5038 [ SIGBUS ] { .handler = bus_handler,
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
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());
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);
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
5070 static inline int copy_from_user_tt(void *to, const void *from, int n)
5072 - return(access_ok_tt(VERIFY_READ, from, n) ?
5073 - __do_copy_from_user(to, from, n,
5074 - ¤t->thread.fault_addr,
5075 - ¤t->thread.fault_catcher) : n);
5076 + if(!access_ok_tt(VERIFY_READ, from, n))
5079 + return(__do_copy_from_user(to, from, n, ¤t->thread.fault_addr,
5080 + ¤t->thread.fault_catcher));
5083 static inline int copy_to_user_tt(void *to, const void *from, int n)
5085 - return(access_ok_tt(VERIFY_WRITE, to, n) ?
5086 - __do_copy_to_user(to, from, n,
5087 - ¤t->thread.fault_addr,
5088 - ¤t->thread.fault_catcher) : n);
5089 + if(!access_ok_tt(VERIFY_WRITE, to, n))
5092 + return(__do_copy_to_user(to, from, n, ¤t->thread.fault_addr,
5093 + ¤t->thread.fault_catcher));
5096 extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
5101 - if(!access_ok_tt(VERIFY_READ, src, 1)) return(-EFAULT);
5102 + if(!access_ok_tt(VERIFY_READ, src, 1))
5105 n = __do_strncpy_from_user(dst, src, count,
5106 ¤t->thread.fault_addr,
5107 ¤t->thread.fault_catcher);
5110 static inline int clear_user_tt(void *mem, int len)
5112 - return(access_ok_tt(VERIFY_WRITE, mem, len) ?
5113 - __do_clear_user(mem, len,
5114 - ¤t->thread.fault_addr,
5115 - ¤t->thread.fault_catcher) : len);
5116 + if(!access_ok_tt(VERIFY_WRITE, mem, len))
5119 + return(__do_clear_user(mem, len, ¤t->thread.fault_addr,
5120 + ¤t->thread.fault_catcher));
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 @@
5129 void release_thread_tt(struct task_struct *task)
5131 - os_kill_process(task->thread.mode.tt.extern_pid, 0);
5132 + int pid = task->thread.mode.tt.extern_pid;
5134 + if(os_getpid() != pid)
5135 + os_kill_process(pid, 0);
5138 void exit_thread_tt(void)
5139 @@ -125,27 +128,27 @@
5140 UPT_SC(¤t->thread.regs.regs) = (void *) (&sig + 1);
5141 suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
5144 + force_flush_all();
5145 + if(current->thread.prev_sched != NULL)
5146 + schedule_tail(current->thread.prev_sched);
5147 + current->thread.prev_sched = NULL;
5149 init_new_thread_signals(1);
5151 - schedule_tail(current->thread.prev_sched);
5154 free_page(current->thread.temp_stack);
5155 set_cmdline("(kernel thread)");
5156 - force_flush_all();
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, ¤t->thread.exec_buf))
5168 static int new_thread_proc(void *stack)
5170 + local_irq_disable();
5171 init_new_thread_stack(stack, new_thread_handler);
5172 os_usr1_process(os_getpid());
5174 @@ -165,35 +168,32 @@
5175 UPT_SC(¤t->thread.regs.regs) = (void *) (&sig + 1);
5176 suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
5179 - schedule_tail(NULL);
5181 + force_flush_all();
5182 + if(current->thread.prev_sched != NULL)
5183 + schedule_tail(current->thread.prev_sched);
5184 + current->thread.prev_sched = NULL;
5187 change_sig(SIGVTALRM, 1);
5189 - force_flush_all();
5190 if(current->mm != current->parent->mm)
5191 protect_memory(uml_reserved, high_physmem - uml_reserved, 1,
5193 - task_protections((unsigned long) current->thread_info);
5195 - current->thread.prev_sched = NULL;
5196 + task_protections((unsigned long) current_thread);
5198 free_page(current->thread.temp_stack);
5199 + local_irq_disable();
5200 change_sig(SIGUSR1, 0);
5201 set_user_mode(current);
5204 -static int sigusr1 = SIGUSR1;
5206 int fork_tramp(void *stack)
5208 - int sig = sigusr1;
5210 local_irq_disable();
5211 + arch_init_thread();
5212 init_new_thread_stack(stack, finish_fork_handler);
5214 - kill(os_getpid(), sig);
5215 + os_usr1_process(os_getpid());
5221 pages = (1 << CONFIG_KERNEL_STACK_ORDER);
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);
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 @@
5236 char gdb_init_string[] =
5240 -handle SIGWINCH nostop noprint pass
5244 +handle SIGWINCH nostop noprint pass \n\
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
5254 register_winch_irq(tracer_winch[0], fd, -1, data);
5259 static void tracer_winch_handler(int sig)
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);
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
5274 #include "user_util.h"
5275 #include "uml_uaccess.h"
5277 +#include "kern_util.h"
5279 int __do_copy_from_user(void *to, const void *from, int n,
5280 void **fault_addr, void **fault_catcher)
5282 + struct tt_regs save = TASK_REGS(get_current())->tt;
5283 unsigned long fault;
5286 fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
5287 __do_copy, &faulted);
5288 + TASK_REGS(get_current())->tt = save;
5290 if(!faulted) return(0);
5291 else return(n - (fault - (unsigned long) from));
5294 int __do_strncpy_from_user(char *dst, const char *src, unsigned long count,
5295 void **fault_addr, void **fault_catcher)
5297 + struct tt_regs save = TASK_REGS(get_current())->tt;
5298 unsigned long fault;
5301 fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher,
5302 __do_strncpy, &faulted);
5303 + TASK_REGS(get_current())->tt = save;
5305 if(!faulted) return(strlen(dst));
5309 int __do_clear_user(void *mem, unsigned long len,
5310 void **fault_addr, void **fault_catcher)
5312 + struct tt_regs save = TASK_REGS(get_current())->tt;
5313 unsigned long fault;
5316 fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher,
5317 __do_clear, &faulted);
5318 + TASK_REGS(get_current())->tt = save;
5320 if(!faulted) return(0);
5321 else return(len - (fault - (unsigned long) mem));
5324 int __do_strnlen_user(const char *str, unsigned long n,
5325 void **fault_addr, void **fault_catcher)
5327 + struct tt_regs save = TASK_REGS(get_current())->tt;
5329 unsigned long *faddrp = (unsigned long *)fault_addr;
5334 *fault_catcher = NULL;
5336 + TASK_REGS(get_current())->tt = save;
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
5344 #include <sys/time.h>
5347 +#include "kern_util.h"
5350 #define TTY_LOG_DIR "./"
5352 #define TTY_LOG_OPEN 1
5353 #define TTY_LOG_CLOSE 2
5354 #define TTY_LOG_WRITE 3
5355 +#define TTY_LOG_EXEC 4
5358 +#define TTY_WRITE 2
5360 struct tty_log_buf {
5365 + unsigned long sec;
5366 + unsigned long usec;
5369 -int open_tty_log(void *tty)
5370 +int open_tty_log(void *tty, void *current_tty)
5373 struct tty_log_buf data;
5374 char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")];
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,
5382 + data = ((struct tty_log_buf) { .what = TTY_LOG_OPEN,
5383 + .tty = (unsigned long) tty,
5384 + .len = sizeof(current_tty),
5387 + .usec = tv.tv_usec } );
5388 write(tty_log_fd, &data, sizeof(data));
5389 + write(tty_log_fd, ¤t_tty, data.len);
5393 - gettimeofday(&tv, NULL);
5394 sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec,
5395 (unsigned int) tv.tv_usec);
5397 @@ -62,30 +74,114 @@
5398 void close_tty_log(int fd, void *tty)
5400 struct tty_log_buf data;
5401 + struct timeval tv;
5403 if(tty_log_fd != -1){
5404 - data = ((struct tty_log_buf) { what : TTY_LOG_CLOSE,
5405 - tty : (unsigned long) tty,
5407 + gettimeofday(&tv, NULL);
5408 + data = ((struct tty_log_buf) { .what = TTY_LOG_CLOSE,
5409 + .tty = (unsigned long) tty,
5413 + .usec = tv.tv_usec } );
5414 write(tty_log_fd, &data, sizeof(data));
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)
5423 + int total = 0, try, missed, n;
5427 + try = (len > sizeof(chunk)) ? sizeof(chunk) : len;
5428 + missed = copy_from_user_proc(chunk, (char *) buf, try);
5430 + n = write(fd, chunk, try);
5444 +int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read)
5446 + struct timeval tv;
5447 struct tty_log_buf data;
5450 if(fd == tty_log_fd){
5451 - data = ((struct tty_log_buf) { what : TTY_LOG_WRITE,
5452 - tty : (unsigned long) tty,
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,
5459 + .direction = direction,
5461 + .usec = tv.tv_usec } );
5462 write(tty_log_fd, &data, sizeof(data));
5464 - return(write(fd, buf, len));
5466 + return(log_chunk(fd, buf, len));
5469 +void log_exec(char **argv, void *tty)
5471 + struct timeval tv;
5472 + struct tty_log_buf data;
5476 + if(tty_log_fd == -1) return;
5478 + gettimeofday(&tv, NULL);
5481 + for(ptr = argv; ; ptr++){
5482 + if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
5484 + if(arg == NULL) break;
5485 + len += strlen_user_proc(arg);
5488 + data = ((struct tty_log_buf) { .what = TTY_LOG_EXEC,
5489 + .tty = (unsigned long) tty,
5493 + .usec = tv.tv_usec } );
5494 + write(tty_log_fd, &data, sizeof(data));
5496 + for(ptr = argv; ; ptr++){
5497 + if(copy_from_user_proc(&arg, ptr, sizeof(arg)))
5499 + if(arg == NULL) break;
5500 + log_chunk(tty_log_fd, arg, strlen_user_proc(arg));
5504 +extern void register_tty_logger(int (*opener)(void *, void *),
5505 + int (*writer)(int, const char *, int,
5507 + void (*closer)(int, void *));
5509 +static int register_logger(void)
5511 + register_tty_logger(open_tty_log, write_tty_log, close_tty_log);
5515 +__uml_initcall(register_logger);
5517 static int __init set_tty_log_dir(char *name, int *add)
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);
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
5533 #include "mode_kern.h"
5536 -#define DEFAULT_COMMAND_LINE "root=6200"
5537 +#define DEFAULT_COMMAND_LINE "root=ubd0"
5539 struct cpuinfo_um boot_cpu_data = {
5540 .loops_per_jiffy = 0,
5541 .ipi_pipe = { -1, -1 }
5544 +/* Placeholder to make UML link until the vsyscall stuff is actually
5547 +void *__kernel_vsyscall;
5549 unsigned long thread_saved_pc(struct task_struct *task)
5551 return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas,
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);
5569 @@ -134,12 +143,12 @@
5571 snprintf(argv1_begin,
5572 (argv1_end - argv1_begin) * sizeof(*ptr),
5575 ptr = &argv1_begin[strlen(argv1_begin)];
5577 else ptr = argv1_begin;
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));
5585 static int __init uml_ncpus_setup(char *line, int *add)
5587 if (!sscanf(line, "%d", &ncpus)) {
5588 - printk("Couldn't parse [%s]\n", line);
5589 + printf("Couldn't parse [%s]\n", line);
5595 static int __init mode_tt_setup(char *line, int *add)
5597 - printk("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
5598 + printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
5604 static int __init mode_tt_setup(char *line, int *add)
5606 - printk("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
5607 + printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
5614 task_protections((unsigned long) &init_thread_info);
5615 + os_flush_stdout();
5617 return(CHOOSE_MODE(start_uml_tt(), start_uml_skas()));
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
5623 static int umid_is_random = 1;
5624 static int umid_inited = 0;
5626 -static int make_umid(void);
5627 +static int make_umid(int (*printer)(const char *fmt, ...));
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, ...))
5634 - printk("Unique machine name can't be set twice\n");
5635 + (*printer)("Unique machine name can't be set twice\n");
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));
5646 umid_is_random = is_random;
5649 static int __init set_umid_arg(char *name, int *add)
5651 - return(set_umid(name, 0));
5652 + return(set_umid(name, 0, printf));
5655 __uml_setup("umid=", set_umid_arg,
5660 - if(!umid_inited && make_umid()) return(-1);
5661 + if(!umid_inited && make_umid(printk)) return(-1);
5663 n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1;
5666 fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))),
5669 - printk("Open of machine pid file \"%s\" failed - "
5670 + printf("Open of machine pid file \"%s\" failed - "
5671 "errno = %d\n", file, -fd);
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);
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",
5692 char *home = getenv("HOME");
5695 - printk("make_uml_dir : no value in environment for "
5696 + printf("make_uml_dir : no value in environment for "
5700 @@ -239,25 +240,25 @@
5701 strcpy(uml_dir, dir);
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);
5711 -static int __init make_umid(void)
5712 +static int __init make_umid(int (*printer)(const char *fmt, ...))
5715 char tmp[strlen(uml_dir) + UMID_LEN + 1];
5717 strlcpy(tmp, uml_dir, sizeof(tmp));
5721 strcat(tmp, "XXXXXX");
5724 - printk("make_umid - mkstemp failed, errno = %d\n",
5726 + (*printer)("make_umid - mkstemp failed, errno = %d\n",
5735 - set_umid(&tmp[strlen(uml_dir)], 1);
5736 + set_umid(&tmp[strlen(uml_dir)], 1, printer);
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);
5748 err = mkdir(tmp, 0777);
5752 - printk("Failed to create %s - errno = %d\n", umid, errno);
5753 + (*printer)("Failed to create %s - errno = %d\n", umid, errno);
5757 @@ -295,7 +296,13 @@
5760 __uml_postsetup(make_uml_dir);
5761 -__uml_postsetup(make_umid);
5763 +static int __init make_umid_setup(void)
5765 + return(make_umid(printf));
5768 +__uml_postsetup(make_umid_setup);
5769 __uml_postsetup(create_pid_file);
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 @@
5779 -int clone_and_wait(int (*fn)(void *), void *arg, void *sp, int flags)
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);
5790 int raw(int fd, int complain)
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
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
5812 -int create_unix_socket(char *file, int len)
5813 +int create_unix_socket(char *file, int len, int close_on_exec)
5815 struct sockaddr_un addr;
5817 @@ -327,6 +327,10 @@
5821 + if(close_on_exec && fcntl(sock, F_SETFD, 1) < 0)
5822 + printk("create_unix_socket : Setting FD_CLOEXEC failed, "
5823 + "errno = %d", errno);
5825 addr.sun_family = AF_UNIX;
5827 /* XXX Be more careful about overflow */
5828 @@ -342,6 +346,37 @@
5832 +void os_flush_stdout(void)
5837 +int os_lock_file(int fd, int excl)
5839 + int type = excl ? F_WRLCK : F_RDLCK;
5840 + struct flock lock = ((struct flock) { .l_type = type,
5841 + .l_whence = SEEK_SET,
5846 + err = fcntl(fd, F_SETLK, &lock);
5851 + err = fcntl(fd, F_GETLK, &lock);
5857 + printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid);
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
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
5875 obj-$(CONFIG_HIGHMEM) += highmem.o
5876 +obj-$(CONFIG_MODULES) += module.o
5878 USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o
5879 USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
5881 SYMLINKS = semaphore.c highmem.c module.c
5882 SYMLINKS := $(foreach f,$(SYMLINKS),$(src)/$f)
5884 +clean-files := $(SYMLINKS)
5886 semaphore.c-dir = kernel
5888 module.c-dir = kernel
5891 $(call make_link,$@)
5894 - $(MAKE) -C util clean
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
5905 #include <sys/signal.h>
5906 +#include <asm/ldt.h>
5907 #include "kern_util.h"
5909 #include "sysdep/ptrace.h"
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;
5919 static char token(int fd, char *buf, int len, char stop)
5921 @@ -104,6 +105,25 @@
5925 +static void disable_lcall(void)
5927 + struct modify_ldt_ldt_s ldt;
5930 + bzero(&ldt, sizeof(ldt));
5931 + ldt.entry_number = 7;
5932 + ldt.base_addr = 0;
5934 + err = modify_ldt(1, &ldt, sizeof(ldt));
5936 + printk("Failed to disable lcall7 - errno = %d\n", errno);
5939 +void arch_init_thread(void)
5944 void arch_check_bugs(void)
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;
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))
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 "
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 "
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 "
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);
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
5985 . = ALIGN(4096); /* Init code and data */
5988 - .text.init : { *(.text.init) }
5999 #include "asm/common.lds.S"
6001 - .data.init : { *(.data.init) }
6002 + init.data : { *(init.data) }
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
6010 #include "linux/kernel.h"
6011 #include "linux/stringify.h"
6012 +#include "linux/time.h"
6013 #include "asm/page.h"
6015 extern void print_head(void);
6019 print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE);
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);
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);
6029 + print_constant_int("UM_NSEC_PER_SEC", NSEC_PER_SEC);
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
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
6047 +# Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
6048 +# Licensed under the GPL
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.
6055 +STAT64_INO_FIELD := $(shell grep -q __st_ino /usr/include/bits/stat.h && \
6058 +hostfs-objs := hostfs_kern.o hostfs_user.o
6061 +obj-$(CONFIG_HOSTFS) += hostfs.o
6063 +SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs))
6065 +USER_OBJS := $(filter %_user.o,$(obj-y) $(obj-m) $(SINGLE_OBJS))
6066 +USER_OBJS := $(foreach file,$(USER_OBJS),$(obj)/$(file))
6068 +USER_CFLAGS += -DSTAT64_INO_FIELD=$(STAT64_INO_FIELD)
6070 +$(USER_OBJS) : %.o: %.c
6071 + $(CC) $(CFLAGS_$(notdir $@)) $(USER_CFLAGS) -c -o $@ $<
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
6086 +#ifndef __UM_FS_HOSTFS
6087 +#define __UM_FS_HOSTFS
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.
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
6107 +struct hostfs_iattr {
6108 + unsigned int ia_valid;
6113 + struct timespec ia_atime;
6114 + struct timespec ia_mtime;
6115 + struct timespec ia_ctime;
6116 + unsigned int ia_attr_flags;
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,
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,
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
6160 + * ---------------------------------------------------------------------------
6161 + * Local variables:
6162 + * c-file-style: "linux"
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
6170 + * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
6171 + * Licensed under the GPL
6173 + * Ported the filesystem routines to 2.5.
6174 + * 2003-02-10 Petr Baudis <pasky@ucw.cz>
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"
6193 +#include "user_util.h"
6194 +#include "2_5compat.h"
6197 +struct hostfs_inode_info {
6198 + char *host_filename;
6201 + struct inode vfs_inode;
6204 +static inline struct hostfs_inode_info *HOSTFS_I(struct inode *inode)
6206 + return(list_entry(inode, struct hostfs_inode_info, vfs_inode));
6209 +#define FILE_HOSTFS_I(file) HOSTFS_I((file)->f_dentry->d_inode)
6211 +int hostfs_d_delete(struct dentry *dentry)
6216 +struct dentry_operations hostfs_dentry_ops = {
6217 + .d_delete = hostfs_d_delete,
6220 +/* Changed in hostfs_args before the kernel starts running */
6221 +static char *root_ino = "/";
6222 +static int append = 0;
6224 +#define HOSTFS_SUPER_MAGIC 0x00c0ffee
6226 +static struct inode_operations hostfs_iops;
6227 +static struct inode_operations hostfs_dir_iops;
6228 +static struct address_space_operations hostfs_link_aops;
6230 +static int __init hostfs_args(char *options, int *add)
6234 + ptr = strchr(options, ',');
6237 + if(*options != '\0')
6238 + root_ino = options;
6242 + ptr = strchr(options, ',');
6245 + if(*options != '\0'){
6246 + if(!strcmp(options, "append"))
6248 + else printf("hostfs_args - unsupported option - %s\n",
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"
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"
6267 +static char *dentry_name(struct dentry *dentry, int extra)
6269 + struct dentry *parent;
6270 + char *root, *name;
6275 + while(parent->d_parent != parent){
6276 + len += parent->d_name.len + 1;
6277 + parent = parent->d_parent;
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);
6287 + while(parent->d_parent != parent){
6288 + len -= parent->d_name.len + 1;
6290 + strncpy(&name[len + 1], parent->d_name.name,
6291 + parent->d_name.len);
6292 + parent = parent->d_parent;
6294 + strncpy(name, root, strlen(root));
6298 +static char *inode_name(struct inode *ino, int extra)
6300 + struct dentry *dentry;
6302 + dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias);
6303 + return(dentry_name(dentry, extra));
6306 +static int read_name(struct inode *ino, char *name)
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
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;
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);
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()))
6335 +static char *follow_link(char *link)
6338 + char *name, *resolved, *end;
6343 + name = kmalloc(len, GFP_KERNEL);
6347 + n = do_readlink(link, name, len);
6359 + end = strrchr(link, '/');
6363 + *(end + 1) = '\0';
6364 + len = strlen(link) + strlen(name) + 1;
6366 + resolved = kmalloc(len, GFP_KERNEL);
6367 + if(resolved == NULL){
6372 + sprintf(resolved, "%s%s", link, name);
6380 + return(ERR_PTR(n));
6383 +static int read_inode(struct inode *ino)
6388 + /* Unfortunately, we are called from iget() when we don't have a dentry
6391 + if(list_empty(&ino->i_dentry))
6395 + name = inode_name(ino, 0);
6399 + if(file_type(name, NULL) == OS_TYPE_SYMLINK){
6400 + name = follow_link(name);
6402 + err = PTR_ERR(name);
6407 + err = read_name(ino, name);
6413 +int hostfs_statfs(struct super_block *sb, struct kstatfs *sf)
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
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;
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;
6440 +static struct inode *hostfs_alloc_inode(struct super_block *sb)
6442 + struct hostfs_inode_info *hi;
6444 + hi = kmalloc(sizeof(*hi), GFP_KERNEL);
6448 + *hi = ((struct hostfs_inode_info) { .host_filename = NULL,
6451 + inode_init_once(&hi->vfs_inode);
6452 + return(&hi->vfs_inode);
6455 +static void hostfs_destroy_inode(struct inode *inode)
6457 + if(HOSTFS_I(inode)->host_filename)
6458 + kfree(HOSTFS_I(inode)->host_filename);
6460 + if(HOSTFS_I(inode)->fd != -1)
6461 + close_file(&HOSTFS_I(inode)->fd);
6463 + kfree(HOSTFS_I(inode));
6466 +static void hostfs_read_inode(struct inode *inode)
6468 + read_inode(inode);
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,
6478 +int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
6482 + unsigned long long next, ino;
6485 + name = dentry_name(file->f_dentry, 0);
6486 + if(name == NULL) return(-ENOMEM);
6487 + dir = open_dir(name, &error);
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,
6495 + file->f_pos = next;
6501 +int hostfs_file_open(struct inode *ino, struct file *file)
6504 + int mode = 0, r = 0, w = 0, fd;
6506 + mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
6507 + if((mode & HOSTFS_I(ino)->mode) == mode)
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.
6513 + if(HOSTFS_I(ino)->fd != -1){
6514 + close_file(&HOSTFS_I(ino)->fd);
6515 + HOSTFS_I(ino)->fd = -1;
6518 + HOSTFS_I(ino)->mode |= mode;
6519 + if(HOSTFS_I(ino)->mode & FMODE_READ)
6521 + if(HOSTFS_I(ino)->mode & FMODE_WRITE)
6526 + name = dentry_name(file->f_dentry, 0);
6530 + fd = open_file(name, r, w, append);
6532 + if(fd < 0) return(fd);
6533 + FILE_HOSTFS_I(file)->fd = fd;
6538 +int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync)
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,
6550 + .fsync = hostfs_fsync,
6553 +static struct file_operations hostfs_dir_fops = {
6554 + .readdir = hostfs_readdir,
6555 + .read = generic_read_dir,
6558 +int hostfs_writepage(struct page *page, struct writeback_control *wbc)
6560 + struct address_space *mapping = page->mapping;
6561 + struct inode *inode = mapping->host;
6563 + unsigned long long base;
6564 + int count = PAGE_CACHE_SIZE;
6565 + int end_index = inode->i_size >> PAGE_CACHE_SHIFT;
6568 + if (page->index >= end_index)
6569 + count = inode->i_size & (PAGE_CACHE_SIZE-1);
6571 + buffer = kmap(page);
6572 + base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
6574 + err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count);
6576 + ClearPageUptodate(page);
6580 + if (base > inode->i_size)
6581 + inode->i_size = base;
6583 + if (PageError(page))
6584 + ClearPageError(page);
6590 + unlock_page(page);
6594 +int hostfs_readpage(struct file *file, struct page *page)
6600 + start = (long long) page->index << PAGE_CACHE_SHIFT;
6601 + buffer = kmap(page);
6602 + err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer,
6604 + if(err < 0) goto out;
6606 + memset(&buffer[err], 0, PAGE_CACHE_SIZE - err);
6608 + flush_dcache_page(page);
6609 + SetPageUptodate(page);
6610 + if (PageError(page)) ClearPageError(page);
6614 + unlock_page(page);
6618 +int hostfs_prepare_write(struct file *file, struct page *page,
6619 + unsigned int from, unsigned int to)
6622 + long long start, tmp;
6625 + start = (long long) page->index << PAGE_CACHE_SHIFT;
6626 + buffer = kmap(page);
6629 + err = read_file(FILE_HOSTFS_I(file)->fd, &tmp, buffer,
6631 + if(err < 0) goto out;
6633 + if(to != PAGE_CACHE_SIZE){
6635 + err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer + to,
6636 + PAGE_CACHE_SIZE - to);
6637 + if(err < 0) goto out;
6645 +int hostfs_commit_write(struct file *file, struct page *page, unsigned from,
6648 + struct address_space *mapping = page->mapping;
6649 + struct inode *inode = mapping->host;
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,
6658 + if(err > 0) err = 0;
6659 + if(!err && (start > inode->i_size))
6660 + inode->i_size = start;
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
6674 +static int init_inode(struct inode *inode, struct dentry *dentry)
6677 + int type, err = -ENOMEM, rdev;
6680 + name = dentry_name(dentry, 0);
6683 + type = file_type(name, &rdev);
6686 + else type = OS_TYPE_DIR;
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;
6695 + if(type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops;
6696 + else inode->i_fop = &hostfs_file_fops;
6698 + if(type == OS_TYPE_SYMLINK)
6699 + inode->i_mapping->a_ops = &hostfs_link_aops;
6700 + else inode->i_mapping->a_ops = &hostfs_aops;
6703 + case OS_TYPE_CHARDEV:
6704 + init_special_inode(inode, S_IFCHR, rdev);
6706 + case OS_TYPE_BLOCKDEV:
6707 + init_special_inode(inode, S_IFBLK, rdev);
6709 + case OS_TYPE_FIFO:
6710 + init_special_inode(inode, S_IFIFO, 0);
6712 + case OS_TYPE_SOCK:
6713 + init_special_inode(inode, S_IFSOCK, 0);
6720 +int hostfs_create(struct inode *dir, struct dentry *dentry, int mode,
6721 + struct nameidata *nd)
6723 + struct inode *inode;
6728 + inode = iget(dir->i_sb, 0);
6729 + if(inode == NULL) goto out;
6731 + error = init_inode(inode, dentry);
6736 + name = dentry_name(dentry, 0);
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);
6746 + else error = read_name(inode, name);
6752 + HOSTFS_I(inode)->fd = fd;
6753 + HOSTFS_I(inode)->mode = FMODE_READ | FMODE_WRITE;
6754 + d_instantiate(dentry, inode);
6763 +struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry,
6764 + struct nameidata *nd)
6766 + struct inode *inode;
6771 + inode = iget(ino->i_sb, 0);
6775 + err = init_inode(inode, dentry);
6780 + name = dentry_name(dentry, 0);
6784 + err = read_name(inode, name);
6786 + if(err == -ENOENT){
6793 + d_add(dentry, inode);
6794 + dentry->d_op = &hostfs_dentry_ops;
6800 + return(ERR_PTR(err));
6803 +static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
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';
6817 +int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
6819 + char *from_name, *to_name;
6822 + if((from_name = inode_dentry_name(ino, from)) == NULL)
6824 + to_name = dentry_name(to, 0);
6825 + if(to_name == NULL){
6829 + err = link_file(to_name, from_name);
6835 +int hostfs_unlink(struct inode *ino, struct dentry *dentry)
6840 + if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
6844 + err = unlink_file(file);
6849 +int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
6854 + if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
6855 + err = make_symlink(file, to);
6860 +int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode)
6865 + if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
6866 + err = do_mkdir(file, mode);
6871 +int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
6876 + if((file = inode_dentry_name(ino, dentry)) == NULL) return(-ENOMEM);
6877 + err = do_rmdir(file);
6882 +int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
6884 + struct inode *inode;
6886 + int err = -ENOMEM;
6888 + inode = iget(dir->i_sb, 0);
6892 + err = init_inode(inode, dentry);
6897 + name = dentry_name(dentry, 0);
6901 + init_special_inode(inode, mode, dev);
6902 + err = do_mknod(name, mode, dev);
6906 + err = read_name(inode, name);
6911 + d_instantiate(dentry, inode);
6922 +int hostfs_rename(struct inode *from_ino, struct dentry *from,
6923 + struct inode *to_ino, struct dentry *to)
6925 + char *from_name, *to_name;
6928 + if((from_name = inode_dentry_name(from_ino, from)) == NULL)
6930 + if((to_name = inode_dentry_name(to_ino, to)) == NULL){
6934 + err = rename_file(from_name, to_name);
6940 +void hostfs_truncate(struct inode *ino)
6942 + not_implemented();
6945 +int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd)
6948 + int r = 0, w = 0, x = 0, err;
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);
6957 + if(!err) err = vfs_permission(ino, desired);
6961 +int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
6963 + struct hostfs_iattr attrs;
6968 + attr->ia_valid &= ~ATTR_SIZE;
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;
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;
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;
6989 + if(attr->ia_valid & ATTR_SIZE){
6990 + attrs.ia_valid |= HOSTFS_ATTR_SIZE;
6991 + attrs.ia_size = attr->ia_size;
6993 + if(attr->ia_valid & ATTR_ATIME){
6994 + attrs.ia_valid |= HOSTFS_ATTR_ATIME;
6995 + attrs.ia_atime = attr->ia_atime;
6997 + if(attr->ia_valid & ATTR_MTIME){
6998 + attrs.ia_valid |= HOSTFS_ATTR_MTIME;
6999 + attrs.ia_mtime = attr->ia_mtime;
7001 + if(attr->ia_valid & ATTR_CTIME){
7002 + attrs.ia_valid |= HOSTFS_ATTR_CTIME;
7003 + attrs.ia_ctime = attr->ia_ctime;
7005 + if(attr->ia_valid & ATTR_ATIME_SET){
7006 + attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
7008 + if(attr->ia_valid & ATTR_MTIME_SET){
7009 + attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
7011 + name = dentry_name(dentry, 0);
7012 + if(name == NULL) return(-ENOMEM);
7013 + err = set_attr(name, &attrs);
7018 + return(inode_setattr(dentry->d_inode, attr));
7021 +int hostfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
7022 + struct kstat *stat)
7024 + generic_fillattr(dentry->d_inode, stat);
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,
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,
7059 +int hostfs_link_readpage(struct file *file, struct page *page)
7061 + char *buffer, *name;
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);
7071 + if(err == PAGE_CACHE_SIZE)
7074 + flush_dcache_page(page);
7075 + SetPageUptodate(page);
7076 + if (PageError(page)) ClearPageError(page);
7080 + unlock_page(page);
7084 +static struct address_space_operations hostfs_link_aops = {
7085 + .readpage = hostfs_link_readpage,
7088 +static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
7090 + struct inode *root_inode;
7091 + char *name, *data = d;
7094 + sb->s_blocksize = 1024;
7095 + sb->s_blocksize_bits = 10;
7096 + sb->s_magic = HOSTFS_SUPER_MAGIC;
7097 + sb->s_op = &hostfs_sbops;
7099 + if((data == NULL) || (*data == '\0'))
7103 + name = kmalloc(strlen(data) + 1, GFP_KERNEL);
7107 + strcpy(name, data);
7109 + root_inode = iget(sb, 0);
7110 + if(root_inode == NULL)
7113 + err = init_inode(root_inode, NULL);
7117 + HOSTFS_I(root_inode)->host_filename = name;
7120 + sb->s_root = d_alloc_root(root_inode);
7121 + if(sb->s_root == NULL)
7124 + err = read_inode(root_inode);
7138 +static struct super_block *hostfs_read_sb(struct file_system_type *type,
7139 + int flags, const char *dev_name,
7142 + return(get_sb_nodev(type, flags, data, hostfs_fill_sb_common));
7145 +static struct file_system_type hostfs_type = {
7146 + .owner = THIS_MODULE,
7148 + .get_sb = hostfs_read_sb,
7149 + .kill_sb = kill_anon_super,
7153 +static int __init init_hostfs(void)
7155 + return(register_filesystem(&hostfs_type));
7158 +static void __exit exit_hostfs(void)
7160 + unregister_filesystem(&hostfs_type);
7163 +module_init(init_hostfs)
7164 +module_exit(exit_hostfs)
7165 +MODULE_LICENSE("GPL");
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
7172 + * ---------------------------------------------------------------------------
7173 + * Local variables:
7174 + * c-file-style: "linux"
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
7182 + * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
7183 + * Licensed under the GPL
7186 +#include <unistd.h>
7189 +#include <dirent.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"
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)
7206 + struct stat64 buf;
7208 + if(lstat64(path, &buf) < 0)
7211 + /* See the Makefile for why STAT64_INO_FIELD is passed in
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;
7224 + if(mtime_out != NULL) {
7225 + mtime_out->tv_sec = buf.st_mtime;
7226 + mtime_out->tv_nsec = 0;
7228 + if(ctime_out != NULL) {
7229 + ctime_out->tv_sec = buf.st_ctime;
7230 + ctime_out->tv_nsec = 0;
7232 + if(blksize_out != NULL) *blksize_out = buf.st_blksize;
7233 + if(blocks_out != NULL) *blocks_out = buf.st_blocks;
7237 +int file_type(const char *path, int *rdev)
7239 + struct stat64 buf;
7241 + if(lstat64(path, &buf) < 0)
7244 + *rdev = buf.st_rdev;
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);
7255 +int access_file(char *path, int r, int w, int x)
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);
7266 +int open_file(char *path, int r, int w, int append)
7276 + else panic("Impossible mode in open_file");
7280 + fd = open64(path, mode);
7281 + if(fd < 0) return(-errno);
7285 +void *open_dir(char *path, int *err_out)
7289 + dir = opendir(path);
7291 + if(dir == NULL) return(NULL);
7295 +char *read_dir(void *stream, unsigned long long *pos,
7296 + unsigned long long *ino_out, int *len_out)
7298 + DIR *dir = stream;
7299 + struct dirent *ent;
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);
7310 +int read_file(int fd, unsigned long long *offset, char *buf, int len)
7314 + n = pread64(fd, buf, len, *offset);
7315 + if(n < 0) return(-errno);
7320 +int write_file(int fd, unsigned long long *offset, const char *buf, int len)
7324 + n = pwrite64(fd, buf, len, *offset);
7325 + if(n < 0) return(-errno);
7330 +int lseek_file(int fd, long long offset, int whence)
7334 + ret = lseek64(fd, offset, whence);
7335 + if(ret < 0) return(-errno);
7339 +void close_file(void *stream)
7341 + close(*((int *) stream));
7344 +void close_dir(void *stream)
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)
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);
7370 +int set_attr(const char *file, struct hostfs_iattr *attrs)
7372 + struct utimbuf buf;
7375 + if(attrs->ia_valid & HOSTFS_ATTR_MODE){
7376 + if(chmod(file, attrs->ia_mode) != 0) return(-errno);
7378 + if(attrs->ia_valid & HOSTFS_ATTR_UID){
7379 + if(chown(file, attrs->ia_uid, -1)) return(-errno);
7381 + if(attrs->ia_valid & HOSTFS_ATTR_GID){
7382 + if(chown(file, -1, attrs->ia_gid)) return(-errno);
7384 + if(attrs->ia_valid & HOSTFS_ATTR_SIZE){
7385 + if(truncate(file, attrs->ia_size)) return(-errno);
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);
7394 + struct timespec ts;
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);
7401 + buf.actime = attrs->ia_atime.tv_sec;
7402 + buf.modtime = ts.tv_sec;
7403 + if(utime(file, &buf) != 0)
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);
7411 + buf.actime = ts.tv_sec;
7412 + buf.modtime = attrs->ia_mtime.tv_sec;
7413 + if(utime(file, &buf) != 0)
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,
7422 + if(err != 0) return(err);
7427 +int make_symlink(const char *from, const char *to)
7431 + err = symlink(to, from);
7432 + if(err) return(-errno);
7436 +int unlink_file(const char *file)
7440 + err = unlink(file);
7441 + if(err) return(-errno);
7445 +int do_mkdir(const char *file, int mode)
7449 + err = mkdir(file, mode);
7450 + if(err) return(-errno);
7454 +int do_rmdir(const char *file)
7458 + err = rmdir(file);
7459 + if(err) return(-errno);
7463 +int do_mknod(const char *file, int mode, int dev)
7467 + err = mknod(file, mode, dev);
7468 + if(err) return(-errno);
7472 +int link_file(const char *to, const char *from)
7476 + err = link(to, from);
7477 + if(err) return(-errno);
7481 +int do_readlink(char *file, char *buf, int size)
7485 + n = readlink(file, buf, size);
7493 +int rename_file(char *from, char *to)
7497 + err = rename(from, to);
7498 + if(err < 0) return(-errno);
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,
7508 + struct statfs64 buf;
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];
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
7537 + * ---------------------------------------------------------------------------
7538 + * Local variables:
7539 + * c-file-style: "linux"
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
7547 +# Copyright (C) 2002, 2003 Jeff Dike (jdike@karaya.com)
7548 +# Licensed under the GPL
7551 +hppfs-objs := hppfs_kern.o
7554 +obj-$(CONFIG_HPPFS) += hppfs.o
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
7570 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
7571 + * Licensed under the GPL
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>
7587 +static int init_inode(struct inode *inode, struct dentry *dentry);
7589 +struct hppfs_data {
7590 + struct list_head list;
7591 + char contents[PAGE_SIZE - sizeof(struct list_head)];
7594 +struct hppfs_private {
7595 + struct file proc_file;
7598 + struct hppfs_data *contents;
7601 +struct hppfs_inode_info {
7602 + struct dentry *proc_dentry;
7603 + struct inode vfs_inode;
7606 +static inline struct hppfs_inode_info *HPPFS_I(struct inode *inode)
7608 + return(list_entry(inode, struct hppfs_inode_info, vfs_inode));
7611 +#define HPPFS_SUPER_MAGIC 0xb00000ee
7613 +static struct super_operations hppfs_sbops;
7615 +static int is_pid(struct dentry *dentry)
7617 + struct super_block *sb;
7620 + sb = dentry->d_sb;
7621 + if((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root))
7624 + for(i = 0; i < dentry->d_name.len; i++){
7625 + if(!isdigit(dentry->d_name.name[i]))
7631 +static char *dentry_name(struct dentry *dentry, int extra)
7633 + struct dentry *parent;
7634 + char *root, *name;
7635 + const char *seg_name;
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;
7648 + len += strlen(root);
7649 + name = kmalloc(len + extra + 1, GFP_KERNEL);
7650 + if(name == NULL) return(NULL);
7654 + while(parent->d_parent != parent){
7655 + if(is_pid(parent)){
7657 + seg_len = strlen("pid");
7660 + seg_name = parent->d_name.name;
7661 + seg_len = parent->d_name.len;
7664 + len -= seg_len + 1;
7666 + strncpy(&name[len + 1], seg_name, seg_len);
7667 + parent = parent->d_parent;
7669 + strncpy(name, root, strlen(root));
7673 +struct dentry_operations hppfs_dentry_ops = {
7676 +static int file_removed(struct dentry *dentry, const char *file)
7682 + if(file != NULL) extra += strlen(file) + 1;
7684 + host_file = dentry_name(dentry, extra + strlen("/remove"));
7685 + if(host_file == NULL){
7686 + printk("file_removed : allocation failed\n");
7691 + strcat(host_file, "/");
7692 + strcat(host_file, file);
7694 + strcat(host_file, "/remove");
7696 + fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
7699 + os_close_file(fd);
7705 +static void hppfs_read_inode(struct inode *ino)
7707 + struct inode *proc_ino;
7709 + if(HPPFS_I(ino)->proc_dentry == NULL)
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;
7726 +static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry,
7727 + struct nameidata *nd)
7729 + struct dentry *proc_dentry, *new, *parent;
7730 + struct inode *inode;
7733 + deleted = file_removed(dentry, NULL);
7735 + return(ERR_PTR(deleted));
7737 + return(ERR_PTR(-ENOENT));
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);
7749 + new = (*parent->d_inode->i_op->lookup)(parent->d_inode,
7750 + proc_dentry, NULL);
7752 + dput(proc_dentry);
7753 + proc_dentry = new;
7756 + up(&parent->d_inode->i_sem);
7758 + if(IS_ERR(proc_dentry))
7759 + return(proc_dentry);
7761 + inode = iget(ino->i_sb, 0);
7765 + err = init_inode(inode, proc_dentry);
7769 + hppfs_read_inode(inode);
7771 + d_add(dentry, inode);
7772 + dentry->d_op = &hppfs_dentry_ops;
7778 + dput(proc_dentry);
7780 + return(ERR_PTR(err));
7783 +static struct inode_operations hppfs_file_iops = {
7786 +static ssize_t read_proc(struct file *file, char *buf, ssize_t count,
7787 + loff_t *ppos, int is_user)
7789 + ssize_t (*read)(struct file *, char *, size_t, loff_t *);
7792 + read = file->f_dentry->d_inode->i_fop->read;
7795 + set_fs(KERNEL_DS);
7797 + n = (*read)(file, buf, count, &file->f_pos);
7802 + if(ppos) *ppos = file->f_pos;
7806 +static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count)
7813 + new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
7814 + if(new_buf == NULL){
7815 + printk("hppfs_read_file : kmalloc failed\n");
7820 + cur = min_t(ssize_t, count, PAGE_SIZE);
7821 + err = os_read_file(fd, new_buf, cur);
7823 + printk("hppfs_read : read failed, errno = %d\n",
7831 + if(copy_to_user(buf, new_buf, err)){
7844 +static ssize_t hppfs_read(struct file *file, char *buf, size_t count,
7847 + struct hppfs_private *hppfs = file->private_data;
7848 + struct hppfs_data *data;
7852 + if(hppfs->contents != NULL){
7853 + if(*ppos >= hppfs->len) return(0);
7855 + data = hppfs->contents;
7857 + while(off >= sizeof(data->contents)){
7858 + data = list_entry(data->list.next, struct hppfs_data,
7860 + off -= sizeof(data->contents);
7863 + if(off + count > hppfs->len)
7864 + count = hppfs->len - off;
7865 + copy_to_user(buf, &data->contents[off], count);
7868 + else if(hppfs->host_fd != -1){
7869 + err = os_seek_file(hppfs->host_fd, *ppos);
7871 + printk("hppfs_read : seek failed, errno = %d\n", err);
7874 + count = hppfs_read_file(hppfs->host_fd, buf, count);
7878 + else count = read_proc(&hppfs->proc_file, buf, count, ppos, 1);
7883 +static ssize_t hppfs_write(struct file *file, const char *buf, size_t len,
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 *);
7891 + write = proc_file->f_dentry->d_inode->i_fop->write;
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;
7900 +static int open_host_sock(char *host_file, int *filter_out)
7905 + end = &host_file[strlen(host_file)];
7906 + strcpy(end, "/rw");
7908 + fd = os_connect_socket(host_file);
7912 + strcpy(end, "/r");
7914 + fd = os_connect_socket(host_file);
7918 +static void free_contents(struct hppfs_data *head)
7920 + struct hppfs_data *data;
7921 + struct list_head *ele, *next;
7923 + if(head == NULL) return;
7925 + list_for_each_safe(ele, next, &head->list){
7926 + data = list_entry(ele, struct hppfs_data, list);
7932 +static struct hppfs_data *hppfs_get_data(int fd, int filter,
7933 + struct file *proc_file,
7934 + struct file *hppfs_file,
7937 + struct hppfs_data *data, *new, *head;
7941 + data = kmalloc(sizeof(*data), GFP_KERNEL);
7943 + printk("hppfs_get_data : head allocation failed\n");
7947 + INIT_LIST_HEAD(&data->list);
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);
7958 + printk("hppfs_get_data : failed to shut down "
7964 + n = os_read_file(fd, data->contents, sizeof(data->contents));
7967 + printk("hppfs_get_data : read failed, errno = %d\n",
7976 + if(n < sizeof(data->contents))
7979 + new = kmalloc(sizeof(*data), GFP_KERNEL);
7981 + printk("hppfs_get_data : data allocation failed\n");
7986 + INIT_LIST_HEAD(&new->list);
7987 + list_add(&new->list, &data->list);
7993 + free_contents(head);
7995 + return(ERR_PTR(err));
7998 +static struct hppfs_private *hppfs_data(void)
8000 + struct hppfs_private *data;
8002 + data = kmalloc(sizeof(*data), GFP_KERNEL);
8006 + *data = ((struct hppfs_private ) { .host_fd = -1,
8008 + .contents = NULL } );
8012 +static int file_mode(int fmode)
8014 + if(fmode == (FMODE_READ | FMODE_WRITE))
8016 + if(fmode == FMODE_READ)
8018 + if(fmode == FMODE_WRITE)
8023 +static int hppfs_open(struct inode *inode, struct file *file)
8025 + struct hppfs_private *data;
8026 + struct dentry *proc_dentry;
8028 + int err, fd, type, filter;
8031 + data = hppfs_data();
8035 + host_file = dentry_name(file->f_dentry, strlen("/rw"));
8036 + if(host_file == NULL)
8039 + proc_dentry = HPPFS_I(inode)->proc_dentry;
8041 + /* XXX This isn't closed anywhere */
8042 + err = open_private_file(&data->proc_file, proc_dentry,
8043 + file_mode(file->f_mode));
8047 + type = os_file_type(host_file);
8048 + if(type == OS_TYPE_FILE){
8049 + fd = os_open_file(host_file, of_read(OPENFLAGS()), 0);
8051 + data->host_fd = fd;
8052 + else printk("hppfs_open : failed to open '%s', errno = %d\n",
8055 + data->contents = NULL;
8057 + else if(type == OS_TYPE_DIR){
8058 + fd = open_host_sock(host_file, &filter);
8060 + data->contents = hppfs_get_data(fd, filter,
8062 + file, &data->len);
8063 + if(!IS_ERR(data->contents))
8064 + data->host_fd = fd;
8066 + else printk("hppfs_open : failed to open a socket in "
8067 + "'%s', errno = %d\n", host_file, -fd);
8071 + file->private_data = data;
8077 + free_contents(data->contents);
8083 +static int hppfs_dir_open(struct inode *inode, struct file *file)
8085 + struct hppfs_private *data;
8086 + struct dentry *proc_dentry;
8090 + data = hppfs_data();
8094 + proc_dentry = HPPFS_I(inode)->proc_dentry;
8095 + err = open_private_file(&data->proc_file, proc_dentry,
8096 + file_mode(file->f_mode));
8100 + file->private_data = data;
8109 +static loff_t hppfs_llseek(struct file *file, loff_t off, int where)
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);
8116 + llseek = proc_file->f_dentry->d_inode->i_fop->llseek;
8117 + if(llseek != NULL){
8118 + ret = (*llseek)(proc_file, off, where);
8123 + return(default_llseek(file, off, where));
8126 +static struct file_operations hppfs_file_fops = {
8128 + .llseek = hppfs_llseek,
8129 + .read = hppfs_read,
8130 + .write = hppfs_write,
8131 + .open = hppfs_open,
8134 +struct hppfs_dirent {
8136 + filldir_t filldir;
8137 + struct dentry *dentry;
8140 +static int hppfs_filldir(void *d, const char *name, int size,
8141 + loff_t offset, ino_t inode, unsigned int type)
8143 + struct hppfs_dirent *dirent = d;
8145 + if(file_removed(dirent->dentry, name))
8148 + return((*dirent->filldir)(dirent->vfs_dirent, name, size, offset,
8152 +static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir)
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 } );
8163 + readdir = proc_file->f_dentry->d_inode->i_fop->readdir;
8165 + proc_file->f_pos = file->f_pos;
8166 + err = (*readdir)(proc_file, &dirent, hppfs_filldir);
8167 + file->f_pos = proc_file->f_pos;
8172 +static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync)
8177 +static struct file_operations hppfs_dir_fops = {
8179 + .readdir = hppfs_readdir,
8180 + .open = hppfs_dir_open,
8181 + .fsync = hppfs_fsync,
8184 +static int hppfs_statfs(struct super_block *sb, struct kstatfs *sf)
8191 + sf->f_type = HPPFS_SUPER_MAGIC;
8195 +static struct inode *hppfs_alloc_inode(struct super_block *sb)
8197 + struct hppfs_inode_info *hi;
8199 + hi = kmalloc(sizeof(*hi), GFP_KERNEL);
8203 + *hi = ((struct hppfs_inode_info) { .proc_dentry = NULL });
8204 + inode_init_once(&hi->vfs_inode);
8205 + return(&hi->vfs_inode);
8208 +void hppfs_delete_inode(struct inode *ino)
8213 +static void hppfs_destroy_inode(struct inode *inode)
8215 + kfree(HPPFS_I(inode));
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,
8226 +static int hppfs_readlink(struct dentry *dentry, char *buffer, int buflen)
8228 + struct file proc_file;
8229 + struct dentry *proc_dentry;
8230 + int (*readlink)(struct dentry *, char *, int);
8233 + proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
8234 + err = open_private_file(&proc_file, proc_dentry, O_RDONLY);
8238 + readlink = proc_dentry->d_inode->i_op->readlink;
8239 + n = (*readlink)(proc_dentry, buffer, buflen);
8241 + close_private_file(&proc_file);
8246 +static int hppfs_follow_link(struct dentry *dentry, struct nameidata *nd)
8248 + struct file proc_file;
8249 + struct dentry *proc_dentry;
8250 + int (*follow_link)(struct dentry *, struct nameidata *);
8253 + proc_dentry = HPPFS_I(dentry->d_inode)->proc_dentry;
8254 + err = open_private_file(&proc_file, proc_dentry, O_RDONLY);
8258 + follow_link = proc_dentry->d_inode->i_op->follow_link;
8259 + n = (*follow_link)(proc_dentry, nd);
8261 + close_private_file(&proc_file);
8266 +static struct inode_operations hppfs_dir_iops = {
8267 + .lookup = hppfs_lookup,
8270 +static struct inode_operations hppfs_link_iops = {
8271 + .readlink = hppfs_readlink,
8272 + .follow_link = hppfs_follow_link,
8275 +static int init_inode(struct inode *inode, struct dentry *dentry)
8277 + if(S_ISDIR(dentry->d_inode->i_mode)){
8278 + inode->i_op = &hppfs_dir_iops;
8279 + inode->i_fop = &hppfs_dir_fops;
8281 + else if(S_ISLNK(dentry->d_inode->i_mode)){
8282 + inode->i_op = &hppfs_link_iops;
8283 + inode->i_fop = &hppfs_file_fops;
8286 + inode->i_op = &hppfs_file_iops;
8287 + inode->i_fop = &hppfs_file_fops;
8290 + HPPFS_I(inode)->proc_dentry = dentry;
8295 +static int hppfs_fill_super(struct super_block *sb, void *d, int silent)
8297 + struct inode *root_inode;
8298 + struct file_system_type *procfs;
8299 + struct super_block *proc_sb;
8303 + procfs = get_fs_type("proc");
8304 + if(procfs == NULL)
8307 + if(list_empty(&procfs->fs_supers))
8310 + proc_sb = list_entry(procfs->fs_supers.next, struct super_block,
8313 + sb->s_blocksize = 1024;
8314 + sb->s_blocksize_bits = 10;
8315 + sb->s_magic = HPPFS_SUPER_MAGIC;
8316 + sb->s_op = &hppfs_sbops;
8318 + root_inode = iget(sb, 0);
8319 + if(root_inode == NULL)
8322 + err = init_inode(root_inode, proc_sb->s_root);
8327 + sb->s_root = d_alloc_root(root_inode);
8328 + if(sb->s_root == NULL)
8331 + hppfs_read_inode(root_inode);
8341 +static struct super_block *hppfs_read_super(struct file_system_type *type,
8342 + int flags, const char *dev_name,
8345 + return(get_sb_nodev(type, flags, data, hppfs_fill_super));
8348 +static struct file_system_type hppfs_type = {
8349 + .owner = THIS_MODULE,
8351 + .get_sb = hppfs_read_super,
8352 + .kill_sb = kill_anon_super,
8356 +static int __init init_hppfs(void)
8358 + return(register_filesystem(&hppfs_type));
8361 +static void __exit exit_hppfs(void)
8363 + unregister_filesystem(&hppfs_type);
8366 +module_init(init_hppfs)
8367 +module_exit(exit_hppfs)
8368 +MODULE_LICENSE("GPL");
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
8375 + * ---------------------------------------------------------------------------
8376 + * Local variables:
8377 + * c-file-style: "linux"
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
8384 pr_reg[16] = PT_REGS_SS(regs); \
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;
8393 + * Architecture-neutral AT_ values in 0-17, leave some room
8394 + * for more of them, start the x86-specific ones at 32.
8396 +#define AT_SYSINFO 32
8397 +#define AT_SYSINFO_EHDR 33
8399 +#define ARCH_DLINFO \
8401 + NEW_AUX_ENT(AT_SYSINFO, VSYSCALL_ENTRY); \
8402 + NEW_AUX_ENT(AT_SYSINFO_EHDR, VSYSCALL_BASE); \
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.
8413 +#define ELF_CORE_EXTRA_PHDRS (VSYSCALL_EHDR->e_phnum)
8414 +#define ELF_CORE_WRITE_EXTRA_PHDRS \
8416 + const struct elf_phdr *const vsyscall_phdrs = \
8417 + (const struct elf_phdr *) (VSYSCALL_BASE \
8418 + + VSYSCALL_EHDR->e_phoff); \
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; \
8428 + phdr.p_offset += ofs; \
8429 + phdr.p_paddr = 0; /* match other core phdrs */ \
8430 + DUMP_WRITE(&phdr, sizeof(phdr)); \
8433 +#define ELF_CORE_WRITE_EXTRA_DATA \
8435 + const struct elf_phdr *const vsyscall_phdrs = \
8436 + (const struct elf_phdr *) (VSYSCALL_BASE \
8437 + + VSYSCALL_EHDR->e_phoff); \
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); \
8446 /********* Bits for asm-um/delay.h **********/
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
8453 +#include <asm-generic/vmlinux.lds.h>
8455 .fini : { *(.fini) } =0x9090
8457 PROVIDE (etext = .);
8462 + __con_initcall_start = .;
8463 + .con_initcall.init : { *(.con_initcall.init) }
8464 + __con_initcall_end = .;
8466 __uml_initcall_start = .;
8467 .uml.initcall.init : { *(.uml.initcall.init) }
8468 __uml_initcall_end = .;
8470 .uml.exitcall : { *(.uml.exitcall.exit) }
8471 __uml_exitcall_end = .;
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) }
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 = .;
8495 __initramfs_start = .;
8496 .init.ramfs : { *(.init.ramfs) }
8497 __initramfs_end = .;
8499 + /* Sections to be discarded */
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
8508 +#ifndef __UM_CPUFEATURE_H
8509 +#define __UM_CPUFEATURE_H
8511 +#include "asm/arch/cpufeature.h"
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
8518 #define CURRENT_THREAD(dummy) (((unsigned long) &dummy) & \
8519 (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER))
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)); })
8526 +#define current (current_thread->task)
8528 #endif /* __ASSEMBLY__ */
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
8534 FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
8535 FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
8538 __end_of_fixed_addresses
8542 #define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT))
8543 #define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT)
8546 + * This is the range that is readable by user mode, and things
8547 + * acting like user mode such as get_user_pages.
8549 +#define FIXADDR_USER_START (__fix_to_virt(FIX_VSYSCALL))
8550 +#define FIXADDR_USER_END (FIXADDR_USER_START + PAGE_SIZE)
8552 extern void __this_fixmap_does_not_exist(void);
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
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.
8565 -struct task_struct;
8567 -#include "asm/ptrace.h"
8573 #define CONSOLE_IRQ 2
8575 #define LAST_IRQ XTERM_IRQ
8576 #define NR_IRQS (LAST_IRQ + 1)
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,
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
8587 +#ifndef __UM_LOCAL_H
8588 +#define __UM_LOCAL_H
8590 +#include "asm/arch/local.h"
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
8597 +#ifndef __UM_MODULE_GENERIC_H
8598 +#define __UM_MODULE_GENERIC_H
8600 +#include "asm/arch/module.h"
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
8607 +#ifndef __UM_MODULE_I386_H
8608 +#define __UM_MODULE_I386_H
8610 +/* UML is simple */
8611 +struct mod_arch_specific
8615 +#define Elf_Shdr Elf32_Shdr
8616 +#define Elf_Sym Elf32_Sym
8617 +#define Elf_Ehdr Elf32_Ehdr
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
8626 #include "asm/arch/page.h"
8627 -#include "asm/bug.h"
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
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
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))
8659 + * Bits 0 through 3 are taken
8661 +#define PTE_FILE_MAX_BITS 28
8663 +#define pte_to_pgoff(pte) ((pte).pte_low >> 4)
8665 +#define pgoff_to_pte(off) \
8666 + ((pte_t) { ((off) << 4) + _PAGE_FILE })
8668 static inline pte_t pte_mknewprot(pte_t pte)
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..
8675 +static inline int pte_user(pte_t pte)
8677 + return((pte_val(pte) & _PAGE_USER) &&
8678 + !(pte_val(pte) & _PAGE_PROTNONE));
8681 static inline int pte_read(pte_t pte)
8683 return((pte_val(pte) & _PAGE_USER) &&
8684 @@ -253,6 +270,14 @@
8685 !(pte_val(pte) & _PAGE_PROTNONE));
8689 + * The following only works if pte_present() is not true.
8691 +static inline int pte_file(pte_t pte)
8693 + return (pte).pte_low & _PAGE_FILE;
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)))
8703 -/* to find an entry in a page-table-directory. */
8705 + * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
8707 + * this macro returns the index of the entry in the pgd page which would
8708 + * control the given virtual address
8710 #define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
8712 -/* to find an entry in a page-table-directory */
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;
8717 #define pgd_offset(mm, address) \
8718 ((mm)->pgd + ((address) >> PGDIR_SHIFT))
8720 -/* to find an entry in a kernel page-table-directory */
8723 + * a shortcut which implies the use of the kernel's pgd, instead
8726 #define pgd_offset_k(address) pgd_offset(&init_mm, address)
8728 #define pmd_index(address) \
8729 @@ -374,7 +411,12 @@
8730 return (pmd_t *) dir;
8733 -/* Find an entry in the third-level page table.. */
8735 + * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
8737 + * this macro returns the index of the entry in the pte page which would
8738 + * control the given virtual address
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)
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)
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
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"
8771 @@ -101,14 +99,19 @@
8774 extern struct task_struct *alloc_task_struct(void);
8775 -extern void free_task_struct(struct task_struct *task);
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);
8782 extern unsigned long thread_saved_pc(struct task_struct *t);
8784 +static inline void mm_copy_segments(struct mm_struct *from_mm,
8785 + struct mm_struct *new_mm)
8789 #define init_stack (init_thread_union.stack)
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
8796 #ifndef __UM_PROCESSOR_I386_H
8797 #define __UM_PROCESSOR_I386_H
8799 -extern int cpu_has_xmm;
8800 -extern int cpu_has_cmov;
8801 +extern int host_has_xmm;
8802 +extern int host_has_cmov;
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
8810 +#ifndef _UM_SECTIONS_H
8811 +#define _UM_SECTIONS_H
8813 +/* nothing to see, move along */
8814 +#include <asm-generic/sections.h>
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
8822 extern cpumask_t cpu_online_map;
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
8833 extern void block_signals(void);
8834 extern void unblock_signals(void);
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)
8843 #define local_irq_save(flags) do { local_save_flags(flags); \
8844 local_irq_disable(); } while(0)
8849 +extern void *_switch_to(void *prev, void *next, void *last);
8850 +#define switch_to(prev, next, last) prev = _switch_to(prev, next, last)
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
8857 #ifndef __ASSEMBLY__
8859 #include <asm/processor.h>
8860 +#include <asm/types.h>
8862 struct thread_info {
8863 struct task_struct *task; /* main task structure */
8865 static inline struct thread_info *current_thread_info(void)
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));
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)
8885 #define get_thread_info(ti) get_task_struct((ti)->task)
8886 #define put_thread_info(ti) put_task_struct((ti)->task)
8889 #define TIF_POLLING_NRFLAG 3 /* true if poll_idle() is polling
8892 +#define TIF_RESTART_BLOCK 4
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)
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
8906 #ifndef __UM_TIMEX_H
8907 #define __UM_TIMEX_H
8909 -#include "linux/time.h"
8911 typedef unsigned long cycles_t;
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
8918 return __set_page_dirty_buffers(page);
8921 +extern long do_mprotect(struct mm_struct *mm, unsigned long start,
8922 + size_t len, unsigned long prot);
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 @@
8929 extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
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);
8939 static inline unsigned long do_mmap(struct file *file, unsigned long addr,
8940 unsigned long len, unsigned long prot,
8942 if ((offset + PAGE_ALIGN(len)) < offset)
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);
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
8956 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
8957 + * Licensed under the GPL
8960 +#ifndef __PROC_MM_H
8961 +#define __PROC_MM_H
8963 +#include "linux/sched.h"
8966 +#define MM_MUNMAP 55
8967 +#define MM_MPROTECT 56
8968 +#define MM_COPY_SEGMENTS 57
8971 + unsigned long addr;
8972 + unsigned long len;
8973 + unsigned long prot;
8974 + unsigned long flags;
8976 + unsigned long offset;
8980 + unsigned long addr;
8981 + unsigned long len;
8984 +struct mm_mprotect {
8985 + unsigned long addr;
8986 + unsigned long len;
8987 + unsigned int prot;
8990 +struct proc_mm_op {
8993 + struct mm_mmap mmap;
8994 + struct mm_munmap munmap;
8995 + struct mm_mprotect mprotect;
8996 + int copy_segments;
9000 +extern struct mm_struct *proc_mm_get_mm(int fd);
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
9007 slab.o swap.o truncate.o vmscan.o $(mmu-y)
9009 obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o
9010 +obj-$(CONFIG_PROC_MM) += proc_mm.o
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
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>
9022 #include <asm/pgalloc.h>
9023 @@ -673,6 +674,24 @@
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
9032 + .vm_page_prot = PAGE_READONLY,
9033 + .vm_flags = VM_READ | VM_EXEC,
9036 +static int init_fixmap_vma(void)
9038 + fixmap_vma.vm_start = FIXADDR_START;
9039 + fixmap_vma.vm_end = FIXADDR_TOP;
9043 +__initcall(init_fixmap_vma);
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 @@
9050 vma = find_extend_vma(mm, start);
9052 -#ifdef FIXADDR_USER_START
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
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,
9065 +#ifdef FIXADDR_START
9066 + if (!vma && start >= FIXADDR_START && start < FIXADDR_TOP) {
9067 unsigned long pg = start & PAGE_MASK;
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).
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)
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
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)
9100 unsigned long vm_flags, nstart, end, tmp;
9101 struct vm_area_struct * vma, * next, * prev;
9104 vm_flags = calc_vm_prot_bits(prot);
9106 - down_write(¤t->mm->mmap_sem);
9107 + down_write(&mm->mmap_sem);
9109 - vma = find_vma_prev(current->mm, start, &prev);
9110 + vma = find_vma_prev(mm, start, &prev);
9112 if (!vma || vma->vm_start > start)
9114 @@ -304,6 +305,11 @@
9115 prev->vm_mm->map_count--;
9118 - up_write(¤t->mm->mmap_sem);
9119 + up_write(&mm->mmap_sem);
9123 +asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot)
9125 + return(do_mprotect(current->mm, start, len, prot));
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
9132 + * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
9133 + * Licensed under the GPL
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"
9144 +static struct file_operations proc_mm_fops;
9146 +struct mm_struct *proc_mm_get_mm(int fd)
9148 + struct mm_struct *ret = ERR_PTR(-EBADF);
9149 + struct file *file;
9155 + ret = ERR_PTR(-EINVAL);
9156 + if(file->f_op != &proc_mm_fops)
9159 + ret = file->private_data;
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);
9171 +static ssize_t write_proc_mm(struct file *file, const char *buffer,
9172 + size_t count, loff_t *ppos)
9174 + struct mm_struct *mm = file->private_data;
9175 + struct proc_mm_op req;
9178 + if(count > sizeof(req))
9181 + n = copy_from_user(&req, buffer, count);
9188 + struct mm_mmap *map = &req.u.mmap;
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)
9198 + struct mm_munmap *unmap = &req.u.munmap;
9200 + down_write(&mm->mmap_sem);
9201 + ret = do_munmap(mm, unmap->addr, unmap->len);
9202 + up_write(&mm->mmap_sem);
9208 + case MM_MPROTECT: {
9209 + struct mm_mprotect *protect = &req.u.mprotect;
9211 + ret = do_mprotect(mm, protect->addr, protect->len,
9218 + case MM_COPY_SEGMENTS: {
9219 + struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments);
9222 + ret = PTR_ERR(from);
9226 + mm_copy_segments(from, mm);
9237 +static int open_proc_mm(struct inode *inode, struct file *file)
9239 + struct mm_struct *mm = mm_alloc();
9246 + ret = init_new_context(current, mm);
9250 + spin_lock(&mmlist_lock);
9251 + list_add(&mm->mmlist, ¤t->mm->mmlist);
9253 + spin_unlock(&mmlist_lock);
9255 + file->private_data = mm;
9265 +static int release_proc_mm(struct inode *inode, struct file *file)
9267 + struct mm_struct *mm = file->private_data;
9273 +static struct file_operations proc_mm_fops = {
9274 + .open = open_proc_mm,
9275 + .release = release_proc_mm,
9276 + .write = write_proc_mm,
9279 +static int make_proc_mm(void)
9281 + struct proc_dir_entry *ent;
9283 + ent = create_proc_entry("mm", 0222, &proc_root);
9285 + printk("make_proc_mm : Failed to register /proc/mm\n");
9288 + ent->proc_fops = &proc_mm_fops;
9293 +__initcall(make_proc_mm);
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
9300 + * ---------------------------------------------------------------------------
9301 + * Local variables:
9302 + * c-file-style: "linux"