From 2f2ec659da04061a8147d711635ae1ce005ba4df Mon Sep 17 00:00:00 2001 From: yury Date: Thu, 18 Nov 2004 09:25:39 +0000 Subject: [PATCH] - at Peter's request removed all 2.4.x related patches, configs and series, HEAD is gonna to be only 2.6.x oriented. --- .../config-linux-2.4.18-p4smp-61chaos | 1035 - .../kernel_configs/config-linux-2.4.20-i386-rh | 1849 - .../kernel_configs/config-linux-2.4.20-uml | 298 - .../kernel_configs/config-linux-2.4.24-uml | 306 - .../kernel-2.4.18-chaos-2.4.18-i686-smp.config | 1103 - .../kernel-2.4.18-chaos-2.4.18-i686.config | 1103 - .../kernel-2.4.20-hp_pnnl-2.4-ia64-smp.config | 1042 - .../kernel-2.4.20-hp_pnnl-2.4-ia64.config | 1042 - .../kernel-2.4.20-rh-2.4-i686-smp.config | 1863 - .../kernel-2.4.20-rh-2.4-i686.config | 1863 - .../kernel-2.4.21-suse-2.4.21-2-x86_64.config | 2036 - .../kernel_configs/uml_2.6.0_test3.config | 325 - .../3.5G-address-space-2.4.24-vanilla.patch | 352 - .../patches/add_page_private-2.4.24.patch | 23 - .../patches/configurable-x86-stack-2.4.24.patch | 330 - .../patches/dev_read_only-2.4.24.patch | 58 - .../kernel_patches/patches/directio-2.4.24.patch | 15 - lustre/kernel_patches/patches/dsp.patch | 142 - .../patches/dynamic-locks-2.4.24.patch | 281 - .../patches/export-add_to_page_cache.patch | 23 - .../patches/export-truncate-2.4.24.patch | 35 - .../patches/export-zap-page-range-2.4.24.patch | 12 - .../patches/export_lookup_create-2.4.24.patch | 34 - .../patches/export_num_siblings-2.4.24.patch | 10 - lustre/kernel_patches/patches/exports-2.4.24.patch | 53 - lustre/kernel_patches/patches/ext3-2.4-ino_t.patch | 144 - .../patches/ext3-delete_thread-2.4.24.patch | 444 - .../patches/ext3-delete_thread-suse.patch | 496 - .../patches/ext3-dentry-fid-2.4.24.patch | 52 - .../patches/ext3-ea-in-inode-2.4.24.patch | 757 - .../patches/ext3-error-export-2.4.24.patch | 16 - .../patches/ext3-extents-2.4.24.patch | 2765 -- .../patches/ext3-extents-asyncdel-2.4.24.patch | 28 - .../patches/ext3-extents-in-ea-2.4.24.patch | 365 - .../ext3-extents-in-ea-exports-symbol-2.4.24.patch | 116 - .../patches/ext3-extents-in-ea-ioctl-2.4.24.patch | 154 - .../kernel_patches/patches/ext3-htree-2.4.24.patch | 2573 -- .../patches/ext3-inode-reuse-2.4.24.patch | 352 - .../patches/ext3-map_inode_page-2.4.24.patch | 105 - .../patches/ext3-mballoc-2.4.24.patch | 373 - .../patches/ext3-mballoc2-2.4.24.patch | 1762 - .../patches/ext3-mds-num-2.4.24.patch | 300 - .../patches/ext3-nlinks-2.4.24.patch | 170 - .../patches/ext3-no-write-super-2.4.24.patch | 15 - .../patches/ext3-noread-2.4.24.patch | 218 - .../patches/ext3-orphan_lock-2.4.24.patch | 82 - .../patches/ext3-pdirops-2.4.24-chaos.patch | 1239 - .../patches/ext3-pdirops-2.4.24.patch | 1248 - .../patches/ext3-raw-lookup-pdirops-2.4.24.patch | 65 - .../kernel_patches/patches/ext3-san-2.4.24.patch | 117 - .../patches/ext3-truncate-buffer-head-2.4.24.patch | 10 - .../patches/ext3-trusted_ea-2.4.24.patch | 180 - .../patches/ext3-xattr-ptr-arith-fix-2.4.24.patch | 18 - .../patches/extN-wantedi-2.4.24.patch | 231 - .../patches/gfp_memalloc-2.4.24.patch | 59 - .../patches/inode-max-readahead-2.4.24.patch | 22 - .../patches/invalidate_show-2.4.24.patch | 115 - .../patches/iod-stock-24-exports.patch | 48 - .../patches/iod-stock-exports-2.4.24.patch | 52 - lustre/kernel_patches/patches/iopen-2.4.24.patch | 492 - .../patches/jbd-commit-tricks-2.4.24.patch | 132 - .../jbd-dont-account-blocks-twice-2.4.24.patch | 17 - .../kernel_text_address-2.4.24-vanilla.patch | 54 - .../patches/kksymoops-2.4.24.vanilla.patch | 713 - .../patches/linux-2.4.24-xattr-0.8.54.patch | 5474 --- lustre/kernel_patches/patches/listman-2.4.24.patch | 22 - .../kernel_patches/patches/netconsole-2.4.24.patch | 1676 - .../patches/nfs_export_kernel-2.4.24.patch | 746 - .../patches/procfs-ndynamic-2.4.24.patch | 13 - .../patches/tcp-zero-copy-2.4.24.patch | 467 - .../patches/uml-2.4.24-do_mmap_pgoff-fix.patch | 42 - .../patches/uml-export-end_iomem-2.4.24.patch | 12 - .../patches/uml-patch-2.4.24-1.patch | 41971 ------------------- .../patches/vfs-pdirops-2.4.24.patch | 271 - .../kernel_patches/patches/vfs_intent-2.4.24.patch | 1963 - lustre/kernel_patches/series/vanilla-2.4.24 | 53 - 76 files changed, 84042 deletions(-) delete mode 100644 lustre/kernel_patches/kernel_configs/config-linux-2.4.18-p4smp-61chaos delete mode 100644 lustre/kernel_patches/kernel_configs/config-linux-2.4.20-i386-rh delete mode 100644 lustre/kernel_patches/kernel_configs/config-linux-2.4.20-uml delete mode 100644 lustre/kernel_patches/kernel_configs/config-linux-2.4.24-uml delete mode 100644 lustre/kernel_patches/kernel_configs/kernel-2.4.18-chaos-2.4.18-i686-smp.config delete mode 100644 lustre/kernel_patches/kernel_configs/kernel-2.4.18-chaos-2.4.18-i686.config delete mode 100644 lustre/kernel_patches/kernel_configs/kernel-2.4.20-hp_pnnl-2.4-ia64-smp.config delete mode 100644 lustre/kernel_patches/kernel_configs/kernel-2.4.20-hp_pnnl-2.4-ia64.config delete mode 100644 lustre/kernel_patches/kernel_configs/kernel-2.4.20-rh-2.4-i686-smp.config delete mode 100644 lustre/kernel_patches/kernel_configs/kernel-2.4.20-rh-2.4-i686.config delete mode 100644 lustre/kernel_patches/kernel_configs/kernel-2.4.21-suse-2.4.21-2-x86_64.config delete mode 100644 lustre/kernel_patches/kernel_configs/uml_2.6.0_test3.config delete mode 100644 lustre/kernel_patches/patches/3.5G-address-space-2.4.24-vanilla.patch delete mode 100644 lustre/kernel_patches/patches/add_page_private-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/configurable-x86-stack-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/dev_read_only-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/directio-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/dsp.patch delete mode 100644 lustre/kernel_patches/patches/dynamic-locks-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/export-add_to_page_cache.patch delete mode 100644 lustre/kernel_patches/patches/export-truncate-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/export-zap-page-range-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/export_lookup_create-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/export_num_siblings-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/exports-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/ext3-2.4-ino_t.patch delete mode 100644 lustre/kernel_patches/patches/ext3-delete_thread-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/ext3-delete_thread-suse.patch delete mode 100644 lustre/kernel_patches/patches/ext3-dentry-fid-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/ext3-ea-in-inode-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/ext3-error-export-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/ext3-extents-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/ext3-extents-asyncdel-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/ext3-extents-in-ea-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/ext3-extents-in-ea-exports-symbol-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/ext3-extents-in-ea-ioctl-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/ext3-htree-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/ext3-inode-reuse-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/ext3-map_inode_page-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/ext3-mballoc-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/ext3-mballoc2-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/ext3-mds-num-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/ext3-nlinks-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/ext3-no-write-super-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/ext3-noread-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/ext3-orphan_lock-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/ext3-pdirops-2.4.24-chaos.patch delete mode 100644 lustre/kernel_patches/patches/ext3-pdirops-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/ext3-raw-lookup-pdirops-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/ext3-san-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/ext3-truncate-buffer-head-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/ext3-trusted_ea-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/ext3-xattr-ptr-arith-fix-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/extN-wantedi-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/gfp_memalloc-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/inode-max-readahead-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/invalidate_show-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/iod-stock-24-exports.patch delete mode 100644 lustre/kernel_patches/patches/iod-stock-exports-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/iopen-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/jbd-commit-tricks-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/jbd-dont-account-blocks-twice-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/kernel_text_address-2.4.24-vanilla.patch delete mode 100644 lustre/kernel_patches/patches/kksymoops-2.4.24.vanilla.patch delete mode 100644 lustre/kernel_patches/patches/linux-2.4.24-xattr-0.8.54.patch delete mode 100644 lustre/kernel_patches/patches/listman-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/netconsole-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/nfs_export_kernel-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/procfs-ndynamic-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/tcp-zero-copy-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/uml-2.4.24-do_mmap_pgoff-fix.patch delete mode 100644 lustre/kernel_patches/patches/uml-export-end_iomem-2.4.24.patch delete mode 100644 lustre/kernel_patches/patches/uml-patch-2.4.24-1.patch delete mode 100644 lustre/kernel_patches/patches/vfs-pdirops-2.4.24.patch delete mode 100755 lustre/kernel_patches/patches/vfs_intent-2.4.24.patch delete mode 100644 lustre/kernel_patches/series/vanilla-2.4.24 diff --git a/lustre/kernel_patches/kernel_configs/config-linux-2.4.18-p4smp-61chaos b/lustre/kernel_patches/kernel_configs/config-linux-2.4.18-p4smp-61chaos deleted file mode 100644 index 0de1146..0000000 --- a/lustre/kernel_patches/kernel_configs/config-linux-2.4.18-p4smp-61chaos +++ /dev/null @@ -1,1035 +0,0 @@ -# -# Automatically generated by make menuconfig: don't edit -# -CONFIG_X86=y -CONFIG_ISA=y -# CONFIG_SBUS is not set -CONFIG_UID16=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODVERSIONS=y -CONFIG_KMOD=y - -# -# Processor type and features -# -CONFIG_LOLAT=y -# CONFIG_LOLAT_SYSCTL is not set -# CONFIG_M386 is not set -# CONFIG_M486 is not set -# CONFIG_M586 is not set -# CONFIG_M586TSC is not set -# CONFIG_M586MMX is not set -# CONFIG_M686 is not set -# CONFIG_MPENTIUMIII is not set -CONFIG_MPENTIUM4=y -# CONFIG_MK6 is not set -# CONFIG_MK7 is not set -# CONFIG_MELAN is not set -# CONFIG_MCRUSOE is not set -# CONFIG_MWINCHIPC6 is not set -# CONFIG_MWINCHIP2 is not set -# CONFIG_MWINCHIP3D is not set -# CONFIG_MCYRIXIII is not set -CONFIG_X86_WP_WORKS_OK=y -CONFIG_X86_INVLPG=y -CONFIG_X86_CMPXCHG=y -CONFIG_X86_XADD=y -CONFIG_X86_BSWAP=y -CONFIG_X86_POPAD_OK=y -# CONFIG_RWSEM_GENERIC_SPINLOCK is not set -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_X86_L1_CACHE_SHIFT=7 -CONFIG_X86_TSC=y -CONFIG_X86_GOOD_APIC=y -CONFIG_X86_PGE=y -CONFIG_X86_USE_PPRO_CHECKSUM=y -CONFIG_X86_MCE=y -# CONFIG_CPU_FREQ is not set -# CONFIG_TOSHIBA is not set -# CONFIG_I8K is not set -CONFIG_MICROCODE=m -CONFIG_X86_MSR=m -CONFIG_X86_CPUID=m -# CONFIG_E820_PROC is not set -# CONFIG_NOHIGHMEM is not set -CONFIG_HIGHMEM4G=y -# CONFIG_HIGHMEM64G is not set -CONFIG_HIGHMEM=y -CONFIG_HIGHIO=y -# CONFIG_MATH_EMULATION is not set -CONFIG_MTRR=y -CONFIG_SMP=y -# CONFIG_MULTIQUAD is not set -CONFIG_HAVE_DEC_LOCK=y - -# -# General setup -# -CONFIG_HZ=100 -CONFIG_NET=y -CONFIG_X86_IO_APIC=y -CONFIG_X86_LOCAL_APIC=y -CONFIG_PCI=y -# CONFIG_PCI_GOBIOS is not set -# CONFIG_PCI_GODIRECT is not set -CONFIG_PCI_GOANY=y -CONFIG_PCI_BIOS=y -CONFIG_PCI_DIRECT=y -CONFIG_PCI_NAMES=y - -# -# Performance-monitoring counters support -# -CONFIG_PERFCTR=m -CONFIG_KPERFCTR=y -# CONFIG_PERFCTR_DEBUG is not set -# CONFIG_PERFCTR_INIT_TESTS is not set -CONFIG_PERFCTR_VIRTUAL=y -CONFIG_PERFCTR_GLOBAL=y -# CONFIG_EISA is not set -# CONFIG_MCA is not set -# CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set -# CONFIG_HOTPLUG_PCI is not set -CONFIG_SYSVIPC=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_SYSCTL=y -CONFIG_KCORE_ELF=y -# CONFIG_KCORE_AOUT is not set -CONFIG_BINFMT_AOUT=m -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=m -# CONFIG_IKCONFIG is not set -CONFIG_PM=y - -# -# Additional device driver support -# -# CONFIG_CIPE is not set -# CONFIG_CRYPTO_AEP is not set -# CONFIG_MEGARAC is not set -CONFIG_FC_QLA2200=m -CONFIG_FC_QLA2300=m -# CONFIG_SCSI_ISCSI is not set -CONFIG_IBMASM=m -CONFIG_IBMSER=m -# CONFIG_ACPI is not set -CONFIG_APM=y -CONFIG_APM_IGNORE_USER_SUSPEND=y -# CONFIG_APM_DO_ENABLE is not set -# CONFIG_APM_CPU_IDLE is not set -# CONFIG_APM_DISPLAY_BLANK is not set -CONFIG_APM_RTC_IS_GMT=y -# CONFIG_APM_ALLOW_INTS is not set -# CONFIG_APM_REAL_MODE_POWER_OFF is not set - -# -# Binary emulation of other systems -# -# CONFIG_ABI is not set -# CONFIG_ABI_SVR4 is not set -# CONFIG_BINFMT_COFF is not set -# CONFIG_BINFMT_XOUT is not set -# CONFIG_BINFMT_XOUT_X286 is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_PARTITIONS is not set -# CONFIG_MTD_CONCAT is not set -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set -CONFIG_MTD_CHAR=m -# CONFIG_MTD_BLOCK is not set -# CONFIG_MTD_BLOCK_RO is not set -# CONFIG_FTL is not set -# CONFIG_NFTL is not set - -# -# RAM/ROM/Flash chip drivers -# -# CONFIG_MTD_CFI is not set -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_GEN_PROBE=y -CONFIG_MTD_CFI_ADV_OPTIONS=y -CONFIG_MTD_CFI_NOSWAP=y -# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set -# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set -CONFIG_MTD_CFI_GEOMETRY=y -CONFIG_MTD_CFI_B1=y -# CONFIG_MTD_CFI_B2 is not set -# CONFIG_MTD_CFI_B4 is not set -# CONFIG_MTD_CFI_B8 is not set -CONFIG_MTD_CFI_I1=y -# CONFIG_MTD_CFI_I2 is not set -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_CFI_AMDSTD=y -# CONFIG_MTD_RAM is not set -CONFIG_MTD_ROM=y -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set -# CONFIG_MTD_AMDSTD is not set -# CONFIG_MTD_SHARP is not set -# CONFIG_MTD_JEDEC is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_PNC2000 is not set -# CONFIG_MTD_SC520CDP is not set -# CONFIG_MTD_NETSC520 is not set -# CONFIG_MTD_SBC_GXX is not set -# CONFIG_MTD_ELAN_104NC is not set -# CONFIG_MTD_DILNETPC is not set -# CONFIG_MTD_MIXMEM is not set -# CONFIG_MTD_OCTAGON is not set -# CONFIG_MTD_VMAX is not set -# CONFIG_MTD_L440GX is not set -# CONFIG_MTD_AMD766ROM is not set -CONFIG_MTD_ICH2ROM=m -# CONFIG_MTD_PCI is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLKMTD is not set -# CONFIG_MTD_DOC1000 is not set -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOCPROBE is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# Parallel port support -# -CONFIG_PARPORT=m -CONFIG_PARPORT_PC=m -CONFIG_PARPORT_PC_CML1=m -CONFIG_PARPORT_SERIAL=m -# CONFIG_PARPORT_PC_FIFO is not set -# CONFIG_PARPORT_PC_SUPERIO is not set -# CONFIG_PARPORT_AMIGA is not set -# CONFIG_PARPORT_MFC3 is not set -# CONFIG_PARPORT_ATARI is not set -# CONFIG_PARPORT_GSC is not set -# CONFIG_PARPORT_SUNBPP is not set -# CONFIG_PARPORT_OTHER is not set -CONFIG_PARPORT_1284=y - -# -# Plug and Play configuration -# -CONFIG_PNP=y -CONFIG_ISAPNP=y -# CONFIG_PNPBIOS is not set - -# -# Block devices -# -CONFIG_BLK_DEV_FD=y -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_CISS_SCSI_TAPE is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_ENBD=m -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_INITRD=y - -# -# Multi-device support (RAID and LVM) -# -CONFIG_MD=y -CONFIG_BLK_DEV_MD=y -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_MD_MULTIPATH is not set -CONFIG_BLK_DEV_LVM=m - -# -# Cryptography support (CryptoAPI) -# -# CONFIG_CRYPTO is not set -# CONFIG_CIPHERS is not set -# CONFIG_CRYPTODEV is not set -# CONFIG_CRYPTOLOOP is not set - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_NETLINK_DEV=y -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_FILTER=y -CONFIG_UNIX=y -CONFIG_INET=y -# CONFIG_TUX is not set -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_FWMARK=y -CONFIG_IP_ROUTE_NAT=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_TOS=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_ROUTE_LARGE_TABLES=y -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -# CONFIG_ARPD is not set -# CONFIG_INET_ECN is not set -CONFIG_SYN_COOKIES=y - -# -# IP: Netfilter Configuration -# -CONFIG_IP_NF_CONNTRACK=m -# CONFIG_IP_NF_FTP is not set -# CONFIG_IP_NF_IRC is not set -# CONFIG_IP_NF_QUEUE is not set -# CONFIG_IP_NF_IPTABLES is not set -# CONFIG_IP_NF_ARPTABLES is not set -# CONFIG_IP_NF_COMPAT_IPCHAINS is not set -# CONFIG_IP_NF_COMPAT_IPFWADM is not set - -# -# IP: Virtual Server Configuration -# -# CONFIG_IP_VS is not set -# CONFIG_IPV6 is not set -CONFIG_KHTTPD=m -# CONFIG_ATM is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set - -# -# Appletalk devices -# -# CONFIG_DEV_APPLETALK is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_LLC is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -CONFIG_NET_PKTGEN=m - -# -# Telephony Support -# -# CONFIG_PHONE is not set -# CONFIG_PHONE_IXJ is not set -# CONFIG_PHONE_IXJ_PCMCIA is not set - -# -# ATA/IDE/MFM/RLL support -# -CONFIG_IDE=y - -# -# IDE, ATA and ATAPI Block devices -# -CONFIG_BLK_DEV_IDE=y -# CONFIG_BLK_DEV_HD_IDE is not set -# CONFIG_BLK_DEV_HD is not set -CONFIG_BLK_DEV_IDEDISK=y -CONFIG_IDEDISK_MULTI_MODE=y -# CONFIG_IDEDISK_STROKE is not set -# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set -# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set -# CONFIG_BLK_DEV_IDEDISK_IBM is not set -# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set -# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set -# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set -# CONFIG_BLK_DEV_IDEDISK_WD is not set -# CONFIG_BLK_DEV_COMMERIAL is not set -# CONFIG_BLK_DEV_TIVO is not set -# CONFIG_BLK_DEV_IDECS is not set -CONFIG_BLK_DEV_IDECD=m -# CONFIG_BLK_DEV_IDETAPE is not set -CONFIG_BLK_DEV_IDEFLOPPY=y -# CONFIG_BLK_DEV_IDESCSI is not set -# CONFIG_IDE_TASK_IOCTL is not set -# CONFIG_BLK_DEV_CMD640 is not set -# CONFIG_BLK_DEV_CMD640_ENHANCED is not set -CONFIG_BLK_DEV_ISAPNP=y -# CONFIG_BLK_DEV_RZ1000 is not set -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_IDEPCI_SHARE_IRQ=y -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_OFFBOARD is not set -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y -# CONFIG_IDEDMA_ONLYDISK is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_PCI_WIP is not set -# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set -# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set -CONFIG_BLK_DEV_ADMA=y -CONFIG_BLK_DEV_AEC62XX=y -CONFIG_AEC62XX_TUNING=y -CONFIG_BLK_DEV_ALI15X3=y -# CONFIG_WDC_ALI15X3 is not set -CONFIG_BLK_DEV_AMD74XX=y -# CONFIG_AMD74XX_OVERRIDE is not set -CONFIG_BLK_DEV_CMD64X=y -CONFIG_BLK_DEV_CMD680=y -CONFIG_BLK_DEV_CY82C693=y -CONFIG_BLK_DEV_CS5530=y -CONFIG_BLK_DEV_HPT34X=y -# CONFIG_HPT34X_AUTODMA is not set -CONFIG_BLK_DEV_HPT366=y -CONFIG_BLK_DEV_PIIX=y -CONFIG_PIIX_TUNING=y -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_ADMA100 is not set -CONFIG_BLK_DEV_PDC202XX=y -# CONFIG_PDC202XX_BURST is not set -# CONFIG_PDC202XX_FORCE is not set -CONFIG_BLK_DEV_SVWKS=y -CONFIG_BLK_DEV_SIS5513=y -CONFIG_BLK_DEV_SLC90E66=y -# CONFIG_BLK_DEV_TRM290 is not set -CONFIG_BLK_DEV_VIA82CXXX=y -CONFIG_BLK_DEV_CENATEK=y -# CONFIG_IDE_CHIPSETS is not set -# CONFIG_BLK_DEV_ELEVATOR_NOOP is not set -CONFIG_IDEDMA_AUTO=y -# CONFIG_IDEDMA_IVB is not set -# CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y -# CONFIG_BLK_DEV_ATARAID is not set -# CONFIG_BLK_DEV_ATARAID_PDC is not set -# CONFIG_BLK_DEV_ATARAID_HPT is not set - -# -# SCSI support -# -CONFIG_SCSI=y -CONFIG_BLK_DEV_SD=y -CONFIG_SD_EXTRA_DEVS=40 -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=m -CONFIG_BLK_DEV_SR_VENDOR=y -CONFIG_SR_EXTRA_DEVS=4 -CONFIG_CHR_DEV_SG=m -# CONFIG_SCSI_DEBUG_QUEUES is not set -CONFIG_SCSI_MULTI_LUN=y -CONFIG_SCSI_CONSTANTS=y -CONFIG_SCSI_LOGGING=y - -# -# SCSI low-level drivers -# -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_7000FASST is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set -# CONFIG_SCSI_AHA1740 is not set -# CONFIG_SCSI_AACRAID is not set -CONFIG_SCSI_AIC7XXX=y -CONFIG_AIC7XXX_CMDS_PER_DEVICE=253 -CONFIG_AIC7XXX_RESET_DELAY_MS=15000 -# CONFIG_AIC7XXX_PROBE_EISA_VL is not set -# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_SCSI_AM53C974 is not set -# CONFIG_SCSI_MEGARAID is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_DMA is not set -# CONFIG_SCSI_EATA_PIO is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_GENERIC_NCR5380 is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_PPA is not set -# CONFIG_SCSI_IMM is not set -# CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_NCR53C7xx is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_NCR53C8XX is not set -# CONFIG_SCSI_SYM53C8XX is not set -# CONFIG_SCSI_PAS16 is not set -# CONFIG_SCSI_PCI2000 is not set -# CONFIG_SCSI_PCI2220I is not set -# CONFIG_SCSI_PSI240I is not set -# CONFIG_SCSI_QLOGIC_FAS is not set -# CONFIG_SCSI_QLOGIC_ISP is not set -# CONFIG_SCSI_QLOGIC_FC is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_NEWISP is not set -# CONFIG_SCSI_SEAGATE is not set -# CONFIG_SCSI_SIM710 is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set -# CONFIG_SCSI_ULTRASTOR is not set -CONFIG_SCSI_DEBUG=m - -# -# Fusion MPT device support -# -CONFIG_FUSION=y -CONFIG_FUSION_BOOT=y -CONFIG_FUSION_ISENSE=m -CONFIG_FUSION_CTL=m -# CONFIG_FUSION_LAN is not set - -# -# IEEE 1394 (FireWire) support (EXPERIMENTAL) -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set -# CONFIG_I2O_PCI is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set -CONFIG_DUMMY=m -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_ETHERTAP is not set -# CONFIG_NET_SB1000 is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -# CONFIG_SUNLANCE is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -# CONFIG_SUNGEM is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_AT1700 is not set -# CONFIG_DEPCA is not set -# CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_AC3200 is not set -# CONFIG_APRICOT is not set -# CONFIG_CS89x0 is not set -CONFIG_TULIP=m -# CONFIG_TC35815 is not set -# CONFIG_TULIP_MWI is not set -CONFIG_TULIP_MMIO=y -CONFIG_DE4X5=m -# CONFIG_DGRS is not set -# CONFIG_DM9102 is not set -CONFIG_EEPRO100=m -CONFIG_NET_E100=m -# CONFIG_LNE390 is not set -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_NE3210 is not set -# CONFIG_ES3210 is not set -# CONFIG_8139CP is not set -# CONFIG_8139TOO is not set -# CONFIG_8139TOO_PIO is not set -# CONFIG_8139TOO_TUNE_TWISTER is not set -# CONFIG_8139TOO_8129 is not set -# CONFIG_8139_NEW_RX_RESET is not set -# CONFIG_SIS900 is not set -# CONFIG_SIS900_OLD is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_VIA_RHINE_MMIO is not set -# CONFIG_WINBOND_840 is not set -# CONFIG_NET_POCKET is not set - -# -# Ethernet (1000 Mbit) -# -CONFIG_ACENIC=m -# CONFIG_ACENIC_OMIT_TIGON_I is not set -# CONFIG_DL2K is not set -# CONFIG_MYRI_SBUS is not set -CONFIG_NS83820=m -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_SK98LIN is not set -CONFIG_NET_BROADCOM=m -CONFIG_TIGON3=m -CONFIG_NET_E1000=m -# CONFIG_FDDI is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_HIPPI is not set -# CONFIG_PLIP is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set -# CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set -# CONFIG_SHAPER is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set - -# -# Quadrics Supercomputers -# - -# -# QsNet -# -CONFIG_QUADRICS=y -CONFIG_QSNETMOD=m -CONFIG_ELAN3MOD=m -CONFIG_EPMOD=m -CONFIG_EIPMOD=m -CONFIG_RMSMOD=m -CONFIG_JTAG=m - -# -# QsNet II -# - -# -# Amateur Radio support -# -# CONFIG_HAMRADIO is not set - -# -# IrDA (infrared) support -# -# CONFIG_IRDA is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set -CONFIG_KALLSYMS=y - -# -# Old CD-ROM drivers (not SCSI, not IDE) -# -# CONFIG_CD_NO_IDESCSI is not set - -# -# Input core support -# -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set - -# -# Character devices -# -CONFIG_ECC=m -CONFIG_CHAOSTEST=m -CONFIG_P4THERM=m -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_SERIAL=y -CONFIG_SERIAL_CONSOLE=y -CONFIG_SERIAL_EXTENDED=y -# CONFIG_SERIAL_MANY_PORTS is not set -CONFIG_SERIAL_SHARE_IRQ=y -# CONFIG_SERIAL_DETECT_IRQ is not set -# CONFIG_SERIAL_MULTIPORT is not set -# CONFIG_HUB6 is not set -# CONFIG_SERIAL_NONSTANDARD is not set -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=2048 -# CONFIG_PRINTER is not set -# CONFIG_PPDEV is not set - -# -# I2C support -# -CONFIG_I2C=y -# CONFIG_I2C_ALGOBIT is not set -# CONFIG_I2C_ALGOPCF is not set -CONFIG_I2C_MAINBOARD=y -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_HYDRA is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_TSUNAMI is not set -CONFIG_I2C_I801=m -# CONFIG_I2C_I810 is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VOODOO3 is not set -CONFIG_I2C_ISA=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_PROC=y - -# -# Hardware sensors support -# -CONFIG_SENSORS=y -CONFIG_SENSORS_ADM1021=m -# CONFIG_SENSORS_ADM1024 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_FSCPOS is not set -# CONFIG_SENSORS_FSCSCY is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_MAXILIFE is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_MTP008 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -CONFIG_SENSORS_LM87=m -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_THMC50 is not set -# CONFIG_SENSORS_VIA686A is not set -CONFIG_SENSORS_W83781D=y -# CONFIG_SENSORS_OTHER is not set - -# -# Mice -# -# CONFIG_BUSMOUSE is not set -CONFIG_MOUSE=y -CONFIG_PSMOUSE=y -# CONFIG_82C710_MOUSE is not set -# CONFIG_PC110_PAD is not set -# CONFIG_MK712_MOUSE is not set - -# -# Joysticks -# -# CONFIG_INPUT_GAMEPORT is not set -# CONFIG_QIC02_TAPE is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_AMD_RNG is not set -# CONFIG_INTEL_RNG is not set -# CONFIG_AMD_PM768 is not set -# CONFIG_NVRAM is not set -CONFIG_RTC=y -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_SONYPI is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_FTAPE is not set -CONFIG_AGP=m -CONFIG_AGP_INTEL=y -# CONFIG_AGP_I810 is not set -# CONFIG_AGP_VIA is not set -# CONFIG_AGP_AMD is not set -# CONFIG_AGP_SIS is not set -# CONFIG_AGP_ALI is not set -# CONFIG_AGP_SWORKS is not set -# CONFIG_DRM is not set -# CONFIG_MWAVE is not set -# CONFIG_BATTERY_GERICOM is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Crypto Hardware support -# -# CONFIG_CRYPTO is not set - -# -# File systems -# -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set -# CONFIG_ADFS_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_ADFS_FS_RW is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BEFS_DEBUG is not set -# CONFIG_BFS_FS is not set -CONFIG_EXT3_FS=y -CONFIG_EXTN_FS=m -CONFIG_JBD=y -CONFIG_JBD_DEBUG=y -CONFIG_FAT_FS=m -CONFIG_MSDOS_FS=m -CONFIG_UMSDOS_FS=m -CONFIG_VFAT_FS=m -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set -CONFIG_CRAMFS=y -CONFIG_TMPFS=y -CONFIG_RAMFS=y -CONFIG_ISO9660_FS=y -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -# CONFIG_JFS_FS is not set -# CONFIG_JFS_DEBUG is not set -# CONFIG_JFS_STATISTICS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_RW is not set -# CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y -# CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -CONFIG_ROMFS_FS=m -CONFIG_EXT2_FS=y -# CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set -# CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set - -# -# Network File Systems -# -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set -CONFIG_NFS_FS=m -CONFIG_NFS_V3=y -# CONFIG_ROOT_NFS is not set -CONFIG_NFSD=m -CONFIG_NFSD_V3=y -CONFIG_NFSD_TCP=y -CONFIG_SUNRPC=m -CONFIG_LOCKD=m -CONFIG_LOCKD_V4=y -# CONFIG_SMB_FS is not set -# CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set -# CONFIG_PFS_FS is not set -CONFIG_ZISOFS_FS=y - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -CONFIG_OSF_PARTITION=y -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -CONFIG_MAC_PARTITION=y -CONFIG_MSDOS_PARTITION=y -CONFIG_BSD_DISKLABEL=y -CONFIG_MINIX_SUBPARTITION=y -CONFIG_SOLARIS_X86_PARTITION=y -CONFIG_UNIXWARE_DISKLABEL=y -# CONFIG_LDM_PARTITION is not set -CONFIG_SGI_PARTITION=y -# CONFIG_ULTRIX_PARTITION is not set -CONFIG_SUN_PARTITION=y -# CONFIG_SMB_NLS is not set -CONFIG_NLS=y - -# -# Native Language Support -# -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=m -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -CONFIG_NLS_CODEPAGE_850=m -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -CONFIG_NLS_ISO8859_1=m -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Console drivers -# -CONFIG_VGA_CONSOLE=y -CONFIG_VIDEO_SELECT=y -# CONFIG_VIDEO_IGNORE_BAD_MODE is not set -# CONFIG_MDA_CONSOLE is not set - -# -# Frame-buffer support -# -# CONFIG_FB is not set -# CONFIG_SPEAKUP is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -# CONFIG_USB is not set - -# -# Bluetooth support -# -# CONFIG_BLUEZ is not set - -# -# Kernel hacking -# -CONFIG_DEBUG_KERNEL=y -CONFIG_FRAME_POINTER=y -CONFIG_STACK_TRACE_SCAN=y -CONFIG_STACK_TRACE_FPTR=y -CONFIG_STACK_TRACE_PARAM_COUNT=4 -# CONFIG_DEBUG_HIGHMEM is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_IOVIRT is not set -CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_SPINLOCK=y -CONFIG_MCL_COREDUMP=y -CONFIG_BOOTIMG=y -# CONFIG_OPROFILE is not set - -# -# Library routines -# -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y diff --git a/lustre/kernel_patches/kernel_configs/config-linux-2.4.20-i386-rh b/lustre/kernel_patches/kernel_configs/config-linux-2.4.20-i386-rh deleted file mode 100644 index dec210a..0000000 --- a/lustre/kernel_patches/kernel_configs/config-linux-2.4.20-i386-rh +++ /dev/null @@ -1,1849 +0,0 @@ -# -# Automatically generated by make menuconfig: don't edit -# -CONFIG_X86=y -# CONFIG_SBUS is not set -CONFIG_UID16=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODVERSIONS=y -CONFIG_KMOD=y - -# -# Processor type and features -# -CONFIG_LOLAT=y -# CONFIG_M386 is not set -# CONFIG_M486 is not set -# CONFIG_M586 is not set -# CONFIG_M586TSC is not set -# CONFIG_M586MMX is not set -CONFIG_M686=y -# CONFIG_MPENTIUMIII is not set -# CONFIG_MPENTIUM4 is not set -# CONFIG_MK6 is not set -# CONFIG_MK7 is not set -# CONFIG_MELAN is not set -# CONFIG_MCRUSOE is not set -# CONFIG_MWINCHIPC6 is not set -# CONFIG_MWINCHIP2 is not set -# CONFIG_MWINCHIP3D is not set -# CONFIG_MCYRIXIII is not set -CONFIG_X86_WP_WORKS_OK=y -CONFIG_X86_INVLPG=y -CONFIG_X86_CMPXCHG=y -CONFIG_X86_XADD=y -CONFIG_X86_BSWAP=y -CONFIG_X86_POPAD_OK=y -# CONFIG_RWSEM_GENERIC_SPINLOCK is not set -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_X86_L1_CACHE_SHIFT=7 -CONFIG_X86_HAS_TSC=y -CONFIG_X86_GOOD_APIC=y -CONFIG_X86_PGE=y -CONFIG_X86_USE_PPRO_CHECKSUM=y -CONFIG_X86_PPRO_FENCE=y -CONFIG_X86_F00F_WORKS_OK=y -CONFIG_X86_MCE=y - -# -# CPU Frequency scaling -# -CONFIG_CPU_FREQ=y -# CONFIG_CPU_FREQ_24_API is not set -CONFIG_X86_POWERNOW_K6=m -# CONFIG_X86_LONGHAUL is not set -CONFIG_X86_SPEEDSTEP=m -# CONFIG_X86_P4_CLOCKMOD is not set -# CONFIG_X86_LONGRUN is not set -CONFIG_TOSHIBA=m -CONFIG_I8K=m -CONFIG_MICROCODE=m -CONFIG_X86_MSR=m -CONFIG_X86_CPUID=m -# CONFIG_E820_PROC is not set -CONFIG_EDD=m -# CONFIG_NOHIGHMEM is not set -CONFIG_HIGHMEM4G=y -# CONFIG_HIGHMEM64G is not set -CONFIG_HIGHMEM=y -CONFIG_HIGHPTE=y -CONFIG_HIGHIO=y -# CONFIG_MATH_EMULATION is not set -CONFIG_MTRR=y -# CONFIG_SMP is not set -CONFIG_X86_UP_APIC=y -CONFIG_X86_UP_IOAPIC=y -CONFIG_X86_LOCAL_APIC=y -CONFIG_X86_IO_APIC=y -# CONFIG_X86_TSC_DISABLE is not set -CONFIG_X86_TSC=y - -# -# General setup -# -CONFIG_NET=y -CONFIG_PCI=y -# CONFIG_PCI_GOBIOS is not set -# CONFIG_PCI_GODIRECT is not set -CONFIG_PCI_GOANY=y -CONFIG_PCI_BIOS=y -CONFIG_PCI_DIRECT=y -CONFIG_ISA=y -CONFIG_PCI_NAMES=y -CONFIG_EISA=y -# CONFIG_MCA is not set -CONFIG_HOTPLUG=y - -# -# PCMCIA/CardBus support -# -CONFIG_PCMCIA=m -CONFIG_CARDBUS=y -CONFIG_TCIC=y -CONFIG_I82092=y -CONFIG_I82365=y - -# -# PCI Hotplug Support -# -# CONFIG_HOTPLUG_PCI is not set -# CONFIG_HOTPLUG_PCI_ACPI is not set -# CONFIG_HOTPLUG_PCI_COMPAQ is not set -# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set -# CONFIG_HOTPLUG_PCI_IBM is not set -# CONFIG_HOTPLUG_PCI_H2999 is not set -CONFIG_SYSVIPC=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_SYSCTL=y -CONFIG_KCORE_ELF=y -# CONFIG_KCORE_AOUT is not set -CONFIG_BINFMT_AOUT=m -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=m -CONFIG_PM=y -# CONFIG_ACPI is not set -CONFIG_APM=y -# CONFIG_APM_IGNORE_USER_SUSPEND is not set -# CONFIG_APM_DO_ENABLE is not set -CONFIG_APM_CPU_IDLE=y -# CONFIG_APM_DISPLAY_BLANK is not set -CONFIG_APM_RTC_IS_GMT=y -# CONFIG_APM_ALLOW_INTS is not set -# CONFIG_APM_REAL_MODE_POWER_OFF is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -CONFIG_PARPORT=m -CONFIG_PARPORT_PC=m -CONFIG_PARPORT_PC_CML1=m -CONFIG_PARPORT_SERIAL=m -# CONFIG_PARPORT_PC_FIFO is not set -# CONFIG_PARPORT_PC_SUPERIO is not set -CONFIG_PARPORT_PC_PCMCIA=m -# CONFIG_PARPORT_AMIGA is not set -# CONFIG_PARPORT_MFC3 is not set -# CONFIG_PARPORT_ATARI is not set -# CONFIG_PARPORT_GSC is not set -# CONFIG_PARPORT_SUNBPP is not set -# CONFIG_PARPORT_OTHER is not set -CONFIG_PARPORT_1284=y - -# -# Plug and Play configuration -# -CONFIG_PNP=y -CONFIG_ISAPNP=y - -# -# Block devices -# -CONFIG_BLK_DEV_FD=y -CONFIG_BLK_DEV_XD=m -CONFIG_PARIDE=m -CONFIG_PARIDE_PARPORT=m -CONFIG_PARIDE_PD=m -CONFIG_PARIDE_PCD=m -CONFIG_PARIDE_PF=m -CONFIG_PARIDE_PT=m -CONFIG_PARIDE_PG=m -CONFIG_PARIDE_ATEN=m -CONFIG_PARIDE_BPCK=m -CONFIG_PARIDE_BPCK6=m -CONFIG_PARIDE_COMM=m -CONFIG_PARIDE_DSTR=m -CONFIG_PARIDE_FIT2=m -CONFIG_PARIDE_FIT3=m -CONFIG_PARIDE_EPAT=m -CONFIG_PARIDE_EPATC8=y -CONFIG_PARIDE_EPIA=m -CONFIG_PARIDE_FRIQ=m -CONFIG_PARIDE_FRPW=m -CONFIG_PARIDE_KBIC=m -CONFIG_PARIDE_KTTI=m -CONFIG_PARIDE_ON20=m -CONFIG_PARIDE_ON26=m -CONFIG_BLK_CPQ_DA=m -CONFIG_BLK_CPQ_CISS_DA=m -CONFIG_CISS_SCSI_TAPE=y -CONFIG_BLK_DEV_DAC960=m -CONFIG_BLK_DEV_UMEM=m -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_INITRD=y -CONFIG_BLK_STATS=y - -# -# Multi-device support (RAID and LVM) -# -CONFIG_MD=y -CONFIG_BLK_DEV_MD=y -CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID5=m -CONFIG_MD_MULTIPATH=m -CONFIG_BLK_DEV_LVM=m - -# -# Cryptography support (CryptoAPI) -# -CONFIG_CRYPTO=m -CONFIG_CIPHERS=m -CONFIG_CIPHER_AES=m -CONFIG_CIPHER_IDENTITY=m -CONFIG_CRYPTODEV=m -CONFIG_CRYPTOLOOP=m - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_NETLINK_DEV=y -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_FILTER=y -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_TUX=m -CONFIG_TUX_EXTCGI=y -# CONFIG_TUX_EXTENDED_LOG is not set -# CONFIG_TUX_DEBUG is not set -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_FWMARK=y -CONFIG_IP_ROUTE_NAT=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_TOS=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_ROUTE_LARGE_TABLES=y -# CONFIG_IP_PNP is not set -CONFIG_NET_IPIP=m -CONFIG_NET_IPGRE=m -CONFIG_NET_IPGRE_BROADCAST=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -# CONFIG_ARPD is not set -# CONFIG_INET_ECN is not set -CONFIG_SYN_COOKIES=y - -# -# IP: Netfilter Configuration -# -CONFIG_IP_NF_CONNTRACK=m -CONFIG_IP_NF_FTP=m -CONFIG_IP_NF_IRC=m -CONFIG_IP_NF_QUEUE=m -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_LIMIT=m -CONFIG_IP_NF_MATCH_MAC=m -CONFIG_IP_NF_MATCH_PKTTYPE=m -CONFIG_IP_NF_MATCH_MARK=m -CONFIG_IP_NF_MATCH_MULTIPORT=m -CONFIG_IP_NF_MATCH_TOS=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_DSCP=m -CONFIG_IP_NF_MATCH_AH_ESP=m -CONFIG_IP_NF_MATCH_LENGTH=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_MATCH_TCPMSS=m -CONFIG_IP_NF_MATCH_HELPER=m -CONFIG_IP_NF_MATCH_STATE=m -CONFIG_IP_NF_MATCH_CONNTRACK=m -CONFIG_IP_NF_MATCH_UNCLEAN=m -CONFIG_IP_NF_MATCH_OWNER=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_MIRROR=m -CONFIG_IP_NF_NAT=m -CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_IP_NF_NAT_LOCAL=y -CONFIG_IP_NF_NAT_SNMP_BASIC=m -CONFIG_IP_NF_NAT_IRC=m -CONFIG_IP_NF_NAT_FTP=m -CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_TOS=m -CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_TARGET_DSCP=m -CONFIG_IP_NF_TARGET_MARK=m -CONFIG_IP_NF_TARGET_LOG=m -CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_IP_NF_TARGET_TCPMSS=m -CONFIG_IP_NF_ARPTABLES=m -CONFIG_IP_NF_ARPFILTER=m -CONFIG_IP_NF_COMPAT_IPCHAINS=m -CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IP_NF_COMPAT_IPFWADM=m -CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IPV6=m - -# -# IPv6: Netfilter Configuration -# -# CONFIG_IP6_NF_QUEUE is not set -CONFIG_IP6_NF_IPTABLES=m -CONFIG_IP6_NF_MATCH_LIMIT=m -CONFIG_IP6_NF_MATCH_MAC=m -CONFIG_IP6_NF_MATCH_MULTIPORT=m -CONFIG_IP6_NF_MATCH_OWNER=m -CONFIG_IP6_NF_MATCH_MARK=m -CONFIG_IP6_NF_MATCH_LENGTH=m -CONFIG_IP6_NF_MATCH_EUI64=m -CONFIG_IP6_NF_FILTER=m -CONFIG_IP6_NF_TARGET_LOG=m -CONFIG_IP6_NF_MANGLE=m -CONFIG_IP6_NF_TARGET_MARK=m -# CONFIG_KHTTPD is not set -CONFIG_ATM=y -CONFIG_ATM_CLIP=y -# CONFIG_ATM_CLIP_NO_ICMP is not set -CONFIG_ATM_LANE=m -CONFIG_ATM_MPOA=m -CONFIG_ATM_BR2684=m -CONFIG_ATM_BR2684_IPFILTER=y -CONFIG_VLAN_8021Q=m -CONFIG_IPX=m -# CONFIG_IPX_INTERN is not set -CONFIG_ATALK=m - -# -# Appletalk devices -# -CONFIG_DEV_APPLETALK=y -CONFIG_LTPC=m -CONFIG_COPS=m -CONFIG_COPS_DAYNA=y -CONFIG_COPS_TANGENT=y -CONFIG_IPDDP=m -CONFIG_IPDDP_ENCAP=y -CONFIG_IPDDP_DECAP=y -CONFIG_DECNET=m -CONFIG_DECNET_SIOCGIFCONF=y -CONFIG_DECNET_ROUTER=y -CONFIG_DECNET_ROUTE_FWMARK=y -CONFIG_BRIDGE=m -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_LLC is not set -CONFIG_NET_DIVERT=y -# CONFIG_ECONET is not set -CONFIG_WAN_ROUTER=m -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set - -# -# QoS and/or fair queueing -# -CONFIG_NET_SCHED=y -CONFIG_NET_SCH_CBQ=m -CONFIG_NET_SCH_HTB=m -CONFIG_NET_SCH_CSZ=m -# CONFIG_NET_SCH_ATM is not set -CONFIG_NET_SCH_PRIO=m -CONFIG_NET_SCH_RED=m -CONFIG_NET_SCH_SFQ=m -CONFIG_NET_SCH_TEQL=m -CONFIG_NET_SCH_TBF=m -CONFIG_NET_SCH_GRED=m -CONFIG_NET_SCH_DSMARK=m -CONFIG_NET_SCH_INGRESS=m -CONFIG_NET_QOS=y -CONFIG_NET_ESTIMATOR=y -CONFIG_NET_CLS=y -CONFIG_NET_CLS_TCINDEX=m -CONFIG_NET_CLS_ROUTE4=m -CONFIG_NET_CLS_ROUTE=y -CONFIG_NET_CLS_FW=m -CONFIG_NET_CLS_U32=m -CONFIG_NET_CLS_RSVP=m -CONFIG_NET_CLS_RSVP6=m -CONFIG_NET_CLS_POLICE=y - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set - -# -# Telephony Support -# -CONFIG_PHONE=m -CONFIG_PHONE_IXJ=m -CONFIG_PHONE_IXJ_PCMCIA=m - -# -# ATA/IDE/MFM/RLL support -# -CONFIG_IDE=y - -# -# IDE, ATA and ATAPI Block devices -# -CONFIG_BLK_DEV_IDE=y -# CONFIG_BLK_DEV_HD_IDE is not set -# CONFIG_BLK_DEV_HD is not set -CONFIG_BLK_DEV_IDEDISK=y -CONFIG_IDEDISK_MULTI_MODE=y -# CONFIG_IDEDISK_STROKE is not set -CONFIG_BLK_DEV_IDECS=m -CONFIG_BLK_DEV_IDECD=m -CONFIG_BLK_DEV_IDETAPE=m -CONFIG_BLK_DEV_IDEFLOPPY=y -CONFIG_BLK_DEV_IDESCSI=m -# CONFIG_IDE_TASK_IOCTL is not set -CONFIG_BLK_DEV_CMD640=y -# CONFIG_BLK_DEV_CMD640_ENHANCED is not set -CONFIG_BLK_DEV_ISAPNP=y -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_BLK_DEV_GENERIC=y -CONFIG_IDEPCI_SHARE_IRQ=y -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_OFFBOARD is not set -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y -# CONFIG_IDEDMA_ONLYDISK is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_PCI_WIP is not set -CONFIG_BLK_DEV_ADMA=y -CONFIG_BLK_DEV_AEC62XX=y -CONFIG_BLK_DEV_ALI15X3=y -# CONFIG_WDC_ALI15X3 is not set -CONFIG_BLK_DEV_AMD74XX=y -# CONFIG_AMD74XX_OVERRIDE is not set -CONFIG_BLK_DEV_CMD64X=y -CONFIG_BLK_DEV_TRIFLEX=y -CONFIG_BLK_DEV_CY82C693=y -CONFIG_BLK_DEV_CS5530=y -CONFIG_BLK_DEV_HPT34X=y -# CONFIG_HPT34X_AUTODMA is not set -CONFIG_BLK_DEV_HPT366=y -CONFIG_BLK_DEV_PIIX=y -CONFIG_BLK_DEV_NFORCE=y -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_OPTI621 is not set -CONFIG_BLK_DEV_PDC202XX_OLD=y -# CONFIG_PDC202XX_BURST is not set -CONFIG_BLK_DEV_PDC202XX_NEW=y -CONFIG_PDC202XX_FORCE=y -CONFIG_BLK_DEV_RZ1000=y -# CONFIG_BLK_DEV_SC1200 is not set -CONFIG_BLK_DEV_SVWKS=y -CONFIG_BLK_DEV_SIIMAGE=y -CONFIG_BLK_DEV_SIS5513=y -CONFIG_BLK_DEV_SLC90E66=y -# CONFIG_BLK_DEV_TRM290 is not set -CONFIG_BLK_DEV_VIA82CXXX=y -# CONFIG_IDE_CHIPSETS is not set -CONFIG_IDEDMA_AUTO=y -# CONFIG_IDEDMA_IVB is not set -# CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_PDC202XX=y -CONFIG_BLK_DEV_IDE_MODES=y -CONFIG_BLK_DEV_ATARAID=m -CONFIG_BLK_DEV_ATARAID_PDC=m -CONFIG_BLK_DEV_ATARAID_HPT=m -CONFIG_BLK_DEV_ATARAID_SII=m - -# -# SCSI support -# -CONFIG_SCSI=m -CONFIG_BLK_DEV_SD=m -CONFIG_SD_EXTRA_DEVS=40 -CONFIG_CHR_DEV_ST=m -CONFIG_CHR_DEV_OSST=m -CONFIG_BLK_DEV_SR=m -CONFIG_BLK_DEV_SR_VENDOR=y -CONFIG_SR_EXTRA_DEVS=4 -CONFIG_CHR_DEV_SG=m -# CONFIG_SCSI_DEBUG_QUEUES is not set -# CONFIG_SCSI_MULTI_LUN is not set -CONFIG_SCSI_CONSTANTS=y -CONFIG_SCSI_LOGGING=y - -# -# SCSI low-level drivers -# -CONFIG_BLK_DEV_3W_XXXX_RAID=m -CONFIG_SCSI_7000FASST=m -CONFIG_SCSI_ACARD=m -CONFIG_SCSI_AHA152X=m -CONFIG_SCSI_AHA1542=m -CONFIG_SCSI_AHA1740=m -CONFIG_SCSI_AACRAID=m -CONFIG_SCSI_AIC7XXX=m -CONFIG_AIC7XXX_CMDS_PER_DEVICE=253 -CONFIG_AIC7XXX_RESET_DELAY_MS=15000 -# CONFIG_AIC7XXX_PROBE_EISA_VL is not set -# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set -CONFIG_SCSI_AIC79XX=m -CONFIG_AIC79XX_CMDS_PER_DEVICE=253 -CONFIG_AIC79XX_RESET_DELAY_MS=15000 -# CONFIG_AIC79XX_BUILD_FIRMWARE is not set -CONFIG_AIC79XX_ENABLE_RD_STRM=y -# CONFIG_AIC79XX_DEBUG_ENABLE is not set -CONFIG_AIC79XX_DEBUG_MASK=0 -CONFIG_SCSI_AIC7XXX_OLD=m -CONFIG_AIC7XXX_OLD_TCQ_ON_BY_DEFAULT=y -CONFIG_AIC7XXX_OLD_CMDS_PER_DEVICE=32 -CONFIG_AIC7XXX_OLD_PROC_STATS=y -CONFIG_SCSI_DPT_I2O=m -CONFIG_SCSI_ADVANSYS=m -CONFIG_SCSI_IN2000=m -CONFIG_SCSI_AM53C974=m -CONFIG_SCSI_MEGARAID=m -CONFIG_SCSI_BUSLOGIC=m -# CONFIG_SCSI_OMIT_FLASHPOINT is not set -CONFIG_SCSI_CPQFCTS=m -CONFIG_SCSI_DMX3191D=m -CONFIG_SCSI_DTC3280=m -CONFIG_SCSI_EATA=m -CONFIG_SCSI_EATA_TAGGED_QUEUE=y -# CONFIG_SCSI_EATA_LINKED_COMMANDS is not set -CONFIG_SCSI_EATA_MAX_TAGS=16 -CONFIG_SCSI_EATA_DMA=m -CONFIG_SCSI_EATA_PIO=m -CONFIG_SCSI_FUTURE_DOMAIN=m -CONFIG_SCSI_GDTH=m -CONFIG_SCSI_GENERIC_NCR5380=m -# CONFIG_SCSI_GENERIC_NCR53C400 is not set -CONFIG_SCSI_G_NCR5380_PORT=y -# CONFIG_SCSI_G_NCR5380_MEM is not set -CONFIG_SCSI_IPS=m -CONFIG_SCSI_INITIO=m -CONFIG_SCSI_INIA100=m -CONFIG_SCSI_PPA=m -CONFIG_SCSI_IMM=m -# CONFIG_SCSI_IZIP_EPP16 is not set -# CONFIG_SCSI_IZIP_SLOW_CTR is not set -CONFIG_SCSI_NCR53C406A=m -CONFIG_SCSI_NCR53C7xx=m -# CONFIG_SCSI_NCR53C7xx_sync is not set -CONFIG_SCSI_NCR53C7xx_FAST=y -CONFIG_SCSI_NCR53C7xx_DISCONNECT=y -CONFIG_SCSI_SYM53C8XX_2=m -CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 -CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 -CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 -# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set -CONFIG_SCSI_NCR53C8XX=m -CONFIG_SCSI_SYM53C8XX=m -CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 -CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 -CONFIG_SCSI_NCR53C8XX_SYNC=40 -# CONFIG_SCSI_NCR53C8XX_PROFILE is not set -# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set -# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set -# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set -CONFIG_SCSI_PAS16=m -CONFIG_SCSI_PCI2000=m -CONFIG_SCSI_PCI2220I=m -CONFIG_SCSI_PSI240I=m -CONFIG_SCSI_QLOGIC_FAS=m -CONFIG_SCSI_QLOGIC_ISP=m -CONFIG_SCSI_QLOGIC_FC=m -# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set -CONFIG_SCSI_QLOGIC_1280=m -CONFIG_SCSI_NEWISP=m -CONFIG_SCSI_SEAGATE=m -CONFIG_SCSI_SIM710=m -CONFIG_SCSI_SYM53C416=m -CONFIG_SCSI_DC390T=m -# CONFIG_SCSI_DC390T_NOGENSUPP is not set -CONFIG_SCSI_T128=m -CONFIG_SCSI_U14_34F=m -# CONFIG_SCSI_U14_34F_LINKED_COMMANDS is not set -CONFIG_SCSI_U14_34F_MAX_TAGS=8 -CONFIG_SCSI_ULTRASTOR=m -CONFIG_SCSI_NSP32=m -CONFIG_SCSI_DEBUG=m - -# -# PCMCIA SCSI adapter support -# -CONFIG_SCSI_PCMCIA=y -CONFIG_PCMCIA_AHA152X=m -CONFIG_PCMCIA_FDOMAIN=m -CONFIG_PCMCIA_NINJA_SCSI=m -CONFIG_PCMCIA_QLOGIC=m - -# -# Fusion MPT device support -# -CONFIG_FUSION=m -# CONFIG_FUSION_BOOT is not set -CONFIG_FUSION_MAX_SGE=40 -# CONFIG_FUSION_ISENSE is not set -CONFIG_FUSION_CTL=m -CONFIG_FUSION_LAN=m -CONFIG_NET_FC=y - -# -# IEEE 1394 (FireWire) support (EXPERIMENTAL) -# -CONFIG_IEEE1394=m -# CONFIG_IEEE1394_PCILYNX is not set -CONFIG_IEEE1394_OHCI1394=m -CONFIG_IEEE1394_VIDEO1394=m -CONFIG_IEEE1394_SBP2=m -CONFIG_IEEE1394_SBP2_PHYS_DMA=y -CONFIG_IEEE1394_ETH1394=m -CONFIG_IEEE1394_DV1394=m -CONFIG_IEEE1394_RAWIO=m -CONFIG_IEEE1394_CMP=m -CONFIG_IEEE1394_AMDTP=m -# CONFIG_IEEE1394_VERBOSEDEBUG is not set - -# -# I2O device support -# -CONFIG_I2O=m -CONFIG_I2O_PCI=m -CONFIG_I2O_BLOCK=m -CONFIG_I2O_LAN=m -CONFIG_I2O_SCSI=m -CONFIG_I2O_PROC=m - -# -# Network device support -# -CONFIG_NETDEVICES=y - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set -CONFIG_DUMMY=m -CONFIG_BONDING=m -CONFIG_EQUALIZER=m -CONFIG_TUN=m -CONFIG_ETHERTAP=m -CONFIG_NET_SB1000=m - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -# CONFIG_SUNLANCE is not set -CONFIG_HAPPYMEAL=m -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -CONFIG_SUNGEM=m -CONFIG_NET_VENDOR_3COM=y -CONFIG_EL1=m -CONFIG_EL2=m -CONFIG_ELPLUS=m -CONFIG_EL16=m -CONFIG_EL3=m -CONFIG_3C515=m -# CONFIG_ELMC is not set -# CONFIG_ELMC_II is not set -CONFIG_VORTEX=m -CONFIG_LANCE=m -CONFIG_NET_VENDOR_SMC=y -CONFIG_WD80x3=m -# CONFIG_ULTRAMCA is not set -CONFIG_ULTRA=m -CONFIG_ULTRA32=m -CONFIG_SMC9194=m -CONFIG_NET_VENDOR_RACAL=y -CONFIG_NI5010=m -CONFIG_NI52=m -CONFIG_NI65=m -CONFIG_AT1700=m -CONFIG_DEPCA=m -CONFIG_HP100=m -CONFIG_NET_ISA=y -CONFIG_E2100=m -CONFIG_EWRK3=m -CONFIG_EEXPRESS=m -CONFIG_EEXPRESS_PRO=m -CONFIG_HPLAN_PLUS=m -CONFIG_HPLAN=m -CONFIG_LP486E=m -CONFIG_ETH16I=m -CONFIG_NE2000=m -CONFIG_NET_PCI=y -CONFIG_PCNET32=m -CONFIG_AMD8111_ETH=m -CONFIG_ADAPTEC_STARFIRE=m -CONFIG_AC3200=m -CONFIG_APRICOT=m -CONFIG_CS89x0=m -CONFIG_TULIP=m -# CONFIG_TULIP_MWI is not set -CONFIG_TULIP_MMIO=y -CONFIG_DE4X5=m -CONFIG_DGRS=m -CONFIG_DM9102=m -CONFIG_EEPRO100=m -CONFIG_E100=m -CONFIG_LNE390=m -CONFIG_FEALNX=m -CONFIG_NATSEMI=m -CONFIG_NE2K_PCI=m -CONFIG_NE3210=m -CONFIG_ES3210=m -CONFIG_8139CP=m -CONFIG_8139TOO=m -# CONFIG_8139TOO_PIO is not set -# CONFIG_8139TOO_TUNE_TWISTER is not set -CONFIG_8139TOO_8129=y -# CONFIG_8139_OLD_RX_RESET is not set -CONFIG_SIS900=m -CONFIG_EPIC100=m -CONFIG_SUNDANCE=m -CONFIG_SUNDANCE_MMIO=y -CONFIG_TLAN=m -CONFIG_TC35815=m -CONFIG_VIA_RHINE=m -# CONFIG_VIA_RHINE_MMIO is not set -CONFIG_WINBOND_840=m -CONFIG_NET_POCKET=y -CONFIG_ATP=m -CONFIG_DE600=m -CONFIG_DE620=m - -# -# Ethernet (1000 Mbit) -# -CONFIG_ACENIC=m -# CONFIG_ACENIC_OMIT_TIGON_I is not set -CONFIG_DL2K=m -CONFIG_E1000=m -# CONFIG_MYRI_SBUS is not set -CONFIG_NS83820=m -CONFIG_HAMACHI=m -CONFIG_YELLOWFIN=m -CONFIG_R8169=m -CONFIG_SK98LIN=m -CONFIG_TIGON3=m -CONFIG_FDDI=y -CONFIG_DEFXX=m -CONFIG_SKFP=m -CONFIG_NETCONSOLE=m -# CONFIG_HIPPI is not set -CONFIG_PLIP=m -CONFIG_PPP=m -CONFIG_PPP_MULTILINK=y -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m -# CONFIG_PPP_BSDCOMP is not set -# CONFIG_PPPOE is not set -CONFIG_PPPOATM=m -CONFIG_SLIP=m -CONFIG_SLIP_COMPRESSED=y -CONFIG_SLIP_SMART=y -CONFIG_SLIP_MODE_SLIP6=y - -# -# Wireless LAN (non-hamradio) -# -CONFIG_NET_RADIO=y -CONFIG_STRIP=m -CONFIG_WAVELAN=m -CONFIG_ARLAN=m -CONFIG_AIRONET4500=m -CONFIG_AIRONET4500_NONCS=m -CONFIG_AIRONET4500_PNP=y -CONFIG_AIRONET4500_PCI=y -CONFIG_AIRONET4500_ISA=y -CONFIG_AIRONET4500_I365=y -CONFIG_AIRONET4500_PROC=m -CONFIG_AIRO=m -CONFIG_HERMES=m -CONFIG_PLX_HERMES=m -CONFIG_PCI_HERMES=m -CONFIG_PCMCIA_HERMES=m -CONFIG_AIRO_CS=m -CONFIG_NET_WIRELESS=y -CONFIG_PCMCIA_HERMES_OLD=m - -# -# Token Ring devices -# -CONFIG_TR=y -CONFIG_IBMTR=m -CONFIG_IBMOL=m -CONFIG_IBMLS=m -CONFIG_3C359=m -CONFIG_TMS380TR=m -CONFIG_TMSPCI=m -CONFIG_TMSISA=m -CONFIG_ABYSS=m -# CONFIG_MADGEMC is not set -CONFIG_SMCTR=m -CONFIG_NET_FC=y -CONFIG_IPHASE5526=m -CONFIG_RCPCI=m -CONFIG_SHAPER=m - -# -# Wan interfaces -# -CONFIG_WAN=y -CONFIG_HOSTESS_SV11=m -CONFIG_COSA=m -# CONFIG_COMX is not set -# CONFIG_DSCC4 is not set -# CONFIG_LANMEDIA is not set -CONFIG_ATI_XX20=m -CONFIG_SEALEVEL_4021=m -# CONFIG_SYNCLINK_SYNCPPP is not set -# CONFIG_HDLC is not set -CONFIG_DLCI=m -CONFIG_DLCI_COUNT=24 -CONFIG_DLCI_MAX=8 -CONFIG_SDLA=m -CONFIG_WAN_ROUTER_DRIVERS=y -CONFIG_VENDOR_SANGOMA=m -CONFIG_WANPIPE_CHDLC=y -CONFIG_WANPIPE_FR=y -CONFIG_WANPIPE_X25=y -CONFIG_WANPIPE_PPP=y -CONFIG_WANPIPE_MULTPPP=y -CONFIG_CYCLADES_SYNC=m -CONFIG_CYCLOMX_X25=y -# CONFIG_LAPBETHER is not set -# CONFIG_X25_ASY is not set -CONFIG_SBNI=m -CONFIG_SBNI_MULTILINE=y - -# -# PCMCIA network device support -# -CONFIG_NET_PCMCIA=y -CONFIG_PCMCIA_3C589=m -CONFIG_PCMCIA_3C574=m -CONFIG_PCMCIA_FMVJ18X=m -CONFIG_PCMCIA_PCNET=m -CONFIG_PCMCIA_AXNET=m -CONFIG_PCMCIA_NMCLAN=m -CONFIG_PCMCIA_SMC91C92=m -CONFIG_PCMCIA_XIRC2PS=m -# CONFIG_ARCNET_COM20020_CS is not set -CONFIG_PCMCIA_IBMTR=m -CONFIG_PCMCIA_XIRCOM=m -CONFIG_PCMCIA_XIRTULIP=m -CONFIG_NET_PCMCIA_RADIO=y -CONFIG_PCMCIA_RAYCS=m -CONFIG_PCMCIA_NETWAVE=m -CONFIG_PCMCIA_WAVELAN=m -CONFIG_PCMCIA_WVLAN=m -CONFIG_AIRONET4500_CS=m - -# -# ATM drivers -# -CONFIG_ATM_TCP=m -CONFIG_ATM_LANAI=m -CONFIG_ATM_ENI=m -# CONFIG_ATM_ENI_DEBUG is not set -# CONFIG_ATM_ENI_TUNE_BURST is not set -CONFIG_ATM_FIRESTREAM=m -CONFIG_ATM_ZATM=m -# CONFIG_ATM_ZATM_DEBUG is not set -CONFIG_ATM_ZATM_EXACT_TS=y -CONFIG_ATM_NICSTAR=m -CONFIG_ATM_NICSTAR_USE_SUNI=y -CONFIG_ATM_NICSTAR_USE_IDT77105=y -CONFIG_ATM_IDT77252=m -# CONFIG_ATM_IDT77252_DEBUG is not set -# CONFIG_ATM_IDT77252_RCV_ALL is not set -CONFIG_ATM_IDT77252_USE_SUNI=y -CONFIG_ATM_AMBASSADOR=m -# CONFIG_ATM_AMBASSADOR_DEBUG is not set -CONFIG_ATM_HORIZON=m -# CONFIG_ATM_HORIZON_DEBUG is not set -CONFIG_ATM_IA=m -# CONFIG_ATM_IA_DEBUG is not set -CONFIG_ATM_FORE200E_MAYBE=m -CONFIG_ATM_FORE200E_PCA=y -CONFIG_ATM_FORE200E_PCA_DEFAULT_FW=y -CONFIG_ATM_FORE200E_TX_RETRY=16 -CONFIG_ATM_FORE200E_DEBUG=0 -CONFIG_ATM_FORE200E=m - -# -# Amateur Radio support -# -CONFIG_HAMRADIO=y -CONFIG_AX25=m -# CONFIG_AX25_DAMA_SLAVE is not set -CONFIG_NETROM=m -CONFIG_ROSE=m - -# -# AX.25 network device drivers -# -# CONFIG_MKISS is not set -# CONFIG_6PACK is not set -# CONFIG_BPQETHER is not set -# CONFIG_DMASCC is not set -# CONFIG_SCC is not set -# CONFIG_BAYCOM_SER_FDX is not set -# CONFIG_BAYCOM_SER_HDX is not set -# CONFIG_BAYCOM_PAR is not set -# CONFIG_BAYCOM_EPP is not set -CONFIG_SOUNDMODEM=m -CONFIG_SOUNDMODEM_SBC=y -CONFIG_SOUNDMODEM_WSS=y -CONFIG_SOUNDMODEM_AFSK1200=y -CONFIG_SOUNDMODEM_AFSK2400_7=y -CONFIG_SOUNDMODEM_AFSK2400_8=y -CONFIG_SOUNDMODEM_AFSK2666=y -CONFIG_SOUNDMODEM_HAPN4800=y -CONFIG_SOUNDMODEM_PSK4800=y -CONFIG_SOUNDMODEM_FSK9600=y -# CONFIG_YAM is not set - -# -# IrDA (infrared) support -# -CONFIG_IRDA=m -CONFIG_IRLAN=m -CONFIG_IRNET=m -CONFIG_IRCOMM=m -CONFIG_IRDA_ULTRA=y -CONFIG_IRDA_CACHE_LAST_LSAP=y -CONFIG_IRDA_FAST_RR=y -# CONFIG_IRDA_DEBUG is not set - -# -# Infrared-port device drivers -# -CONFIG_IRTTY_SIR=m -CONFIG_IRPORT_SIR=m -CONFIG_DONGLE=y -CONFIG_ESI_DONGLE=m -CONFIG_ACTISYS_DONGLE=m -CONFIG_TEKRAM_DONGLE=m -CONFIG_GIRBIL_DONGLE=m -CONFIG_LITELINK_DONGLE=m -CONFIG_MCP2120_DONGLE=m -CONFIG_OLD_BELKIN_DONGLE=m -CONFIG_ACT200L_DONGLE=m -CONFIG_MA600_DONGLE=m -CONFIG_USB_IRDA=m -CONFIG_NSC_FIR=m -CONFIG_WINBOND_FIR=m -CONFIG_TOSHIBA_OLD=m -CONFIG_TOSHIBA_FIR=m -CONFIG_SMC_IRCC_FIR=m -CONFIG_ALI_FIR=m -CONFIG_VLSI_FIR=m - -# -# ISDN subsystem -# -CONFIG_ISDN=m -CONFIG_ISDN_BOOL=y -CONFIG_ISDN_PPP=y -CONFIG_ISDN_PPP_VJ=y -CONFIG_ISDN_MPP=y -CONFIG_ISDN_PPP_BSDCOMP=m -CONFIG_ISDN_AUDIO=y -CONFIG_ISDN_TTY_FAX=y - -# -# ISDN feature submodules -# -CONFIG_ISDN_DRV_LOOP=m -# CONFIG_ISDN_DIVERSION is not set - -# -# Passive ISDN cards -# -CONFIG_ISDN_DRV_HISAX=m -CONFIG_ISDN_HISAX=y -CONFIG_HISAX_EURO=y -CONFIG_DE_AOC=y -# CONFIG_HISAX_NO_SENDCOMPLETE is not set -# CONFIG_HISAX_NO_LLC is not set -# CONFIG_HISAX_NO_KEYPAD is not set -CONFIG_HISAX_1TR6=y -CONFIG_HISAX_NI1=y -CONFIG_HISAX_MAX_CARDS=8 -CONFIG_HISAX_16_0=y -CONFIG_HISAX_16_3=y -CONFIG_HISAX_AVM_A1=y -CONFIG_HISAX_IX1MICROR2=y -CONFIG_HISAX_ASUSCOM=y -CONFIG_HISAX_TELEINT=y -CONFIG_HISAX_HFCS=y -CONFIG_HISAX_SPORTSTER=y -CONFIG_HISAX_MIC=y -CONFIG_HISAX_ISURF=y -CONFIG_HISAX_HSTSAPHIR=y -CONFIG_HISAX_TELESPCI=y -CONFIG_HISAX_S0BOX=y -CONFIG_HISAX_FRITZPCI=y -CONFIG_HISAX_AVM_A1_PCMCIA=y -CONFIG_HISAX_ELSA=y -CONFIG_HISAX_DIEHLDIVA=y -CONFIG_HISAX_SEDLBAUER=y -CONFIG_HISAX_NETJET=y -CONFIG_HISAX_NETJET_U=y -CONFIG_HISAX_NICCY=y -CONFIG_HISAX_BKM_A4T=y -CONFIG_HISAX_SCT_QUADRO=y -CONFIG_HISAX_GAZEL=y -CONFIG_HISAX_HFC_PCI=y -CONFIG_HISAX_W6692=y -CONFIG_HISAX_HFC_SX=y -CONFIG_HISAX_ENTERNOW_PCI=y -CONFIG_HISAX_DEBUG=y -CONFIG_HISAX_SEDLBAUER_CS=m -CONFIG_HISAX_ELSA_CS=m -CONFIG_HISAX_AVM_A1_CS=m -CONFIG_HISAX_ST5481=m -CONFIG_HISAX_FRITZ_PCIPNP=m - -# -# Active ISDN cards -# -CONFIG_ISDN_DRV_ICN=m -CONFIG_ISDN_DRV_PCBIT=m -# CONFIG_ISDN_DRV_SC is not set -# CONFIG_ISDN_DRV_ACT2000 is not set -CONFIG_ISDN_DRV_EICON=y -CONFIG_ISDN_DRV_EICON_DIVAS=m -# CONFIG_ISDN_DRV_EICON_OLD is not set -CONFIG_ISDN_DRV_TPAM=m -CONFIG_ISDN_CAPI=m -CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y -CONFIG_ISDN_CAPI_MIDDLEWARE=y -CONFIG_ISDN_CAPI_CAPI20=m -CONFIG_ISDN_CAPI_CAPIFS_BOOL=y -CONFIG_ISDN_CAPI_CAPIFS=m -CONFIG_ISDN_CAPI_CAPIDRV=m -CONFIG_ISDN_DRV_AVMB1_B1ISA=m -CONFIG_ISDN_DRV_AVMB1_B1PCI=m -CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y -CONFIG_ISDN_DRV_AVMB1_T1ISA=m -CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m -CONFIG_ISDN_DRV_AVMB1_AVM_CS=m -CONFIG_ISDN_DRV_AVMB1_T1PCI=m -CONFIG_ISDN_DRV_AVMB1_C4=m -CONFIG_HYSDN=m -CONFIG_HYSDN_CAPI=y -CONFIG_KALLSYMS=y - -# -# Old CD-ROM drivers (not SCSI, not IDE) -# -# CONFIG_CD_NO_IDESCSI is not set - -# -# Input core support -# -CONFIG_INPUT=m -CONFIG_INPUT_KEYBDEV=m -CONFIG_INPUT_MOUSEDEV=m -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -CONFIG_INPUT_JOYDEV=m -CONFIG_INPUT_EVDEV=m - -# -# Character devices -# -CONFIG_VT=y -CONFIG_ECC=m -CONFIG_VT_CONSOLE=y -CONFIG_SERIAL=y -CONFIG_SERIAL_CONSOLE=y -CONFIG_SERIAL_EXTENDED=y -CONFIG_SERIAL_MANY_PORTS=y -CONFIG_SERIAL_SHARE_IRQ=y -# CONFIG_SERIAL_DETECT_IRQ is not set -CONFIG_SERIAL_MULTIPORT=y -# CONFIG_HUB6 is not set -CONFIG_SERIAL_NONSTANDARD=y -CONFIG_COMPUTONE=m -CONFIG_ROCKETPORT=m -CONFIG_CYCLADES=m -# CONFIG_CYZ_INTR is not set -CONFIG_DIGIEPCA=m -CONFIG_ESPSERIAL=m -CONFIG_MOXA_INTELLIO=m -CONFIG_MOXA_SMARTIO=m -CONFIG_ISI=m -CONFIG_SYNCLINK=m -# CONFIG_SYNCLINKMP is not set -CONFIG_N_HDLC=m -CONFIG_RISCOM8=m -CONFIG_SPECIALIX=m -CONFIG_SPECIALIX_RTSCTS=y -CONFIG_SX=m -# CONFIG_RIO is not set -CONFIG_STALDRV=y -CONFIG_STALLION=m -CONFIG_ISTALLION=m -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=2048 -CONFIG_PRINTER=m -CONFIG_LP_CONSOLE=y -CONFIG_PPDEV=m -CONFIG_TIPAR=m - -# -# I2C support -# -CONFIG_I2C=m -CONFIG_I2C_ALGOBIT=m -CONFIG_I2C_PHILIPSPAR=m -CONFIG_I2C_ELV=m -CONFIG_I2C_VELLEMAN=m -# CONFIG_SCx200_I2C is not set -# CONFIG_SCx200_ACB is not set -CONFIG_I2C_ALGOPCF=m -CONFIG_I2C_ELEKTOR=m -CONFIG_I2C_MAINBOARD=y -CONFIG_I2C_ALI1535=m -CONFIG_I2C_ALI15X3=m -CONFIG_I2C_HYDRA=m -CONFIG_I2C_AMD756=m -# CONFIG_I2C_TSUNAMI is not set -CONFIG_I2C_I801=m -CONFIG_I2C_I810=m -CONFIG_I2C_PIIX4=m -CONFIG_I2C_SIS5595=m -CONFIG_I2C_VIA=m -CONFIG_I2C_VIAPRO=m -CONFIG_I2C_VOODOO3=m -CONFIG_I2C_ISA=m -CONFIG_I2C_CHARDEV=m -CONFIG_I2C_PROC=m - -# -# Hardware sensors support -# -CONFIG_SENSORS=y -CONFIG_SENSORS_ADM1021=m -CONFIG_SENSORS_ADM1024=m -CONFIG_SENSORS_ADM1025=m -CONFIG_SENSORS_ADM9240=m -CONFIG_SENSORS_DS1621=m -CONFIG_SENSORS_FSCPOS=m -CONFIG_SENSORS_FSCSCY=m -CONFIG_SENSORS_GL518SM=m -CONFIG_SENSORS_GL520SM=m -CONFIG_SENSORS_MAXILIFE=m -CONFIG_SENSORS_IT87=m -CONFIG_SENSORS_MTP008=m -CONFIG_SENSORS_LM75=m -CONFIG_SENSORS_LM78=m -CONFIG_SENSORS_LM80=m -CONFIG_SENSORS_LM87=m -CONFIG_SENSORS_LM92=m -CONFIG_SENSORS_SIS5595=m -CONFIG_SENSORS_SMSC47M1=m -CONFIG_SENSORS_THMC50=m -CONFIG_SENSORS_VIA686A=m -CONFIG_SENSORS_VT1211=m -CONFIG_SENSORS_VT8231=m -CONFIG_SENSORS_W83781D=m -CONFIG_SENSORS_OTHER=y -CONFIG_SENSORS_BT869=m -CONFIG_SENSORS_DDCMON=m -CONFIG_SENSORS_EEPROM=m -CONFIG_SENSORS_MATORB=m -CONFIG_SENSORS_PCF8574=m -CONFIG_SENSORS_PCF8591=m - -# -# Mice -# -CONFIG_BUSMOUSE=m -CONFIG_ATIXL_BUSMOUSE=m -CONFIG_LOGIBUSMOUSE=m -CONFIG_MS_BUSMOUSE=m -CONFIG_MOUSE=y -CONFIG_PSMOUSE=y -CONFIG_82C710_MOUSE=m -CONFIG_PC110_PAD=m -CONFIG_MK712_MOUSE=m - -# -# Joysticks -# -CONFIG_INPUT_GAMEPORT=m -CONFIG_INPUT_NS558=m -CONFIG_INPUT_LIGHTNING=m -CONFIG_INPUT_PCIGAME=m -CONFIG_INPUT_CS461X=m -CONFIG_INPUT_EMU10K1=m -CONFIG_INPUT_SERIO=m -CONFIG_INPUT_SERPORT=m -CONFIG_INPUT_ANALOG=m -CONFIG_INPUT_A3D=m -CONFIG_INPUT_ADI=m -CONFIG_INPUT_COBRA=m -CONFIG_INPUT_GF2K=m -CONFIG_INPUT_GRIP=m -CONFIG_INPUT_INTERACT=m -CONFIG_INPUT_TMDC=m -CONFIG_INPUT_SIDEWINDER=m -CONFIG_INPUT_IFORCE_USB=m -CONFIG_INPUT_IFORCE_232=m -CONFIG_INPUT_WARRIOR=m -CONFIG_INPUT_MAGELLAN=m -CONFIG_INPUT_SPACEORB=m -CONFIG_INPUT_SPACEBALL=m -CONFIG_INPUT_STINGER=m -CONFIG_INPUT_DB9=m -CONFIG_INPUT_GAMECON=m -CONFIG_INPUT_TURBOGRAFX=m -# CONFIG_QIC02_TAPE is not set -CONFIG_IPMI_HANDLER=m -# CONFIG_IPMI_PANIC_EVENT is not set -CONFIG_IPMI_DEVICE_INTERFACE=m -CONFIG_IPMI_KCS=m -CONFIG_IPMI_WATCHDOG=m - -# -# Watchdog Cards -# -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set -CONFIG_ACQUIRE_WDT=m -CONFIG_ADVANTECH_WDT=m -CONFIG_ALIM7101_WDT=m -CONFIG_SC520_WDT=m -CONFIG_PCWATCHDOG=m -CONFIG_EUROTECH_WDT=m -CONFIG_IB700_WDT=m -CONFIG_WAFER_WDT=m -CONFIG_I810_TCO=m -# CONFIG_MIXCOMWD is not set -# CONFIG_60XX_WDT is not set -CONFIG_SC1200_WDT=m -# CONFIG_SCx200_WDT is not set -CONFIG_SOFT_WATCHDOG=m -CONFIG_W83877F_WDT=m -CONFIG_WDT=m -CONFIG_WDTPCI=m -# CONFIG_WDT_501 is not set -CONFIG_MACHZ_WDT=m -CONFIG_AMD7XX_TCO=m -# CONFIG_SCx200_GPIO is not set -CONFIG_AMD_RNG=m -CONFIG_INTEL_RNG=m -CONFIG_AMD_PM768=m -CONFIG_NVRAM=m -CONFIG_RTC=y -CONFIG_DTLK=m -CONFIG_R3964=m -# CONFIG_APPLICOM is not set -CONFIG_SONYPI=m - -# -# Ftape, the floppy tape device driver -# -CONFIG_FTAPE=m -CONFIG_ZFTAPE=m -CONFIG_ZFT_DFLT_BLK_SZ=10240 -CONFIG_ZFT_COMPRESSOR=m -CONFIG_FT_NR_BUFFERS=3 -# CONFIG_FT_PROC_FS is not set -CONFIG_FT_NORMAL_DEBUG=y -# CONFIG_FT_FULL_DEBUG is not set -# CONFIG_FT_NO_TRACE is not set -# CONFIG_FT_NO_TRACE_AT_ALL is not set -CONFIG_FT_STD_FDC=y -# CONFIG_FT_MACH2 is not set -# CONFIG_FT_PROBE_FC10 is not set -# CONFIG_FT_ALT_FDC is not set -CONFIG_FT_FDC_THR=8 -CONFIG_FT_FDC_MAX_RATE=2000 -CONFIG_FT_ALPHA_CLOCK=0 -CONFIG_AGP=m -CONFIG_AGP_INTEL=y -CONFIG_AGP_I810=y -CONFIG_AGP_VIA=y -CONFIG_AGP_AMD=y -CONFIG_AGP_AMD_8151=y -CONFIG_AGP_SIS=y -CONFIG_AGP_ALI=y -CONFIG_AGP_SWORKS=y -CONFIG_DRM=y -# CONFIG_DRM_OLD is not set -CONFIG_DRM_NEW=y -CONFIG_DRM_TDFX=m -CONFIG_DRM_R128=m -CONFIG_DRM_RADEON=m -CONFIG_DRM_I810=m -# CONFIG_DRM_I810_XFREE_41 is not set -CONFIG_DRM_I830=m -CONFIG_DRM_MGA=m -CONFIG_DRM_SIS=m - -# -# PCMCIA character devices -# -CONFIG_PCMCIA_SERIAL_CS=m -CONFIG_SYNCLINK_CS=m -CONFIG_MWAVE=m -CONFIG_BATTERY_GERICOM=m - -# -# Multimedia devices -# -CONFIG_VIDEO_DEV=m - -# -# Video For Linux -# -CONFIG_VIDEO_PROC_FS=y -CONFIG_I2C_PARPORT=m -CONFIG_VIDEO_BT848=m -CONFIG_VIDEO_PMS=m -CONFIG_VIDEO_BWQCAM=m -CONFIG_VIDEO_CQCAM=m -CONFIG_VIDEO_W9966=m -CONFIG_VIDEO_CPIA=m -CONFIG_VIDEO_CPIA_PP=m -CONFIG_VIDEO_CPIA_USB=m -CONFIG_VIDEO_SAA5249=m -CONFIG_TUNER_3036=m -CONFIG_VIDEO_STRADIS=m -CONFIG_VIDEO_ZORAN=m -CONFIG_VIDEO_ZORAN_BUZ=m -CONFIG_VIDEO_ZORAN_DC10=m -CONFIG_VIDEO_ZORAN_LML33=m -CONFIG_VIDEO_ZR36120=m -CONFIG_VIDEO_MEYE=m - -# -# Radio Adapters -# -CONFIG_RADIO_CADET=m -CONFIG_RADIO_RTRACK=m -CONFIG_RADIO_RTRACK2=m -CONFIG_RADIO_AZTECH=m -CONFIG_RADIO_GEMTEK=m -CONFIG_RADIO_GEMTEK_PCI=m -CONFIG_RADIO_MAXIRADIO=m -CONFIG_RADIO_MAESTRO=m -CONFIG_RADIO_MIROPCM20=m -CONFIG_RADIO_MIROPCM20_RDS=m -CONFIG_RADIO_SF16FMI=m -CONFIG_RADIO_SF16FMR2=m -CONFIG_RADIO_TERRATEC=m -CONFIG_RADIO_TRUST=m -CONFIG_RADIO_TYPHOON=m -CONFIG_RADIO_TYPHOON_PROC_FS=y -CONFIG_RADIO_ZOLTRIX=m - -# -# Crypto Hardware support -# -CONFIG_CRYPTO=m -CONFIG_CRYPTO_BROADCOM=m - -# -# File systems -# -CONFIG_QUOTA=y -# CONFIG_QFMT_V1 is not set -CONFIG_QFMT_V2=y -# CONFIG_QIFACE_COMPAT is not set -CONFIG_AUTOFS_FS=m -CONFIG_AUTOFS4_FS=m -CONFIG_REISERFS_FS=m -# CONFIG_REISERFS_CHECK is not set -CONFIG_REISERFS_PROC_INFO=y -# CONFIG_ADFS_FS is not set -CONFIG_AFS_FS=m -# CONFIG_ADFS_FS_RW is not set -# CONFIG_AFFS_FS is not set -CONFIG_HFS_FS=m -CONFIG_BEFS_FS=m -# CONFIG_BEFS_DEBUG is not set -CONFIG_BFS_FS=m -CONFIG_EXT3_FS=m -CONFIG_EXT3_FS_XATTR=y -CONFIG_EXT3_FS_XATTR_SHARING=y -CONFIG_EXT3_FS_XATTR_USER=y -CONFIG_JBD=m -# CONFIG_JBD_DEBUG is not set -CONFIG_FAT_FS=m -CONFIG_MSDOS_FS=m -CONFIG_UMSDOS_FS=m -CONFIG_VFAT_FS=m -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set -CONFIG_CRAMFS=m -CONFIG_TMPFS=y -CONFIG_RAMFS=y -CONFIG_ISO9660_FS=y -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_JFS_FS=m -CONFIG_JFS_DEBUG=y -# CONFIG_JFS_STATISTICS is not set -CONFIG_MINIX_FS=m -CONFIG_VXFS_FS=m -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_RW is not set -# CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y -# CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -CONFIG_ROMFS_FS=m -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XATTR_SHARING is not set -# CONFIG_EXT2_FS_XATTR_USER is not set -CONFIG_SYSV_FS=m -CONFIG_UDF_FS=m -CONFIG_UDF_RW=y -CONFIG_UFS_FS=m -# CONFIG_UFS_FS_WRITE is not set - -# -# Network File Systems -# -CONFIG_CODA_FS=m -CONFIG_INTERMEZZO_FS=m -CONFIG_NFS_FS=m -CONFIG_NFS_V3=y -# CONFIG_ROOT_NFS is not set -CONFIG_NFSD=m -CONFIG_NFSD_V3=y -# CONFIG_NFSD_TCP is not set -CONFIG_SUNRPC=m -CONFIG_LOCKD=m -CONFIG_LOCKD_V4=y -CONFIG_SMB_FS=m -# CONFIG_SMB_NLS_DEFAULT is not set -CONFIG_NCP_FS=m -CONFIG_NCPFS_PACKET_SIGNING=y -CONFIG_NCPFS_IOCTL_LOCKING=y -CONFIG_NCPFS_STRONG=y -CONFIG_NCPFS_NFS_NS=y -CONFIG_NCPFS_OS2_NS=y -CONFIG_NCPFS_SMALLDOS=y -CONFIG_NCPFS_NLS=y -CONFIG_NCPFS_EXTRAS=y -CONFIG_ZISOFS_FS=y -CONFIG_FS_MBCACHE=y - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -CONFIG_OSF_PARTITION=y -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -CONFIG_MAC_PARTITION=y -CONFIG_MSDOS_PARTITION=y -CONFIG_BSD_DISKLABEL=y -CONFIG_MINIX_SUBPARTITION=y -CONFIG_SOLARIS_X86_PARTITION=y -CONFIG_UNIXWARE_DISKLABEL=y -# CONFIG_LDM_PARTITION is not set -CONFIG_SGI_PARTITION=y -# CONFIG_ULTRIX_PARTITION is not set -CONFIG_SUN_PARTITION=y -# CONFIG_EFI_PARTITION is not set -CONFIG_SMB_NLS=y -CONFIG_NLS=y - -# -# Native Language Support -# -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_737=m -CONFIG_NLS_CODEPAGE_775=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_CODEPAGE_852=m -CONFIG_NLS_CODEPAGE_855=m -CONFIG_NLS_CODEPAGE_857=m -CONFIG_NLS_CODEPAGE_860=m -CONFIG_NLS_CODEPAGE_861=m -CONFIG_NLS_CODEPAGE_862=m -CONFIG_NLS_CODEPAGE_863=m -CONFIG_NLS_CODEPAGE_864=m -CONFIG_NLS_CODEPAGE_865=m -CONFIG_NLS_CODEPAGE_866=m -CONFIG_NLS_CODEPAGE_869=m -CONFIG_NLS_CODEPAGE_936=m -CONFIG_NLS_CODEPAGE_950=m -CONFIG_NLS_CODEPAGE_932=m -CONFIG_NLS_CODEPAGE_949=m -CONFIG_NLS_CODEPAGE_874=m -CONFIG_NLS_ISO8859_8=m -CONFIG_NLS_CODEPAGE_1250=m -CONFIG_NLS_CODEPAGE_1251=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_ISO8859_2=m -CONFIG_NLS_ISO8859_3=m -CONFIG_NLS_ISO8859_4=m -CONFIG_NLS_ISO8859_5=m -CONFIG_NLS_ISO8859_6=m -CONFIG_NLS_ISO8859_7=m -CONFIG_NLS_ISO8859_9=m -CONFIG_NLS_ISO8859_13=m -CONFIG_NLS_ISO8859_14=m -CONFIG_NLS_ISO8859_15=m -CONFIG_NLS_KOI8_R=m -CONFIG_NLS_KOI8_U=m -CONFIG_NLS_UTF8=m - -# -# Console drivers -# -CONFIG_VGA_CONSOLE=y -CONFIG_VIDEO_SELECT=y -# CONFIG_VIDEO_IGNORE_BAD_MODE is not set -CONFIG_MDA_CONSOLE=m - -# -# Frame-buffer support -# -CONFIG_FB=y -CONFIG_DUMMY_CONSOLE=y -CONFIG_FB_RIVA=m -CONFIG_FB_CLGEN=m -CONFIG_FB_PM2=m -# CONFIG_FB_PM2_FIFO_DISCONNECT is not set -CONFIG_FB_PM2_PCI=y -CONFIG_FB_PM3=m -# CONFIG_FB_CYBER2000 is not set -CONFIG_FB_VESA=y -CONFIG_FB_VGA16=m -CONFIG_FB_HGA=m -CONFIG_VIDEO_SELECT=y -CONFIG_FB_MATROX=m -CONFIG_FB_MATROX_MILLENIUM=y -CONFIG_FB_MATROX_MYSTIQUE=y -# CONFIG_FB_MATROX_G450 is not set -CONFIG_FB_MATROX_G100A=y -CONFIG_FB_MATROX_G100=y -CONFIG_FB_MATROX_I2C=m -CONFIG_FB_MATROX_MAVEN=m -# CONFIG_FB_MATROX_PROC is not set -CONFIG_FB_MATROX_MULTIHEAD=y -CONFIG_FB_ATY=m -CONFIG_FB_ATY_GX=y -CONFIG_FB_ATY_CT=y -CONFIG_FB_ATY_CT_VAIO_LCD=y -CONFIG_FB_RADEON=m -CONFIG_FB_ATY128=m -CONFIG_FB_SIS=m -CONFIG_FB_SIS_300=y -CONFIG_FB_SIS_315=y -CONFIG_FB_NEOMAGIC=m -CONFIG_FB_3DFX=m -CONFIG_FB_VOODOO1=m -# CONFIG_FB_TRIDENT is not set -# CONFIG_FB_VIRTUAL is not set -# CONFIG_FBCON_ADVANCED is not set -CONFIG_FBCON_MFB=m -CONFIG_FBCON_CFB8=y -CONFIG_FBCON_CFB16=y -CONFIG_FBCON_CFB24=y -CONFIG_FBCON_CFB32=y -CONFIG_FBCON_VGA_PLANES=m -CONFIG_FBCON_HGA=m -# CONFIG_FBCON_FONTWIDTH8_ONLY is not set -# CONFIG_FBCON_FONTS is not set -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y - -# -# Sound -# -CONFIG_SOUND=m -CONFIG_SOUND_ALI5455=m -CONFIG_SOUND_BT878=m -CONFIG_SOUND_CMPCI=m -CONFIG_SOUND_CMPCI_FM=y -CONFIG_SOUND_CMPCI_FMIO=388 -CONFIG_SOUND_CMPCI_FMIO=388 -CONFIG_SOUND_CMPCI_MIDI=y -CONFIG_SOUND_CMPCI_MPUIO=330 -CONFIG_SOUND_CMPCI_JOYSTICK=y -CONFIG_SOUND_CMPCI_CM8738=y -# CONFIG_SOUND_CMPCI_SPDIFINVERSE is not set -CONFIG_SOUND_CMPCI_SPDIFLOOP=y -CONFIG_SOUND_CMPCI_SPEAKERS=2 -CONFIG_SOUND_EMU10K1=m -CONFIG_MIDI_EMU10K1=y -CONFIG_SOUND_AUDIGY=m -CONFIG_SOUND_FUSION=m -CONFIG_SOUND_CS4281=m -CONFIG_SOUND_ES1370=m -CONFIG_SOUND_ES1371=m -CONFIG_SOUND_ESSSOLO1=m -CONFIG_SOUND_MAESTRO=m -CONFIG_SOUND_MAESTRO3=m -CONFIG_SOUND_FORTE=m -CONFIG_SOUND_ICH=m -CONFIG_SOUND_RME96XX=m -CONFIG_SOUND_SONICVIBES=m -CONFIG_SOUND_TRIDENT=m -CONFIG_SOUND_MSNDCLAS=m -# CONFIG_MSNDCLAS_HAVE_BOOT is not set -CONFIG_MSNDCLAS_INIT_FILE="/etc/sound/msndinit.bin" -CONFIG_MSNDCLAS_PERM_FILE="/etc/sound/msndperm.bin" -CONFIG_SOUND_MSNDPIN=m -# CONFIG_MSNDPIN_HAVE_BOOT is not set -CONFIG_MSNDPIN_INIT_FILE="/etc/sound/pndspini.bin" -CONFIG_MSNDPIN_PERM_FILE="/etc/sound/pndsperm.bin" -CONFIG_SOUND_VIA82CXXX=m -CONFIG_MIDI_VIA82CXXX=y -CONFIG_SOUND_OSS=m -# CONFIG_SOUND_TRACEINIT is not set -CONFIG_SOUND_DMAP=y -CONFIG_SOUND_AD1816=m -CONFIG_SOUND_AD1889=m -CONFIG_SOUND_SGALAXY=m -CONFIG_SOUND_ADLIB=m -CONFIG_SOUND_ACI_MIXER=m -CONFIG_SOUND_CS4232=m -CONFIG_SOUND_SSCAPE=m -CONFIG_SOUND_GUS=m -CONFIG_SOUND_GUS16=y -CONFIG_SOUND_GUSMAX=y -CONFIG_SOUND_VMIDI=m -CONFIG_SOUND_TRIX=m -CONFIG_SOUND_MSS=m -CONFIG_SOUND_MPU401=m -CONFIG_SOUND_NM256=m -CONFIG_SOUND_MAD16=m -CONFIG_MAD16_OLDCARD=y -CONFIG_SOUND_PAS=m -# CONFIG_PAS_JOYSTICK is not set -CONFIG_SOUND_PSS=m -# CONFIG_PSS_MIXER is not set -# CONFIG_PSS_HAVE_BOOT is not set -CONFIG_SOUND_SB=m -CONFIG_SOUND_AWE32_SYNTH=m -CONFIG_SOUND_WAVEFRONT=m -CONFIG_SOUND_MAUI=m -CONFIG_SOUND_YM3812=m -CONFIG_SOUND_OPL3SA1=m -CONFIG_SOUND_OPL3SA2=m -CONFIG_SOUND_YMFPCI=m -CONFIG_SOUND_YMFPCI_LEGACY=y -CONFIG_SOUND_UART6850=m -CONFIG_SOUND_AEDSP16=m -CONFIG_SC6600=y -CONFIG_SC6600_JOY=y -CONFIG_SC6600_CDROM=4 -CONFIG_SC6600_CDROMBASE=0 -CONFIG_AEDSP16_SBPRO=y -CONFIG_AEDSP16_MPU401=y -CONFIG_SOUND_TVMIXER=m - -# -# USB support -# -CONFIG_USB=m -# CONFIG_USB_DEBUG is not set -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_BANDWIDTH is not set -CONFIG_USB_EHCI_HCD=m -CONFIG_USB_UHCI=m -CONFIG_USB_UHCI_ALT=m -CONFIG_USB_OHCI=m -CONFIG_USB_AUDIO=m -# CONFIG_USB_EMI26 is not set -CONFIG_USB_MIDI=m -CONFIG_USB_STORAGE=m -# CONFIG_USB_STORAGE_DEBUG is not set -CONFIG_USB_STORAGE_DATAFAB=y -CONFIG_USB_STORAGE_FREECOM=y -CONFIG_USB_STORAGE_ISD200=y -CONFIG_USB_STORAGE_DPCM=y -CONFIG_USB_STORAGE_HP8200e=y -CONFIG_USB_STORAGE_SDDR09=y -CONFIG_USB_STORAGE_SDDR55=y -CONFIG_USB_STORAGE_JUMPSHOT=y -CONFIG_USB_ACM=m -CONFIG_USB_PRINTER=m -CONFIG_USB_HID=m -CONFIG_USB_HIDINPUT=y -CONFIG_USB_HIDDEV=y -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set -CONFIG_USB_AIPTEK=m -CONFIG_USB_WACOM=m -CONFIG_USB_POWERMATE=m -# CONFIG_USB_DC2XX is not set -CONFIG_USB_MDC800=m -CONFIG_USB_SCANNER=m -CONFIG_USB_MICROTEK=m -CONFIG_USB_HPUSBSCSI=m -CONFIG_USB_IBMCAM=m -CONFIG_USB_OV511=m -CONFIG_USB_PWC=m -CONFIG_USB_SE401=m -CONFIG_USB_STV680=m -CONFIG_USB_VICAM=m -CONFIG_USB_DSBR=m -CONFIG_USB_DABUSB=m -CONFIG_USB_PEGASUS=m -CONFIG_USB_RTL8150=m -CONFIG_USB_KAWETH=m -CONFIG_USB_CATC=m -CONFIG_USB_CDCETHER=m -CONFIG_USB_USBNET=m -CONFIG_USB_USS720=m - -# -# USB Serial Converter support -# -CONFIG_USB_SERIAL=m -# CONFIG_USB_SERIAL_DEBUG is not set -CONFIG_USB_SERIAL_GENERIC=y -CONFIG_USB_SERIAL_BELKIN=m -CONFIG_USB_SERIAL_WHITEHEAT=m -CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m -CONFIG_USB_SERIAL_EMPEG=m -CONFIG_USB_SERIAL_FTDI_SIO=m -CONFIG_USB_SERIAL_VISOR=m -CONFIG_USB_SERIAL_IPAQ=m -CONFIG_USB_SERIAL_IR=m -CONFIG_USB_SERIAL_EDGEPORT=m -CONFIG_USB_SERIAL_EDGEPORT_TI=m -CONFIG_USB_SERIAL_KEYSPAN_PDA=m -CONFIG_USB_SERIAL_KEYSPAN=m -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y -CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA19W is not set -CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y -CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y -# CONFIG_USB_SERIAL_KEYSPAN_USA49W is not set -CONFIG_USB_SERIAL_MCT_U232=m -CONFIG_USB_SERIAL_KLSI=m -CONFIG_USB_SERIAL_KOBIL_SCT=m -CONFIG_USB_SERIAL_PL2303=m -CONFIG_USB_SERIAL_CYBERJACK=m -CONFIG_USB_SERIAL_XIRCOM=m -CONFIG_USB_SERIAL_OMNINET=m -CONFIG_USB_RIO500=m -CONFIG_USB_AUERSWALD=m -CONFIG_USB_TIGL=m -CONFIG_USB_BRLVGER=m -CONFIG_USB_LCD=m - -# -# Additional device driver support -# -CONFIG_NET_BROADCOM=m -CONFIG_CIPE=m -CONFIG_CRYPTO_AEP=m -CONFIG_MEGARAC=m -CONFIG_FC_QLA2200=m -CONFIG_FC_QLA2300=m -CONFIG_SCSI_ISCSI=m - -# -# Bluetooth support -# -CONFIG_BLUEZ=m -CONFIG_BLUEZ_L2CAP=m -CONFIG_BLUEZ_SCO=m -CONFIG_BLUEZ_RFCOMM=m -CONFIG_BLUEZ_RFCOMM_TTY=y -CONFIG_BLUEZ_BNEP=m -CONFIG_BLUEZ_BNEP_MC_FILTER=y -CONFIG_BLUEZ_BNEP_PROTO_FILTER=y - -# -# Bluetooth device drivers -# -CONFIG_BLUEZ_HCIUSB=m -CONFIG_BLUEZ_USB_ZERO_PACKET=y -CONFIG_BLUEZ_HCIUART=m -CONFIG_BLUEZ_HCIUART_H4=y -CONFIG_BLUEZ_HCIUART_BCSP=y -CONFIG_BLUEZ_HCIUART_BCSP_TXCRC=y -CONFIG_BLUEZ_HCIDTL1=m -CONFIG_BLUEZ_HCIBT3C=m -CONFIG_BLUEZ_HCIBLUECARD=m -CONFIG_BLUEZ_HCIBTUART=m -CONFIG_BLUEZ_HCIVHCI=m - -# -# Profiling support -# -# CONFIG_PROFILING is not set - -# -# Kernel hacking -# -CONFIG_DEBUG_KERNEL=y -CONFIG_DEBUG_STACKOVERFLOW=y -# CONFIG_DEBUG_HIGHMEM is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_IOVIRT is not set -CONFIG_MAGIC_SYSRQ=y -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_FRAME_POINTER is not set -CONFIG_MCL_COREDUMP=y -CONFIG_BOOTIMG=y - -# -# Library routines -# -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y diff --git a/lustre/kernel_patches/kernel_configs/config-linux-2.4.20-uml b/lustre/kernel_patches/kernel_configs/config-linux-2.4.20-uml deleted file mode 100644 index 9934753..0000000 --- a/lustre/kernel_patches/kernel_configs/config-linux-2.4.20-uml +++ /dev/null @@ -1,298 +0,0 @@ -# -# Automatically generated make config: don't edit -# -CONFIG_USERMODE=y -# CONFIG_ISA is not set -# CONFIG_SBUS is not set -# CONFIG_PCI is not set -CONFIG_UID16=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y - -# -# General Setup -# -# CONFIG_MODE_SKAS is not set -CONFIG_MODE_TT=y -CONFIG_MODE_TT=y -CONFIG_NET=y -CONFIG_SYSVIPC=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_SYSCTL=y -# CONFIG_BINFMT_AOUT is not set -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=y -CONFIG_HOSTFS=y -# CONFIG_HPPFS is not set -CONFIG_MCONSOLE=y -CONFIG_MAGIC_SYSRQ=y -# CONFIG_HOST_2G_2G is not set -# CONFIG_UML_SMP is not set -# CONFIG_SMP is not set -CONFIG_NEST_LEVEL=0 -CONFIG_KERNEL_HALF_GIGS=1 -# CONFIG_HIGHMEM is not set -# CONFIG_PROC_MM is not set -CONFIG_KERNEL_STACK_ORDER=3 - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_KMOD=y - -# -# Character Devices -# -CONFIG_STDIO_CONSOLE=y -CONFIG_SSL=y -CONFIG_FD_CHAN=y -# CONFIG_NULL_CHAN is not set -CONFIG_PORT_CHAN=y -CONFIG_PTY_CHAN=y -CONFIG_TTY_CHAN=y -CONFIG_XTERM_CHAN=y -CONFIG_CON_ZERO_CHAN="fd:0,fd:1" -CONFIG_CON_CHAN="xterm" -CONFIG_SSL_CHAN="pty" -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 -# CONFIG_WATCHDOG is not set -# CONFIG_WATCHDOG_NOWAYOUT is not set -# CONFIG_SOFT_WATCHDOG is not set -# CONFIG_UML_WATCHDOG is not set -# CONFIG_UML_SOUND is not set -# CONFIG_SOUND is not set -# CONFIG_HOSTAUDIO is not set -# CONFIG_TTY_LOG is not set - -# -# Block Devices -# -CONFIG_BLK_DEV_UBD=y -# CONFIG_BLK_DEV_UBD_SYNC is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set -# CONFIG_MMAPPER is not set -CONFIG_NETDEVICES=y - -# -# Network Devices -# -CONFIG_UML_NET=y -CONFIG_UML_NET_ETHERTAP=y -CONFIG_UML_NET_TUNTAP=y -CONFIG_UML_NET_SLIP=y -# CONFIG_UML_NET_SLIRP is not set -CONFIG_UML_NET_DAEMON=y -CONFIG_UML_NET_MCAST=y -# CONFIG_UML_NET_PCAP is not set -CONFIG_DUMMY=y -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -CONFIG_TUN=y -CONFIG_PPP=y -# CONFIG_PPP_MULTILINK is not set -# CONFIG_PPP_FILTER is not set -# CONFIG_PPP_ASYNC is not set -# CONFIG_PPP_SYNC_TTY is not set -# CONFIG_PPP_DEFLATE is not set -# CONFIG_PPP_BSDCOMP is not set -# CONFIG_PPPOE is not set -CONFIG_SLIP=y -# CONFIG_SLIP_COMPRESSED is not set -# CONFIG_SLIP_SMART is not set -# CONFIG_SLIP_MODE_SLIP6 is not set - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -# CONFIG_NETLINK_DEV is not set -# CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set -CONFIG_UNIX=y -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_INET_ECN is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_IPV6 is not set -# CONFIG_KHTTPD is not set -# CONFIG_ATM is not set -# CONFIG_VLAN_8021Q is not set - -# -# -# -# CONFIG_IPX is not set -# CONFIG_ATALK is not set - -# -# Appletalk devices -# -# CONFIG_DEV_APPLETALK is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_LLC is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set - -# -# File systems -# -CONFIG_QUOTA=y -# CONFIG_AUTOFS_FS is not set -CONFIG_AUTOFS4_FS=m -CONFIG_REISERFS_FS=y -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set -# CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BEFS_DEBUG is not set -# CONFIG_BFS_FS is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_XATTR_SHARING is not set -# CONFIG_EXT3_FS_XATTR_USER is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set -# CONFIG_CRAMFS is not set -CONFIG_TMPFS=y -CONFIG_TMPFS_XATTR=y -CONFIG_RAMFS=y -# CONFIG_ISO9660_FS is not set -# CONFIG_JOLIET is not set -# CONFIG_ZISOFS is not set -# CONFIG_JFS_FS is not set -# CONFIG_JFS_DEBUG is not set -# CONFIG_JFS_STATISTICS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_RW is not set -# CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -CONFIG_DEVFS_FS=y -CONFIG_DEVFS_MOUNT=y -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y -# CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -# CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XATTR_SHARING is not set -# CONFIG_EXT2_FS_XATTR_USER is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set -# CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set - -# -# Network File Systems -# -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set -# CONFIG_NFS_FS is not set -# CONFIG_NFS_V3 is not set -# CONFIG_ROOT_NFS is not set -# CONFIG_NFSD is not set -# CONFIG_NFSD_V3 is not set -# CONFIG_NFSD_TCP is not set -# CONFIG_SUNRPC is not set -# CONFIG_LOCKD is not set -# CONFIG_SMB_FS is not set -# CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set -# CONFIG_ZISOFS_FS is not set -CONFIG_FS_MBCACHE=y - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_SMB_NLS is not set -# CONFIG_NLS is not set - -# -# SCSI support -# -# CONFIG_SCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_MD_MULTIPATH is not set -# CONFIG_BLK_DEV_LVM is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Library routines -# -# CONFIG_ZLIB_INFLATE is not set -# CONFIG_ZLIB_DEFLATE is not set - -# -# Kernel hacking -# -CONFIG_DEBUG_SLAB=y -CONFIG_DEBUGSYM=y -CONFIG_PT_PROXY=y -# CONFIG_GPROF is not set -# CONFIG_GCOV is not set diff --git a/lustre/kernel_patches/kernel_configs/config-linux-2.4.24-uml b/lustre/kernel_patches/kernel_configs/config-linux-2.4.24-uml deleted file mode 100644 index c2896f3..0000000 --- a/lustre/kernel_patches/kernel_configs/config-linux-2.4.24-uml +++ /dev/null @@ -1,306 +0,0 @@ -# -# Automatically generated by make menuconfig: don't edit -# -CONFIG_USERMODE=y -# CONFIG_ISA is not set -# CONFIG_SBUS is not set -# CONFIG_PCI is not set -CONFIG_UID16=y -CONFIG_RWSEM_XCHGADD_ALGORITHM=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y - -# -# General Setup -# -# CONFIG_MODE_SKAS is not set -CONFIG_MODE_TT=y -CONFIG_MODE_TT=y -CONFIG_NET=y -CONFIG_SYSVIPC=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_SYSCTL=y -# CONFIG_BINFMT_AOUT is not set -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=y -CONFIG_HOSTFS=y -# CONFIG_HPPFS is not set -CONFIG_MCONSOLE=y -CONFIG_MAGIC_SYSRQ=y -# CONFIG_HOST_2G_2G is not set -# CONFIG_UML_SMP is not set -# CONFIG_SMP is not set -CONFIG_NEST_LEVEL=0 -CONFIG_KERNEL_HALF_GIGS=1 -# CONFIG_HIGHMEM is not set -# CONFIG_PROC_MM is not set -CONFIG_KERNEL_STACK_ORDER=3 -CONFIG_UML_REAL_TIME_CLOCK=y - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_KMOD=y - -# -# Character Devices -# -CONFIG_STDIO_CONSOLE=y -CONFIG_SSL=y -CONFIG_FD_CHAN=y -# CONFIG_NULL_CHAN is not set -CONFIG_PORT_CHAN=y -CONFIG_PTY_CHAN=y -CONFIG_TTY_CHAN=y -CONFIG_XTERM_CHAN=y -CONFIG_CON_ZERO_CHAN="fd:0,fd:1" -CONFIG_CON_CHAN="xterm" -CONFIG_SSL_CHAN="pty" -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 -# CONFIG_WATCHDOG is not set -# CONFIG_WATCHDOG_NOWAYOUT is not set -# CONFIG_SOFT_WATCHDOG is not set -# CONFIG_UML_WATCHDOG is not set -# CONFIG_UML_SOUND is not set -# CONFIG_SOUND is not set -# CONFIG_HOSTAUDIO is not set -# CONFIG_TTY_LOG is not set - -# -# Block Devices -# -CONFIG_BLK_DEV_UBD=y -# CONFIG_BLK_DEV_UBD_SYNC is not set -# CONFIG_COW is not set -CONFIG_COW_COMMON=y -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_BLK_DEV_INITRD is not set -# CONFIG_MMAPPER is not set -CONFIG_NETDEVICES=y - -# -# Network Devices -# -CONFIG_UML_NET=y -CONFIG_UML_NET_ETHERTAP=y -CONFIG_UML_NET_TUNTAP=y -CONFIG_UML_NET_SLIP=y -# CONFIG_UML_NET_SLIRP is not set -CONFIG_UML_NET_DAEMON=y -CONFIG_UML_NET_MCAST=y -# CONFIG_UML_NET_PCAP is not set -CONFIG_DUMMY=y -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -CONFIG_TUN=y -CONFIG_PPP=y -# CONFIG_PPP_MULTILINK is not set -# CONFIG_PPP_FILTER is not set -# CONFIG_PPP_ASYNC is not set -# CONFIG_PPP_SYNC_TTY is not set -# CONFIG_PPP_DEFLATE is not set -# CONFIG_PPP_BSDCOMP is not set -# CONFIG_PPPOE is not set -CONFIG_SLIP=y -# CONFIG_SLIP_COMPRESSED is not set -# CONFIG_SLIP_SMART is not set -# CONFIG_SLIP_MODE_SLIP6 is not set - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -# CONFIG_NETLINK_DEV is not set -# CONFIG_NETFILTER is not set -# CONFIG_FILTER is not set -CONFIG_UNIX=y -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_INET_ECN is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_IPV6 is not set -# CONFIG_KHTTPD is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -CONFIG_IPV6_SCTP__=y -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_IPX is not set -# CONFIG_ATALK is not set - -# -# Appletalk devices -# -# CONFIG_DEV_APPLETALK is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_LLC is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set - -# -# File systems -# -CONFIG_QUOTA=y -# CONFIG_QFMT_V2 is not set -# CONFIG_AUTOFS_FS is not set -CONFIG_AUTOFS4_FS=m -CONFIG_REISERFS_FS=y -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set -# CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_HFSPLUS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BEFS_DEBUG is not set -# CONFIG_BFS_FS is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_XATTR_SHARING is not set -# CONFIG_EXT3_FS_XATTR_USER is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set -# CONFIG_UMSDOS_FS is not set -# CONFIG_VFAT_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set -# CONFIG_CRAMFS is not set -CONFIG_TMPFS=y -CONFIG_RAMFS=y -# CONFIG_ISO9660_FS is not set -# CONFIG_JOLIET is not set -# CONFIG_ZISOFS is not set -# CONFIG_JFS_FS is not set -# CONFIG_JFS_DEBUG is not set -# CONFIG_JFS_STATISTICS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_RW is not set -# CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -CONFIG_DEVFS_FS=y -CONFIG_DEVFS_MOUNT=y -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y -# CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -# CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -# CONFIG_EXT2_FS_XATTR_SHARING is not set -# CONFIG_EXT2_FS_XATTR_USER is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set -# CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set - -# -# Network File Systems -# -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set -# CONFIG_NFS_FS is not set -# CONFIG_NFS_V3 is not set -# CONFIG_NFS_DIRECTIO is not set -# CONFIG_ROOT_NFS is not set -# CONFIG_NFSD is not set -# CONFIG_NFSD_V3 is not set -# CONFIG_NFSD_TCP is not set -# CONFIG_SUNRPC is not set -# CONFIG_LOCKD is not set -# CONFIG_SMB_FS is not set -# CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set -# CONFIG_ZISOFS_FS is not set -CONFIG_FS_MBCACHE=y - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_SMB_NLS is not set -# CONFIG_NLS is not set - -# -# SCSI support -# -# CONFIG_SCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set -# CONFIG_BLK_DEV_MD is not set -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_MD_MULTIPATH is not set -# CONFIG_BLK_DEV_LVM is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Library routines -# -# CONFIG_CRC32 is not set -# CONFIG_ZLIB_INFLATE is not set -# CONFIG_ZLIB_DEFLATE is not set - -# -# Kernel hacking -# -CONFIG_DEBUG_SLAB=y -CONFIG_DEBUGSYM=y -CONFIG_PT_PROXY=y -# CONFIG_GPROF is not set -# CONFIG_GCOV is not set diff --git a/lustre/kernel_patches/kernel_configs/kernel-2.4.18-chaos-2.4.18-i686-smp.config b/lustre/kernel_patches/kernel_configs/kernel-2.4.18-chaos-2.4.18-i686-smp.config deleted file mode 100644 index db8f485..0000000 --- a/lustre/kernel_patches/kernel_configs/kernel-2.4.18-chaos-2.4.18-i686-smp.config +++ /dev/null @@ -1,1103 +0,0 @@ -# -# Automatically generated make config: don't edit -# -CONFIG_X86=y -CONFIG_ISA=y -# CONFIG_SBUS is not set -CONFIG_UID16=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODVERSIONS=y -CONFIG_KMOD=y - -# -# Processor type and features -# -CONFIG_LOLAT=y -# CONFIG_LOLAT_SYSCTL is not set -# CONFIG_M386 is not set -# CONFIG_M486 is not set -# CONFIG_M586 is not set -# CONFIG_M586TSC is not set -# CONFIG_M586MMX is not set -# CONFIG_M686 is not set -# CONFIG_MPENTIUMIII is not set -CONFIG_MPENTIUM4=y -# CONFIG_MK6 is not set -# CONFIG_MK7 is not set -# CONFIG_MELAN is not set -# CONFIG_MCRUSOE is not set -# CONFIG_MWINCHIPC6 is not set -# CONFIG_MWINCHIP2 is not set -# CONFIG_MWINCHIP3D is not set -# CONFIG_MCYRIXIII is not set -CONFIG_X86_WP_WORKS_OK=y -CONFIG_X86_INVLPG=y -CONFIG_X86_CMPXCHG=y -CONFIG_X86_XADD=y -CONFIG_X86_BSWAP=y -CONFIG_X86_POPAD_OK=y -# CONFIG_RWSEM_GENERIC_SPINLOCK is not set -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_X86_L1_CACHE_SHIFT=7 -CONFIG_X86_TSC=y -CONFIG_X86_GOOD_APIC=y -CONFIG_X86_PGE=y -CONFIG_X86_USE_PPRO_CHECKSUM=y -CONFIG_X86_MCE=y -# CONFIG_CPU_FREQ is not set -# CONFIG_USE_IRQ_STACKS is not set -# CONFIG_TOSHIBA is not set -# CONFIG_I8K is not set -CONFIG_MICROCODE=m -CONFIG_X86_MSR=m -CONFIG_X86_CPUID=m -# CONFIG_E820_PROC is not set -# CONFIG_NOHIGHMEM is not set -CONFIG_HIGHMEM4G=y -# CONFIG_HIGHMEM64G is not set -CONFIG_HIGHMEM=y -CONFIG_HIGHIO=y -# CONFIG_MATH_EMULATION is not set -CONFIG_MTRR=y -CONFIG_SMP=y -# CONFIG_MULTIQUAD is not set -CONFIG_HAVE_DEC_LOCK=y - -# -# General setup -# -CONFIG_HZ=100 -CONFIG_NET=y -CONFIG_X86_IO_APIC=y -CONFIG_X86_LOCAL_APIC=y -CONFIG_PCI=y -# CONFIG_PCI_GOBIOS is not set -# CONFIG_PCI_GODIRECT is not set -CONFIG_PCI_GOANY=y -CONFIG_PCI_BIOS=y -CONFIG_PCI_DIRECT=y -CONFIG_PCI_NAMES=y - -# -# Performance-monitoring counters support -# -CONFIG_PERFCTR=m -CONFIG_KPERFCTR=y -# CONFIG_PERFCTR_DEBUG is not set -# CONFIG_PERFCTR_INIT_TESTS is not set -CONFIG_PERFCTR_VIRTUAL=y -CONFIG_PERFCTR_GLOBAL=y -# CONFIG_EISA is not set -# CONFIG_MCA is not set -# CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set -# CONFIG_HOTPLUG_PCI is not set -CONFIG_SYSVIPC=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_SYSCTL=y -CONFIG_KCORE_ELF=y -# CONFIG_KCORE_AOUT is not set -CONFIG_BINFMT_AOUT=m -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=m -# CONFIG_IKCONFIG is not set -CONFIG_PM=y - -# -# Additional device driver support -# -# CONFIG_CIPE is not set -# CONFIG_CRYPTO_AEP is not set -# CONFIG_MEGARAC is not set -CONFIG_FC_QLA2200=m -CONFIG_FC_QLA2300=m -# CONFIG_SCSI_ISCSI is not set -CONFIG_IBMASM=m -CONFIG_IBMSER=m -CONFIG_NEW_DIGI_EPCA=m -CONFIG_NVIDIA=m -# CONFIG_ACPI is not set -CONFIG_APM=y -CONFIG_APM_IGNORE_USER_SUSPEND=y -# CONFIG_APM_DO_ENABLE is not set -# CONFIG_APM_CPU_IDLE is not set -# CONFIG_APM_DISPLAY_BLANK is not set -CONFIG_APM_RTC_IS_GMT=y -# CONFIG_APM_ALLOW_INTS is not set -# CONFIG_APM_REAL_MODE_POWER_OFF is not set - -# -# Binary emulation of other systems -# -# CONFIG_ABI is not set -# CONFIG_ABI_SVR4 is not set - -# -# Support for foreign binary formats -# -# CONFIG_BINFMT_COFF is not set -# CONFIG_BINFMT_XOUT is not set -# CONFIG_BINFMT_XOUT_X286 is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_PARTITIONS is not set -# CONFIG_MTD_CONCAT is not set -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=m -# CONFIG_MTD_BLOCK is not set -# CONFIG_MTD_BLOCK_RO is not set -# CONFIG_FTL is not set -# CONFIG_NFTL is not set - -# -# RAM/ROM/Flash chip drivers -# -# CONFIG_MTD_CFI is not set -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_GEN_PROBE=y -CONFIG_MTD_CFI_ADV_OPTIONS=y -CONFIG_MTD_CFI_NOSWAP=y -# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set -# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set -CONFIG_MTD_CFI_GEOMETRY=y -CONFIG_MTD_CFI_B1=y -# CONFIG_MTD_CFI_B2 is not set -# CONFIG_MTD_CFI_B4 is not set -# CONFIG_MTD_CFI_B8 is not set -CONFIG_MTD_CFI_I1=y -# CONFIG_MTD_CFI_I2 is not set -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_CFI_AMDSTD=y -# CONFIG_MTD_RAM is not set -CONFIG_MTD_ROM=y -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set -# CONFIG_MTD_AMDSTD is not set -# CONFIG_MTD_SHARP is not set -# CONFIG_MTD_JEDEC is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_PNC2000 is not set -# CONFIG_MTD_SC520CDP is not set -# CONFIG_MTD_NETSC520 is not set -# CONFIG_MTD_SBC_GXX is not set -# CONFIG_MTD_ELAN_104NC is not set -# CONFIG_MTD_DILNETPC is not set -# CONFIG_MTD_MIXMEM is not set -# CONFIG_MTD_OCTAGON is not set -# CONFIG_MTD_VMAX is not set -# CONFIG_MTD_L440GX is not set -# CONFIG_MTD_AMD766ROM is not set -CONFIG_MTD_ICH2ROM=m -# CONFIG_MTD_PCI is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLKMTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC1000 is not set -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOCPROBE is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# Parallel port support -# -CONFIG_PARPORT=m -CONFIG_PARPORT_PC=m -CONFIG_PARPORT_PC_CML1=m -# CONFIG_PARPORT_SERIAL is not set -# CONFIG_PARPORT_PC_FIFO is not set -# CONFIG_PARPORT_PC_SUPERIO is not set -# CONFIG_PARPORT_AMIGA is not set -# CONFIG_PARPORT_MFC3 is not set -# CONFIG_PARPORT_ATARI is not set -# CONFIG_PARPORT_GSC is not set -# CONFIG_PARPORT_SUNBPP is not set -# CONFIG_PARPORT_OTHER is not set -CONFIG_PARPORT_1284=y - -# -# Plug and Play configuration -# -CONFIG_PNP=y -CONFIG_ISAPNP=y -# CONFIG_PNPBIOS is not set - -# -# Block devices -# -CONFIG_BLK_DEV_FD=y -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_CISS_SCSI_TAPE is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_NBD=m -# CONFIG_BLK_DEV_ENBD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_INITRD=y - -# -# Multi-device support (RAID and LVM) -# -CONFIG_MD=y -CONFIG_BLK_DEV_MD=y -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_MD_MULTIPATH is not set -CONFIG_BLK_DEV_LVM=m - -# -# Cryptography support (CryptoAPI) -# -# CONFIG_CRYPTO is not set -# CONFIG_CIPHERS is not set -# CONFIG_CRYPTODEV is not set -# CONFIG_CRYPTOLOOP is not set - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_NETLINK_DEV=y -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_FILTER=y -CONFIG_UNIX=y -CONFIG_INET=y -# CONFIG_TUX is not set -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_FWMARK=y -CONFIG_IP_ROUTE_NAT=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_TOS=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_ROUTE_LARGE_TABLES=y -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -# CONFIG_ARPD is not set -# CONFIG_INET_ECN is not set -CONFIG_SYN_COOKIES=y - -# -# IP: Netfilter Configuration -# -CONFIG_IP_NF_CONNTRACK=m -# CONFIG_IP_NF_FTP is not set -# CONFIG_IP_NF_IRC is not set -# CONFIG_IP_NF_QUEUE is not set -CONFIG_IP_NF_IPTABLES=m -# CONFIG_IP_NF_MATCH_LIMIT is not set -# CONFIG_IP_NF_MATCH_MAC is not set -# CONFIG_IP_NF_MATCH_MARK is not set -# CONFIG_IP_NF_MATCH_MULTIPORT is not set -# CONFIG_IP_NF_MATCH_TOS is not set -# CONFIG_IP_NF_MATCH_AH_ESP is not set -# CONFIG_IP_NF_MATCH_LENGTH is not set -# CONFIG_IP_NF_MATCH_TTL is not set -# CONFIG_IP_NF_MATCH_TCPMSS is not set -CONFIG_IP_NF_MATCH_STATE=m -# CONFIG_IP_NF_MATCH_UNCLEAN is not set -CONFIG_IP_NF_MATCH_OWNER=m -CONFIG_IP_NF_FILTER=m -# CONFIG_IP_NF_TARGET_REJECT is not set -# CONFIG_IP_NF_TARGET_MIRROR is not set -# CONFIG_IP_NF_NAT is not set -# CONFIG_IP_NF_MANGLE is not set -CONFIG_IP_NF_TARGET_LOG=m -# CONFIG_IP_NF_TARGET_ULOG is not set -# CONFIG_IP_NF_TARGET_TCPMSS is not set -# CONFIG_IP_NF_ARPTABLES is not set -# CONFIG_IP_NF_COMPAT_IPCHAINS is not set -# CONFIG_IP_NF_COMPAT_IPFWADM is not set - -# -# IP: Virtual Server Configuration -# -# CONFIG_IP_VS is not set -# CONFIG_IPV6 is not set -CONFIG_KHTTPD=m -# CONFIG_ATM is not set -# CONFIG_VLAN_8021Q is not set - -# -# -# -# CONFIG_IPX is not set -# CONFIG_ATALK is not set - -# -# Appletalk devices -# -# CONFIG_DEV_APPLETALK is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_LLC is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -CONFIG_NET_PKTGEN=m - -# -# Telephony Support -# -# CONFIG_PHONE is not set -# CONFIG_PHONE_IXJ is not set -# CONFIG_PHONE_IXJ_PCMCIA is not set - -# -# ATA/IDE/MFM/RLL support -# -CONFIG_IDE=y - -# -# IDE, ATA and ATAPI Block devices -# -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_HD_IDE is not set -# CONFIG_BLK_DEV_HD is not set -CONFIG_BLK_DEV_IDEDISK=y -CONFIG_IDEDISK_MULTI_MODE=y -# CONFIG_IDEDISK_STROKE is not set -# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set -# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set -# CONFIG_BLK_DEV_IDEDISK_IBM is not set -# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set -# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set -# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set -# CONFIG_BLK_DEV_IDEDISK_WD is not set -# CONFIG_BLK_DEV_COMMERIAL is not set -# CONFIG_BLK_DEV_TIVO is not set -# CONFIG_BLK_DEV_IDECS is not set -CONFIG_BLK_DEV_IDECD=m -# CONFIG_BLK_DEV_IDETAPE is not set -CONFIG_BLK_DEV_IDEFLOPPY=y -# CONFIG_BLK_DEV_IDESCSI is not set -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -# CONFIG_BLK_DEV_CMD640 is not set -# CONFIG_BLK_DEV_CMD640_ENHANCED is not set -CONFIG_BLK_DEV_ISAPNP=y -# CONFIG_BLK_DEV_RZ1000 is not set -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_IDEPCI_SHARE_IRQ=y -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_OFFBOARD is not set -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y -# CONFIG_IDEDMA_ONLYDISK is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_PCI_WIP is not set -# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set -# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set -CONFIG_BLK_DEV_ADMA=y -CONFIG_BLK_DEV_AEC62XX=y -CONFIG_AEC62XX_TUNING=y -CONFIG_BLK_DEV_ALI15X3=y -# CONFIG_WDC_ALI15X3 is not set -CONFIG_BLK_DEV_AMD74XX=y -# CONFIG_AMD74XX_OVERRIDE is not set -CONFIG_BLK_DEV_CMD64X=y -CONFIG_BLK_DEV_CMD680=y -CONFIG_BLK_DEV_CY82C693=y -CONFIG_BLK_DEV_CS5530=y -CONFIG_BLK_DEV_HPT34X=y -# CONFIG_HPT34X_AUTODMA is not set -CONFIG_BLK_DEV_HPT366=y -CONFIG_BLK_DEV_PIIX=y -CONFIG_PIIX_TUNING=y -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_ADMA100 is not set -CONFIG_BLK_DEV_PDC202XX=y -# CONFIG_PDC202XX_BURST is not set -# CONFIG_PDC202XX_FORCE is not set -CONFIG_BLK_DEV_SVWKS=y -CONFIG_BLK_DEV_SIS5513=y -CONFIG_BLK_DEV_SLC90E66=y -# CONFIG_BLK_DEV_TRM290 is not set -CONFIG_BLK_DEV_VIA82CXXX=y -CONFIG_BLK_DEV_CENATEK=y -# CONFIG_IDE_CHIPSETS is not set -# CONFIG_BLK_DEV_ELEVATOR_NOOP is not set -CONFIG_IDEDMA_AUTO=y -# CONFIG_IDEDMA_IVB is not set -# CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y -# CONFIG_BLK_DEV_ATARAID is not set -# CONFIG_BLK_DEV_ATARAID_PDC is not set -# CONFIG_BLK_DEV_ATARAID_HPT is not set - -# -# SCSI support -# -CONFIG_SCSI=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -CONFIG_SD_EXTRA_DEVS=40 -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=m -CONFIG_BLK_DEV_SR_VENDOR=y -CONFIG_SR_EXTRA_DEVS=4 -CONFIG_CHR_DEV_SG=m - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_DEBUG_QUEUES is not set -CONFIG_SCSI_MULTI_LUN=y -CONFIG_SCSI_CONSTANTS=y -CONFIG_SCSI_LOGGING=y - -# -# SCSI low-level drivers -# -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_7000FASST is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set -# CONFIG_SCSI_AHA1740 is not set -# CONFIG_SCSI_AACRAID is not set -CONFIG_SCSI_AIC7XXX=y -CONFIG_AIC7XXX_CMDS_PER_DEVICE=253 -CONFIG_AIC7XXX_RESET_DELAY_MS=15000 -# CONFIG_AIC7XXX_PROBE_EISA_VL is not set -# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set -# CONFIG_SCSI_AIC79XX is not set -CONFIG_SCSI_DPT_I2O=y -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_SCSI_AM53C974 is not set -# CONFIG_SCSI_MEGARAID is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_DMA is not set -# CONFIG_SCSI_EATA_PIO is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_GENERIC_NCR5380 is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_PPA is not set -# CONFIG_SCSI_IMM is not set -# CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_NCR53C7xx is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_NCR53C8XX is not set -# CONFIG_SCSI_SYM53C8XX is not set -# CONFIG_SCSI_PAS16 is not set -# CONFIG_SCSI_PCI2000 is not set -# CONFIG_SCSI_PCI2220I is not set -# CONFIG_SCSI_PSI240I is not set -# CONFIG_SCSI_QLOGIC_FAS is not set -# CONFIG_SCSI_QLOGIC_ISP is not set -# CONFIG_SCSI_QLOGIC_FC is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_NEWISP is not set -# CONFIG_SCSI_SEAGATE is not set -# CONFIG_SCSI_SIM710 is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set -# CONFIG_SCSI_ULTRASTOR is not set -CONFIG_SCSI_DEBUG=m - -# -# Fusion MPT device support -# -CONFIG_FUSION=y -CONFIG_FUSION_BOOT=y -CONFIG_FUSION_ISENSE=m -CONFIG_FUSION_CTL=m -# CONFIG_FUSION_LAN is not set - -# -# IEEE 1394 (FireWire) support (EXPERIMENTAL) -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set -# CONFIG_I2O_PCI is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set -CONFIG_DUMMY=m -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -CONFIG_TUN=m -# CONFIG_ETHERTAP is not set -# CONFIG_NET_SB1000 is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -# CONFIG_SUNLANCE is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -# CONFIG_SUNGEM is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_AT1700 is not set -# CONFIG_DEPCA is not set -# CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_AC3200 is not set -# CONFIG_APRICOT is not set -# CONFIG_CS89x0 is not set -CONFIG_TULIP=m -# CONFIG_TC35815 is not set -# CONFIG_TULIP_MWI is not set -CONFIG_TULIP_MMIO=y -CONFIG_DE4X5=m -# CONFIG_DGRS is not set -# CONFIG_DM9102 is not set -CONFIG_EEPRO100=m -CONFIG_NET_E100=m -# CONFIG_LNE390 is not set -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_NE3210 is not set -# CONFIG_ES3210 is not set -# CONFIG_8139CP is not set -# CONFIG_8139TOO is not set -# CONFIG_8139TOO_PIO is not set -# CONFIG_8139TOO_TUNE_TWISTER is not set -# CONFIG_8139TOO_8129 is not set -# CONFIG_8139_NEW_RX_RESET is not set -# CONFIG_SIS900 is not set -# CONFIG_SIS900_OLD is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_VIA_RHINE_MMIO is not set -# CONFIG_WINBOND_840 is not set -# CONFIG_NET_POCKET is not set - -# -# Ethernet (1000 Mbit) -# -CONFIG_ACENIC=m -# CONFIG_ACENIC_OMIT_TIGON_I is not set -# CONFIG_DL2K is not set -# CONFIG_MYRI_SBUS is not set -CONFIG_NS83820=m -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_SK98LIN is not set -CONFIG_NET_BROADCOM=m -CONFIG_TIGON3=m -CONFIG_NET_E1000=m -# CONFIG_FDDI is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_HIPPI is not set -# CONFIG_PLIP is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set -# CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set -# CONFIG_SHAPER is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set - -# -# Quadrics Supercomputers -# - -# -# QsNet -# -CONFIG_QUADRICS=y -CONFIG_QSNETMOD=m -CONFIG_ELAN3MOD=m -CONFIG_EPMOD=m -CONFIG_EIPMOD=m -CONFIG_RMSMOD=m -CONFIG_JTAG=m - -# -# QsNet II -# - -# -# Amateur Radio support -# -# CONFIG_HAMRADIO is not set - -# -# IrDA (infrared) support -# -# CONFIG_IRDA is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set -CONFIG_KALLSYMS=y - -# -# Old CD-ROM drivers (not SCSI, not IDE) -# -# CONFIG_CD_NO_IDESCSI is not set - -# -# Input core support -# -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set - -# -# Character devices -# -CONFIG_ECC=m -CONFIG_CHAOSTEST=m -CONFIG_P4THERM=m -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_SERIAL=y -CONFIG_SERIAL_CONSOLE=y -CONFIG_SERIAL_EXTENDED=y -# CONFIG_SERIAL_MANY_PORTS is not set -CONFIG_SERIAL_SHARE_IRQ=y -# CONFIG_SERIAL_DETECT_IRQ is not set -# CONFIG_SERIAL_MULTIPORT is not set -# CONFIG_HUB6 is not set -# CONFIG_SERIAL_NONSTANDARD is not set -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=2048 -# CONFIG_PRINTER is not set -# CONFIG_PPDEV is not set - -# -# I2C support -# -CONFIG_I2C=y -# CONFIG_I2C_ALGOBIT is not set -# CONFIG_I2C_ALGOPCF is not set -CONFIG_I2C_MAINBOARD=y -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_HYDRA is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_TSUNAMI is not set -CONFIG_I2C_I801=m -# CONFIG_I2C_I810 is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VOODOO3 is not set -CONFIG_I2C_ISA=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_PROC=y - -# -# Hardware sensors support -# -CONFIG_SENSORS=y -CONFIG_SENSORS_ADM1021=m -# CONFIG_SENSORS_ADM1024 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_FSCPOS is not set -# CONFIG_SENSORS_FSCSCY is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_MAXILIFE is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_MTP008 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -CONFIG_SENSORS_LM87=m -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_THMC50 is not set -# CONFIG_SENSORS_VIA686A is not set -CONFIG_SENSORS_W83781D=y -# CONFIG_SENSORS_OTHER is not set - -# -# Mice -# -# CONFIG_BUSMOUSE is not set -CONFIG_MOUSE=y -CONFIG_PSMOUSE=y -# CONFIG_82C710_MOUSE is not set -# CONFIG_PC110_PAD is not set -# CONFIG_MK712_MOUSE is not set - -# -# Joysticks -# -# CONFIG_INPUT_GAMEPORT is not set - -# -# Input core support is needed for gameports -# - -# -# Input core support is needed for joysticks -# -# CONFIG_QIC02_TAPE is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_AMD_RNG is not set -# CONFIG_INTEL_RNG is not set -# CONFIG_AMD_PM768 is not set -# CONFIG_NVRAM is not set -CONFIG_RTC=y -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_SONYPI is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_FTAPE is not set -CONFIG_AGP=m -CONFIG_AGP_INTEL=y -# CONFIG_AGP_I810 is not set -# CONFIG_AGP_VIA is not set -# CONFIG_AGP_AMD is not set -# CONFIG_AGP_SIS is not set -# CONFIG_AGP_ALI is not set -# CONFIG_AGP_SWORKS is not set -# CONFIG_DRM is not set -# CONFIG_MWAVE is not set -# CONFIG_BATTERY_GERICOM is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Crypto Hardware support -# -# CONFIG_CRYPTO is not set - -# -# File systems -# -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set -# CONFIG_ADFS_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_ADFS_FS_RW is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BEFS_DEBUG is not set -# CONFIG_BFS_FS is not set -CONFIG_EXT3_FS=y -CONFIG_JBD=y -CONFIG_JBD_DEBUG=y -CONFIG_FAT_FS=m -CONFIG_MSDOS_FS=m -CONFIG_UMSDOS_FS=m -CONFIG_VFAT_FS=m -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set -CONFIG_CRAMFS=y -CONFIG_TMPFS=y -CONFIG_RAMFS=y -CONFIG_ISO9660_FS=y -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -# CONFIG_JFS_FS is not set -# CONFIG_JFS_DEBUG is not set -# CONFIG_JFS_STATISTICS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_RW is not set -# CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y -# CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -CONFIG_ROMFS_FS=m -CONFIG_EXT2_FS=y -# CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set -# CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set - -# -# Network File Systems -# -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set -CONFIG_NFS_FS=m -CONFIG_NFS_V3=y -# CONFIG_ROOT_NFS is not set -CONFIG_NFSD=m -CONFIG_NFSD_V3=y -CONFIG_NFSD_TCP=y -CONFIG_SUNRPC=m -CONFIG_LOCKD=m -CONFIG_LOCKD_V4=y -# CONFIG_SMB_FS is not set -# CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set -CONFIG_PFS_FS=m -CONFIG_PFS_DIRECTIO=m -CONFIG_ZISOFS_FS=y - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -CONFIG_OSF_PARTITION=y -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -CONFIG_MAC_PARTITION=y -CONFIG_MSDOS_PARTITION=y -CONFIG_BSD_DISKLABEL=y -CONFIG_MINIX_SUBPARTITION=y -CONFIG_SOLARIS_X86_PARTITION=y -CONFIG_UNIXWARE_DISKLABEL=y -# CONFIG_LDM_PARTITION is not set -CONFIG_SGI_PARTITION=y -# CONFIG_ULTRIX_PARTITION is not set -CONFIG_SUN_PARTITION=y -# CONFIG_SMB_NLS is not set -CONFIG_NLS=y - -# -# Native Language Support -# -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=m -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -CONFIG_NLS_CODEPAGE_850=m -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -CONFIG_NLS_ISO8859_1=m -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Console drivers -# -CONFIG_VGA_CONSOLE=y -CONFIG_VIDEO_SELECT=y -# CONFIG_VIDEO_IGNORE_BAD_MODE is not set -# CONFIG_MDA_CONSOLE is not set - -# -# Frame-buffer support -# -# CONFIG_FB is not set -# CONFIG_SPEAKUP is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -# CONFIG_USB is not set - -# -# Bluetooth support -# -# CONFIG_BLUEZ is not set - -# -# Kernel hacking -# -CONFIG_DEBUG_KERNEL=y -CONFIG_FRAME_POINTER=y -CONFIG_STACK_TRACE_SCAN=y -CONFIG_STACK_TRACE_FPTR=y -CONFIG_STACK_TRACE_PARAM_COUNT=4 -# CONFIG_DEBUG_HIGHMEM is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_IOVIRT is not set -CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_SPINLOCK=y -CONFIG_MCL_COREDUMP=y -CONFIG_BOOTIMG=y -# CONFIG_OPROFILE is not set -# CONFIG_NOBIGSTACK is not set -CONFIG_STACK_SIZE_16KB=y -# CONFIG_STACK_SIZE_32KB is not set -# CONFIG_STACK_SIZE_64KB is not set -CONFIG_STACK_SIZE_SHIFT=2 - -# -# Library routines -# -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y diff --git a/lustre/kernel_patches/kernel_configs/kernel-2.4.18-chaos-2.4.18-i686.config b/lustre/kernel_patches/kernel_configs/kernel-2.4.18-chaos-2.4.18-i686.config deleted file mode 100644 index db8f485..0000000 --- a/lustre/kernel_patches/kernel_configs/kernel-2.4.18-chaos-2.4.18-i686.config +++ /dev/null @@ -1,1103 +0,0 @@ -# -# Automatically generated make config: don't edit -# -CONFIG_X86=y -CONFIG_ISA=y -# CONFIG_SBUS is not set -CONFIG_UID16=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODVERSIONS=y -CONFIG_KMOD=y - -# -# Processor type and features -# -CONFIG_LOLAT=y -# CONFIG_LOLAT_SYSCTL is not set -# CONFIG_M386 is not set -# CONFIG_M486 is not set -# CONFIG_M586 is not set -# CONFIG_M586TSC is not set -# CONFIG_M586MMX is not set -# CONFIG_M686 is not set -# CONFIG_MPENTIUMIII is not set -CONFIG_MPENTIUM4=y -# CONFIG_MK6 is not set -# CONFIG_MK7 is not set -# CONFIG_MELAN is not set -# CONFIG_MCRUSOE is not set -# CONFIG_MWINCHIPC6 is not set -# CONFIG_MWINCHIP2 is not set -# CONFIG_MWINCHIP3D is not set -# CONFIG_MCYRIXIII is not set -CONFIG_X86_WP_WORKS_OK=y -CONFIG_X86_INVLPG=y -CONFIG_X86_CMPXCHG=y -CONFIG_X86_XADD=y -CONFIG_X86_BSWAP=y -CONFIG_X86_POPAD_OK=y -# CONFIG_RWSEM_GENERIC_SPINLOCK is not set -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_X86_L1_CACHE_SHIFT=7 -CONFIG_X86_TSC=y -CONFIG_X86_GOOD_APIC=y -CONFIG_X86_PGE=y -CONFIG_X86_USE_PPRO_CHECKSUM=y -CONFIG_X86_MCE=y -# CONFIG_CPU_FREQ is not set -# CONFIG_USE_IRQ_STACKS is not set -# CONFIG_TOSHIBA is not set -# CONFIG_I8K is not set -CONFIG_MICROCODE=m -CONFIG_X86_MSR=m -CONFIG_X86_CPUID=m -# CONFIG_E820_PROC is not set -# CONFIG_NOHIGHMEM is not set -CONFIG_HIGHMEM4G=y -# CONFIG_HIGHMEM64G is not set -CONFIG_HIGHMEM=y -CONFIG_HIGHIO=y -# CONFIG_MATH_EMULATION is not set -CONFIG_MTRR=y -CONFIG_SMP=y -# CONFIG_MULTIQUAD is not set -CONFIG_HAVE_DEC_LOCK=y - -# -# General setup -# -CONFIG_HZ=100 -CONFIG_NET=y -CONFIG_X86_IO_APIC=y -CONFIG_X86_LOCAL_APIC=y -CONFIG_PCI=y -# CONFIG_PCI_GOBIOS is not set -# CONFIG_PCI_GODIRECT is not set -CONFIG_PCI_GOANY=y -CONFIG_PCI_BIOS=y -CONFIG_PCI_DIRECT=y -CONFIG_PCI_NAMES=y - -# -# Performance-monitoring counters support -# -CONFIG_PERFCTR=m -CONFIG_KPERFCTR=y -# CONFIG_PERFCTR_DEBUG is not set -# CONFIG_PERFCTR_INIT_TESTS is not set -CONFIG_PERFCTR_VIRTUAL=y -CONFIG_PERFCTR_GLOBAL=y -# CONFIG_EISA is not set -# CONFIG_MCA is not set -# CONFIG_HOTPLUG is not set -# CONFIG_PCMCIA is not set -# CONFIG_HOTPLUG_PCI is not set -CONFIG_SYSVIPC=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_SYSCTL=y -CONFIG_KCORE_ELF=y -# CONFIG_KCORE_AOUT is not set -CONFIG_BINFMT_AOUT=m -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=m -# CONFIG_IKCONFIG is not set -CONFIG_PM=y - -# -# Additional device driver support -# -# CONFIG_CIPE is not set -# CONFIG_CRYPTO_AEP is not set -# CONFIG_MEGARAC is not set -CONFIG_FC_QLA2200=m -CONFIG_FC_QLA2300=m -# CONFIG_SCSI_ISCSI is not set -CONFIG_IBMASM=m -CONFIG_IBMSER=m -CONFIG_NEW_DIGI_EPCA=m -CONFIG_NVIDIA=m -# CONFIG_ACPI is not set -CONFIG_APM=y -CONFIG_APM_IGNORE_USER_SUSPEND=y -# CONFIG_APM_DO_ENABLE is not set -# CONFIG_APM_CPU_IDLE is not set -# CONFIG_APM_DISPLAY_BLANK is not set -CONFIG_APM_RTC_IS_GMT=y -# CONFIG_APM_ALLOW_INTS is not set -# CONFIG_APM_REAL_MODE_POWER_OFF is not set - -# -# Binary emulation of other systems -# -# CONFIG_ABI is not set -# CONFIG_ABI_SVR4 is not set - -# -# Support for foreign binary formats -# -# CONFIG_BINFMT_COFF is not set -# CONFIG_BINFMT_XOUT is not set -# CONFIG_BINFMT_XOUT_X286 is not set - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=y -# CONFIG_MTD_DEBUG is not set -# CONFIG_MTD_PARTITIONS is not set -# CONFIG_MTD_CONCAT is not set -# CONFIG_MTD_REDBOOT_PARTS is not set -# CONFIG_MTD_CMDLINE_PARTS is not set - -# -# User Modules And Translation Layers -# -CONFIG_MTD_CHAR=m -# CONFIG_MTD_BLOCK is not set -# CONFIG_MTD_BLOCK_RO is not set -# CONFIG_FTL is not set -# CONFIG_NFTL is not set - -# -# RAM/ROM/Flash chip drivers -# -# CONFIG_MTD_CFI is not set -CONFIG_MTD_JEDECPROBE=y -CONFIG_MTD_GEN_PROBE=y -CONFIG_MTD_CFI_ADV_OPTIONS=y -CONFIG_MTD_CFI_NOSWAP=y -# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set -# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set -CONFIG_MTD_CFI_GEOMETRY=y -CONFIG_MTD_CFI_B1=y -# CONFIG_MTD_CFI_B2 is not set -# CONFIG_MTD_CFI_B4 is not set -# CONFIG_MTD_CFI_B8 is not set -CONFIG_MTD_CFI_I1=y -# CONFIG_MTD_CFI_I2 is not set -# CONFIG_MTD_CFI_I4 is not set -# CONFIG_MTD_CFI_I8 is not set -CONFIG_MTD_CFI_INTELEXT=y -CONFIG_MTD_CFI_AMDSTD=y -# CONFIG_MTD_RAM is not set -CONFIG_MTD_ROM=y -# CONFIG_MTD_ABSENT is not set -# CONFIG_MTD_OBSOLETE_CHIPS is not set -# CONFIG_MTD_AMDSTD is not set -# CONFIG_MTD_SHARP is not set -# CONFIG_MTD_JEDEC is not set - -# -# Mapping drivers for chip access -# -# CONFIG_MTD_PHYSMAP is not set -# CONFIG_MTD_PNC2000 is not set -# CONFIG_MTD_SC520CDP is not set -# CONFIG_MTD_NETSC520 is not set -# CONFIG_MTD_SBC_GXX is not set -# CONFIG_MTD_ELAN_104NC is not set -# CONFIG_MTD_DILNETPC is not set -# CONFIG_MTD_MIXMEM is not set -# CONFIG_MTD_OCTAGON is not set -# CONFIG_MTD_VMAX is not set -# CONFIG_MTD_L440GX is not set -# CONFIG_MTD_AMD766ROM is not set -CONFIG_MTD_ICH2ROM=m -# CONFIG_MTD_PCI is not set - -# -# Self-contained MTD device drivers -# -# CONFIG_MTD_PMC551 is not set -# CONFIG_MTD_SLRAM is not set -# CONFIG_MTD_MTDRAM is not set -# CONFIG_MTD_BLKMTD is not set - -# -# Disk-On-Chip Device Drivers -# -# CONFIG_MTD_DOC1000 is not set -# CONFIG_MTD_DOC2000 is not set -# CONFIG_MTD_DOC2001 is not set -# CONFIG_MTD_DOCPROBE is not set - -# -# NAND Flash Device Drivers -# -# CONFIG_MTD_NAND is not set - -# -# Parallel port support -# -CONFIG_PARPORT=m -CONFIG_PARPORT_PC=m -CONFIG_PARPORT_PC_CML1=m -# CONFIG_PARPORT_SERIAL is not set -# CONFIG_PARPORT_PC_FIFO is not set -# CONFIG_PARPORT_PC_SUPERIO is not set -# CONFIG_PARPORT_AMIGA is not set -# CONFIG_PARPORT_MFC3 is not set -# CONFIG_PARPORT_ATARI is not set -# CONFIG_PARPORT_GSC is not set -# CONFIG_PARPORT_SUNBPP is not set -# CONFIG_PARPORT_OTHER is not set -CONFIG_PARPORT_1284=y - -# -# Plug and Play configuration -# -CONFIG_PNP=y -CONFIG_ISAPNP=y -# CONFIG_PNPBIOS is not set - -# -# Block devices -# -CONFIG_BLK_DEV_FD=y -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_CISS_SCSI_TAPE is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_NBD=m -# CONFIG_BLK_DEV_ENBD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_INITRD=y - -# -# Multi-device support (RAID and LVM) -# -CONFIG_MD=y -CONFIG_BLK_DEV_MD=y -# CONFIG_MD_LINEAR is not set -# CONFIG_MD_RAID0 is not set -# CONFIG_MD_RAID1 is not set -# CONFIG_MD_RAID5 is not set -# CONFIG_MD_MULTIPATH is not set -CONFIG_BLK_DEV_LVM=m - -# -# Cryptography support (CryptoAPI) -# -# CONFIG_CRYPTO is not set -# CONFIG_CIPHERS is not set -# CONFIG_CRYPTODEV is not set -# CONFIG_CRYPTOLOOP is not set - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_NETLINK_DEV=y -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_FILTER=y -CONFIG_UNIX=y -CONFIG_INET=y -# CONFIG_TUX is not set -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_FWMARK=y -CONFIG_IP_ROUTE_NAT=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_TOS=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_ROUTE_LARGE_TABLES=y -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -# CONFIG_ARPD is not set -# CONFIG_INET_ECN is not set -CONFIG_SYN_COOKIES=y - -# -# IP: Netfilter Configuration -# -CONFIG_IP_NF_CONNTRACK=m -# CONFIG_IP_NF_FTP is not set -# CONFIG_IP_NF_IRC is not set -# CONFIG_IP_NF_QUEUE is not set -CONFIG_IP_NF_IPTABLES=m -# CONFIG_IP_NF_MATCH_LIMIT is not set -# CONFIG_IP_NF_MATCH_MAC is not set -# CONFIG_IP_NF_MATCH_MARK is not set -# CONFIG_IP_NF_MATCH_MULTIPORT is not set -# CONFIG_IP_NF_MATCH_TOS is not set -# CONFIG_IP_NF_MATCH_AH_ESP is not set -# CONFIG_IP_NF_MATCH_LENGTH is not set -# CONFIG_IP_NF_MATCH_TTL is not set -# CONFIG_IP_NF_MATCH_TCPMSS is not set -CONFIG_IP_NF_MATCH_STATE=m -# CONFIG_IP_NF_MATCH_UNCLEAN is not set -CONFIG_IP_NF_MATCH_OWNER=m -CONFIG_IP_NF_FILTER=m -# CONFIG_IP_NF_TARGET_REJECT is not set -# CONFIG_IP_NF_TARGET_MIRROR is not set -# CONFIG_IP_NF_NAT is not set -# CONFIG_IP_NF_MANGLE is not set -CONFIG_IP_NF_TARGET_LOG=m -# CONFIG_IP_NF_TARGET_ULOG is not set -# CONFIG_IP_NF_TARGET_TCPMSS is not set -# CONFIG_IP_NF_ARPTABLES is not set -# CONFIG_IP_NF_COMPAT_IPCHAINS is not set -# CONFIG_IP_NF_COMPAT_IPFWADM is not set - -# -# IP: Virtual Server Configuration -# -# CONFIG_IP_VS is not set -# CONFIG_IPV6 is not set -CONFIG_KHTTPD=m -# CONFIG_ATM is not set -# CONFIG_VLAN_8021Q is not set - -# -# -# -# CONFIG_IPX is not set -# CONFIG_ATALK is not set - -# -# Appletalk devices -# -# CONFIG_DEV_APPLETALK is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_LLC is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -CONFIG_NET_PKTGEN=m - -# -# Telephony Support -# -# CONFIG_PHONE is not set -# CONFIG_PHONE_IXJ is not set -# CONFIG_PHONE_IXJ_PCMCIA is not set - -# -# ATA/IDE/MFM/RLL support -# -CONFIG_IDE=y - -# -# IDE, ATA and ATAPI Block devices -# -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_HD_IDE is not set -# CONFIG_BLK_DEV_HD is not set -CONFIG_BLK_DEV_IDEDISK=y -CONFIG_IDEDISK_MULTI_MODE=y -# CONFIG_IDEDISK_STROKE is not set -# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set -# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set -# CONFIG_BLK_DEV_IDEDISK_IBM is not set -# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set -# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set -# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set -# CONFIG_BLK_DEV_IDEDISK_WD is not set -# CONFIG_BLK_DEV_COMMERIAL is not set -# CONFIG_BLK_DEV_TIVO is not set -# CONFIG_BLK_DEV_IDECS is not set -CONFIG_BLK_DEV_IDECD=m -# CONFIG_BLK_DEV_IDETAPE is not set -CONFIG_BLK_DEV_IDEFLOPPY=y -# CONFIG_BLK_DEV_IDESCSI is not set -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -# CONFIG_BLK_DEV_CMD640 is not set -# CONFIG_BLK_DEV_CMD640_ENHANCED is not set -CONFIG_BLK_DEV_ISAPNP=y -# CONFIG_BLK_DEV_RZ1000 is not set -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_IDEPCI_SHARE_IRQ=y -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_OFFBOARD is not set -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y -# CONFIG_IDEDMA_ONLYDISK is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_PCI_WIP is not set -# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set -# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set -CONFIG_BLK_DEV_ADMA=y -CONFIG_BLK_DEV_AEC62XX=y -CONFIG_AEC62XX_TUNING=y -CONFIG_BLK_DEV_ALI15X3=y -# CONFIG_WDC_ALI15X3 is not set -CONFIG_BLK_DEV_AMD74XX=y -# CONFIG_AMD74XX_OVERRIDE is not set -CONFIG_BLK_DEV_CMD64X=y -CONFIG_BLK_DEV_CMD680=y -CONFIG_BLK_DEV_CY82C693=y -CONFIG_BLK_DEV_CS5530=y -CONFIG_BLK_DEV_HPT34X=y -# CONFIG_HPT34X_AUTODMA is not set -CONFIG_BLK_DEV_HPT366=y -CONFIG_BLK_DEV_PIIX=y -CONFIG_PIIX_TUNING=y -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_ADMA100 is not set -CONFIG_BLK_DEV_PDC202XX=y -# CONFIG_PDC202XX_BURST is not set -# CONFIG_PDC202XX_FORCE is not set -CONFIG_BLK_DEV_SVWKS=y -CONFIG_BLK_DEV_SIS5513=y -CONFIG_BLK_DEV_SLC90E66=y -# CONFIG_BLK_DEV_TRM290 is not set -CONFIG_BLK_DEV_VIA82CXXX=y -CONFIG_BLK_DEV_CENATEK=y -# CONFIG_IDE_CHIPSETS is not set -# CONFIG_BLK_DEV_ELEVATOR_NOOP is not set -CONFIG_IDEDMA_AUTO=y -# CONFIG_IDEDMA_IVB is not set -# CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y -# CONFIG_BLK_DEV_ATARAID is not set -# CONFIG_BLK_DEV_ATARAID_PDC is not set -# CONFIG_BLK_DEV_ATARAID_HPT is not set - -# -# SCSI support -# -CONFIG_SCSI=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -CONFIG_SD_EXTRA_DEVS=40 -# CONFIG_CHR_DEV_ST is not set -# CONFIG_CHR_DEV_OSST is not set -CONFIG_BLK_DEV_SR=m -CONFIG_BLK_DEV_SR_VENDOR=y -CONFIG_SR_EXTRA_DEVS=4 -CONFIG_CHR_DEV_SG=m - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_DEBUG_QUEUES is not set -CONFIG_SCSI_MULTI_LUN=y -CONFIG_SCSI_CONSTANTS=y -CONFIG_SCSI_LOGGING=y - -# -# SCSI low-level drivers -# -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_7000FASST is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set -# CONFIG_SCSI_AHA1740 is not set -# CONFIG_SCSI_AACRAID is not set -CONFIG_SCSI_AIC7XXX=y -CONFIG_AIC7XXX_CMDS_PER_DEVICE=253 -CONFIG_AIC7XXX_RESET_DELAY_MS=15000 -# CONFIG_AIC7XXX_PROBE_EISA_VL is not set -# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set -# CONFIG_SCSI_AIC79XX is not set -CONFIG_SCSI_DPT_I2O=y -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_SCSI_AM53C974 is not set -# CONFIG_SCSI_MEGARAID is not set -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_DMA is not set -# CONFIG_SCSI_EATA_PIO is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_GENERIC_NCR5380 is not set -# CONFIG_SCSI_IPS is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_PPA is not set -# CONFIG_SCSI_IMM is not set -# CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_NCR53C7xx is not set -# CONFIG_SCSI_SYM53C8XX_2 is not set -# CONFIG_SCSI_NCR53C8XX is not set -# CONFIG_SCSI_SYM53C8XX is not set -# CONFIG_SCSI_PAS16 is not set -# CONFIG_SCSI_PCI2000 is not set -# CONFIG_SCSI_PCI2220I is not set -# CONFIG_SCSI_PSI240I is not set -# CONFIG_SCSI_QLOGIC_FAS is not set -# CONFIG_SCSI_QLOGIC_ISP is not set -# CONFIG_SCSI_QLOGIC_FC is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -# CONFIG_SCSI_NEWISP is not set -# CONFIG_SCSI_SEAGATE is not set -# CONFIG_SCSI_SIM710 is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set -# CONFIG_SCSI_ULTRASTOR is not set -CONFIG_SCSI_DEBUG=m - -# -# Fusion MPT device support -# -CONFIG_FUSION=y -CONFIG_FUSION_BOOT=y -CONFIG_FUSION_ISENSE=m -CONFIG_FUSION_CTL=m -# CONFIG_FUSION_LAN is not set - -# -# IEEE 1394 (FireWire) support (EXPERIMENTAL) -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set -# CONFIG_I2O_PCI is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set -CONFIG_DUMMY=m -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -CONFIG_TUN=m -# CONFIG_ETHERTAP is not set -# CONFIG_NET_SB1000 is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -# CONFIG_SUNLANCE is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -# CONFIG_SUNGEM is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_AT1700 is not set -# CONFIG_DEPCA is not set -# CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_AC3200 is not set -# CONFIG_APRICOT is not set -# CONFIG_CS89x0 is not set -CONFIG_TULIP=m -# CONFIG_TC35815 is not set -# CONFIG_TULIP_MWI is not set -CONFIG_TULIP_MMIO=y -CONFIG_DE4X5=m -# CONFIG_DGRS is not set -# CONFIG_DM9102 is not set -CONFIG_EEPRO100=m -CONFIG_NET_E100=m -# CONFIG_LNE390 is not set -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_NE3210 is not set -# CONFIG_ES3210 is not set -# CONFIG_8139CP is not set -# CONFIG_8139TOO is not set -# CONFIG_8139TOO_PIO is not set -# CONFIG_8139TOO_TUNE_TWISTER is not set -# CONFIG_8139TOO_8129 is not set -# CONFIG_8139_NEW_RX_RESET is not set -# CONFIG_SIS900 is not set -# CONFIG_SIS900_OLD is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_TLAN is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_VIA_RHINE_MMIO is not set -# CONFIG_WINBOND_840 is not set -# CONFIG_NET_POCKET is not set - -# -# Ethernet (1000 Mbit) -# -CONFIG_ACENIC=m -# CONFIG_ACENIC_OMIT_TIGON_I is not set -# CONFIG_DL2K is not set -# CONFIG_MYRI_SBUS is not set -CONFIG_NS83820=m -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_SK98LIN is not set -CONFIG_NET_BROADCOM=m -CONFIG_TIGON3=m -CONFIG_NET_E1000=m -# CONFIG_FDDI is not set -# CONFIG_NETCONSOLE is not set -# CONFIG_HIPPI is not set -# CONFIG_PLIP is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set -# CONFIG_NET_FC is not set -# CONFIG_RCPCI is not set -# CONFIG_SHAPER is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set - -# -# Quadrics Supercomputers -# - -# -# QsNet -# -CONFIG_QUADRICS=y -CONFIG_QSNETMOD=m -CONFIG_ELAN3MOD=m -CONFIG_EPMOD=m -CONFIG_EIPMOD=m -CONFIG_RMSMOD=m -CONFIG_JTAG=m - -# -# QsNet II -# - -# -# Amateur Radio support -# -# CONFIG_HAMRADIO is not set - -# -# IrDA (infrared) support -# -# CONFIG_IRDA is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set -CONFIG_KALLSYMS=y - -# -# Old CD-ROM drivers (not SCSI, not IDE) -# -# CONFIG_CD_NO_IDESCSI is not set - -# -# Input core support -# -# CONFIG_INPUT is not set -# CONFIG_INPUT_KEYBDEV is not set -# CONFIG_INPUT_MOUSEDEV is not set -# CONFIG_INPUT_JOYDEV is not set -# CONFIG_INPUT_EVDEV is not set - -# -# Character devices -# -CONFIG_ECC=m -CONFIG_CHAOSTEST=m -CONFIG_P4THERM=m -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_SERIAL=y -CONFIG_SERIAL_CONSOLE=y -CONFIG_SERIAL_EXTENDED=y -# CONFIG_SERIAL_MANY_PORTS is not set -CONFIG_SERIAL_SHARE_IRQ=y -# CONFIG_SERIAL_DETECT_IRQ is not set -# CONFIG_SERIAL_MULTIPORT is not set -# CONFIG_HUB6 is not set -# CONFIG_SERIAL_NONSTANDARD is not set -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=2048 -# CONFIG_PRINTER is not set -# CONFIG_PPDEV is not set - -# -# I2C support -# -CONFIG_I2C=y -# CONFIG_I2C_ALGOBIT is not set -# CONFIG_I2C_ALGOPCF is not set -CONFIG_I2C_MAINBOARD=y -# CONFIG_I2C_ALI1535 is not set -# CONFIG_I2C_ALI15X3 is not set -# CONFIG_I2C_HYDRA is not set -# CONFIG_I2C_AMD756 is not set -# CONFIG_I2C_TSUNAMI is not set -CONFIG_I2C_I801=m -# CONFIG_I2C_I810 is not set -# CONFIG_I2C_PIIX4 is not set -# CONFIG_I2C_SIS5595 is not set -# CONFIG_I2C_VIA is not set -# CONFIG_I2C_VIAPRO is not set -# CONFIG_I2C_VOODOO3 is not set -CONFIG_I2C_ISA=y -CONFIG_I2C_CHARDEV=y -CONFIG_I2C_PROC=y - -# -# Hardware sensors support -# -CONFIG_SENSORS=y -CONFIG_SENSORS_ADM1021=m -# CONFIG_SENSORS_ADM1024 is not set -# CONFIG_SENSORS_ADM1025 is not set -# CONFIG_SENSORS_ADM9240 is not set -# CONFIG_SENSORS_DS1621 is not set -# CONFIG_SENSORS_FSCPOS is not set -# CONFIG_SENSORS_FSCSCY is not set -# CONFIG_SENSORS_GL518SM is not set -# CONFIG_SENSORS_GL520SM is not set -# CONFIG_SENSORS_MAXILIFE is not set -# CONFIG_SENSORS_IT87 is not set -# CONFIG_SENSORS_MTP008 is not set -# CONFIG_SENSORS_LM75 is not set -# CONFIG_SENSORS_LM78 is not set -# CONFIG_SENSORS_LM80 is not set -CONFIG_SENSORS_LM87=m -# CONFIG_SENSORS_SIS5595 is not set -# CONFIG_SENSORS_THMC50 is not set -# CONFIG_SENSORS_VIA686A is not set -CONFIG_SENSORS_W83781D=y -# CONFIG_SENSORS_OTHER is not set - -# -# Mice -# -# CONFIG_BUSMOUSE is not set -CONFIG_MOUSE=y -CONFIG_PSMOUSE=y -# CONFIG_82C710_MOUSE is not set -# CONFIG_PC110_PAD is not set -# CONFIG_MK712_MOUSE is not set - -# -# Joysticks -# -# CONFIG_INPUT_GAMEPORT is not set - -# -# Input core support is needed for gameports -# - -# -# Input core support is needed for joysticks -# -# CONFIG_QIC02_TAPE is not set - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_AMD_RNG is not set -# CONFIG_INTEL_RNG is not set -# CONFIG_AMD_PM768 is not set -# CONFIG_NVRAM is not set -CONFIG_RTC=y -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set -# CONFIG_SONYPI is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_FTAPE is not set -CONFIG_AGP=m -CONFIG_AGP_INTEL=y -# CONFIG_AGP_I810 is not set -# CONFIG_AGP_VIA is not set -# CONFIG_AGP_AMD is not set -# CONFIG_AGP_SIS is not set -# CONFIG_AGP_ALI is not set -# CONFIG_AGP_SWORKS is not set -# CONFIG_DRM is not set -# CONFIG_MWAVE is not set -# CONFIG_BATTERY_GERICOM is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# Crypto Hardware support -# -# CONFIG_CRYPTO is not set - -# -# File systems -# -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set -# CONFIG_ADFS_FS is not set -# CONFIG_AFS_FS is not set -# CONFIG_ADFS_FS_RW is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BEFS_DEBUG is not set -# CONFIG_BFS_FS is not set -CONFIG_EXT3_FS=y -CONFIG_JBD=y -CONFIG_JBD_DEBUG=y -CONFIG_FAT_FS=m -CONFIG_MSDOS_FS=m -CONFIG_UMSDOS_FS=m -CONFIG_VFAT_FS=m -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set -CONFIG_CRAMFS=y -CONFIG_TMPFS=y -CONFIG_RAMFS=y -CONFIG_ISO9660_FS=y -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -# CONFIG_JFS_FS is not set -# CONFIG_JFS_DEBUG is not set -# CONFIG_JFS_STATISTICS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_RW is not set -# CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y -# CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -CONFIG_ROMFS_FS=m -CONFIG_EXT2_FS=y -# CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set -# CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set - -# -# Network File Systems -# -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set -CONFIG_NFS_FS=m -CONFIG_NFS_V3=y -# CONFIG_ROOT_NFS is not set -CONFIG_NFSD=m -CONFIG_NFSD_V3=y -CONFIG_NFSD_TCP=y -CONFIG_SUNRPC=m -CONFIG_LOCKD=m -CONFIG_LOCKD_V4=y -# CONFIG_SMB_FS is not set -# CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set -CONFIG_PFS_FS=m -CONFIG_PFS_DIRECTIO=m -CONFIG_ZISOFS_FS=y - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -CONFIG_OSF_PARTITION=y -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -CONFIG_MAC_PARTITION=y -CONFIG_MSDOS_PARTITION=y -CONFIG_BSD_DISKLABEL=y -CONFIG_MINIX_SUBPARTITION=y -CONFIG_SOLARIS_X86_PARTITION=y -CONFIG_UNIXWARE_DISKLABEL=y -# CONFIG_LDM_PARTITION is not set -CONFIG_SGI_PARTITION=y -# CONFIG_ULTRIX_PARTITION is not set -CONFIG_SUN_PARTITION=y -# CONFIG_SMB_NLS is not set -CONFIG_NLS=y - -# -# Native Language Support -# -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=m -# CONFIG_NLS_CODEPAGE_737 is not set -# CONFIG_NLS_CODEPAGE_775 is not set -CONFIG_NLS_CODEPAGE_850=m -# CONFIG_NLS_CODEPAGE_852 is not set -# CONFIG_NLS_CODEPAGE_855 is not set -# CONFIG_NLS_CODEPAGE_857 is not set -# CONFIG_NLS_CODEPAGE_860 is not set -# CONFIG_NLS_CODEPAGE_861 is not set -# CONFIG_NLS_CODEPAGE_862 is not set -# CONFIG_NLS_CODEPAGE_863 is not set -# CONFIG_NLS_CODEPAGE_864 is not set -# CONFIG_NLS_CODEPAGE_865 is not set -# CONFIG_NLS_CODEPAGE_866 is not set -# CONFIG_NLS_CODEPAGE_869 is not set -# CONFIG_NLS_CODEPAGE_936 is not set -# CONFIG_NLS_CODEPAGE_950 is not set -# CONFIG_NLS_CODEPAGE_932 is not set -# CONFIG_NLS_CODEPAGE_949 is not set -# CONFIG_NLS_CODEPAGE_874 is not set -# CONFIG_NLS_ISO8859_8 is not set -# CONFIG_NLS_CODEPAGE_1250 is not set -# CONFIG_NLS_CODEPAGE_1251 is not set -CONFIG_NLS_ISO8859_1=m -# CONFIG_NLS_ISO8859_2 is not set -# CONFIG_NLS_ISO8859_3 is not set -# CONFIG_NLS_ISO8859_4 is not set -# CONFIG_NLS_ISO8859_5 is not set -# CONFIG_NLS_ISO8859_6 is not set -# CONFIG_NLS_ISO8859_7 is not set -# CONFIG_NLS_ISO8859_9 is not set -# CONFIG_NLS_ISO8859_13 is not set -# CONFIG_NLS_ISO8859_14 is not set -# CONFIG_NLS_ISO8859_15 is not set -# CONFIG_NLS_KOI8_R is not set -# CONFIG_NLS_KOI8_U is not set -# CONFIG_NLS_UTF8 is not set - -# -# Console drivers -# -CONFIG_VGA_CONSOLE=y -CONFIG_VIDEO_SELECT=y -# CONFIG_VIDEO_IGNORE_BAD_MODE is not set -# CONFIG_MDA_CONSOLE is not set - -# -# Frame-buffer support -# -# CONFIG_FB is not set -# CONFIG_SPEAKUP is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -# CONFIG_USB is not set - -# -# Bluetooth support -# -# CONFIG_BLUEZ is not set - -# -# Kernel hacking -# -CONFIG_DEBUG_KERNEL=y -CONFIG_FRAME_POINTER=y -CONFIG_STACK_TRACE_SCAN=y -CONFIG_STACK_TRACE_FPTR=y -CONFIG_STACK_TRACE_PARAM_COUNT=4 -# CONFIG_DEBUG_HIGHMEM is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_IOVIRT is not set -CONFIG_MAGIC_SYSRQ=y -CONFIG_DEBUG_SPINLOCK=y -CONFIG_MCL_COREDUMP=y -CONFIG_BOOTIMG=y -# CONFIG_OPROFILE is not set -# CONFIG_NOBIGSTACK is not set -CONFIG_STACK_SIZE_16KB=y -# CONFIG_STACK_SIZE_32KB is not set -# CONFIG_STACK_SIZE_64KB is not set -CONFIG_STACK_SIZE_SHIFT=2 - -# -# Library routines -# -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=y diff --git a/lustre/kernel_patches/kernel_configs/kernel-2.4.20-hp_pnnl-2.4-ia64-smp.config b/lustre/kernel_patches/kernel_configs/kernel-2.4.20-hp_pnnl-2.4-ia64-smp.config deleted file mode 100644 index 1c65518..0000000 --- a/lustre/kernel_patches/kernel_configs/kernel-2.4.20-hp_pnnl-2.4-ia64-smp.config +++ /dev/null @@ -1,1042 +0,0 @@ -# -# Automatically generated make config: don't edit -# - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODVERSIONS=y -CONFIG_KMOD=y - -# -# General setup -# -CONFIG_IA64=y -# CONFIG_ISA is not set -# CONFIG_EISA is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -# CONFIG_ITANIUM is not set -CONFIG_MCKINLEY=y -# CONFIG_IA64_GENERIC is not set -# CONFIG_IA64_DIG is not set -# CONFIG_IA64_HP_SIM is not set -CONFIG_IA64_HP_ZX1=y -# CONFIG_IA64_SGI_SN1 is not set -# CONFIG_IA64_SGI_SN2 is not set -# CONFIG_IA64_PAGE_SIZE_4KB is not set -CONFIG_IA64_PAGE_SIZE_8KB=y -# CONFIG_IA64_PAGE_SIZE_16KB is not set -# CONFIG_IA64_PAGE_SIZE_64KB is not set -CONFIG_IA64_L1_CACHE_SHIFT=7 -CONFIG_IA64_MCA=y -CONFIG_PM=y -CONFIG_KCORE_ELF=y -CONFIG_IA64_PAL_IDLE=y -CONFIG_SMP=y -CONFIG_IA32_SUPPORT=y -CONFIG_PERFMON=y -CONFIG_IA64_PALINFO=y -CONFIG_EFI_VARS=y -CONFIG_NET=y -CONFIG_SYSVIPC=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_SYSCTL=y -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=m - -# -# Misc devices -# -# CONFIG_BMC is not set -CONFIG_ACPI=y -CONFIG_ACPI_EFI=y -CONFIG_ACPI_INTERPRETER=y -CONFIG_ACPI_KERNEL_CONFIG=y - -# -# ACPI Support -# -CONFIG_ACPI_PCI=y -CONFIG_ACPI=y -CONFIG_ACPI_EFI=y -CONFIG_ACPI_BOOT=y -CONFIG_ACPI_BUS=y -CONFIG_ACPI_INTERPRETER=y -CONFIG_ACPI_POWER=y -CONFIG_ACPI_SYSTEM=y -CONFIG_ACPI_BUTTON=y -CONFIG_ACPI_FAN=y -CONFIG_ACPI_PROCESSOR=y -CONFIG_ACPI_THERMAL=y -# CONFIG_ACPI_DEBUG is not set -CONFIG_PCI=y -CONFIG_PCI_NAMES=y -CONFIG_HOTPLUG=y - -# -# PCI Hotplug Support -# -# CONFIG_HOTPLUG_PCI is not set -# CONFIG_HOTPLUG_PCI_COMPAQ is not set -# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set -# CONFIG_HOTPLUG_PCI_ACPI is not set - -# -# PCMCIA/CardBus support -# -# CONFIG_PCMCIA is not set - -# -# Parallel port support -# -CONFIG_PARPORT=m -CONFIG_PARPORT_PC=m -CONFIG_PARPORT_PC_CML1=m -CONFIG_PARPORT_SERIAL=m -# CONFIG_PARPORT_PC_FIFO is not set -# CONFIG_PARPORT_PC_SUPERIO is not set -# CONFIG_PARPORT_AMIGA is not set -# CONFIG_PARPORT_MFC3 is not set -# CONFIG_PARPORT_ATARI is not set -# CONFIG_PARPORT_GSC is not set -# CONFIG_PARPORT_SUNBPP is not set -# CONFIG_PARPORT_OTHER is not set -CONFIG_PARPORT_1284=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_NETLINK_DEV=m -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_FILTER=y -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_FWMARK=y -CONFIG_IP_ROUTE_NAT=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_TOS=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_ROUTE_LARGE_TABLES=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -CONFIG_NET_IPIP=m -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -# CONFIG_INET_ECN is not set -CONFIG_SYN_COOKIES=y - -# -# IP: Netfilter Configuration -# -CONFIG_IP_NF_CONNTRACK=m -CONFIG_IP_NF_FTP=m -CONFIG_IP_NF_IRC=m -CONFIG_IP_NF_QUEUE=m -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_LIMIT=m -CONFIG_IP_NF_MATCH_MAC=m -CONFIG_IP_NF_MATCH_PKTTYPE=m -CONFIG_IP_NF_MATCH_MARK=m -CONFIG_IP_NF_MATCH_MULTIPORT=m -CONFIG_IP_NF_MATCH_TOS=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_DSCP=m -# CONFIG_IP_NF_MATCH_AH_ESP is not set -CONFIG_IP_NF_MATCH_LENGTH=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_MATCH_TCPMSS=m -CONFIG_IP_NF_MATCH_HELPER=m -CONFIG_IP_NF_MATCH_STATE=m -CONFIG_IP_NF_MATCH_CONNTRACK=m -CONFIG_IP_NF_MATCH_UNCLEAN=m -CONFIG_IP_NF_MATCH_OWNER=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_MIRROR=m -CONFIG_IP_NF_NAT=m -CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_REDIRECT=m -# CONFIG_IP_NF_NAT_LOCAL is not set -CONFIG_IP_NF_NAT_SNMP_BASIC=m -CONFIG_IP_NF_NAT_IRC=m -CONFIG_IP_NF_NAT_FTP=m -CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_TOS=m -CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_TARGET_DSCP=m -CONFIG_IP_NF_TARGET_MARK=m -CONFIG_IP_NF_TARGET_LOG=m -# CONFIG_IP_NF_TARGET_ULOG is not set -CONFIG_IP_NF_TARGET_TCPMSS=m -# CONFIG_IP_NF_ARPTABLES is not set -# CONFIG_IP_NF_COMPAT_IPCHAINS is not set -# CONFIG_IP_NF_COMPAT_IPFWADM is not set - -# -# IP: Virtual Server Configuration -# -CONFIG_IP_VS=m -# CONFIG_IP_VS_DEBUG is not set -CONFIG_IP_VS_TAB_BITS=12 - -# -# IPVS scheduler -# -CONFIG_IP_VS_RR=m -CONFIG_IP_VS_WRR=m -CONFIG_IP_VS_LC=m -CONFIG_IP_VS_WLC=m -CONFIG_IP_VS_LBLC=m -CONFIG_IP_VS_LBLCR=m -CONFIG_IP_VS_DH=m -CONFIG_IP_VS_SH=m - -# -# IPVS application helper -# -CONFIG_IP_VS_FTP=m -# CONFIG_IPV6 is not set -# CONFIG_KHTTPD is not set -# CONFIG_ATM is not set -# CONFIG_VLAN_8021Q is not set - -# -# -# -# CONFIG_IPX is not set -# CONFIG_ATALK is not set - -# -# Appletalk devices -# -# CONFIG_DEV_APPLETALK is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_LLC is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Plug and Play configuration -# -# CONFIG_PNP is not set -# CONFIG_ISAPNP is not set - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_CISS_SCSI_TAPE is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_NBD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=65536 -CONFIG_BLK_DEV_INITRD=y -# CONFIG_BLK_STATS is not set - -# -# IEEE 1394 (FireWire) support (EXPERIMENTAL) -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set -# CONFIG_I2O_PCI is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set - -# -# Multi-device support (RAID and LVM) -# -CONFIG_MD=y -CONFIG_BLK_DEV_MD=y -CONFIG_MD_LINEAR=y -CONFIG_MD_RAID0=y -CONFIG_MD_RAID1=y -CONFIG_MD_RAID5=y -CONFIG_MD_MULTIPATH=y -CONFIG_BLK_DEV_LVM=y - -# -# Fusion MPT device support -# -CONFIG_FUSION=y -CONFIG_FUSION_BOOT=y -CONFIG_FUSION_MAX_SGE=40 -CONFIG_FUSION_ISENSE=m -CONFIG_FUSION_CTL=m -CONFIG_FUSION_LAN=m -CONFIG_NET_FC=y - -# -# ATA/IDE/MFM/RLL support -# -CONFIG_IDE=y - -# -# IDE, ATA and ATAPI Block devices -# -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_HD_IDE is not set -# CONFIG_BLK_DEV_HD is not set -CONFIG_BLK_DEV_IDEDISK=y -# CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set -# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set -# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set -# CONFIG_BLK_DEV_IDEDISK_IBM is not set -# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set -# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set -# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set -# CONFIG_BLK_DEV_IDEDISK_WD is not set -# CONFIG_BLK_DEV_COMMERIAL is not set -# CONFIG_BLK_DEV_TIVO is not set -# CONFIG_BLK_DEV_IDECS is not set -CONFIG_BLK_DEV_IDECD=y -# CONFIG_BLK_DEV_IDETAPE is not set -CONFIG_BLK_DEV_IDEFLOPPY=y -CONFIG_BLK_DEV_IDESCSI=y -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -# CONFIG_BLK_DEV_CMD640 is not set -# CONFIG_BLK_DEV_CMD640_ENHANCED is not set -# CONFIG_BLK_DEV_ISAPNP is not set -# CONFIG_BLK_DEV_RZ1000 is not set -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_IDEPCI_SHARE_IRQ=y -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_OFFBOARD is not set -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y -# CONFIG_IDEDMA_ONLYDISK is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_PCI_WIP is not set -# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set -# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set -CONFIG_BLK_DEV_ADMA=y -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_AEC62XX_TUNING is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_WDC_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_AMD74XX_OVERRIDE is not set -CONFIG_BLK_DEV_CMD64X=y -# CONFIG_BLK_DEV_CMD680 is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_HPT34X_AUTODMA is not set -# CONFIG_BLK_DEV_HPT366 is not set -CONFIG_BLK_DEV_PIIX=y -CONFIG_PIIX_TUNING=y -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_PDC202XX is not set -# CONFIG_PDC202XX_BURST is not set -# CONFIG_PDC202XX_FORCE is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIS5513 is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set -# CONFIG_IDE_CHIPSETS is not set -CONFIG_IDEDMA_AUTO=y -# CONFIG_IDEDMA_IVB is not set -# CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y -# CONFIG_BLK_DEV_ATARAID is not set -# CONFIG_BLK_DEV_ATARAID_PDC is not set -# CONFIG_BLK_DEV_ATARAID_HPT is not set - -# -# SCSI support -# -CONFIG_SCSI=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -CONFIG_SD_EXTRA_DEVS=40 -CONFIG_CHR_DEV_ST=y -CONFIG_CHR_DEV_OSST=y -CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y -CONFIG_SR_EXTRA_DEVS=2 -CONFIG_CHR_DEV_SG=y - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_DEBUG_QUEUES is not set -CONFIG_SCSI_MULTI_LUN=y -CONFIG_SCSI_CONSTANTS=y -CONFIG_SCSI_LOGGING=y - -# -# SCSI low-level drivers -# -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_7000FASST is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set -# CONFIG_SCSI_AHA1740 is not set -CONFIG_SCSI_AACRAID=m -CONFIG_SCSI_AIC7XXX=y -CONFIG_AIC7XXX_CMDS_PER_DEVICE=253 -CONFIG_AIC7XXX_RESET_DELAY_MS=15000 -# CONFIG_AIC7XXX_PROBE_EISA_VL is not set -# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_SCSI_AM53C974 is not set -CONFIG_SCSI_MEGARAID=y -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_DMA is not set -# CONFIG_SCSI_EATA_PIO is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_GENERIC_NCR5380 is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_PPA is not set -# CONFIG_SCSI_IMM is not set -# CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_NCR53C7xx is not set -CONFIG_SCSI_SYM53C8XX_2=y -CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 -CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 -CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 -# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set -# CONFIG_SCSI_PAS16 is not set -# CONFIG_SCSI_PCI2000 is not set -# CONFIG_SCSI_PCI2220I is not set -# CONFIG_SCSI_PSI240I is not set -# CONFIG_SCSI_QLOGIC_FAS is not set -# CONFIG_SCSI_QLOGIC_ISP is not set -# CONFIG_SCSI_QLOGIC_FC is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -CONFIG_SCSI_QLOGIC_QLA2XXX=y -CONFIG_SCSI_QLOGIC_QLA2XXX_QLA2100=m -CONFIG_SCSI_QLOGIC_QLA2XXX_QLA2200=m -CONFIG_SCSI_QLOGIC_QLA2XXX_QLA2300=m -# CONFIG_SCSI_SIM710 is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set -# CONFIG_SCSI_DEBUG is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set -CONFIG_DUMMY=m -CONFIG_BONDING=m -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_ETHERTAP is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -# CONFIG_SUNLANCE is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -# CONFIG_SUNGEM is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_APRICOT is not set -# CONFIG_CS89x0 is not set -# CONFIG_TULIP is not set -# CONFIG_DE4X5 is not set -# CONFIG_DGRS is not set -# CONFIG_DM9102 is not set -CONFIG_EEPRO100=y -# CONFIG_E100 is not set -# CONFIG_LNE390 is not set -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_NE3210 is not set -# CONFIG_ES3210 is not set -# CONFIG_8139CP is not set -# CONFIG_8139TOO is not set -# CONFIG_8139TOO_PIO is not set -# CONFIG_8139TOO_TUNE_TWISTER is not set -# CONFIG_8139TOO_8129 is not set -# CONFIG_8139_OLD_RX_RESET is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_SUNDANCE_MMIO is not set -# CONFIG_TLAN is not set -# CONFIG_TC35815 is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_VIA_RHINE_MMIO is not set -# CONFIG_WINBOND_840 is not set -# CONFIG_NET_POCKET is not set - -# -# Ethernet (1000 Mbit) -# -CONFIG_ACENIC=m -CONFIG_ACENIC_OMIT_TIGON_I=y -# CONFIG_DL2K is not set -CONFIG_E1000=y -# CONFIG_MYRI_SBUS is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_SK98LIN is not set -CONFIG_TIGON3=y - -# -# Quadrics QsNet -# -CONFIG_QSNET=m -CONFIG_ELAN3=m -CONFIG_EP3=m -CONFIG_EIP=m -CONFIG_ELAN4=m -CONFIG_RMS=m -CONFIG_JTAG=m -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PLIP is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set -CONFIG_NET_FC=y -CONFIG_IPHASE5526=m -# CONFIG_RCPCI is not set -# CONFIG_SHAPER is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set - -# -# Amateur Radio support -# -# CONFIG_HAMRADIO is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# CD-ROM drivers (not for SCSI or IDE/ATAPI drives) -# -# CONFIG_CD_NO_IDESCSI is not set - -# -# Input core support -# -CONFIG_INPUT=y -CONFIG_INPUT_KEYBDEV=y -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -CONFIG_INPUT_JOYDEV=m -CONFIG_INPUT_EVDEV=m - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_SERIAL=y -CONFIG_SERIAL_CONSOLE=y -CONFIG_SERIAL_HCDP=y -CONFIG_SERIAL_EXTENDED=y -CONFIG_SERIAL_ACPI=y -CONFIG_SERIAL_MANY_PORTS=y -CONFIG_SERIAL_SHARE_IRQ=y -# CONFIG_SERIAL_DETECT_IRQ is not set -CONFIG_SERIAL_MULTIPORT=y -# CONFIG_HUB6 is not set -# CONFIG_SERIAL_NONSTANDARD is not set -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 -# CONFIG_PRINTER is not set -# CONFIG_PPDEV is not set - -# -# I2C support -# -CONFIG_I2C=m -CONFIG_I2C_ALGOBIT=m -# CONFIG_I2C_PHILIPSPAR is not set -# CONFIG_I2C_ELV is not set -# CONFIG_I2C_VELLEMAN is not set -# CONFIG_I2C_ALGOPCF is not set -CONFIG_I2C_CHARDEV=m -CONFIG_I2C_PROC=m - -# -# Mice -# -# CONFIG_BUSMOUSE is not set -# CONFIG_MOUSE is not set - -# -# Joysticks -# -# CONFIG_INPUT_GAMEPORT is not set -# CONFIG_INPUT_NS558 is not set -# CONFIG_INPUT_LIGHTNING is not set -# CONFIG_INPUT_PCIGAME is not set -# CONFIG_INPUT_CS461X is not set -# CONFIG_INPUT_EMU10K1 is not set -# CONFIG_INPUT_SERIO is not set -# CONFIG_INPUT_SERPORT is not set - -# -# Joysticks -# -# CONFIG_INPUT_ANALOG is not set -# CONFIG_INPUT_A3D is not set -# CONFIG_INPUT_ADI is not set -# CONFIG_INPUT_COBRA is not set -# CONFIG_INPUT_GF2K is not set -# CONFIG_INPUT_GRIP is not set -# CONFIG_INPUT_INTERACT is not set -# CONFIG_INPUT_TMDC is not set -# CONFIG_INPUT_SIDEWINDER is not set -# CONFIG_INPUT_IFORCE_USB is not set -# CONFIG_INPUT_IFORCE_232 is not set -# CONFIG_INPUT_WARRIOR is not set -# CONFIG_INPUT_MAGELLAN is not set -# CONFIG_INPUT_SPACEORB is not set -# CONFIG_INPUT_SPACEBALL is not set -# CONFIG_INPUT_STINGER is not set -# CONFIG_INPUT_DB9 is not set -# CONFIG_INPUT_GAMECON is not set -# CONFIG_INPUT_TURBOGRAFX is not set -# CONFIG_QIC02_TAPE is not set -CONFIG_IPMI_HANDLER=m -CONFIG_IPMI_PANIC_EVENT=y -CONFIG_IPMI_DEVICE_INTERFACE=m -CONFIG_IPMI_KCS=m -CONFIG_IPMI_WATCHDOG=m - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set -# CONFIG_AMD_PM768 is not set -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set -CONFIG_EFI_RTC=y -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_FTAPE is not set -# CONFIG_AGP is not set -# CONFIG_DRM is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# File systems -# -# CONFIG_QUOTA is not set -# CONFIG_QFMT_V1 is not set -# CONFIG_QFMT_V2 is not set -# CONFIG_QIFACE_COMPAT is not set -CONFIG_AUTOFS_FS=y -CONFIG_AUTOFS4_FS=y -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set -# CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BEFS_DEBUG is not set -# CONFIG_BFS_FS is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -CONFIG_EXT3_FS_XATTR_SHARING=y -CONFIG_EXT3_FS_XATTR_USER=y -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -# CONFIG_UMSDOS_FS is not set -CONFIG_VFAT_FS=y -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set -CONFIG_CRAMFS=y -CONFIG_TMPFS=y -CONFIG_RAMFS=y -CONFIG_ISO9660_FS=y -CONFIG_JOLIET=y -# CONFIG_ZISOFS is not set -# CONFIG_JFS_FS is not set -# CONFIG_JFS_DEBUG is not set -# CONFIG_JFS_STATISTICS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_RW is not set -# CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y -# CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -# CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_XATTR_SHARING=y -CONFIG_EXT2_FS_XATTR_USER=y -# CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set -# CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set -CONFIG_XFS_FS=y -# CONFIG_XFS_POSIX_ACL is not set -CONFIG_XFS_RT=y -# CONFIG_XFS_QUOTA is not set -CONFIG_XFS_DMAPI=y -# CONFIG_XFS_DEBUG is not set -CONFIG_PAGEBUF_DEBUG=y - -# -# Network File Systems -# -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -CONFIG_ROOT_NFS=y -CONFIG_NFSD=y -CONFIG_NFSD_V3=y -# CONFIG_NFSD_TCP is not set -CONFIG_SUNRPC=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_SMB_FS=m -CONFIG_SMB_NLS_DEFAULT=y -CONFIG_SMB_NLS_REMOTE="cp437" -# CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set -# CONFIG_ZISOFS_FS is not set -CONFIG_FS_MBCACHE=y - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -CONFIG_EFI_PARTITION=y -CONFIG_SMB_NLS=y -CONFIG_NLS=y - -# -# Native Language Support -# -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_737=m -CONFIG_NLS_CODEPAGE_775=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_CODEPAGE_852=m -CONFIG_NLS_CODEPAGE_855=m -CONFIG_NLS_CODEPAGE_857=m -CONFIG_NLS_CODEPAGE_860=m -CONFIG_NLS_CODEPAGE_861=m -CONFIG_NLS_CODEPAGE_862=m -CONFIG_NLS_CODEPAGE_863=m -CONFIG_NLS_CODEPAGE_864=m -CONFIG_NLS_CODEPAGE_865=m -CONFIG_NLS_CODEPAGE_866=m -CONFIG_NLS_CODEPAGE_869=m -CONFIG_NLS_CODEPAGE_936=m -CONFIG_NLS_CODEPAGE_950=m -CONFIG_NLS_CODEPAGE_932=m -CONFIG_NLS_CODEPAGE_949=m -CONFIG_NLS_CODEPAGE_874=m -CONFIG_NLS_ISO8859_8=m -# CONFIG_NLS_CODEPAGE_1250 is not set -CONFIG_NLS_CODEPAGE_1251=m -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_ISO8859_2=m -CONFIG_NLS_ISO8859_3=m -CONFIG_NLS_ISO8859_4=m -CONFIG_NLS_ISO8859_5=m -CONFIG_NLS_ISO8859_6=m -CONFIG_NLS_ISO8859_7=m -CONFIG_NLS_ISO8859_9=m -CONFIG_NLS_ISO8859_13=m -CONFIG_NLS_ISO8859_14=m -CONFIG_NLS_ISO8859_15=m -CONFIG_NLS_KOI8_R=m -CONFIG_NLS_KOI8_U=m -CONFIG_NLS_UTF8=m - -# -# Console drivers -# -CONFIG_VGA_CONSOLE=y - -# -# Frame-buffer support -# -# CONFIG_FB is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_BANDWIDTH is not set -# CONFIG_USB_LONG_TIMEOUT is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_EHCI_HCD is not set -CONFIG_USB_UHCI_ALT=y -CONFIG_USB_OHCI=y - -# -# USB Device Class drivers -# -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_BLUETOOTH is not set -# CONFIG_USB_MIDI is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# USB Human Interface Devices (HID) -# -CONFIG_USB_HID=y -# CONFIG_USB_HIDINPUT is not set -# CONFIG_USB_HIDDEV is not set -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set - -# -# USB Imaging devices -# -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set - -# -# USB Multimedia devices -# - -# -# Video4Linux support is needed for USB Multimedia device support -# - -# -# USB Network adaptors -# -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set - -# -# USB port drivers -# -# CONFIG_USB_USS720 is not set - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_TIGL is not set -# CONFIG_USB_BRLVGER is not set -# CONFIG_USB_LCD is not set - -# -# Library routines -# -CONFIG_ZLIB_INFLATE=y -# CONFIG_ZLIB_DEFLATE is not set - -# -# Bluetooth support -# -# CONFIG_BLUEZ is not set - -# -# Kernel hacking -# -# CONFIG_IA64_GRANULE_16MB is not set -CONFIG_IA64_GRANULE_64MB=y -CONFIG_DUMP=m -CONFIG_DUMP_COMPRESS_RLE=m -CONFIG_DUMP_COMPRESS_GZIP=m -CONFIG_DEBUG_KERNEL=y -# CONFIG_IA64_PRINT_HAZARDS is not set -# CONFIG_DISABLE_VHPT is not set -CONFIG_MAGIC_SYSRQ=y -CONFIG_IA64_EARLY_PRINTK=y -CONFIG_IA64_EARLY_PRINTK_UART=y -CONFIG_IA64_EARLY_PRINTK_UART_BASE=0 -# CONFIG_IA64_EARLY_PRINTK_VGA is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_IA64_DEBUG_CMPXCHG is not set -# CONFIG_IA64_DEBUG_IRQ is not set -CONFIG_KALLSYMS=y diff --git a/lustre/kernel_patches/kernel_configs/kernel-2.4.20-hp_pnnl-2.4-ia64.config b/lustre/kernel_patches/kernel_configs/kernel-2.4.20-hp_pnnl-2.4-ia64.config deleted file mode 100644 index 38669e8..0000000 --- a/lustre/kernel_patches/kernel_configs/kernel-2.4.20-hp_pnnl-2.4-ia64.config +++ /dev/null @@ -1,1042 +0,0 @@ -# -# Automatically generated make config: don't edit -# - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODVERSIONS=y -CONFIG_KMOD=y - -# -# General setup -# -CONFIG_IA64=y -# CONFIG_ISA is not set -# CONFIG_EISA is not set -# CONFIG_MCA is not set -# CONFIG_SBUS is not set -CONFIG_RWSEM_GENERIC_SPINLOCK=y -# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set -# CONFIG_ITANIUM is not set -CONFIG_MCKINLEY=y -# CONFIG_IA64_GENERIC is not set -# CONFIG_IA64_DIG is not set -# CONFIG_IA64_HP_SIM is not set -CONFIG_IA64_HP_ZX1=y -# CONFIG_IA64_SGI_SN1 is not set -# CONFIG_IA64_SGI_SN2 is not set -# CONFIG_IA64_PAGE_SIZE_4KB is not set -CONFIG_IA64_PAGE_SIZE_8KB=y -# CONFIG_IA64_PAGE_SIZE_16KB=y -# CONFIG_IA64_PAGE_SIZE_64KB is not set -CONFIG_IA64_L1_CACHE_SHIFT=7 -CONFIG_IA64_MCA=y -CONFIG_PM=y -CONFIG_KCORE_ELF=y -CONFIG_IA64_PAL_IDLE=y -# CONFIG_SMP is not set -CONFIG_IA32_SUPPORT=y -CONFIG_PERFMON=y -CONFIG_IA64_PALINFO=y -CONFIG_EFI_VARS=y -CONFIG_NET=y -CONFIG_SYSVIPC=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_SYSCTL=y -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=m - -# -# Misc devices -# -# CONFIG_BMC is not set -CONFIG_ACPI=y -CONFIG_ACPI_EFI=y -CONFIG_ACPI_INTERPRETER=y -CONFIG_ACPI_KERNEL_CONFIG=y - -# -# ACPI Support -# -CONFIG_ACPI_PCI=y -CONFIG_ACPI=y -CONFIG_ACPI_EFI=y -CONFIG_ACPI_BOOT=y -CONFIG_ACPI_BUS=y -CONFIG_ACPI_INTERPRETER=y -CONFIG_ACPI_POWER=y -CONFIG_ACPI_SYSTEM=y -CONFIG_ACPI_BUTTON=y -CONFIG_ACPI_FAN=y -CONFIG_ACPI_PROCESSOR=y -CONFIG_ACPI_THERMAL=y -# CONFIG_ACPI_DEBUG is not set -CONFIG_PCI=y -CONFIG_PCI_NAMES=y -CONFIG_HOTPLUG=y - -# -# PCI Hotplug Support -# -# CONFIG_HOTPLUG_PCI is not set -# CONFIG_HOTPLUG_PCI_COMPAQ is not set -# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set -# CONFIG_HOTPLUG_PCI_ACPI is not set - -# -# PCMCIA/CardBus support -# -# CONFIG_PCMCIA is not set - -# -# Parallel port support -# -CONFIG_PARPORT=m -CONFIG_PARPORT_PC=m -CONFIG_PARPORT_PC_CML1=m -CONFIG_PARPORT_SERIAL=m -# CONFIG_PARPORT_PC_FIFO is not set -# CONFIG_PARPORT_PC_SUPERIO is not set -# CONFIG_PARPORT_AMIGA is not set -# CONFIG_PARPORT_MFC3 is not set -# CONFIG_PARPORT_ATARI is not set -# CONFIG_PARPORT_GSC is not set -# CONFIG_PARPORT_SUNBPP is not set -# CONFIG_PARPORT_OTHER is not set -CONFIG_PARPORT_1284=y - -# -# Networking options -# -CONFIG_PACKET=y -# CONFIG_PACKET_MMAP is not set -CONFIG_NETLINK_DEV=m -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_FILTER=y -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_FWMARK=y -CONFIG_IP_ROUTE_NAT=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_TOS=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_ROUTE_LARGE_TABLES=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -# CONFIG_IP_PNP_BOOTP is not set -# CONFIG_IP_PNP_RARP is not set -CONFIG_NET_IPIP=m -# CONFIG_NET_IPGRE is not set -# CONFIG_IP_MROUTE is not set -# CONFIG_ARPD is not set -# CONFIG_INET_ECN is not set -CONFIG_SYN_COOKIES=y - -# -# IP: Netfilter Configuration -# -CONFIG_IP_NF_CONNTRACK=m -CONFIG_IP_NF_FTP=m -CONFIG_IP_NF_IRC=m -CONFIG_IP_NF_QUEUE=m -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_LIMIT=m -CONFIG_IP_NF_MATCH_MAC=m -CONFIG_IP_NF_MATCH_PKTTYPE=m -CONFIG_IP_NF_MATCH_MARK=m -CONFIG_IP_NF_MATCH_MULTIPORT=m -CONFIG_IP_NF_MATCH_TOS=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_DSCP=m -# CONFIG_IP_NF_MATCH_AH_ESP is not set -CONFIG_IP_NF_MATCH_LENGTH=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_MATCH_TCPMSS=m -CONFIG_IP_NF_MATCH_HELPER=m -CONFIG_IP_NF_MATCH_STATE=m -CONFIG_IP_NF_MATCH_CONNTRACK=m -CONFIG_IP_NF_MATCH_UNCLEAN=m -CONFIG_IP_NF_MATCH_OWNER=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_MIRROR=m -CONFIG_IP_NF_NAT=m -CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_REDIRECT=m -# CONFIG_IP_NF_NAT_LOCAL is not set -CONFIG_IP_NF_NAT_SNMP_BASIC=m -CONFIG_IP_NF_NAT_IRC=m -CONFIG_IP_NF_NAT_FTP=m -CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_TOS=m -CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_TARGET_DSCP=m -CONFIG_IP_NF_TARGET_MARK=m -CONFIG_IP_NF_TARGET_LOG=m -# CONFIG_IP_NF_TARGET_ULOG is not set -CONFIG_IP_NF_TARGET_TCPMSS=m -# CONFIG_IP_NF_ARPTABLES is not set -# CONFIG_IP_NF_COMPAT_IPCHAINS is not set -# CONFIG_IP_NF_COMPAT_IPFWADM is not set - -# -# IP: Virtual Server Configuration -# -CONFIG_IP_VS=m -# CONFIG_IP_VS_DEBUG is not set -CONFIG_IP_VS_TAB_BITS=12 - -# -# IPVS scheduler -# -CONFIG_IP_VS_RR=m -CONFIG_IP_VS_WRR=m -CONFIG_IP_VS_LC=m -CONFIG_IP_VS_WLC=m -CONFIG_IP_VS_LBLC=m -CONFIG_IP_VS_LBLCR=m -CONFIG_IP_VS_DH=m -CONFIG_IP_VS_SH=m - -# -# IPVS application helper -# -CONFIG_IP_VS_FTP=m -# CONFIG_IPV6 is not set -# CONFIG_KHTTPD is not set -# CONFIG_ATM is not set -# CONFIG_VLAN_8021Q is not set - -# -# -# -# CONFIG_IPX is not set -# CONFIG_ATALK is not set - -# -# Appletalk devices -# -# CONFIG_DEV_APPLETALK is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_LLC is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Plug and Play configuration -# -# CONFIG_PNP is not set -# CONFIG_ISAPNP is not set - -# -# Block devices -# -# CONFIG_BLK_DEV_FD is not set -# CONFIG_BLK_DEV_XD is not set -# CONFIG_PARIDE is not set -# CONFIG_BLK_CPQ_DA is not set -# CONFIG_BLK_CPQ_CISS_DA is not set -# CONFIG_CISS_SCSI_TAPE is not set -# CONFIG_BLK_DEV_DAC960 is not set -# CONFIG_BLK_DEV_UMEM is not set -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_NBD is not set -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=65536 -CONFIG_BLK_DEV_INITRD=y -# CONFIG_BLK_STATS is not set - -# -# IEEE 1394 (FireWire) support (EXPERIMENTAL) -# -# CONFIG_IEEE1394 is not set - -# -# I2O device support -# -# CONFIG_I2O is not set -# CONFIG_I2O_PCI is not set -# CONFIG_I2O_BLOCK is not set -# CONFIG_I2O_LAN is not set -# CONFIG_I2O_SCSI is not set -# CONFIG_I2O_PROC is not set - -# -# Multi-device support (RAID and LVM) -# -CONFIG_MD=y -CONFIG_BLK_DEV_MD=y -CONFIG_MD_LINEAR=y -CONFIG_MD_RAID0=y -CONFIG_MD_RAID1=y -CONFIG_MD_RAID5=y -CONFIG_MD_MULTIPATH=y -CONFIG_BLK_DEV_LVM=y - -# -# Fusion MPT device support -# -CONFIG_FUSION=y -CONFIG_FUSION_BOOT=y -CONFIG_FUSION_MAX_SGE=40 -CONFIG_FUSION_ISENSE=m -CONFIG_FUSION_CTL=m -CONFIG_FUSION_LAN=m -CONFIG_NET_FC=y - -# -# ATA/IDE/MFM/RLL support -# -CONFIG_IDE=y - -# -# IDE, ATA and ATAPI Block devices -# -CONFIG_BLK_DEV_IDE=y - -# -# Please see Documentation/ide.txt for help/info on IDE drives -# -# CONFIG_BLK_DEV_HD_IDE is not set -# CONFIG_BLK_DEV_HD is not set -CONFIG_BLK_DEV_IDEDISK=y -# CONFIG_IDEDISK_MULTI_MODE is not set -# CONFIG_IDEDISK_STROKE is not set -# CONFIG_BLK_DEV_IDEDISK_VENDOR is not set -# CONFIG_BLK_DEV_IDEDISK_FUJITSU is not set -# CONFIG_BLK_DEV_IDEDISK_IBM is not set -# CONFIG_BLK_DEV_IDEDISK_MAXTOR is not set -# CONFIG_BLK_DEV_IDEDISK_QUANTUM is not set -# CONFIG_BLK_DEV_IDEDISK_SEAGATE is not set -# CONFIG_BLK_DEV_IDEDISK_WD is not set -# CONFIG_BLK_DEV_COMMERIAL is not set -# CONFIG_BLK_DEV_TIVO is not set -# CONFIG_BLK_DEV_IDECS is not set -CONFIG_BLK_DEV_IDECD=y -# CONFIG_BLK_DEV_IDETAPE is not set -CONFIG_BLK_DEV_IDEFLOPPY=y -CONFIG_BLK_DEV_IDESCSI=y -# CONFIG_IDE_TASK_IOCTL is not set - -# -# IDE chipset support/bugfixes -# -# CONFIG_BLK_DEV_CMD640 is not set -# CONFIG_BLK_DEV_CMD640_ENHANCED is not set -# CONFIG_BLK_DEV_ISAPNP is not set -# CONFIG_BLK_DEV_RZ1000 is not set -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_IDEPCI_SHARE_IRQ=y -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_OFFBOARD is not set -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y -# CONFIG_IDEDMA_ONLYDISK is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_PCI_WIP is not set -# CONFIG_BLK_DEV_IDEDMA_TIMEOUT is not set -# CONFIG_IDEDMA_NEW_DRIVE_LISTINGS is not set -CONFIG_BLK_DEV_ADMA=y -# CONFIG_BLK_DEV_AEC62XX is not set -# CONFIG_AEC62XX_TUNING is not set -# CONFIG_BLK_DEV_ALI15X3 is not set -# CONFIG_WDC_ALI15X3 is not set -# CONFIG_BLK_DEV_AMD74XX is not set -# CONFIG_AMD74XX_OVERRIDE is not set -CONFIG_BLK_DEV_CMD64X=y -# CONFIG_BLK_DEV_CMD680 is not set -# CONFIG_BLK_DEV_CY82C693 is not set -# CONFIG_BLK_DEV_CS5530 is not set -# CONFIG_BLK_DEV_HPT34X is not set -# CONFIG_HPT34X_AUTODMA is not set -# CONFIG_BLK_DEV_HPT366 is not set -CONFIG_BLK_DEV_PIIX=y -CONFIG_PIIX_TUNING=y -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_OPTI621 is not set -# CONFIG_BLK_DEV_PDC202XX is not set -# CONFIG_PDC202XX_BURST is not set -# CONFIG_PDC202XX_FORCE is not set -# CONFIG_BLK_DEV_SVWKS is not set -# CONFIG_BLK_DEV_SIS5513 is not set -# CONFIG_BLK_DEV_SLC90E66 is not set -# CONFIG_BLK_DEV_TRM290 is not set -# CONFIG_BLK_DEV_VIA82CXXX is not set -# CONFIG_IDE_CHIPSETS is not set -CONFIG_IDEDMA_AUTO=y -# CONFIG_IDEDMA_IVB is not set -# CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_IDE_MODES=y -# CONFIG_BLK_DEV_ATARAID is not set -# CONFIG_BLK_DEV_ATARAID_PDC is not set -# CONFIG_BLK_DEV_ATARAID_HPT is not set - -# -# SCSI support -# -CONFIG_SCSI=y - -# -# SCSI support type (disk, tape, CD-ROM) -# -CONFIG_BLK_DEV_SD=y -CONFIG_SD_EXTRA_DEVS=40 -CONFIG_CHR_DEV_ST=y -CONFIG_CHR_DEV_OSST=y -CONFIG_BLK_DEV_SR=y -CONFIG_BLK_DEV_SR_VENDOR=y -CONFIG_SR_EXTRA_DEVS=2 -CONFIG_CHR_DEV_SG=y - -# -# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -# -# CONFIG_SCSI_DEBUG_QUEUES is not set -CONFIG_SCSI_MULTI_LUN=y -CONFIG_SCSI_CONSTANTS=y -CONFIG_SCSI_LOGGING=y - -# -# SCSI low-level drivers -# -# CONFIG_BLK_DEV_3W_XXXX_RAID is not set -# CONFIG_SCSI_7000FASST is not set -# CONFIG_SCSI_ACARD is not set -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set -# CONFIG_SCSI_AHA1740 is not set -CONFIG_SCSI_AACRAID=m -CONFIG_SCSI_AIC7XXX=y -CONFIG_AIC7XXX_CMDS_PER_DEVICE=253 -CONFIG_AIC7XXX_RESET_DELAY_MS=15000 -# CONFIG_AIC7XXX_PROBE_EISA_VL is not set -# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set -# CONFIG_SCSI_AIC79XX is not set -# CONFIG_SCSI_DPT_I2O is not set -# CONFIG_SCSI_ADVANSYS is not set -# CONFIG_SCSI_IN2000 is not set -# CONFIG_SCSI_AM53C974 is not set -CONFIG_SCSI_MEGARAID=y -# CONFIG_SCSI_BUSLOGIC is not set -# CONFIG_SCSI_CPQFCTS is not set -# CONFIG_SCSI_DMX3191D is not set -# CONFIG_SCSI_DTC3280 is not set -# CONFIG_SCSI_EATA is not set -# CONFIG_SCSI_EATA_DMA is not set -# CONFIG_SCSI_EATA_PIO is not set -# CONFIG_SCSI_FUTURE_DOMAIN is not set -# CONFIG_SCSI_GDTH is not set -# CONFIG_SCSI_GENERIC_NCR5380 is not set -# CONFIG_SCSI_INITIO is not set -# CONFIG_SCSI_INIA100 is not set -# CONFIG_SCSI_PPA is not set -# CONFIG_SCSI_IMM is not set -# CONFIG_SCSI_NCR53C406A is not set -# CONFIG_SCSI_NCR53C7xx is not set -CONFIG_SCSI_SYM53C8XX_2=y -CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=0 -CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 -CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 -# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set -# CONFIG_SCSI_PAS16 is not set -# CONFIG_SCSI_PCI2000 is not set -# CONFIG_SCSI_PCI2220I is not set -# CONFIG_SCSI_PSI240I is not set -# CONFIG_SCSI_QLOGIC_FAS is not set -# CONFIG_SCSI_QLOGIC_ISP is not set -# CONFIG_SCSI_QLOGIC_FC is not set -# CONFIG_SCSI_QLOGIC_1280 is not set -CONFIG_SCSI_QLOGIC_QLA2XXX=y -CONFIG_SCSI_QLOGIC_QLA2XXX_QLA2100=m -CONFIG_SCSI_QLOGIC_QLA2XXX_QLA2200=m -CONFIG_SCSI_QLOGIC_QLA2XXX_QLA2300=m -# CONFIG_SCSI_SIM710 is not set -# CONFIG_SCSI_SYM53C416 is not set -# CONFIG_SCSI_DC390T is not set -# CONFIG_SCSI_T128 is not set -# CONFIG_SCSI_U14_34F is not set -# CONFIG_SCSI_DEBUG is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set -CONFIG_DUMMY=m -CONFIG_BONDING=m -# CONFIG_EQUALIZER is not set -# CONFIG_TUN is not set -# CONFIG_ETHERTAP is not set - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -# CONFIG_SUNLANCE is not set -# CONFIG_HAPPYMEAL is not set -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -# CONFIG_SUNGEM is not set -# CONFIG_NET_VENDOR_3COM is not set -# CONFIG_LANCE is not set -# CONFIG_NET_VENDOR_SMC is not set -# CONFIG_NET_VENDOR_RACAL is not set -# CONFIG_HP100 is not set -# CONFIG_NET_ISA is not set -CONFIG_NET_PCI=y -# CONFIG_PCNET32 is not set -# CONFIG_ADAPTEC_STARFIRE is not set -# CONFIG_APRICOT is not set -# CONFIG_CS89x0 is not set -# CONFIG_TULIP is not set -# CONFIG_DE4X5 is not set -# CONFIG_DGRS is not set -# CONFIG_DM9102 is not set -CONFIG_EEPRO100=y -# CONFIG_E100 is not set -# CONFIG_LNE390 is not set -# CONFIG_FEALNX is not set -# CONFIG_NATSEMI is not set -# CONFIG_NE2K_PCI is not set -# CONFIG_NE3210 is not set -# CONFIG_ES3210 is not set -# CONFIG_8139CP is not set -# CONFIG_8139TOO is not set -# CONFIG_8139TOO_PIO is not set -# CONFIG_8139TOO_TUNE_TWISTER is not set -# CONFIG_8139TOO_8129 is not set -# CONFIG_8139_OLD_RX_RESET is not set -# CONFIG_SIS900 is not set -# CONFIG_EPIC100 is not set -# CONFIG_SUNDANCE is not set -# CONFIG_SUNDANCE_MMIO is not set -# CONFIG_TLAN is not set -# CONFIG_TC35815 is not set -# CONFIG_VIA_RHINE is not set -# CONFIG_VIA_RHINE_MMIO is not set -# CONFIG_WINBOND_840 is not set -# CONFIG_NET_POCKET is not set - -# -# Ethernet (1000 Mbit) -# -CONFIG_ACENIC=m -CONFIG_ACENIC_OMIT_TIGON_I=y -# CONFIG_DL2K is not set -CONFIG_E1000=y -# CONFIG_MYRI_SBUS is not set -# CONFIG_NS83820 is not set -# CONFIG_HAMACHI is not set -# CONFIG_YELLOWFIN is not set -# CONFIG_SK98LIN is not set -CONFIG_TIGON3=y - -# -# Quadrics QsNet -# -CONFIG_QSNET=m -CONFIG_ELAN3=m -CONFIG_EP3=m -CONFIG_EIP=m -CONFIG_ELAN4=m -CONFIG_RMS=m -CONFIG_JTAG=m -# CONFIG_FDDI is not set -# CONFIG_HIPPI is not set -# CONFIG_PLIP is not set -# CONFIG_PPP is not set -# CONFIG_SLIP is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Token Ring devices -# -# CONFIG_TR is not set -CONFIG_NET_FC=y -CONFIG_IPHASE5526=m -# CONFIG_RCPCI is not set -# CONFIG_SHAPER is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set - -# -# Amateur Radio support -# -# CONFIG_HAMRADIO is not set - -# -# ISDN subsystem -# -# CONFIG_ISDN is not set - -# -# CD-ROM drivers (not for SCSI or IDE/ATAPI drives) -# -# CONFIG_CD_NO_IDESCSI is not set - -# -# Input core support -# -CONFIG_INPUT=y -CONFIG_INPUT_KEYBDEV=y -CONFIG_INPUT_MOUSEDEV=y -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -CONFIG_INPUT_JOYDEV=m -CONFIG_INPUT_EVDEV=m - -# -# Character devices -# -CONFIG_VT=y -CONFIG_VT_CONSOLE=y -CONFIG_SERIAL=y -CONFIG_SERIAL_CONSOLE=y -CONFIG_SERIAL_HCDP=y -CONFIG_SERIAL_EXTENDED=y -CONFIG_SERIAL_ACPI=y -CONFIG_SERIAL_MANY_PORTS=y -CONFIG_SERIAL_SHARE_IRQ=y -# CONFIG_SERIAL_DETECT_IRQ is not set -CONFIG_SERIAL_MULTIPORT=y -# CONFIG_HUB6 is not set -# CONFIG_SERIAL_NONSTANDARD is not set -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 -# CONFIG_PRINTER is not set -# CONFIG_PPDEV is not set - -# -# I2C support -# -CONFIG_I2C=m -CONFIG_I2C_ALGOBIT=m -# CONFIG_I2C_PHILIPSPAR is not set -# CONFIG_I2C_ELV is not set -# CONFIG_I2C_VELLEMAN is not set -# CONFIG_I2C_ALGOPCF is not set -CONFIG_I2C_CHARDEV=m -CONFIG_I2C_PROC=m - -# -# Mice -# -# CONFIG_BUSMOUSE is not set -# CONFIG_MOUSE is not set - -# -# Joysticks -# -# CONFIG_INPUT_GAMEPORT is not set -# CONFIG_INPUT_NS558 is not set -# CONFIG_INPUT_LIGHTNING is not set -# CONFIG_INPUT_PCIGAME is not set -# CONFIG_INPUT_CS461X is not set -# CONFIG_INPUT_EMU10K1 is not set -# CONFIG_INPUT_SERIO is not set -# CONFIG_INPUT_SERPORT is not set - -# -# Joysticks -# -# CONFIG_INPUT_ANALOG is not set -# CONFIG_INPUT_A3D is not set -# CONFIG_INPUT_ADI is not set -# CONFIG_INPUT_COBRA is not set -# CONFIG_INPUT_GF2K is not set -# CONFIG_INPUT_GRIP is not set -# CONFIG_INPUT_INTERACT is not set -# CONFIG_INPUT_TMDC is not set -# CONFIG_INPUT_SIDEWINDER is not set -# CONFIG_INPUT_IFORCE_USB is not set -# CONFIG_INPUT_IFORCE_232 is not set -# CONFIG_INPUT_WARRIOR is not set -# CONFIG_INPUT_MAGELLAN is not set -# CONFIG_INPUT_SPACEORB is not set -# CONFIG_INPUT_SPACEBALL is not set -# CONFIG_INPUT_STINGER is not set -# CONFIG_INPUT_DB9 is not set -# CONFIG_INPUT_GAMECON is not set -# CONFIG_INPUT_TURBOGRAFX is not set -# CONFIG_QIC02_TAPE is not set -CONFIG_IPMI_HANDLER=m -CONFIG_IPMI_PANIC_EVENT=y -CONFIG_IPMI_DEVICE_INTERFACE=m -CONFIG_IPMI_KCS=m -CONFIG_IPMI_WATCHDOG=m - -# -# Watchdog Cards -# -# CONFIG_WATCHDOG is not set -# CONFIG_INTEL_RNG is not set -# CONFIG_AMD_PM768 is not set -# CONFIG_NVRAM is not set -# CONFIG_RTC is not set -CONFIG_EFI_RTC=y -# CONFIG_DTLK is not set -# CONFIG_R3964 is not set -# CONFIG_APPLICOM is not set - -# -# Ftape, the floppy tape device driver -# -# CONFIG_FTAPE is not set -# CONFIG_AGP is not set -# CONFIG_DRM is not set - -# -# Multimedia devices -# -# CONFIG_VIDEO_DEV is not set - -# -# File systems -# -# CONFIG_QUOTA is not set -# CONFIG_QFMT_V1 is not set -# CONFIG_QFMT_V2 is not set -# CONFIG_QIFACE_COMPAT is not set -CONFIG_AUTOFS_FS=y -CONFIG_AUTOFS4_FS=y -# CONFIG_REISERFS_FS is not set -# CONFIG_REISERFS_CHECK is not set -# CONFIG_REISERFS_PROC_INFO is not set -# CONFIG_ADFS_FS is not set -# CONFIG_ADFS_FS_RW is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BEFS_DEBUG is not set -# CONFIG_BFS_FS is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -CONFIG_EXT3_FS_XATTR_SHARING=y -CONFIG_EXT3_FS_XATTR_USER=y -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FAT_FS=y -CONFIG_MSDOS_FS=y -# CONFIG_UMSDOS_FS is not set -CONFIG_VFAT_FS=y -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set -CONFIG_CRAMFS=y -CONFIG_TMPFS=y -CONFIG_RAMFS=y -CONFIG_ISO9660_FS=y -CONFIG_JOLIET=y -# CONFIG_ZISOFS is not set -# CONFIG_JFS_FS is not set -# CONFIG_JFS_DEBUG is not set -# CONFIG_JFS_STATISTICS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_RW is not set -# CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y -# CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -# CONFIG_ROMFS_FS is not set -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_XATTR_SHARING=y -CONFIG_EXT2_FS_XATTR_USER=y -# CONFIG_SYSV_FS is not set -# CONFIG_UDF_FS is not set -# CONFIG_UDF_RW is not set -# CONFIG_UFS_FS is not set -# CONFIG_UFS_FS_WRITE is not set -CONFIG_XFS_FS=y -# CONFIG_XFS_POSIX_ACL is not set -CONFIG_XFS_RT=y -# CONFIG_XFS_QUOTA is not set -CONFIG_XFS_DMAPI=y -# CONFIG_XFS_DEBUG is not set -CONFIG_PAGEBUF_DEBUG=y - -# -# Network File Systems -# -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -CONFIG_ROOT_NFS=y -CONFIG_NFSD=y -CONFIG_NFSD_V3=y -# CONFIG_NFSD_TCP is not set -CONFIG_SUNRPC=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_SMB_FS=m -CONFIG_SMB_NLS_DEFAULT=y -CONFIG_SMB_NLS_REMOTE="cp437" -# CONFIG_NCP_FS is not set -# CONFIG_NCPFS_PACKET_SIGNING is not set -# CONFIG_NCPFS_IOCTL_LOCKING is not set -# CONFIG_NCPFS_STRONG is not set -# CONFIG_NCPFS_NFS_NS is not set -# CONFIG_NCPFS_OS2_NS is not set -# CONFIG_NCPFS_SMALLDOS is not set -# CONFIG_NCPFS_NLS is not set -# CONFIG_NCPFS_EXTRAS is not set -# CONFIG_ZISOFS_FS is not set -CONFIG_FS_MBCACHE=y - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -# CONFIG_OSF_PARTITION is not set -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -# CONFIG_MAC_PARTITION is not set -CONFIG_MSDOS_PARTITION=y -# CONFIG_BSD_DISKLABEL is not set -# CONFIG_MINIX_SUBPARTITION is not set -# CONFIG_SOLARIS_X86_PARTITION is not set -# CONFIG_UNIXWARE_DISKLABEL is not set -# CONFIG_LDM_PARTITION is not set -# CONFIG_SGI_PARTITION is not set -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set -CONFIG_EFI_PARTITION=y -CONFIG_SMB_NLS=y -CONFIG_NLS=y - -# -# Native Language Support -# -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=y -CONFIG_NLS_CODEPAGE_737=m -CONFIG_NLS_CODEPAGE_775=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_CODEPAGE_852=m -CONFIG_NLS_CODEPAGE_855=m -CONFIG_NLS_CODEPAGE_857=m -CONFIG_NLS_CODEPAGE_860=m -CONFIG_NLS_CODEPAGE_861=m -CONFIG_NLS_CODEPAGE_862=m -CONFIG_NLS_CODEPAGE_863=m -CONFIG_NLS_CODEPAGE_864=m -CONFIG_NLS_CODEPAGE_865=m -CONFIG_NLS_CODEPAGE_866=m -CONFIG_NLS_CODEPAGE_869=m -CONFIG_NLS_CODEPAGE_936=m -CONFIG_NLS_CODEPAGE_950=m -CONFIG_NLS_CODEPAGE_932=m -CONFIG_NLS_CODEPAGE_949=m -CONFIG_NLS_CODEPAGE_874=m -CONFIG_NLS_ISO8859_8=m -# CONFIG_NLS_CODEPAGE_1250 is not set -CONFIG_NLS_CODEPAGE_1251=m -CONFIG_NLS_ISO8859_1=y -CONFIG_NLS_ISO8859_2=m -CONFIG_NLS_ISO8859_3=m -CONFIG_NLS_ISO8859_4=m -CONFIG_NLS_ISO8859_5=m -CONFIG_NLS_ISO8859_6=m -CONFIG_NLS_ISO8859_7=m -CONFIG_NLS_ISO8859_9=m -CONFIG_NLS_ISO8859_13=m -CONFIG_NLS_ISO8859_14=m -CONFIG_NLS_ISO8859_15=m -CONFIG_NLS_KOI8_R=m -CONFIG_NLS_KOI8_U=m -CONFIG_NLS_UTF8=m - -# -# Console drivers -# -CONFIG_VGA_CONSOLE=y - -# -# Frame-buffer support -# -# CONFIG_FB is not set - -# -# Sound -# -# CONFIG_SOUND is not set - -# -# USB support -# -CONFIG_USB=y -# CONFIG_USB_DEBUG is not set - -# -# Miscellaneous USB options -# -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_BANDWIDTH is not set -# CONFIG_USB_LONG_TIMEOUT is not set - -# -# USB Host Controller Drivers -# -# CONFIG_USB_EHCI_HCD is not set -CONFIG_USB_UHCI_ALT=y -CONFIG_USB_OHCI=y - -# -# USB Device Class drivers -# -# CONFIG_USB_AUDIO is not set -# CONFIG_USB_EMI26 is not set -# CONFIG_USB_BLUETOOTH is not set -# CONFIG_USB_MIDI is not set -# CONFIG_USB_STORAGE is not set -# CONFIG_USB_STORAGE_DEBUG is not set -# CONFIG_USB_STORAGE_DATAFAB is not set -# CONFIG_USB_STORAGE_FREECOM is not set -# CONFIG_USB_STORAGE_ISD200 is not set -# CONFIG_USB_STORAGE_DPCM is not set -# CONFIG_USB_STORAGE_HP8200e is not set -# CONFIG_USB_STORAGE_SDDR09 is not set -# CONFIG_USB_STORAGE_SDDR55 is not set -# CONFIG_USB_STORAGE_JUMPSHOT is not set -# CONFIG_USB_ACM is not set -# CONFIG_USB_PRINTER is not set - -# -# USB Human Interface Devices (HID) -# -CONFIG_USB_HID=y -# CONFIG_USB_HIDINPUT is not set -# CONFIG_USB_HIDDEV is not set -# CONFIG_USB_AIPTEK is not set -# CONFIG_USB_WACOM is not set - -# -# USB Imaging devices -# -# CONFIG_USB_DC2XX is not set -# CONFIG_USB_MDC800 is not set -# CONFIG_USB_SCANNER is not set -# CONFIG_USB_MICROTEK is not set -# CONFIG_USB_HPUSBSCSI is not set - -# -# USB Multimedia devices -# - -# -# Video4Linux support is needed for USB Multimedia device support -# - -# -# USB Network adaptors -# -# CONFIG_USB_PEGASUS is not set -# CONFIG_USB_RTL8150 is not set -# CONFIG_USB_KAWETH is not set -# CONFIG_USB_CATC is not set -# CONFIG_USB_CDCETHER is not set -# CONFIG_USB_USBNET is not set - -# -# USB port drivers -# -# CONFIG_USB_USS720 is not set - -# -# USB Serial Converter support -# -# CONFIG_USB_SERIAL is not set - -# -# USB Miscellaneous drivers -# -# CONFIG_USB_RIO500 is not set -# CONFIG_USB_AUERSWALD is not set -# CONFIG_USB_TIGL is not set -# CONFIG_USB_BRLVGER is not set -# CONFIG_USB_LCD is not set - -# -# Library routines -# -CONFIG_ZLIB_INFLATE=y -# CONFIG_ZLIB_DEFLATE is not set - -# -# Bluetooth support -# -# CONFIG_BLUEZ is not set - -# -# Kernel hacking -# -# CONFIG_IA64_GRANULE_16MB is not set -CONFIG_IA64_GRANULE_64MB=y -CONFIG_DUMP=m -CONFIG_DUMP_COMPRESS_RLE=m -CONFIG_DUMP_COMPRESS_GZIP=m -CONFIG_DEBUG_KERNEL=y -# CONFIG_IA64_PRINT_HAZARDS is not set -# CONFIG_DISABLE_VHPT is not set -CONFIG_MAGIC_SYSRQ=y -CONFIG_IA64_EARLY_PRINTK=y -CONFIG_IA64_EARLY_PRINTK_UART=y -CONFIG_IA64_EARLY_PRINTK_UART_BASE=0 -# CONFIG_IA64_EARLY_PRINTK_VGA is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_IA64_DEBUG_CMPXCHG is not set -# CONFIG_IA64_DEBUG_IRQ is not set -CONFIG_KALLSYMS=y diff --git a/lustre/kernel_patches/kernel_configs/kernel-2.4.20-rh-2.4-i686-smp.config b/lustre/kernel_patches/kernel_configs/kernel-2.4.20-rh-2.4-i686-smp.config deleted file mode 100644 index 2a5d8da..0000000 --- a/lustre/kernel_patches/kernel_configs/kernel-2.4.20-rh-2.4-i686-smp.config +++ /dev/null @@ -1,1863 +0,0 @@ -# -# Automatically generated by make menuconfig: don't edit -# -CONFIG_X86=y -# CONFIG_SBUS is not set -CONFIG_UID16=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODVERSIONS=y -CONFIG_KMOD=y - -# -# Processor type and features -# -# CONFIG_LOLAT is not set -# CONFIG_M386 is not set -# CONFIG_M486 is not set -CONFIG_M586=y -# CONFIG_M586TSC is not set -# CONFIG_M586MMX is not set -# CONFIG_M686 is not set -# CONFIG_MPENTIUMIII is not set -# CONFIG_MPENTIUM4 is not set -# CONFIG_MK6 is not set -# CONFIG_MK7 is not set -# CONFIG_MELAN is not set -# CONFIG_MCRUSOE is not set -# CONFIG_MWINCHIPC6 is not set -# CONFIG_MWINCHIP2 is not set -# CONFIG_MWINCHIP3D is not set -# CONFIG_MCYRIXIII is not set -CONFIG_X86_WP_WORKS_OK=y -CONFIG_X86_INVLPG=y -CONFIG_X86_CMPXCHG=y -CONFIG_X86_XADD=y -CONFIG_X86_BSWAP=y -CONFIG_X86_POPAD_OK=y -# CONFIG_RWSEM_GENERIC_SPINLOCK is not set -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_X86_L1_CACHE_SHIFT=5 -CONFIG_X86_USE_STRING_486=y -CONFIG_X86_ALIGNMENT_16=y -CONFIG_X86_PPRO_FENCE=y -# CONFIG_X86_F00F_WORKS_OK is not set -CONFIG_X86_MCE=y - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set -CONFIG_TOSHIBA=m -CONFIG_I8K=m -CONFIG_MICROCODE=m -CONFIG_X86_MSR=m -CONFIG_X86_CPUID=m -# CONFIG_E820_PROC is not set -CONFIG_EDD=m -# CONFIG_NOHIGHMEM is not set -CONFIG_HIGHMEM4G=y -# CONFIG_HIGHMEM64G is not set -CONFIG_HIGHMEM=y -CONFIG_HIGHPTE=y -CONFIG_HIGHIO=y -# CONFIG_MATH_EMULATION is not set -CONFIG_MTRR=y -CONFIG_SMP=y -# CONFIG_X86_NUMA is not set -# CONFIG_X86_TSC_DISABLE is not set -CONFIG_HAVE_DEC_LOCK=y -# CONFIG_NOBIGSTACK is not set -CONFIG_STACK_SIZE_16KB=y -# CONFIG_STACK_SIZE_32KB is not set -# CONFIG_STACK_SIZE_64KB is not set -CONFIG_STACK_SIZE_SHIFT=2 - -# -# General setup -# -CONFIG_NET=y -CONFIG_X86_IO_APIC=y -CONFIG_X86_LOCAL_APIC=y -CONFIG_PCI=y -# CONFIG_PCI_GOBIOS is not set -# CONFIG_PCI_GODIRECT is not set -CONFIG_PCI_GOANY=y -CONFIG_PCI_BIOS=y -CONFIG_PCI_DIRECT=y -CONFIG_ISA=y -CONFIG_PCI_NAMES=y -CONFIG_EISA=y -# CONFIG_MCA is not set -CONFIG_HOTPLUG=y - -# -# PCMCIA/CardBus support -# -CONFIG_PCMCIA=m -CONFIG_CARDBUS=y -CONFIG_TCIC=y -CONFIG_I82092=y -CONFIG_I82365=y - -# -# PCI Hotplug Support -# -CONFIG_HOTPLUG_PCI=y -# CONFIG_HOTPLUG_PCI_ACPI is not set -CONFIG_HOTPLUG_PCI_COMPAQ=m -# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set -CONFIG_HOTPLUG_PCI_IBM=m -# CONFIG_HOTPLUG_PCI_H2999 is not set -CONFIG_SYSVIPC=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_SYSCTL=y -CONFIG_KCORE_ELF=y -# CONFIG_KCORE_AOUT is not set -CONFIG_BINFMT_AOUT=m -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=m -CONFIG_PM=y -# CONFIG_ACPI is not set -CONFIG_APM=y -# CONFIG_APM_IGNORE_USER_SUSPEND is not set -# CONFIG_APM_DO_ENABLE is not set -CONFIG_APM_CPU_IDLE=y -# CONFIG_APM_DISPLAY_BLANK is not set -CONFIG_APM_RTC_IS_GMT=y -# CONFIG_APM_ALLOW_INTS is not set -# CONFIG_APM_REAL_MODE_POWER_OFF is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -CONFIG_PARPORT=m -CONFIG_PARPORT_PC=m -CONFIG_PARPORT_PC_CML1=m -CONFIG_PARPORT_SERIAL=m -# CONFIG_PARPORT_PC_FIFO is not set -# CONFIG_PARPORT_PC_SUPERIO is not set -CONFIG_PARPORT_PC_PCMCIA=m -# CONFIG_PARPORT_AMIGA is not set -# CONFIG_PARPORT_MFC3 is not set -# CONFIG_PARPORT_ATARI is not set -# CONFIG_PARPORT_GSC is not set -# CONFIG_PARPORT_SUNBPP is not set -# CONFIG_PARPORT_OTHER is not set -CONFIG_PARPORT_1284=y - -# -# Plug and Play configuration -# -CONFIG_PNP=y -CONFIG_ISAPNP=y - -# -# Block devices -# -CONFIG_BLK_DEV_FD=y -CONFIG_BLK_DEV_XD=m -CONFIG_PARIDE=m -CONFIG_PARIDE_PARPORT=m -CONFIG_PARIDE_PD=m -CONFIG_PARIDE_PCD=m -CONFIG_PARIDE_PF=m -CONFIG_PARIDE_PT=m -CONFIG_PARIDE_PG=m -CONFIG_PARIDE_ATEN=m -CONFIG_PARIDE_BPCK=m -CONFIG_PARIDE_BPCK6=m -CONFIG_PARIDE_COMM=m -CONFIG_PARIDE_DSTR=m -CONFIG_PARIDE_FIT2=m -CONFIG_PARIDE_FIT3=m -CONFIG_PARIDE_EPAT=m -CONFIG_PARIDE_EPATC8=y -CONFIG_PARIDE_EPIA=m -CONFIG_PARIDE_FRIQ=m -CONFIG_PARIDE_FRPW=m -CONFIG_PARIDE_KBIC=m -CONFIG_PARIDE_KTTI=m -CONFIG_PARIDE_ON20=m -CONFIG_PARIDE_ON26=m -CONFIG_BLK_CPQ_DA=m -CONFIG_BLK_CPQ_CISS_DA=m -CONFIG_CISS_SCSI_TAPE=y -CONFIG_BLK_DEV_DAC960=m -CONFIG_BLK_DEV_UMEM=m -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_INITRD=y -CONFIG_BLK_STATS=y - -# -# Multi-device support (RAID and LVM) -# -CONFIG_MD=y -CONFIG_BLK_DEV_MD=y -CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID5=m -CONFIG_MD_MULTIPATH=m -CONFIG_BLK_DEV_LVM=m - -# -# Cryptography support (CryptoAPI) -# -CONFIG_CRYPTO=m -CONFIG_CIPHERS=m -CONFIG_CIPHER_AES=m -CONFIG_CIPHER_IDENTITY=m -CONFIG_CRYPTODEV=m -CONFIG_CRYPTOLOOP=m - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_NETLINK_DEV=y -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_FILTER=y -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_TUX=m -CONFIG_TUX_EXTCGI=y -# CONFIG_TUX_EXTENDED_LOG is not set -# CONFIG_TUX_DEBUG is not set -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_FWMARK=y -CONFIG_IP_ROUTE_NAT=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_TOS=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_ROUTE_LARGE_TABLES=y -# CONFIG_IP_PNP is not set -CONFIG_NET_IPIP=m -CONFIG_NET_IPGRE=m -CONFIG_NET_IPGRE_BROADCAST=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -# CONFIG_ARPD is not set -# CONFIG_INET_ECN is not set -CONFIG_SYN_COOKIES=y - -# -# IP: Netfilter Configuration -# -CONFIG_IP_NF_CONNTRACK=m -CONFIG_IP_NF_FTP=m -CONFIG_IP_NF_AMANDA=m -CONFIG_IP_NF_TFTP=m -CONFIG_IP_NF_IRC=m -CONFIG_IP_NF_QUEUE=m -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_LIMIT=m -CONFIG_IP_NF_MATCH_MAC=m -CONFIG_IP_NF_MATCH_PKTTYPE=m -CONFIG_IP_NF_MATCH_MARK=m -CONFIG_IP_NF_MATCH_MULTIPORT=m -CONFIG_IP_NF_MATCH_TOS=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_DSCP=m -CONFIG_IP_NF_MATCH_AH_ESP=m -CONFIG_IP_NF_MATCH_LENGTH=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_MATCH_TCPMSS=m -CONFIG_IP_NF_MATCH_HELPER=m -CONFIG_IP_NF_MATCH_STATE=m -CONFIG_IP_NF_MATCH_CONNTRACK=m -CONFIG_IP_NF_MATCH_UNCLEAN=m -CONFIG_IP_NF_MATCH_OWNER=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_MIRROR=m -CONFIG_IP_NF_NAT=m -CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_IP_NF_NAT_AMANDA=m -CONFIG_IP_NF_NAT_LOCAL=y -CONFIG_IP_NF_NAT_SNMP_BASIC=m -CONFIG_IP_NF_NAT_IRC=m -CONFIG_IP_NF_NAT_FTP=m -CONFIG_IP_NF_NAT_TFTP=m -CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_TOS=m -CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_TARGET_DSCP=m -CONFIG_IP_NF_TARGET_MARK=m -CONFIG_IP_NF_TARGET_LOG=m -CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_IP_NF_TARGET_TCPMSS=m -CONFIG_IP_NF_ARPTABLES=m -CONFIG_IP_NF_ARPFILTER=m -CONFIG_IP_NF_COMPAT_IPCHAINS=m -CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IP_NF_COMPAT_IPFWADM=m -CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IPV6=m - -# -# IPv6: Netfilter Configuration -# -# CONFIG_IP6_NF_QUEUE is not set -CONFIG_IP6_NF_IPTABLES=m -CONFIG_IP6_NF_MATCH_LIMIT=m -CONFIG_IP6_NF_MATCH_MAC=m -CONFIG_IP6_NF_MATCH_RT=m -CONFIG_IP6_NF_MATCH_OPTS=m -CONFIG_IP6_NF_MATCH_FRAG=m -CONFIG_IP6_NF_MATCH_HL=m -CONFIG_IP6_NF_MATCH_MULTIPORT=m -CONFIG_IP6_NF_MATCH_OWNER=m -CONFIG_IP6_NF_MATCH_MARK=m -CONFIG_IP6_NF_MATCH_IPV6HEADER=m -CONFIG_IP6_NF_MATCH_AHESP=m -CONFIG_IP6_NF_MATCH_LENGTH=m -CONFIG_IP6_NF_MATCH_EUI64=m -CONFIG_IP6_NF_FILTER=m -CONFIG_IP6_NF_TARGET_LOG=m -CONFIG_IP6_NF_MANGLE=m -CONFIG_IP6_NF_TARGET_MARK=m -# CONFIG_KHTTPD is not set -CONFIG_ATM=y -CONFIG_ATM_CLIP=y -# CONFIG_ATM_CLIP_NO_ICMP is not set -CONFIG_ATM_LANE=m -CONFIG_ATM_MPOA=m -CONFIG_ATM_BR2684=m -CONFIG_ATM_BR2684_IPFILTER=y -CONFIG_VLAN_8021Q=m -CONFIG_IPX=m -# CONFIG_IPX_INTERN is not set -CONFIG_ATALK=m - -# -# Appletalk devices -# -CONFIG_DEV_APPLETALK=y -CONFIG_LTPC=m -CONFIG_COPS=m -CONFIG_COPS_DAYNA=y -CONFIG_COPS_TANGENT=y -CONFIG_IPDDP=m -CONFIG_IPDDP_ENCAP=y -CONFIG_IPDDP_DECAP=y -CONFIG_DECNET=m -CONFIG_DECNET_SIOCGIFCONF=y -CONFIG_DECNET_ROUTER=y -CONFIG_DECNET_ROUTE_FWMARK=y -CONFIG_BRIDGE=m -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_LLC is not set -CONFIG_NET_DIVERT=y -# CONFIG_ECONET is not set -CONFIG_WAN_ROUTER=m -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set - -# -# QoS and/or fair queueing -# -CONFIG_NET_SCHED=y -CONFIG_NET_SCH_CBQ=m -CONFIG_NET_SCH_HTB=m -CONFIG_NET_SCH_CSZ=m -# CONFIG_NET_SCH_ATM is not set -CONFIG_NET_SCH_PRIO=m -CONFIG_NET_SCH_RED=m -CONFIG_NET_SCH_SFQ=m -CONFIG_NET_SCH_TEQL=m -CONFIG_NET_SCH_TBF=m -CONFIG_NET_SCH_GRED=m -CONFIG_NET_SCH_DSMARK=m -CONFIG_NET_SCH_INGRESS=m -CONFIG_NET_QOS=y -CONFIG_NET_ESTIMATOR=y -CONFIG_NET_CLS=y -CONFIG_NET_CLS_TCINDEX=m -CONFIG_NET_CLS_ROUTE4=m -CONFIG_NET_CLS_ROUTE=y -CONFIG_NET_CLS_FW=m -CONFIG_NET_CLS_U32=m -CONFIG_NET_CLS_RSVP=m -CONFIG_NET_CLS_RSVP6=m -CONFIG_NET_CLS_POLICE=y - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set - -# -# Telephony Support -# -CONFIG_PHONE=m -CONFIG_PHONE_IXJ=m -CONFIG_PHONE_IXJ_PCMCIA=m - -# -# ATA/IDE/MFM/RLL support -# -CONFIG_IDE=y - -# -# IDE, ATA and ATAPI Block devices -# -CONFIG_BLK_DEV_IDE=y -# CONFIG_BLK_DEV_HD_IDE is not set -# CONFIG_BLK_DEV_HD is not set -CONFIG_BLK_DEV_IDEDISK=y -CONFIG_IDEDISK_MULTI_MODE=y -# CONFIG_IDEDISK_STROKE is not set -CONFIG_BLK_DEV_IDECS=m -CONFIG_BLK_DEV_IDECD=m -CONFIG_BLK_DEV_IDETAPE=m -CONFIG_BLK_DEV_IDEFLOPPY=y -CONFIG_BLK_DEV_IDESCSI=m -# CONFIG_IDE_TASK_IOCTL is not set -CONFIG_BLK_DEV_CMD640=y -# CONFIG_BLK_DEV_CMD640_ENHANCED is not set -CONFIG_BLK_DEV_ISAPNP=y -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_BLK_DEV_GENERIC=y -CONFIG_IDEPCI_SHARE_IRQ=y -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_OFFBOARD is not set -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y -# CONFIG_IDEDMA_ONLYDISK is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_PCI_WIP is not set -CONFIG_BLK_DEV_ADMA100=y -CONFIG_BLK_DEV_AEC62XX=y -CONFIG_BLK_DEV_ALI15X3=y -# CONFIG_WDC_ALI15X3 is not set -CONFIG_BLK_DEV_AMD74XX=y -# CONFIG_AMD74XX_OVERRIDE is not set -CONFIG_BLK_DEV_CMD64X=y -CONFIG_BLK_DEV_TRIFLEX=y -CONFIG_BLK_DEV_CY82C693=y -CONFIG_BLK_DEV_CS5530=y -CONFIG_BLK_DEV_HPT34X=y -# CONFIG_HPT34X_AUTODMA is not set -CONFIG_BLK_DEV_HPT366=y -CONFIG_BLK_DEV_PIIX=y -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_OPTI621 is not set -CONFIG_BLK_DEV_PDC202XX_OLD=y -# CONFIG_PDC202XX_BURST is not set -CONFIG_BLK_DEV_PDC202XX_NEW=y -CONFIG_PDC202XX_FORCE=y -CONFIG_BLK_DEV_RZ1000=y -# CONFIG_BLK_DEV_SC1200 is not set -CONFIG_BLK_DEV_SVWKS=y -CONFIG_BLK_DEV_SIIMAGE=y -CONFIG_BLK_DEV_SIS5513=y -CONFIG_BLK_DEV_SLC90E66=y -# CONFIG_BLK_DEV_TRM290 is not set -CONFIG_BLK_DEV_VIA82CXXX=y -# CONFIG_IDE_CHIPSETS is not set -CONFIG_IDEDMA_AUTO=y -# CONFIG_IDEDMA_IVB is not set -# CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_PDC202XX=y -CONFIG_BLK_DEV_IDE_MODES=y -CONFIG_BLK_DEV_ATARAID=m -CONFIG_BLK_DEV_ATARAID_PDC=m -CONFIG_BLK_DEV_ATARAID_HPT=m -CONFIG_BLK_DEV_ATARAID_SII=m - -# -# SCSI support -# -CONFIG_SCSI=m -CONFIG_BLK_DEV_SD=m -CONFIG_SD_EXTRA_DEVS=40 -CONFIG_CHR_DEV_ST=m -CONFIG_CHR_DEV_OSST=m -CONFIG_BLK_DEV_SR=m -CONFIG_BLK_DEV_SR_VENDOR=y -CONFIG_SR_EXTRA_DEVS=4 -CONFIG_CHR_DEV_SG=m -# CONFIG_SCSI_DEBUG_QUEUES is not set -# CONFIG_SCSI_MULTI_LUN is not set -CONFIG_SCSI_CONSTANTS=y -CONFIG_SCSI_LOGGING=y - -# -# SCSI low-level drivers -# -CONFIG_BLK_DEV_3W_XXXX_RAID=m -CONFIG_SCSI_7000FASST=m -CONFIG_SCSI_ACARD=m -CONFIG_SCSI_AHA152X=m -CONFIG_SCSI_AHA1542=m -CONFIG_SCSI_AHA1740=m -CONFIG_SCSI_AACRAID=m -CONFIG_SCSI_AIC7XXX=m -CONFIG_AIC7XXX_CMDS_PER_DEVICE=253 -CONFIG_AIC7XXX_RESET_DELAY_MS=15000 -# CONFIG_AIC7XXX_PROBE_EISA_VL is not set -# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set -CONFIG_SCSI_AIC79XX=m -CONFIG_AIC79XX_CMDS_PER_DEVICE=253 -CONFIG_AIC79XX_RESET_DELAY_MS=15000 -# CONFIG_AIC79XX_BUILD_FIRMWARE is not set -CONFIG_AIC79XX_ENABLE_RD_STRM=y -# CONFIG_AIC79XX_DEBUG_ENABLE is not set -CONFIG_AIC79XX_DEBUG_MASK=0 -CONFIG_SCSI_AIC7XXX_OLD=m -CONFIG_AIC7XXX_OLD_TCQ_ON_BY_DEFAULT=y -CONFIG_AIC7XXX_OLD_CMDS_PER_DEVICE=32 -CONFIG_AIC7XXX_OLD_PROC_STATS=y -CONFIG_SCSI_DPT_I2O=m -CONFIG_SCSI_ADVANSYS=m -CONFIG_SCSI_IN2000=m -CONFIG_SCSI_AM53C974=m -CONFIG_SCSI_MEGARAID=m -CONFIG_SCSI_BUSLOGIC=m -# CONFIG_SCSI_OMIT_FLASHPOINT is not set -CONFIG_SCSI_CPQFCTS=m -CONFIG_SCSI_DMX3191D=m -CONFIG_SCSI_DTC3280=m -CONFIG_SCSI_EATA=m -CONFIG_SCSI_EATA_TAGGED_QUEUE=y -# CONFIG_SCSI_EATA_LINKED_COMMANDS is not set -CONFIG_SCSI_EATA_MAX_TAGS=16 -CONFIG_SCSI_EATA_DMA=m -CONFIG_SCSI_EATA_PIO=m -CONFIG_SCSI_FUTURE_DOMAIN=m -CONFIG_SCSI_GDTH=m -CONFIG_SCSI_GENERIC_NCR5380=m -# CONFIG_SCSI_GENERIC_NCR53C400 is not set -CONFIG_SCSI_G_NCR5380_PORT=y -# CONFIG_SCSI_G_NCR5380_MEM is not set -CONFIG_SCSI_IPS=m -CONFIG_SCSI_INITIO=m -CONFIG_SCSI_INIA100=m -CONFIG_SCSI_PPA=m -CONFIG_SCSI_IMM=m -# CONFIG_SCSI_IZIP_EPP16 is not set -# CONFIG_SCSI_IZIP_SLOW_CTR is not set -CONFIG_SCSI_NCR53C406A=m -CONFIG_SCSI_NCR53C7xx=m -# CONFIG_SCSI_NCR53C7xx_sync is not set -CONFIG_SCSI_NCR53C7xx_FAST=y -CONFIG_SCSI_NCR53C7xx_DISCONNECT=y -CONFIG_SCSI_SYM53C8XX_2=m -CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 -CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 -CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 -# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set -CONFIG_SCSI_NCR53C8XX=m -CONFIG_SCSI_SYM53C8XX=m -CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 -CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 -CONFIG_SCSI_NCR53C8XX_SYNC=40 -# CONFIG_SCSI_NCR53C8XX_PROFILE is not set -# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set -# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set -# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set -CONFIG_SCSI_PAS16=m -CONFIG_SCSI_PCI2000=m -CONFIG_SCSI_PCI2220I=m -CONFIG_SCSI_PSI240I=m -CONFIG_SCSI_QLOGIC_FAS=m -CONFIG_SCSI_QLOGIC_ISP=m -CONFIG_SCSI_QLOGIC_FC=m -# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set -CONFIG_SCSI_QLOGIC_1280=m -CONFIG_SCSI_NEWISP=m -CONFIG_SCSI_SEAGATE=m -CONFIG_SCSI_SIM710=m -CONFIG_SCSI_SYM53C416=m -CONFIG_SCSI_DC390T=m -# CONFIG_SCSI_DC390T_NOGENSUPP is not set -CONFIG_SCSI_T128=m -CONFIG_SCSI_U14_34F=m -# CONFIG_SCSI_U14_34F_LINKED_COMMANDS is not set -CONFIG_SCSI_U14_34F_MAX_TAGS=8 -CONFIG_SCSI_ULTRASTOR=m -CONFIG_SCSI_NSP32=m -CONFIG_SCSI_DEBUG=m - -# -# PCMCIA SCSI adapter support -# -CONFIG_SCSI_PCMCIA=y -CONFIG_PCMCIA_AHA152X=m -CONFIG_PCMCIA_FDOMAIN=m -CONFIG_PCMCIA_NINJA_SCSI=m -CONFIG_PCMCIA_QLOGIC=m - -# -# Fusion MPT device support -# -CONFIG_FUSION=m -# CONFIG_FUSION_BOOT is not set -CONFIG_FUSION_MAX_SGE=40 -# CONFIG_FUSION_ISENSE is not set -CONFIG_FUSION_CTL=m -CONFIG_FUSION_LAN=m -CONFIG_NET_FC=y - -# -# IEEE 1394 (FireWire) support (EXPERIMENTAL) -# -CONFIG_IEEE1394=m -# CONFIG_IEEE1394_PCILYNX is not set -CONFIG_IEEE1394_OHCI1394=m -CONFIG_IEEE1394_VIDEO1394=m -CONFIG_IEEE1394_SBP2=m -CONFIG_IEEE1394_SBP2_PHYS_DMA=y -CONFIG_IEEE1394_ETH1394=m -CONFIG_IEEE1394_DV1394=m -CONFIG_IEEE1394_RAWIO=m -CONFIG_IEEE1394_CMP=m -CONFIG_IEEE1394_AMDTP=m -# CONFIG_IEEE1394_VERBOSEDEBUG is not set - -# -# I2O device support -# -CONFIG_I2O=m -CONFIG_I2O_PCI=m -CONFIG_I2O_BLOCK=m -CONFIG_I2O_LAN=m -CONFIG_I2O_SCSI=m -CONFIG_I2O_PROC=m - -# -# Network device support -# -CONFIG_NETDEVICES=y - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set -CONFIG_DUMMY=m -CONFIG_BONDING=m -CONFIG_EQUALIZER=m -CONFIG_TUN=m -CONFIG_ETHERTAP=m -CONFIG_NET_SB1000=m - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -# CONFIG_SUNLANCE is not set -CONFIG_HAPPYMEAL=m -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -CONFIG_SUNGEM=m -CONFIG_NET_VENDOR_3COM=y -CONFIG_EL1=m -CONFIG_EL2=m -CONFIG_ELPLUS=m -CONFIG_EL16=m -CONFIG_EL3=m -CONFIG_3C515=m -# CONFIG_ELMC is not set -# CONFIG_ELMC_II is not set -CONFIG_VORTEX=m -CONFIG_TYPHOON=m -CONFIG_LANCE=m -CONFIG_NET_VENDOR_SMC=y -CONFIG_WD80x3=m -# CONFIG_ULTRAMCA is not set -CONFIG_ULTRA=m -CONFIG_ULTRA32=m -CONFIG_SMC9194=m -CONFIG_NET_VENDOR_RACAL=y -CONFIG_NI5010=m -CONFIG_NI52=m -CONFIG_NI65=m -CONFIG_AT1700=m -CONFIG_DEPCA=m -CONFIG_HP100=m -CONFIG_NET_ISA=y -CONFIG_E2100=m -# CONFIG_EWRK3 is not set -CONFIG_EEXPRESS=m -CONFIG_EEXPRESS_PRO=m -CONFIG_HPLAN_PLUS=m -CONFIG_HPLAN=m -CONFIG_LP486E=m -CONFIG_ETH16I=m -CONFIG_NE2000=m -CONFIG_NET_PCI=y -CONFIG_PCNET32=m -CONFIG_AMD8111_ETH=m -CONFIG_ADAPTEC_STARFIRE=m -CONFIG_AC3200=m -CONFIG_APRICOT=m -CONFIG_CS89x0=m -CONFIG_TULIP=m -# CONFIG_TULIP_MWI is not set -CONFIG_TULIP_MMIO=y -CONFIG_DE4X5=m -CONFIG_DGRS=m -CONFIG_DM9102=m -CONFIG_EEPRO100=m -# CONFIG_EEPRO100_PIO is not set -CONFIG_E100=m -CONFIG_LNE390=m -CONFIG_FEALNX=m -CONFIG_NATSEMI=m -CONFIG_NE2K_PCI=m -CONFIG_NE3210=m -CONFIG_ES3210=m -CONFIG_8139CP=m -CONFIG_8139TOO=m -# CONFIG_8139TOO_PIO is not set -# CONFIG_8139TOO_TUNE_TWISTER is not set -CONFIG_8139TOO_8129=y -# CONFIG_8139_OLD_RX_RESET is not set -CONFIG_SIS900=m -CONFIG_EPIC100=m -CONFIG_SUNDANCE=m -# CONFIG_SUNDANCE_MMIO is not set -CONFIG_TLAN=m -CONFIG_TC35815=m -CONFIG_VIA_RHINE=m -# CONFIG_VIA_RHINE_MMIO is not set -CONFIG_WINBOND_840=m -CONFIG_NET_POCKET=y -CONFIG_ATP=m -CONFIG_DE600=m -CONFIG_DE620=m - -# -# Ethernet (1000 Mbit) -# -CONFIG_ACENIC=m -# CONFIG_ACENIC_OMIT_TIGON_I is not set -CONFIG_DL2K=m -CONFIG_E1000=m -# CONFIG_MYRI_SBUS is not set -CONFIG_NS83820=m -CONFIG_HAMACHI=m -CONFIG_YELLOWFIN=m -CONFIG_R8169=m -CONFIG_SK98LIN=m -CONFIG_TIGON3=m -CONFIG_FDDI=y -CONFIG_DEFXX=m -CONFIG_SKFP=m -CONFIG_NETCONSOLE=m -# CONFIG_HIPPI is not set -CONFIG_PLIP=m -CONFIG_PPP=m -CONFIG_PPP_MULTILINK=y -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m -# CONFIG_PPP_BSDCOMP is not set -CONFIG_PPPOE=m -CONFIG_PPPOATM=m -CONFIG_SLIP=m -CONFIG_SLIP_COMPRESSED=y -CONFIG_SLIP_SMART=y -CONFIG_SLIP_MODE_SLIP6=y - -# -# Wireless LAN (non-hamradio) -# -CONFIG_NET_RADIO=y -CONFIG_STRIP=m -CONFIG_WAVELAN=m -CONFIG_ARLAN=m -CONFIG_AIRONET4500=m -CONFIG_AIRONET4500_NONCS=m -CONFIG_AIRONET4500_PNP=y -CONFIG_AIRONET4500_PCI=y -CONFIG_AIRONET4500_ISA=y -CONFIG_AIRONET4500_I365=y -CONFIG_AIRONET4500_PROC=m -CONFIG_AIRO=m -CONFIG_HERMES=m -CONFIG_PLX_HERMES=m -CONFIG_PCI_HERMES=m -CONFIG_PCMCIA_HERMES=m -CONFIG_AIRO_CS=m -CONFIG_NET_WIRELESS=y -CONFIG_PCMCIA_HERMES_OLD=m - -# -# Token Ring devices -# -CONFIG_TR=y -CONFIG_IBMTR=m -CONFIG_IBMOL=m -CONFIG_IBMLS=m -CONFIG_3C359=m -CONFIG_TMS380TR=m -CONFIG_TMSPCI=m -CONFIG_TMSISA=m -CONFIG_ABYSS=m -# CONFIG_MADGEMC is not set -CONFIG_SMCTR=m -CONFIG_NET_FC=y -CONFIG_IPHASE5526=m -CONFIG_RCPCI=m -CONFIG_SHAPER=m - -# -# Wan interfaces -# -CONFIG_WAN=y -CONFIG_HOSTESS_SV11=m -CONFIG_COSA=m -# CONFIG_COMX is not set -# CONFIG_DSCC4 is not set -# CONFIG_LANMEDIA is not set -CONFIG_ATI_XX20=m -CONFIG_SEALEVEL_4021=m -# CONFIG_SYNCLINK_SYNCPPP is not set -# CONFIG_HDLC is not set -CONFIG_DLCI=m -CONFIG_DLCI_COUNT=24 -CONFIG_DLCI_MAX=8 -CONFIG_SDLA=m -CONFIG_WAN_ROUTER_DRIVERS=y -CONFIG_VENDOR_SANGOMA=m -CONFIG_WANPIPE_CHDLC=y -CONFIG_WANPIPE_FR=y -CONFIG_WANPIPE_X25=y -CONFIG_WANPIPE_PPP=y -CONFIG_WANPIPE_MULTPPP=y -CONFIG_CYCLADES_SYNC=m -CONFIG_CYCLOMX_X25=y -# CONFIG_LAPBETHER is not set -# CONFIG_X25_ASY is not set -CONFIG_SBNI=m -CONFIG_SBNI_MULTILINE=y - -# -# PCMCIA network device support -# -CONFIG_NET_PCMCIA=y -CONFIG_PCMCIA_3C589=m -CONFIG_PCMCIA_3C574=m -CONFIG_PCMCIA_FMVJ18X=m -CONFIG_PCMCIA_PCNET=m -CONFIG_PCMCIA_AXNET=m -CONFIG_PCMCIA_NMCLAN=m -CONFIG_PCMCIA_SMC91C92=m -CONFIG_PCMCIA_XIRC2PS=m -# CONFIG_ARCNET_COM20020_CS is not set -CONFIG_PCMCIA_IBMTR=m -CONFIG_PCMCIA_XIRCOM=m -CONFIG_PCMCIA_XIRTULIP=m -CONFIG_NET_PCMCIA_RADIO=y -CONFIG_PCMCIA_RAYCS=m -CONFIG_PCMCIA_NETWAVE=m -CONFIG_PCMCIA_WAVELAN=m -CONFIG_PCMCIA_WVLAN=m -CONFIG_AIRONET4500_CS=m - -# -# ATM drivers -# -CONFIG_ATM_TCP=m -CONFIG_ATM_LANAI=m -CONFIG_ATM_ENI=m -# CONFIG_ATM_ENI_DEBUG is not set -# CONFIG_ATM_ENI_TUNE_BURST is not set -CONFIG_ATM_FIRESTREAM=m -CONFIG_ATM_ZATM=m -# CONFIG_ATM_ZATM_DEBUG is not set -CONFIG_ATM_ZATM_EXACT_TS=y -CONFIG_ATM_NICSTAR=m -CONFIG_ATM_NICSTAR_USE_SUNI=y -CONFIG_ATM_NICSTAR_USE_IDT77105=y -CONFIG_ATM_IDT77252=m -# CONFIG_ATM_IDT77252_DEBUG is not set -# CONFIG_ATM_IDT77252_RCV_ALL is not set -CONFIG_ATM_IDT77252_USE_SUNI=y -CONFIG_ATM_AMBASSADOR=m -# CONFIG_ATM_AMBASSADOR_DEBUG is not set -CONFIG_ATM_HORIZON=m -# CONFIG_ATM_HORIZON_DEBUG is not set -CONFIG_ATM_IA=m -# CONFIG_ATM_IA_DEBUG is not set -CONFIG_ATM_FORE200E_MAYBE=m -CONFIG_ATM_FORE200E_PCA=y -CONFIG_ATM_FORE200E_PCA_DEFAULT_FW=y -CONFIG_ATM_FORE200E_TX_RETRY=16 -CONFIG_ATM_FORE200E_DEBUG=0 -CONFIG_ATM_FORE200E=m - -# -# Amateur Radio support -# -CONFIG_HAMRADIO=y -CONFIG_AX25=m -# CONFIG_AX25_DAMA_SLAVE is not set -CONFIG_NETROM=m -CONFIG_ROSE=m - -# -# AX.25 network device drivers -# -# CONFIG_MKISS is not set -# CONFIG_6PACK is not set -# CONFIG_BPQETHER is not set -# CONFIG_DMASCC is not set -# CONFIG_SCC is not set -# CONFIG_BAYCOM_SER_FDX is not set -# CONFIG_BAYCOM_SER_HDX is not set -# CONFIG_BAYCOM_PAR is not set -# CONFIG_BAYCOM_EPP is not set -CONFIG_SOUNDMODEM=m -CONFIG_SOUNDMODEM_SBC=y -CONFIG_SOUNDMODEM_WSS=y -CONFIG_SOUNDMODEM_AFSK1200=y -CONFIG_SOUNDMODEM_AFSK2400_7=y -CONFIG_SOUNDMODEM_AFSK2400_8=y -CONFIG_SOUNDMODEM_AFSK2666=y -CONFIG_SOUNDMODEM_HAPN4800=y -CONFIG_SOUNDMODEM_PSK4800=y -CONFIG_SOUNDMODEM_FSK9600=y -# CONFIG_YAM is not set - -# -# IrDA (infrared) support -# -CONFIG_IRDA=m -CONFIG_IRLAN=m -CONFIG_IRNET=m -CONFIG_IRCOMM=m -CONFIG_IRDA_ULTRA=y -CONFIG_IRDA_CACHE_LAST_LSAP=y -CONFIG_IRDA_FAST_RR=y -# CONFIG_IRDA_DEBUG is not set - -# -# Infrared-port device drivers -# -CONFIG_IRTTY_SIR=m -CONFIG_IRPORT_SIR=m -CONFIG_DONGLE=y -CONFIG_ESI_DONGLE=m -CONFIG_ACTISYS_DONGLE=m -CONFIG_TEKRAM_DONGLE=m -CONFIG_GIRBIL_DONGLE=m -CONFIG_LITELINK_DONGLE=m -CONFIG_MCP2120_DONGLE=m -CONFIG_OLD_BELKIN_DONGLE=m -CONFIG_ACT200L_DONGLE=m -CONFIG_MA600_DONGLE=m -CONFIG_USB_IRDA=m -CONFIG_NSC_FIR=m -CONFIG_WINBOND_FIR=m -CONFIG_TOSHIBA_OLD=m -CONFIG_TOSHIBA_FIR=m -CONFIG_SMC_IRCC_FIR=m -CONFIG_ALI_FIR=m -CONFIG_VLSI_FIR=m - -# -# ISDN subsystem -# -CONFIG_ISDN=m -CONFIG_ISDN_BOOL=y -CONFIG_ISDN_PPP=y -CONFIG_ISDN_PPP_VJ=y -CONFIG_ISDN_MPP=y -CONFIG_ISDN_PPP_BSDCOMP=m -CONFIG_ISDN_AUDIO=y -CONFIG_ISDN_TTY_FAX=y - -# -# ISDN feature submodules -# -CONFIG_ISDN_DRV_LOOP=m -# CONFIG_ISDN_DIVERSION is not set - -# -# Passive ISDN cards -# -CONFIG_ISDN_DRV_HISAX=m -CONFIG_ISDN_HISAX=y -CONFIG_HISAX_EURO=y -CONFIG_DE_AOC=y -# CONFIG_HISAX_NO_SENDCOMPLETE is not set -# CONFIG_HISAX_NO_LLC is not set -# CONFIG_HISAX_NO_KEYPAD is not set -CONFIG_HISAX_1TR6=y -CONFIG_HISAX_NI1=y -CONFIG_HISAX_MAX_CARDS=8 -CONFIG_HISAX_16_0=y -CONFIG_HISAX_16_3=y -CONFIG_HISAX_AVM_A1=y -CONFIG_HISAX_IX1MICROR2=y -CONFIG_HISAX_ASUSCOM=y -CONFIG_HISAX_TELEINT=y -CONFIG_HISAX_HFCS=y -CONFIG_HISAX_SPORTSTER=y -CONFIG_HISAX_MIC=y -CONFIG_HISAX_ISURF=y -CONFIG_HISAX_HSTSAPHIR=y -CONFIG_HISAX_TELESPCI=y -CONFIG_HISAX_S0BOX=y -CONFIG_HISAX_FRITZPCI=y -CONFIG_HISAX_AVM_A1_PCMCIA=y -CONFIG_HISAX_ELSA=y -CONFIG_HISAX_DIEHLDIVA=y -CONFIG_HISAX_SEDLBAUER=y -CONFIG_HISAX_NETJET=y -CONFIG_HISAX_NETJET_U=y -CONFIG_HISAX_NICCY=y -CONFIG_HISAX_BKM_A4T=y -CONFIG_HISAX_SCT_QUADRO=y -CONFIG_HISAX_GAZEL=y -CONFIG_HISAX_HFC_PCI=y -CONFIG_HISAX_W6692=y -CONFIG_HISAX_HFC_SX=y -CONFIG_HISAX_ENTERNOW_PCI=y -CONFIG_HISAX_DEBUG=y -CONFIG_HISAX_SEDLBAUER_CS=m -CONFIG_HISAX_ELSA_CS=m -CONFIG_HISAX_AVM_A1_CS=m -CONFIG_HISAX_ST5481=m -CONFIG_HISAX_FRITZ_PCIPNP=m -CONFIG_USB_AUERISDN=m - -# -# Active ISDN cards -# -CONFIG_ISDN_DRV_ICN=m -CONFIG_ISDN_DRV_PCBIT=m -# CONFIG_ISDN_DRV_SC is not set -# CONFIG_ISDN_DRV_ACT2000 is not set -CONFIG_ISDN_DRV_EICON=y -CONFIG_ISDN_DRV_EICON_DIVAS=m -# CONFIG_ISDN_DRV_EICON_OLD is not set -CONFIG_ISDN_DRV_TPAM=m -CONFIG_ISDN_CAPI=m -CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y -CONFIG_ISDN_CAPI_MIDDLEWARE=y -CONFIG_ISDN_CAPI_CAPI20=m -CONFIG_ISDN_CAPI_CAPIFS_BOOL=y -CONFIG_ISDN_CAPI_CAPIFS=m -CONFIG_ISDN_CAPI_CAPIDRV=m -CONFIG_ISDN_DRV_AVMB1_B1ISA=m -CONFIG_ISDN_DRV_AVMB1_B1PCI=m -CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y -CONFIG_ISDN_DRV_AVMB1_T1ISA=m -CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m -CONFIG_ISDN_DRV_AVMB1_AVM_CS=m -CONFIG_ISDN_DRV_AVMB1_T1PCI=m -CONFIG_ISDN_DRV_AVMB1_C4=m -CONFIG_HYSDN=m -CONFIG_HYSDN_CAPI=y -CONFIG_KALLSYMS=y - -# -# Old CD-ROM drivers (not SCSI, not IDE) -# -# CONFIG_CD_NO_IDESCSI is not set - -# -# Input core support -# -CONFIG_INPUT=m -CONFIG_INPUT_KEYBDEV=m -CONFIG_INPUT_MOUSEDEV=m -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -CONFIG_INPUT_JOYDEV=m -CONFIG_INPUT_EVDEV=m - -# -# Character devices -# -CONFIG_VT=y -CONFIG_ECC=m -CONFIG_VT_CONSOLE=y -CONFIG_SERIAL=y -CONFIG_SERIAL_CONSOLE=y -CONFIG_SERIAL_EXTENDED=y -CONFIG_SERIAL_MANY_PORTS=y -CONFIG_SERIAL_SHARE_IRQ=y -# CONFIG_SERIAL_DETECT_IRQ is not set -CONFIG_SERIAL_MULTIPORT=y -# CONFIG_HUB6 is not set -CONFIG_SERIAL_NONSTANDARD=y -CONFIG_COMPUTONE=m -CONFIG_ROCKETPORT=m -CONFIG_CYCLADES=m -# CONFIG_CYZ_INTR is not set -CONFIG_DIGIEPCA=m -CONFIG_ESPSERIAL=m -CONFIG_MOXA_INTELLIO=m -CONFIG_MOXA_SMARTIO=m -CONFIG_ISI=m -CONFIG_SYNCLINK=m -# CONFIG_SYNCLINKMP is not set -CONFIG_N_HDLC=m -CONFIG_RISCOM8=m -CONFIG_SPECIALIX=m -CONFIG_SPECIALIX_RTSCTS=y -CONFIG_SX=m -# CONFIG_RIO is not set -CONFIG_STALDRV=y -CONFIG_STALLION=m -CONFIG_ISTALLION=m -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=2048 -CONFIG_PRINTER=m -CONFIG_LP_CONSOLE=y -CONFIG_PPDEV=m -CONFIG_TIPAR=m - -# -# I2C support -# -CONFIG_I2C=m -CONFIG_I2C_ALGOBIT=m -CONFIG_I2C_PHILIPSPAR=m -CONFIG_I2C_ELV=m -CONFIG_I2C_VELLEMAN=m -# CONFIG_SCx200_I2C is not set -# CONFIG_SCx200_ACB is not set -CONFIG_I2C_ALGOPCF=m -CONFIG_I2C_ELEKTOR=m -CONFIG_I2C_MAINBOARD=y -CONFIG_I2C_ALI1535=m -CONFIG_I2C_ALI15X3=m -CONFIG_I2C_HYDRA=m -CONFIG_I2C_AMD756=m -# CONFIG_I2C_TSUNAMI is not set -CONFIG_I2C_I801=m -# CONFIG_I2C_I810 is not set -CONFIG_I2C_PIIX4=m -CONFIG_I2C_SIS5595=m -CONFIG_I2C_VIA=m -CONFIG_I2C_VIAPRO=m -CONFIG_I2C_VOODOO3=m -CONFIG_I2C_ISA=m -CONFIG_I2C_CHARDEV=m -CONFIG_I2C_PROC=m - -# -# Hardware sensors support -# -CONFIG_SENSORS=y -CONFIG_SENSORS_ADM1021=m -CONFIG_SENSORS_ADM1024=m -CONFIG_SENSORS_ADM1025=m -CONFIG_SENSORS_ADM9240=m -CONFIG_SENSORS_DS1621=m -CONFIG_SENSORS_FSCPOS=m -CONFIG_SENSORS_FSCSCY=m -CONFIG_SENSORS_GL518SM=m -CONFIG_SENSORS_GL520SM=m -CONFIG_SENSORS_MAXILIFE=m -CONFIG_SENSORS_IT87=m -CONFIG_SENSORS_MTP008=m -CONFIG_SENSORS_LM75=m -CONFIG_SENSORS_LM78=m -CONFIG_SENSORS_LM80=m -CONFIG_SENSORS_LM87=m -CONFIG_SENSORS_LM92=m -CONFIG_SENSORS_SIS5595=m -CONFIG_SENSORS_SMSC47M1=m -CONFIG_SENSORS_THMC50=m -CONFIG_SENSORS_VIA686A=m -CONFIG_SENSORS_VT1211=m -CONFIG_SENSORS_VT8231=m -CONFIG_SENSORS_W83781D=m -CONFIG_SENSORS_OTHER=y -CONFIG_SENSORS_BT869=m -CONFIG_SENSORS_DDCMON=m -CONFIG_SENSORS_EEPROM=m -CONFIG_SENSORS_MATORB=m -CONFIG_SENSORS_PCF8574=m -CONFIG_SENSORS_PCF8591=m - -# -# Mice -# -CONFIG_BUSMOUSE=m -CONFIG_ATIXL_BUSMOUSE=m -CONFIG_LOGIBUSMOUSE=m -CONFIG_MS_BUSMOUSE=m -CONFIG_MOUSE=y -CONFIG_PSMOUSE=y -CONFIG_82C710_MOUSE=m -CONFIG_PC110_PAD=m -CONFIG_MK712_MOUSE=m - -# -# Joysticks -# -CONFIG_INPUT_GAMEPORT=m -CONFIG_INPUT_NS558=m -CONFIG_INPUT_LIGHTNING=m -CONFIG_INPUT_PCIGAME=m -CONFIG_INPUT_CS461X=m -CONFIG_INPUT_EMU10K1=m -CONFIG_INPUT_SERIO=m -CONFIG_INPUT_SERPORT=m -CONFIG_INPUT_ANALOG=m -CONFIG_INPUT_A3D=m -CONFIG_INPUT_ADI=m -CONFIG_INPUT_COBRA=m -CONFIG_INPUT_GF2K=m -CONFIG_INPUT_GRIP=m -CONFIG_INPUT_INTERACT=m -CONFIG_INPUT_TMDC=m -CONFIG_INPUT_SIDEWINDER=m -CONFIG_INPUT_IFORCE_USB=m -CONFIG_INPUT_IFORCE_232=m -CONFIG_INPUT_WARRIOR=m -CONFIG_INPUT_MAGELLAN=m -CONFIG_INPUT_SPACEORB=m -CONFIG_INPUT_SPACEBALL=m -CONFIG_INPUT_STINGER=m -CONFIG_INPUT_DB9=m -CONFIG_INPUT_GAMECON=m -CONFIG_INPUT_TURBOGRAFX=m -# CONFIG_QIC02_TAPE is not set -CONFIG_IPMI_HANDLER=m -# CONFIG_IPMI_PANIC_EVENT is not set -CONFIG_IPMI_DEVICE_INTERFACE=m -CONFIG_IPMI_KCS=m -CONFIG_IPMI_WATCHDOG=m - -# -# Watchdog Cards -# -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set -CONFIG_ACQUIRE_WDT=m -CONFIG_ADVANTECH_WDT=m -CONFIG_ALIM7101_WDT=m -CONFIG_SC520_WDT=m -CONFIG_PCWATCHDOG=m -CONFIG_EUROTECH_WDT=m -CONFIG_IB700_WDT=m -CONFIG_WAFER_WDT=m -CONFIG_I810_TCO=m -# CONFIG_MIXCOMWD is not set -# CONFIG_60XX_WDT is not set -CONFIG_SC1200_WDT=m -# CONFIG_SCx200_WDT is not set -CONFIG_SOFT_WATCHDOG=m -CONFIG_W83877F_WDT=m -CONFIG_WDT=m -CONFIG_WDTPCI=m -# CONFIG_WDT_501 is not set -CONFIG_MACHZ_WDT=m -CONFIG_AMD7XX_TCO=m -# CONFIG_SCx200_GPIO is not set -CONFIG_AMD_RNG=m -CONFIG_INTEL_RNG=m -CONFIG_AMD_PM768=m -CONFIG_NVRAM=m -CONFIG_RTC=y -CONFIG_DTLK=m -CONFIG_R3964=m -# CONFIG_APPLICOM is not set -CONFIG_SONYPI=m - -# -# Ftape, the floppy tape device driver -# -CONFIG_FTAPE=m -CONFIG_ZFTAPE=m -CONFIG_ZFT_DFLT_BLK_SZ=10240 -CONFIG_ZFT_COMPRESSOR=m -CONFIG_FT_NR_BUFFERS=3 -# CONFIG_FT_PROC_FS is not set -CONFIG_FT_NORMAL_DEBUG=y -# CONFIG_FT_FULL_DEBUG is not set -# CONFIG_FT_NO_TRACE is not set -# CONFIG_FT_NO_TRACE_AT_ALL is not set -CONFIG_FT_STD_FDC=y -# CONFIG_FT_MACH2 is not set -# CONFIG_FT_PROBE_FC10 is not set -# CONFIG_FT_ALT_FDC is not set -CONFIG_FT_FDC_THR=8 -CONFIG_FT_FDC_MAX_RATE=2000 -CONFIG_FT_ALPHA_CLOCK=0 -CONFIG_AGP=m -CONFIG_AGP_INTEL=y -CONFIG_AGP_I810=y -CONFIG_AGP_VIA=y -CONFIG_AGP_AMD=y -CONFIG_AGP_AMD_8151=y -CONFIG_AGP_SIS=y -CONFIG_AGP_ALI=y -CONFIG_AGP_SWORKS=y -CONFIG_DRM=y -# CONFIG_DRM_OLD is not set -CONFIG_DRM_NEW=y -CONFIG_DRM_TDFX=m -CONFIG_DRM_R128=m -CONFIG_DRM_RADEON=m -CONFIG_DRM_I810=m -# CONFIG_DRM_I810_XFREE_41 is not set -CONFIG_DRM_I830=m -CONFIG_DRM_MGA=m -# CONFIG_DRM_SIS is not set - -# -# PCMCIA character devices -# -CONFIG_PCMCIA_SERIAL_CS=m -CONFIG_SYNCLINK_CS=m -CONFIG_MWAVE=m -CONFIG_BATTERY_GERICOM=m - -# -# Multimedia devices -# -CONFIG_VIDEO_DEV=m - -# -# Video For Linux -# -CONFIG_VIDEO_PROC_FS=y -CONFIG_I2C_PARPORT=m -CONFIG_VIDEO_BT848=m -CONFIG_VIDEO_PMS=m -CONFIG_VIDEO_BWQCAM=m -CONFIG_VIDEO_CQCAM=m -CONFIG_VIDEO_W9966=m -CONFIG_VIDEO_CPIA=m -CONFIG_VIDEO_CPIA_PP=m -CONFIG_VIDEO_CPIA_USB=m -CONFIG_VIDEO_SAA5249=m -CONFIG_TUNER_3036=m -CONFIG_VIDEO_STRADIS=m -CONFIG_VIDEO_ZORAN=m -CONFIG_VIDEO_ZORAN_BUZ=m -CONFIG_VIDEO_ZORAN_DC10=m -CONFIG_VIDEO_ZORAN_LML33=m -CONFIG_VIDEO_ZR36120=m -CONFIG_VIDEO_MEYE=m - -# -# Radio Adapters -# -CONFIG_RADIO_CADET=m -CONFIG_RADIO_RTRACK=m -CONFIG_RADIO_RTRACK2=m -CONFIG_RADIO_AZTECH=m -CONFIG_RADIO_GEMTEK=m -CONFIG_RADIO_GEMTEK_PCI=m -CONFIG_RADIO_MAXIRADIO=m -CONFIG_RADIO_MAESTRO=m -CONFIG_RADIO_MIROPCM20=m -CONFIG_RADIO_MIROPCM20_RDS=m -CONFIG_RADIO_SF16FMI=m -CONFIG_RADIO_SF16FMR2=m -CONFIG_RADIO_TERRATEC=m -CONFIG_RADIO_TRUST=m -CONFIG_RADIO_TYPHOON=m -CONFIG_RADIO_TYPHOON_PROC_FS=y -CONFIG_RADIO_ZOLTRIX=m - -# -# Crypto Hardware support -# -CONFIG_CRYPTO=m -CONFIG_CRYPTO_BROADCOM=m - -# -# File systems -# -CONFIG_QUOTA=y -# CONFIG_QFMT_V1 is not set -CONFIG_QFMT_V2=y -# CONFIG_QIFACE_COMPAT is not set -CONFIG_AUTOFS_FS=m -CONFIG_AUTOFS4_FS=m -CONFIG_REISERFS_FS=m -# CONFIG_REISERFS_CHECK is not set -CONFIG_REISERFS_PROC_INFO=y -# CONFIG_ADFS_FS is not set -CONFIG_AFS_FS=m -# CONFIG_ADFS_FS_RW is not set -# CONFIG_AFFS_FS is not set -CONFIG_HFS_FS=m -CONFIG_BEFS_FS=m -# CONFIG_BEFS_DEBUG is not set -CONFIG_BFS_FS=m -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -CONFIG_EXT3_FS_XATTR_SHARING=y -CONFIG_EXT3_FS_XATTR_USER=y -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FAT_FS=m -CONFIG_MSDOS_FS=m -CONFIG_UMSDOS_FS=m -CONFIG_VFAT_FS=m -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set -CONFIG_CRAMFS=m -CONFIG_TMPFS=y -CONFIG_RAMFS=y -CONFIG_ISO9660_FS=y -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_JFS_FS=m -# CONFIG_JFS_DEBUG is not set -# CONFIG_JFS_STATISTICS is not set -CONFIG_MINIX_FS=m -CONFIG_VXFS_FS=m -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_RW is not set -# CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y -# CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -CONFIG_ROMFS_FS=m -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_XATTR_SHARING=y -CONFIG_EXT2_FS_XATTR_USER=y -CONFIG_SYSV_FS=m -CONFIG_UDF_FS=m -CONFIG_UDF_RW=y -CONFIG_UFS_FS=m -# CONFIG_UFS_FS_WRITE is not set - -# -# Network File Systems -# -CONFIG_CODA_FS=m -CONFIG_INTERMEZZO_FS=m -CONFIG_NFS_FS=m -CONFIG_NFS_V3=y -# CONFIG_ROOT_NFS is not set -CONFIG_NFSD=m -CONFIG_NFSD_V3=y -# CONFIG_NFSD_TCP is not set -CONFIG_SUNRPC=m -CONFIG_LOCKD=m -CONFIG_LOCKD_V4=y -CONFIG_SMB_FS=m -# CONFIG_SMB_NLS_DEFAULT is not set -CONFIG_NCP_FS=m -CONFIG_NCPFS_PACKET_SIGNING=y -CONFIG_NCPFS_IOCTL_LOCKING=y -CONFIG_NCPFS_STRONG=y -CONFIG_NCPFS_NFS_NS=y -CONFIG_NCPFS_OS2_NS=y -CONFIG_NCPFS_SMALLDOS=y -CONFIG_NCPFS_NLS=y -CONFIG_NCPFS_EXTRAS=y -CONFIG_ZISOFS_FS=y -CONFIG_FS_MBCACHE=y - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -CONFIG_OSF_PARTITION=y -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -CONFIG_MAC_PARTITION=y -CONFIG_MSDOS_PARTITION=y -CONFIG_BSD_DISKLABEL=y -CONFIG_MINIX_SUBPARTITION=y -CONFIG_SOLARIS_X86_PARTITION=y -CONFIG_UNIXWARE_DISKLABEL=y -# CONFIG_LDM_PARTITION is not set -CONFIG_SGI_PARTITION=y -# CONFIG_ULTRIX_PARTITION is not set -CONFIG_SUN_PARTITION=y -# CONFIG_EFI_PARTITION is not set -CONFIG_SMB_NLS=y -CONFIG_NLS=y - -# -# Native Language Support -# -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_737=m -CONFIG_NLS_CODEPAGE_775=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_CODEPAGE_852=m -CONFIG_NLS_CODEPAGE_855=m -CONFIG_NLS_CODEPAGE_857=m -CONFIG_NLS_CODEPAGE_860=m -CONFIG_NLS_CODEPAGE_861=m -CONFIG_NLS_CODEPAGE_862=m -CONFIG_NLS_CODEPAGE_863=m -CONFIG_NLS_CODEPAGE_864=m -CONFIG_NLS_CODEPAGE_865=m -CONFIG_NLS_CODEPAGE_866=m -CONFIG_NLS_CODEPAGE_869=m -CONFIG_NLS_CODEPAGE_936=m -CONFIG_NLS_CODEPAGE_950=m -CONFIG_NLS_CODEPAGE_932=m -CONFIG_NLS_CODEPAGE_949=m -CONFIG_NLS_CODEPAGE_874=m -CONFIG_NLS_ISO8859_8=m -CONFIG_NLS_CODEPAGE_1250=m -CONFIG_NLS_CODEPAGE_1251=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_ISO8859_2=m -CONFIG_NLS_ISO8859_3=m -CONFIG_NLS_ISO8859_4=m -CONFIG_NLS_ISO8859_5=m -CONFIG_NLS_ISO8859_6=m -CONFIG_NLS_ISO8859_7=m -CONFIG_NLS_ISO8859_9=m -CONFIG_NLS_ISO8859_13=m -CONFIG_NLS_ISO8859_14=m -CONFIG_NLS_ISO8859_15=m -CONFIG_NLS_KOI8_R=m -CONFIG_NLS_KOI8_U=m -CONFIG_NLS_UTF8=m - -# -# Console drivers -# -CONFIG_VGA_CONSOLE=y -CONFIG_VIDEO_SELECT=y -# CONFIG_VIDEO_IGNORE_BAD_MODE is not set -CONFIG_MDA_CONSOLE=m - -# -# Frame-buffer support -# -CONFIG_FB=y -CONFIG_DUMMY_CONSOLE=y -CONFIG_FB_RIVA=m -CONFIG_FB_CLGEN=m -CONFIG_FB_PM2=m -# CONFIG_FB_PM2_FIFO_DISCONNECT is not set -CONFIG_FB_PM2_PCI=y -CONFIG_FB_PM3=m -# CONFIG_FB_CYBER2000 is not set -CONFIG_FB_VESA=y -CONFIG_FB_VGA16=m -CONFIG_FB_HGA=m -CONFIG_VIDEO_SELECT=y -CONFIG_FB_MATROX=m -CONFIG_FB_MATROX_MILLENIUM=y -CONFIG_FB_MATROX_MYSTIQUE=y -# CONFIG_FB_MATROX_G450 is not set -CONFIG_FB_MATROX_G100A=y -CONFIG_FB_MATROX_G100=y -CONFIG_FB_MATROX_I2C=m -CONFIG_FB_MATROX_MAVEN=m -# CONFIG_FB_MATROX_PROC is not set -CONFIG_FB_MATROX_MULTIHEAD=y -CONFIG_FB_ATY=m -CONFIG_FB_ATY_GX=y -CONFIG_FB_ATY_CT=y -CONFIG_FB_ATY_CT_VAIO_LCD=y -CONFIG_FB_RADEON=m -CONFIG_FB_ATY128=m -CONFIG_FB_SIS=m -CONFIG_FB_SIS_300=y -CONFIG_FB_SIS_315=y -CONFIG_FB_NEOMAGIC=m -CONFIG_FB_3DFX=m -CONFIG_FB_VOODOO1=m -# CONFIG_FB_TRIDENT is not set -# CONFIG_FB_VIRTUAL is not set -# CONFIG_FBCON_ADVANCED is not set -CONFIG_FBCON_MFB=m -CONFIG_FBCON_CFB8=y -CONFIG_FBCON_CFB16=y -CONFIG_FBCON_CFB24=y -CONFIG_FBCON_CFB32=y -CONFIG_FBCON_VGA_PLANES=m -CONFIG_FBCON_HGA=m -# CONFIG_FBCON_FONTWIDTH8_ONLY is not set -# CONFIG_FBCON_FONTS is not set -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y - -# -# Sound -# -CONFIG_SOUND=m -CONFIG_SOUND_ALI5455=m -CONFIG_SOUND_BT878=m -CONFIG_SOUND_CMPCI=m -CONFIG_SOUND_CMPCI_FM=y -CONFIG_SOUND_CMPCI_FMIO=388 -CONFIG_SOUND_CMPCI_FMIO=388 -CONFIG_SOUND_CMPCI_MIDI=y -CONFIG_SOUND_CMPCI_MPUIO=330 -CONFIG_SOUND_CMPCI_JOYSTICK=y -CONFIG_SOUND_CMPCI_CM8738=y -# CONFIG_SOUND_CMPCI_SPDIFINVERSE is not set -CONFIG_SOUND_CMPCI_SPDIFLOOP=y -CONFIG_SOUND_CMPCI_SPEAKERS=2 -CONFIG_SOUND_EMU10K1=m -CONFIG_MIDI_EMU10K1=y -CONFIG_SOUND_AUDIGY=m -CONFIG_SOUND_FUSION=m -CONFIG_SOUND_CS4281=m -CONFIG_SOUND_ES1370=m -CONFIG_SOUND_ES1371=m -CONFIG_SOUND_ESSSOLO1=m -CONFIG_SOUND_MAESTRO=m -CONFIG_SOUND_MAESTRO3=m -CONFIG_SOUND_FORTE=m -CONFIG_SOUND_ICH=m -CONFIG_SOUND_RME96XX=m -CONFIG_SOUND_SONICVIBES=m -CONFIG_SOUND_TRIDENT=m -CONFIG_SOUND_MSNDCLAS=m -# CONFIG_MSNDCLAS_HAVE_BOOT is not set -CONFIG_MSNDCLAS_INIT_FILE="/etc/sound/msndinit.bin" -CONFIG_MSNDCLAS_PERM_FILE="/etc/sound/msndperm.bin" -CONFIG_SOUND_MSNDPIN=m -# CONFIG_MSNDPIN_HAVE_BOOT is not set -CONFIG_MSNDPIN_INIT_FILE="/etc/sound/pndspini.bin" -CONFIG_MSNDPIN_PERM_FILE="/etc/sound/pndsperm.bin" -CONFIG_SOUND_VIA82CXXX=m -CONFIG_MIDI_VIA82CXXX=y -CONFIG_SOUND_OSS=m -# CONFIG_SOUND_TRACEINIT is not set -CONFIG_SOUND_DMAP=y -CONFIG_SOUND_AD1816=m -CONFIG_SOUND_AD1889=m -CONFIG_SOUND_SGALAXY=m -CONFIG_SOUND_ADLIB=m -CONFIG_SOUND_ACI_MIXER=m -CONFIG_SOUND_CS4232=m -CONFIG_SOUND_SSCAPE=m -CONFIG_SOUND_GUS=m -CONFIG_SOUND_GUS16=y -CONFIG_SOUND_GUSMAX=y -CONFIG_SOUND_VMIDI=m -CONFIG_SOUND_TRIX=m -CONFIG_SOUND_MSS=m -CONFIG_SOUND_MPU401=m -CONFIG_SOUND_NM256=m -CONFIG_SOUND_MAD16=m -CONFIG_MAD16_OLDCARD=y -CONFIG_SOUND_PAS=m -# CONFIG_PAS_JOYSTICK is not set -CONFIG_SOUND_PSS=m -# CONFIG_PSS_MIXER is not set -# CONFIG_PSS_HAVE_BOOT is not set -CONFIG_SOUND_SB=m -CONFIG_SOUND_AWE32_SYNTH=m -CONFIG_SOUND_KAHLUA=m -CONFIG_SOUND_WAVEFRONT=m -CONFIG_SOUND_MAUI=m -CONFIG_SOUND_YM3812=m -CONFIG_SOUND_OPL3SA1=m -CONFIG_SOUND_OPL3SA2=m -CONFIG_SOUND_YMFPCI=m -CONFIG_SOUND_YMFPCI_LEGACY=y -CONFIG_SOUND_UART6850=m -CONFIG_SOUND_AEDSP16=m -CONFIG_SC6600=y -CONFIG_SC6600_JOY=y -CONFIG_SC6600_CDROM=4 -CONFIG_SC6600_CDROMBASE=0 -CONFIG_AEDSP16_SBPRO=y -CONFIG_AEDSP16_MPU401=y -CONFIG_SOUND_TVMIXER=m - -# -# USB support -# -CONFIG_USB=m -# CONFIG_USB_DEBUG is not set -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_BANDWIDTH is not set -CONFIG_USB_EHCI_HCD=m -CONFIG_USB_UHCI=m -CONFIG_USB_UHCI_ALT=m -CONFIG_USB_OHCI=m -CONFIG_USB_AUDIO=m -# CONFIG_USB_EMI26 is not set -CONFIG_USB_MIDI=m -CONFIG_USB_STORAGE=m -# CONFIG_USB_STORAGE_DEBUG is not set -CONFIG_USB_STORAGE_DATAFAB=y -CONFIG_USB_STORAGE_FREECOM=y -CONFIG_USB_STORAGE_ISD200=y -CONFIG_USB_STORAGE_DPCM=y -CONFIG_USB_STORAGE_HP8200e=y -CONFIG_USB_STORAGE_SDDR09=y -CONFIG_USB_STORAGE_SDDR55=y -CONFIG_USB_STORAGE_JUMPSHOT=y -CONFIG_USB_ACM=m -CONFIG_USB_PRINTER=m -CONFIG_USB_HID=m -CONFIG_USB_HIDINPUT=y -CONFIG_USB_HIDDEV=y -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set -CONFIG_USB_AIPTEK=m -CONFIG_USB_WACOM=m -CONFIG_USB_KBTAB=m -CONFIG_USB_POWERMATE=m -# CONFIG_USB_DC2XX is not set -CONFIG_USB_MDC800=m -CONFIG_USB_SCANNER=m -CONFIG_USB_MICROTEK=m -CONFIG_USB_HPUSBSCSI=m -CONFIG_USB_IBMCAM=m -CONFIG_USB_KONICAWC=m -CONFIG_USB_OV511=m -CONFIG_USB_PWC=m -CONFIG_USB_SE401=m -CONFIG_USB_STV680=m -CONFIG_USB_VICAM=m -CONFIG_USB_DSBR=m -CONFIG_USB_DABUSB=m -CONFIG_USB_PEGASUS=m -CONFIG_USB_RTL8150=m -CONFIG_USB_KAWETH=m -CONFIG_USB_CATC=m -CONFIG_USB_CDCETHER=m -CONFIG_USB_USBNET=m -CONFIG_USB_USS720=m - -# -# USB Serial Converter support -# -CONFIG_USB_SERIAL=m -# CONFIG_USB_SERIAL_DEBUG is not set -CONFIG_USB_SERIAL_GENERIC=y -CONFIG_USB_SERIAL_BELKIN=m -CONFIG_USB_SERIAL_WHITEHEAT=m -CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m -CONFIG_USB_SERIAL_EMPEG=m -CONFIG_USB_SERIAL_FTDI_SIO=m -CONFIG_USB_SERIAL_VISOR=m -CONFIG_USB_SERIAL_IPAQ=m -CONFIG_USB_SERIAL_IR=m -CONFIG_USB_SERIAL_EDGEPORT=m -CONFIG_USB_SERIAL_EDGEPORT_TI=m -CONFIG_USB_SERIAL_KEYSPAN_PDA=m -CONFIG_USB_SERIAL_KEYSPAN=m -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y -CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -CONFIG_USB_SERIAL_KEYSPAN_USA19W=y -CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y -CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y -CONFIG_USB_SERIAL_KEYSPAN_MPR=y -CONFIG_USB_SERIAL_KEYSPAN_USA49W=y -CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y -CONFIG_USB_SERIAL_MCT_U232=m -CONFIG_USB_SERIAL_KLSI=m -CONFIG_USB_SERIAL_KOBIL_SCT=m -CONFIG_USB_SERIAL_PL2303=m -CONFIG_USB_SERIAL_CYBERJACK=m -CONFIG_USB_SERIAL_XIRCOM=m -CONFIG_USB_SERIAL_OMNINET=m -CONFIG_USB_RIO500=m -CONFIG_USB_AUERSWALD=m -CONFIG_USB_TIGL=m -CONFIG_USB_BRLVGER=m -CONFIG_USB_LCD=m - -# -# Additional device driver support -# -CONFIG_NET_BROADCOM=m -CONFIG_CIPE=m -CONFIG_CRYPTO_AEP=m -CONFIG_MEGARAC=m -CONFIG_FC_QLA2200=m -CONFIG_FC_QLA2300=m -CONFIG_SCSI_ISCSI=m - -# -# Bluetooth support -# -CONFIG_BLUEZ=m -CONFIG_BLUEZ_L2CAP=m -CONFIG_BLUEZ_SCO=m -CONFIG_BLUEZ_RFCOMM=m -CONFIG_BLUEZ_RFCOMM_TTY=y -CONFIG_BLUEZ_BNEP=m -CONFIG_BLUEZ_BNEP_MC_FILTER=y -CONFIG_BLUEZ_BNEP_PROTO_FILTER=y - -# -# Bluetooth device drivers -# -CONFIG_BLUEZ_HCIUSB=m -CONFIG_BLUEZ_USB_SCO=y -CONFIG_BLUEZ_USB_ZERO_PACKET=y -CONFIG_BLUEZ_HCIUART=m -CONFIG_BLUEZ_HCIUART_H4=y -CONFIG_BLUEZ_HCIUART_BCSP=y -CONFIG_BLUEZ_HCIUART_BCSP_TXCRC=y -CONFIG_BLUEZ_HCIDTL1=m -CONFIG_BLUEZ_HCIBT3C=m -CONFIG_BLUEZ_HCIBLUECARD=m -CONFIG_BLUEZ_HCIBTUART=m -CONFIG_BLUEZ_HCIVHCI=m - -# -# Profiling support -# -CONFIG_PROFILING=y -CONFIG_OPROFILE=m - -# -# Kernel hacking -# -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_STACKOVERFLOW is not set -# CONFIG_DEBUG_HIGHMEM is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_IOVIRT is not set -CONFIG_MAGIC_SYSRQ=y -# CONFIG_DEBUG_SPINLOCK is not set -CONFIG_FRAME_POINTER=y -# CONFIG_MCL_COREDUMP is not set - -# -# Library routines -# -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=m diff --git a/lustre/kernel_patches/kernel_configs/kernel-2.4.20-rh-2.4-i686.config b/lustre/kernel_patches/kernel_configs/kernel-2.4.20-rh-2.4-i686.config deleted file mode 100644 index 2a5d8da..0000000 --- a/lustre/kernel_patches/kernel_configs/kernel-2.4.20-rh-2.4-i686.config +++ /dev/null @@ -1,1863 +0,0 @@ -# -# Automatically generated by make menuconfig: don't edit -# -CONFIG_X86=y -# CONFIG_SBUS is not set -CONFIG_UID16=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODVERSIONS=y -CONFIG_KMOD=y - -# -# Processor type and features -# -# CONFIG_LOLAT is not set -# CONFIG_M386 is not set -# CONFIG_M486 is not set -CONFIG_M586=y -# CONFIG_M586TSC is not set -# CONFIG_M586MMX is not set -# CONFIG_M686 is not set -# CONFIG_MPENTIUMIII is not set -# CONFIG_MPENTIUM4 is not set -# CONFIG_MK6 is not set -# CONFIG_MK7 is not set -# CONFIG_MELAN is not set -# CONFIG_MCRUSOE is not set -# CONFIG_MWINCHIPC6 is not set -# CONFIG_MWINCHIP2 is not set -# CONFIG_MWINCHIP3D is not set -# CONFIG_MCYRIXIII is not set -CONFIG_X86_WP_WORKS_OK=y -CONFIG_X86_INVLPG=y -CONFIG_X86_CMPXCHG=y -CONFIG_X86_XADD=y -CONFIG_X86_BSWAP=y -CONFIG_X86_POPAD_OK=y -# CONFIG_RWSEM_GENERIC_SPINLOCK is not set -CONFIG_RWSEM_XCHGADD_ALGORITHM=y -CONFIG_X86_L1_CACHE_SHIFT=5 -CONFIG_X86_USE_STRING_486=y -CONFIG_X86_ALIGNMENT_16=y -CONFIG_X86_PPRO_FENCE=y -# CONFIG_X86_F00F_WORKS_OK is not set -CONFIG_X86_MCE=y - -# -# CPU Frequency scaling -# -# CONFIG_CPU_FREQ is not set -CONFIG_TOSHIBA=m -CONFIG_I8K=m -CONFIG_MICROCODE=m -CONFIG_X86_MSR=m -CONFIG_X86_CPUID=m -# CONFIG_E820_PROC is not set -CONFIG_EDD=m -# CONFIG_NOHIGHMEM is not set -CONFIG_HIGHMEM4G=y -# CONFIG_HIGHMEM64G is not set -CONFIG_HIGHMEM=y -CONFIG_HIGHPTE=y -CONFIG_HIGHIO=y -# CONFIG_MATH_EMULATION is not set -CONFIG_MTRR=y -CONFIG_SMP=y -# CONFIG_X86_NUMA is not set -# CONFIG_X86_TSC_DISABLE is not set -CONFIG_HAVE_DEC_LOCK=y -# CONFIG_NOBIGSTACK is not set -CONFIG_STACK_SIZE_16KB=y -# CONFIG_STACK_SIZE_32KB is not set -# CONFIG_STACK_SIZE_64KB is not set -CONFIG_STACK_SIZE_SHIFT=2 - -# -# General setup -# -CONFIG_NET=y -CONFIG_X86_IO_APIC=y -CONFIG_X86_LOCAL_APIC=y -CONFIG_PCI=y -# CONFIG_PCI_GOBIOS is not set -# CONFIG_PCI_GODIRECT is not set -CONFIG_PCI_GOANY=y -CONFIG_PCI_BIOS=y -CONFIG_PCI_DIRECT=y -CONFIG_ISA=y -CONFIG_PCI_NAMES=y -CONFIG_EISA=y -# CONFIG_MCA is not set -CONFIG_HOTPLUG=y - -# -# PCMCIA/CardBus support -# -CONFIG_PCMCIA=m -CONFIG_CARDBUS=y -CONFIG_TCIC=y -CONFIG_I82092=y -CONFIG_I82365=y - -# -# PCI Hotplug Support -# -CONFIG_HOTPLUG_PCI=y -# CONFIG_HOTPLUG_PCI_ACPI is not set -CONFIG_HOTPLUG_PCI_COMPAQ=m -# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set -CONFIG_HOTPLUG_PCI_IBM=m -# CONFIG_HOTPLUG_PCI_H2999 is not set -CONFIG_SYSVIPC=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_SYSCTL=y -CONFIG_KCORE_ELF=y -# CONFIG_KCORE_AOUT is not set -CONFIG_BINFMT_AOUT=m -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=m -CONFIG_PM=y -# CONFIG_ACPI is not set -CONFIG_APM=y -# CONFIG_APM_IGNORE_USER_SUSPEND is not set -# CONFIG_APM_DO_ENABLE is not set -CONFIG_APM_CPU_IDLE=y -# CONFIG_APM_DISPLAY_BLANK is not set -CONFIG_APM_RTC_IS_GMT=y -# CONFIG_APM_ALLOW_INTS is not set -# CONFIG_APM_REAL_MODE_POWER_OFF is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Parallel port support -# -CONFIG_PARPORT=m -CONFIG_PARPORT_PC=m -CONFIG_PARPORT_PC_CML1=m -CONFIG_PARPORT_SERIAL=m -# CONFIG_PARPORT_PC_FIFO is not set -# CONFIG_PARPORT_PC_SUPERIO is not set -CONFIG_PARPORT_PC_PCMCIA=m -# CONFIG_PARPORT_AMIGA is not set -# CONFIG_PARPORT_MFC3 is not set -# CONFIG_PARPORT_ATARI is not set -# CONFIG_PARPORT_GSC is not set -# CONFIG_PARPORT_SUNBPP is not set -# CONFIG_PARPORT_OTHER is not set -CONFIG_PARPORT_1284=y - -# -# Plug and Play configuration -# -CONFIG_PNP=y -CONFIG_ISAPNP=y - -# -# Block devices -# -CONFIG_BLK_DEV_FD=y -CONFIG_BLK_DEV_XD=m -CONFIG_PARIDE=m -CONFIG_PARIDE_PARPORT=m -CONFIG_PARIDE_PD=m -CONFIG_PARIDE_PCD=m -CONFIG_PARIDE_PF=m -CONFIG_PARIDE_PT=m -CONFIG_PARIDE_PG=m -CONFIG_PARIDE_ATEN=m -CONFIG_PARIDE_BPCK=m -CONFIG_PARIDE_BPCK6=m -CONFIG_PARIDE_COMM=m -CONFIG_PARIDE_DSTR=m -CONFIG_PARIDE_FIT2=m -CONFIG_PARIDE_FIT3=m -CONFIG_PARIDE_EPAT=m -CONFIG_PARIDE_EPATC8=y -CONFIG_PARIDE_EPIA=m -CONFIG_PARIDE_FRIQ=m -CONFIG_PARIDE_FRPW=m -CONFIG_PARIDE_KBIC=m -CONFIG_PARIDE_KTTI=m -CONFIG_PARIDE_ON20=m -CONFIG_PARIDE_ON26=m -CONFIG_BLK_CPQ_DA=m -CONFIG_BLK_CPQ_CISS_DA=m -CONFIG_CISS_SCSI_TAPE=y -CONFIG_BLK_DEV_DAC960=m -CONFIG_BLK_DEV_UMEM=m -CONFIG_BLK_DEV_LOOP=m -CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=4096 -CONFIG_BLK_DEV_INITRD=y -CONFIG_BLK_STATS=y - -# -# Multi-device support (RAID and LVM) -# -CONFIG_MD=y -CONFIG_BLK_DEV_MD=y -CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID5=m -CONFIG_MD_MULTIPATH=m -CONFIG_BLK_DEV_LVM=m - -# -# Cryptography support (CryptoAPI) -# -CONFIG_CRYPTO=m -CONFIG_CIPHERS=m -CONFIG_CIPHER_AES=m -CONFIG_CIPHER_IDENTITY=m -CONFIG_CRYPTODEV=m -CONFIG_CRYPTOLOOP=m - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -CONFIG_NETLINK_DEV=y -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_FILTER=y -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_TUX=m -CONFIG_TUX_EXTCGI=y -# CONFIG_TUX_EXTENDED_LOG is not set -# CONFIG_TUX_DEBUG is not set -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_FWMARK=y -CONFIG_IP_ROUTE_NAT=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_TOS=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_ROUTE_LARGE_TABLES=y -# CONFIG_IP_PNP is not set -CONFIG_NET_IPIP=m -CONFIG_NET_IPGRE=m -CONFIG_NET_IPGRE_BROADCAST=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -# CONFIG_ARPD is not set -# CONFIG_INET_ECN is not set -CONFIG_SYN_COOKIES=y - -# -# IP: Netfilter Configuration -# -CONFIG_IP_NF_CONNTRACK=m -CONFIG_IP_NF_FTP=m -CONFIG_IP_NF_AMANDA=m -CONFIG_IP_NF_TFTP=m -CONFIG_IP_NF_IRC=m -CONFIG_IP_NF_QUEUE=m -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_LIMIT=m -CONFIG_IP_NF_MATCH_MAC=m -CONFIG_IP_NF_MATCH_PKTTYPE=m -CONFIG_IP_NF_MATCH_MARK=m -CONFIG_IP_NF_MATCH_MULTIPORT=m -CONFIG_IP_NF_MATCH_TOS=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_DSCP=m -CONFIG_IP_NF_MATCH_AH_ESP=m -CONFIG_IP_NF_MATCH_LENGTH=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_MATCH_TCPMSS=m -CONFIG_IP_NF_MATCH_HELPER=m -CONFIG_IP_NF_MATCH_STATE=m -CONFIG_IP_NF_MATCH_CONNTRACK=m -CONFIG_IP_NF_MATCH_UNCLEAN=m -CONFIG_IP_NF_MATCH_OWNER=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_MIRROR=m -CONFIG_IP_NF_NAT=m -CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_IP_NF_NAT_AMANDA=m -CONFIG_IP_NF_NAT_LOCAL=y -CONFIG_IP_NF_NAT_SNMP_BASIC=m -CONFIG_IP_NF_NAT_IRC=m -CONFIG_IP_NF_NAT_FTP=m -CONFIG_IP_NF_NAT_TFTP=m -CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_TOS=m -CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_TARGET_DSCP=m -CONFIG_IP_NF_TARGET_MARK=m -CONFIG_IP_NF_TARGET_LOG=m -CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_IP_NF_TARGET_TCPMSS=m -CONFIG_IP_NF_ARPTABLES=m -CONFIG_IP_NF_ARPFILTER=m -CONFIG_IP_NF_COMPAT_IPCHAINS=m -CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IP_NF_COMPAT_IPFWADM=m -CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IPV6=m - -# -# IPv6: Netfilter Configuration -# -# CONFIG_IP6_NF_QUEUE is not set -CONFIG_IP6_NF_IPTABLES=m -CONFIG_IP6_NF_MATCH_LIMIT=m -CONFIG_IP6_NF_MATCH_MAC=m -CONFIG_IP6_NF_MATCH_RT=m -CONFIG_IP6_NF_MATCH_OPTS=m -CONFIG_IP6_NF_MATCH_FRAG=m -CONFIG_IP6_NF_MATCH_HL=m -CONFIG_IP6_NF_MATCH_MULTIPORT=m -CONFIG_IP6_NF_MATCH_OWNER=m -CONFIG_IP6_NF_MATCH_MARK=m -CONFIG_IP6_NF_MATCH_IPV6HEADER=m -CONFIG_IP6_NF_MATCH_AHESP=m -CONFIG_IP6_NF_MATCH_LENGTH=m -CONFIG_IP6_NF_MATCH_EUI64=m -CONFIG_IP6_NF_FILTER=m -CONFIG_IP6_NF_TARGET_LOG=m -CONFIG_IP6_NF_MANGLE=m -CONFIG_IP6_NF_TARGET_MARK=m -# CONFIG_KHTTPD is not set -CONFIG_ATM=y -CONFIG_ATM_CLIP=y -# CONFIG_ATM_CLIP_NO_ICMP is not set -CONFIG_ATM_LANE=m -CONFIG_ATM_MPOA=m -CONFIG_ATM_BR2684=m -CONFIG_ATM_BR2684_IPFILTER=y -CONFIG_VLAN_8021Q=m -CONFIG_IPX=m -# CONFIG_IPX_INTERN is not set -CONFIG_ATALK=m - -# -# Appletalk devices -# -CONFIG_DEV_APPLETALK=y -CONFIG_LTPC=m -CONFIG_COPS=m -CONFIG_COPS_DAYNA=y -CONFIG_COPS_TANGENT=y -CONFIG_IPDDP=m -CONFIG_IPDDP_ENCAP=y -CONFIG_IPDDP_DECAP=y -CONFIG_DECNET=m -CONFIG_DECNET_SIOCGIFCONF=y -CONFIG_DECNET_ROUTER=y -CONFIG_DECNET_ROUTE_FWMARK=y -CONFIG_BRIDGE=m -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_LLC is not set -CONFIG_NET_DIVERT=y -# CONFIG_ECONET is not set -CONFIG_WAN_ROUTER=m -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set - -# -# QoS and/or fair queueing -# -CONFIG_NET_SCHED=y -CONFIG_NET_SCH_CBQ=m -CONFIG_NET_SCH_HTB=m -CONFIG_NET_SCH_CSZ=m -# CONFIG_NET_SCH_ATM is not set -CONFIG_NET_SCH_PRIO=m -CONFIG_NET_SCH_RED=m -CONFIG_NET_SCH_SFQ=m -CONFIG_NET_SCH_TEQL=m -CONFIG_NET_SCH_TBF=m -CONFIG_NET_SCH_GRED=m -CONFIG_NET_SCH_DSMARK=m -CONFIG_NET_SCH_INGRESS=m -CONFIG_NET_QOS=y -CONFIG_NET_ESTIMATOR=y -CONFIG_NET_CLS=y -CONFIG_NET_CLS_TCINDEX=m -CONFIG_NET_CLS_ROUTE4=m -CONFIG_NET_CLS_ROUTE=y -CONFIG_NET_CLS_FW=m -CONFIG_NET_CLS_U32=m -CONFIG_NET_CLS_RSVP=m -CONFIG_NET_CLS_RSVP6=m -CONFIG_NET_CLS_POLICE=y - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set - -# -# Telephony Support -# -CONFIG_PHONE=m -CONFIG_PHONE_IXJ=m -CONFIG_PHONE_IXJ_PCMCIA=m - -# -# ATA/IDE/MFM/RLL support -# -CONFIG_IDE=y - -# -# IDE, ATA and ATAPI Block devices -# -CONFIG_BLK_DEV_IDE=y -# CONFIG_BLK_DEV_HD_IDE is not set -# CONFIG_BLK_DEV_HD is not set -CONFIG_BLK_DEV_IDEDISK=y -CONFIG_IDEDISK_MULTI_MODE=y -# CONFIG_IDEDISK_STROKE is not set -CONFIG_BLK_DEV_IDECS=m -CONFIG_BLK_DEV_IDECD=m -CONFIG_BLK_DEV_IDETAPE=m -CONFIG_BLK_DEV_IDEFLOPPY=y -CONFIG_BLK_DEV_IDESCSI=m -# CONFIG_IDE_TASK_IOCTL is not set -CONFIG_BLK_DEV_CMD640=y -# CONFIG_BLK_DEV_CMD640_ENHANCED is not set -CONFIG_BLK_DEV_ISAPNP=y -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_BLK_DEV_GENERIC=y -CONFIG_IDEPCI_SHARE_IRQ=y -CONFIG_BLK_DEV_IDEDMA_PCI=y -# CONFIG_BLK_DEV_OFFBOARD is not set -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y -# CONFIG_IDEDMA_ONLYDISK is not set -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_PCI_WIP is not set -CONFIG_BLK_DEV_ADMA100=y -CONFIG_BLK_DEV_AEC62XX=y -CONFIG_BLK_DEV_ALI15X3=y -# CONFIG_WDC_ALI15X3 is not set -CONFIG_BLK_DEV_AMD74XX=y -# CONFIG_AMD74XX_OVERRIDE is not set -CONFIG_BLK_DEV_CMD64X=y -CONFIG_BLK_DEV_TRIFLEX=y -CONFIG_BLK_DEV_CY82C693=y -CONFIG_BLK_DEV_CS5530=y -CONFIG_BLK_DEV_HPT34X=y -# CONFIG_HPT34X_AUTODMA is not set -CONFIG_BLK_DEV_HPT366=y -CONFIG_BLK_DEV_PIIX=y -# CONFIG_BLK_DEV_NS87415 is not set -# CONFIG_BLK_DEV_OPTI621 is not set -CONFIG_BLK_DEV_PDC202XX_OLD=y -# CONFIG_PDC202XX_BURST is not set -CONFIG_BLK_DEV_PDC202XX_NEW=y -CONFIG_PDC202XX_FORCE=y -CONFIG_BLK_DEV_RZ1000=y -# CONFIG_BLK_DEV_SC1200 is not set -CONFIG_BLK_DEV_SVWKS=y -CONFIG_BLK_DEV_SIIMAGE=y -CONFIG_BLK_DEV_SIS5513=y -CONFIG_BLK_DEV_SLC90E66=y -# CONFIG_BLK_DEV_TRM290 is not set -CONFIG_BLK_DEV_VIA82CXXX=y -# CONFIG_IDE_CHIPSETS is not set -CONFIG_IDEDMA_AUTO=y -# CONFIG_IDEDMA_IVB is not set -# CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_PDC202XX=y -CONFIG_BLK_DEV_IDE_MODES=y -CONFIG_BLK_DEV_ATARAID=m -CONFIG_BLK_DEV_ATARAID_PDC=m -CONFIG_BLK_DEV_ATARAID_HPT=m -CONFIG_BLK_DEV_ATARAID_SII=m - -# -# SCSI support -# -CONFIG_SCSI=m -CONFIG_BLK_DEV_SD=m -CONFIG_SD_EXTRA_DEVS=40 -CONFIG_CHR_DEV_ST=m -CONFIG_CHR_DEV_OSST=m -CONFIG_BLK_DEV_SR=m -CONFIG_BLK_DEV_SR_VENDOR=y -CONFIG_SR_EXTRA_DEVS=4 -CONFIG_CHR_DEV_SG=m -# CONFIG_SCSI_DEBUG_QUEUES is not set -# CONFIG_SCSI_MULTI_LUN is not set -CONFIG_SCSI_CONSTANTS=y -CONFIG_SCSI_LOGGING=y - -# -# SCSI low-level drivers -# -CONFIG_BLK_DEV_3W_XXXX_RAID=m -CONFIG_SCSI_7000FASST=m -CONFIG_SCSI_ACARD=m -CONFIG_SCSI_AHA152X=m -CONFIG_SCSI_AHA1542=m -CONFIG_SCSI_AHA1740=m -CONFIG_SCSI_AACRAID=m -CONFIG_SCSI_AIC7XXX=m -CONFIG_AIC7XXX_CMDS_PER_DEVICE=253 -CONFIG_AIC7XXX_RESET_DELAY_MS=15000 -# CONFIG_AIC7XXX_PROBE_EISA_VL is not set -# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set -CONFIG_SCSI_AIC79XX=m -CONFIG_AIC79XX_CMDS_PER_DEVICE=253 -CONFIG_AIC79XX_RESET_DELAY_MS=15000 -# CONFIG_AIC79XX_BUILD_FIRMWARE is not set -CONFIG_AIC79XX_ENABLE_RD_STRM=y -# CONFIG_AIC79XX_DEBUG_ENABLE is not set -CONFIG_AIC79XX_DEBUG_MASK=0 -CONFIG_SCSI_AIC7XXX_OLD=m -CONFIG_AIC7XXX_OLD_TCQ_ON_BY_DEFAULT=y -CONFIG_AIC7XXX_OLD_CMDS_PER_DEVICE=32 -CONFIG_AIC7XXX_OLD_PROC_STATS=y -CONFIG_SCSI_DPT_I2O=m -CONFIG_SCSI_ADVANSYS=m -CONFIG_SCSI_IN2000=m -CONFIG_SCSI_AM53C974=m -CONFIG_SCSI_MEGARAID=m -CONFIG_SCSI_BUSLOGIC=m -# CONFIG_SCSI_OMIT_FLASHPOINT is not set -CONFIG_SCSI_CPQFCTS=m -CONFIG_SCSI_DMX3191D=m -CONFIG_SCSI_DTC3280=m -CONFIG_SCSI_EATA=m -CONFIG_SCSI_EATA_TAGGED_QUEUE=y -# CONFIG_SCSI_EATA_LINKED_COMMANDS is not set -CONFIG_SCSI_EATA_MAX_TAGS=16 -CONFIG_SCSI_EATA_DMA=m -CONFIG_SCSI_EATA_PIO=m -CONFIG_SCSI_FUTURE_DOMAIN=m -CONFIG_SCSI_GDTH=m -CONFIG_SCSI_GENERIC_NCR5380=m -# CONFIG_SCSI_GENERIC_NCR53C400 is not set -CONFIG_SCSI_G_NCR5380_PORT=y -# CONFIG_SCSI_G_NCR5380_MEM is not set -CONFIG_SCSI_IPS=m -CONFIG_SCSI_INITIO=m -CONFIG_SCSI_INIA100=m -CONFIG_SCSI_PPA=m -CONFIG_SCSI_IMM=m -# CONFIG_SCSI_IZIP_EPP16 is not set -# CONFIG_SCSI_IZIP_SLOW_CTR is not set -CONFIG_SCSI_NCR53C406A=m -CONFIG_SCSI_NCR53C7xx=m -# CONFIG_SCSI_NCR53C7xx_sync is not set -CONFIG_SCSI_NCR53C7xx_FAST=y -CONFIG_SCSI_NCR53C7xx_DISCONNECT=y -CONFIG_SCSI_SYM53C8XX_2=m -CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 -CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 -CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 -# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set -CONFIG_SCSI_NCR53C8XX=m -CONFIG_SCSI_SYM53C8XX=m -CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 -CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 -CONFIG_SCSI_NCR53C8XX_SYNC=40 -# CONFIG_SCSI_NCR53C8XX_PROFILE is not set -# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set -# CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set -# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set -CONFIG_SCSI_PAS16=m -CONFIG_SCSI_PCI2000=m -CONFIG_SCSI_PCI2220I=m -CONFIG_SCSI_PSI240I=m -CONFIG_SCSI_QLOGIC_FAS=m -CONFIG_SCSI_QLOGIC_ISP=m -CONFIG_SCSI_QLOGIC_FC=m -# CONFIG_SCSI_QLOGIC_FC_FIRMWARE is not set -CONFIG_SCSI_QLOGIC_1280=m -CONFIG_SCSI_NEWISP=m -CONFIG_SCSI_SEAGATE=m -CONFIG_SCSI_SIM710=m -CONFIG_SCSI_SYM53C416=m -CONFIG_SCSI_DC390T=m -# CONFIG_SCSI_DC390T_NOGENSUPP is not set -CONFIG_SCSI_T128=m -CONFIG_SCSI_U14_34F=m -# CONFIG_SCSI_U14_34F_LINKED_COMMANDS is not set -CONFIG_SCSI_U14_34F_MAX_TAGS=8 -CONFIG_SCSI_ULTRASTOR=m -CONFIG_SCSI_NSP32=m -CONFIG_SCSI_DEBUG=m - -# -# PCMCIA SCSI adapter support -# -CONFIG_SCSI_PCMCIA=y -CONFIG_PCMCIA_AHA152X=m -CONFIG_PCMCIA_FDOMAIN=m -CONFIG_PCMCIA_NINJA_SCSI=m -CONFIG_PCMCIA_QLOGIC=m - -# -# Fusion MPT device support -# -CONFIG_FUSION=m -# CONFIG_FUSION_BOOT is not set -CONFIG_FUSION_MAX_SGE=40 -# CONFIG_FUSION_ISENSE is not set -CONFIG_FUSION_CTL=m -CONFIG_FUSION_LAN=m -CONFIG_NET_FC=y - -# -# IEEE 1394 (FireWire) support (EXPERIMENTAL) -# -CONFIG_IEEE1394=m -# CONFIG_IEEE1394_PCILYNX is not set -CONFIG_IEEE1394_OHCI1394=m -CONFIG_IEEE1394_VIDEO1394=m -CONFIG_IEEE1394_SBP2=m -CONFIG_IEEE1394_SBP2_PHYS_DMA=y -CONFIG_IEEE1394_ETH1394=m -CONFIG_IEEE1394_DV1394=m -CONFIG_IEEE1394_RAWIO=m -CONFIG_IEEE1394_CMP=m -CONFIG_IEEE1394_AMDTP=m -# CONFIG_IEEE1394_VERBOSEDEBUG is not set - -# -# I2O device support -# -CONFIG_I2O=m -CONFIG_I2O_PCI=m -CONFIG_I2O_BLOCK=m -CONFIG_I2O_LAN=m -CONFIG_I2O_SCSI=m -CONFIG_I2O_PROC=m - -# -# Network device support -# -CONFIG_NETDEVICES=y - -# -# ARCnet devices -# -# CONFIG_ARCNET is not set -CONFIG_DUMMY=m -CONFIG_BONDING=m -CONFIG_EQUALIZER=m -CONFIG_TUN=m -CONFIG_ETHERTAP=m -CONFIG_NET_SB1000=m - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -# CONFIG_SUNLANCE is not set -CONFIG_HAPPYMEAL=m -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -CONFIG_SUNGEM=m -CONFIG_NET_VENDOR_3COM=y -CONFIG_EL1=m -CONFIG_EL2=m -CONFIG_ELPLUS=m -CONFIG_EL16=m -CONFIG_EL3=m -CONFIG_3C515=m -# CONFIG_ELMC is not set -# CONFIG_ELMC_II is not set -CONFIG_VORTEX=m -CONFIG_TYPHOON=m -CONFIG_LANCE=m -CONFIG_NET_VENDOR_SMC=y -CONFIG_WD80x3=m -# CONFIG_ULTRAMCA is not set -CONFIG_ULTRA=m -CONFIG_ULTRA32=m -CONFIG_SMC9194=m -CONFIG_NET_VENDOR_RACAL=y -CONFIG_NI5010=m -CONFIG_NI52=m -CONFIG_NI65=m -CONFIG_AT1700=m -CONFIG_DEPCA=m -CONFIG_HP100=m -CONFIG_NET_ISA=y -CONFIG_E2100=m -# CONFIG_EWRK3 is not set -CONFIG_EEXPRESS=m -CONFIG_EEXPRESS_PRO=m -CONFIG_HPLAN_PLUS=m -CONFIG_HPLAN=m -CONFIG_LP486E=m -CONFIG_ETH16I=m -CONFIG_NE2000=m -CONFIG_NET_PCI=y -CONFIG_PCNET32=m -CONFIG_AMD8111_ETH=m -CONFIG_ADAPTEC_STARFIRE=m -CONFIG_AC3200=m -CONFIG_APRICOT=m -CONFIG_CS89x0=m -CONFIG_TULIP=m -# CONFIG_TULIP_MWI is not set -CONFIG_TULIP_MMIO=y -CONFIG_DE4X5=m -CONFIG_DGRS=m -CONFIG_DM9102=m -CONFIG_EEPRO100=m -# CONFIG_EEPRO100_PIO is not set -CONFIG_E100=m -CONFIG_LNE390=m -CONFIG_FEALNX=m -CONFIG_NATSEMI=m -CONFIG_NE2K_PCI=m -CONFIG_NE3210=m -CONFIG_ES3210=m -CONFIG_8139CP=m -CONFIG_8139TOO=m -# CONFIG_8139TOO_PIO is not set -# CONFIG_8139TOO_TUNE_TWISTER is not set -CONFIG_8139TOO_8129=y -# CONFIG_8139_OLD_RX_RESET is not set -CONFIG_SIS900=m -CONFIG_EPIC100=m -CONFIG_SUNDANCE=m -# CONFIG_SUNDANCE_MMIO is not set -CONFIG_TLAN=m -CONFIG_TC35815=m -CONFIG_VIA_RHINE=m -# CONFIG_VIA_RHINE_MMIO is not set -CONFIG_WINBOND_840=m -CONFIG_NET_POCKET=y -CONFIG_ATP=m -CONFIG_DE600=m -CONFIG_DE620=m - -# -# Ethernet (1000 Mbit) -# -CONFIG_ACENIC=m -# CONFIG_ACENIC_OMIT_TIGON_I is not set -CONFIG_DL2K=m -CONFIG_E1000=m -# CONFIG_MYRI_SBUS is not set -CONFIG_NS83820=m -CONFIG_HAMACHI=m -CONFIG_YELLOWFIN=m -CONFIG_R8169=m -CONFIG_SK98LIN=m -CONFIG_TIGON3=m -CONFIG_FDDI=y -CONFIG_DEFXX=m -CONFIG_SKFP=m -CONFIG_NETCONSOLE=m -# CONFIG_HIPPI is not set -CONFIG_PLIP=m -CONFIG_PPP=m -CONFIG_PPP_MULTILINK=y -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m -# CONFIG_PPP_BSDCOMP is not set -CONFIG_PPPOE=m -CONFIG_PPPOATM=m -CONFIG_SLIP=m -CONFIG_SLIP_COMPRESSED=y -CONFIG_SLIP_SMART=y -CONFIG_SLIP_MODE_SLIP6=y - -# -# Wireless LAN (non-hamradio) -# -CONFIG_NET_RADIO=y -CONFIG_STRIP=m -CONFIG_WAVELAN=m -CONFIG_ARLAN=m -CONFIG_AIRONET4500=m -CONFIG_AIRONET4500_NONCS=m -CONFIG_AIRONET4500_PNP=y -CONFIG_AIRONET4500_PCI=y -CONFIG_AIRONET4500_ISA=y -CONFIG_AIRONET4500_I365=y -CONFIG_AIRONET4500_PROC=m -CONFIG_AIRO=m -CONFIG_HERMES=m -CONFIG_PLX_HERMES=m -CONFIG_PCI_HERMES=m -CONFIG_PCMCIA_HERMES=m -CONFIG_AIRO_CS=m -CONFIG_NET_WIRELESS=y -CONFIG_PCMCIA_HERMES_OLD=m - -# -# Token Ring devices -# -CONFIG_TR=y -CONFIG_IBMTR=m -CONFIG_IBMOL=m -CONFIG_IBMLS=m -CONFIG_3C359=m -CONFIG_TMS380TR=m -CONFIG_TMSPCI=m -CONFIG_TMSISA=m -CONFIG_ABYSS=m -# CONFIG_MADGEMC is not set -CONFIG_SMCTR=m -CONFIG_NET_FC=y -CONFIG_IPHASE5526=m -CONFIG_RCPCI=m -CONFIG_SHAPER=m - -# -# Wan interfaces -# -CONFIG_WAN=y -CONFIG_HOSTESS_SV11=m -CONFIG_COSA=m -# CONFIG_COMX is not set -# CONFIG_DSCC4 is not set -# CONFIG_LANMEDIA is not set -CONFIG_ATI_XX20=m -CONFIG_SEALEVEL_4021=m -# CONFIG_SYNCLINK_SYNCPPP is not set -# CONFIG_HDLC is not set -CONFIG_DLCI=m -CONFIG_DLCI_COUNT=24 -CONFIG_DLCI_MAX=8 -CONFIG_SDLA=m -CONFIG_WAN_ROUTER_DRIVERS=y -CONFIG_VENDOR_SANGOMA=m -CONFIG_WANPIPE_CHDLC=y -CONFIG_WANPIPE_FR=y -CONFIG_WANPIPE_X25=y -CONFIG_WANPIPE_PPP=y -CONFIG_WANPIPE_MULTPPP=y -CONFIG_CYCLADES_SYNC=m -CONFIG_CYCLOMX_X25=y -# CONFIG_LAPBETHER is not set -# CONFIG_X25_ASY is not set -CONFIG_SBNI=m -CONFIG_SBNI_MULTILINE=y - -# -# PCMCIA network device support -# -CONFIG_NET_PCMCIA=y -CONFIG_PCMCIA_3C589=m -CONFIG_PCMCIA_3C574=m -CONFIG_PCMCIA_FMVJ18X=m -CONFIG_PCMCIA_PCNET=m -CONFIG_PCMCIA_AXNET=m -CONFIG_PCMCIA_NMCLAN=m -CONFIG_PCMCIA_SMC91C92=m -CONFIG_PCMCIA_XIRC2PS=m -# CONFIG_ARCNET_COM20020_CS is not set -CONFIG_PCMCIA_IBMTR=m -CONFIG_PCMCIA_XIRCOM=m -CONFIG_PCMCIA_XIRTULIP=m -CONFIG_NET_PCMCIA_RADIO=y -CONFIG_PCMCIA_RAYCS=m -CONFIG_PCMCIA_NETWAVE=m -CONFIG_PCMCIA_WAVELAN=m -CONFIG_PCMCIA_WVLAN=m -CONFIG_AIRONET4500_CS=m - -# -# ATM drivers -# -CONFIG_ATM_TCP=m -CONFIG_ATM_LANAI=m -CONFIG_ATM_ENI=m -# CONFIG_ATM_ENI_DEBUG is not set -# CONFIG_ATM_ENI_TUNE_BURST is not set -CONFIG_ATM_FIRESTREAM=m -CONFIG_ATM_ZATM=m -# CONFIG_ATM_ZATM_DEBUG is not set -CONFIG_ATM_ZATM_EXACT_TS=y -CONFIG_ATM_NICSTAR=m -CONFIG_ATM_NICSTAR_USE_SUNI=y -CONFIG_ATM_NICSTAR_USE_IDT77105=y -CONFIG_ATM_IDT77252=m -# CONFIG_ATM_IDT77252_DEBUG is not set -# CONFIG_ATM_IDT77252_RCV_ALL is not set -CONFIG_ATM_IDT77252_USE_SUNI=y -CONFIG_ATM_AMBASSADOR=m -# CONFIG_ATM_AMBASSADOR_DEBUG is not set -CONFIG_ATM_HORIZON=m -# CONFIG_ATM_HORIZON_DEBUG is not set -CONFIG_ATM_IA=m -# CONFIG_ATM_IA_DEBUG is not set -CONFIG_ATM_FORE200E_MAYBE=m -CONFIG_ATM_FORE200E_PCA=y -CONFIG_ATM_FORE200E_PCA_DEFAULT_FW=y -CONFIG_ATM_FORE200E_TX_RETRY=16 -CONFIG_ATM_FORE200E_DEBUG=0 -CONFIG_ATM_FORE200E=m - -# -# Amateur Radio support -# -CONFIG_HAMRADIO=y -CONFIG_AX25=m -# CONFIG_AX25_DAMA_SLAVE is not set -CONFIG_NETROM=m -CONFIG_ROSE=m - -# -# AX.25 network device drivers -# -# CONFIG_MKISS is not set -# CONFIG_6PACK is not set -# CONFIG_BPQETHER is not set -# CONFIG_DMASCC is not set -# CONFIG_SCC is not set -# CONFIG_BAYCOM_SER_FDX is not set -# CONFIG_BAYCOM_SER_HDX is not set -# CONFIG_BAYCOM_PAR is not set -# CONFIG_BAYCOM_EPP is not set -CONFIG_SOUNDMODEM=m -CONFIG_SOUNDMODEM_SBC=y -CONFIG_SOUNDMODEM_WSS=y -CONFIG_SOUNDMODEM_AFSK1200=y -CONFIG_SOUNDMODEM_AFSK2400_7=y -CONFIG_SOUNDMODEM_AFSK2400_8=y -CONFIG_SOUNDMODEM_AFSK2666=y -CONFIG_SOUNDMODEM_HAPN4800=y -CONFIG_SOUNDMODEM_PSK4800=y -CONFIG_SOUNDMODEM_FSK9600=y -# CONFIG_YAM is not set - -# -# IrDA (infrared) support -# -CONFIG_IRDA=m -CONFIG_IRLAN=m -CONFIG_IRNET=m -CONFIG_IRCOMM=m -CONFIG_IRDA_ULTRA=y -CONFIG_IRDA_CACHE_LAST_LSAP=y -CONFIG_IRDA_FAST_RR=y -# CONFIG_IRDA_DEBUG is not set - -# -# Infrared-port device drivers -# -CONFIG_IRTTY_SIR=m -CONFIG_IRPORT_SIR=m -CONFIG_DONGLE=y -CONFIG_ESI_DONGLE=m -CONFIG_ACTISYS_DONGLE=m -CONFIG_TEKRAM_DONGLE=m -CONFIG_GIRBIL_DONGLE=m -CONFIG_LITELINK_DONGLE=m -CONFIG_MCP2120_DONGLE=m -CONFIG_OLD_BELKIN_DONGLE=m -CONFIG_ACT200L_DONGLE=m -CONFIG_MA600_DONGLE=m -CONFIG_USB_IRDA=m -CONFIG_NSC_FIR=m -CONFIG_WINBOND_FIR=m -CONFIG_TOSHIBA_OLD=m -CONFIG_TOSHIBA_FIR=m -CONFIG_SMC_IRCC_FIR=m -CONFIG_ALI_FIR=m -CONFIG_VLSI_FIR=m - -# -# ISDN subsystem -# -CONFIG_ISDN=m -CONFIG_ISDN_BOOL=y -CONFIG_ISDN_PPP=y -CONFIG_ISDN_PPP_VJ=y -CONFIG_ISDN_MPP=y -CONFIG_ISDN_PPP_BSDCOMP=m -CONFIG_ISDN_AUDIO=y -CONFIG_ISDN_TTY_FAX=y - -# -# ISDN feature submodules -# -CONFIG_ISDN_DRV_LOOP=m -# CONFIG_ISDN_DIVERSION is not set - -# -# Passive ISDN cards -# -CONFIG_ISDN_DRV_HISAX=m -CONFIG_ISDN_HISAX=y -CONFIG_HISAX_EURO=y -CONFIG_DE_AOC=y -# CONFIG_HISAX_NO_SENDCOMPLETE is not set -# CONFIG_HISAX_NO_LLC is not set -# CONFIG_HISAX_NO_KEYPAD is not set -CONFIG_HISAX_1TR6=y -CONFIG_HISAX_NI1=y -CONFIG_HISAX_MAX_CARDS=8 -CONFIG_HISAX_16_0=y -CONFIG_HISAX_16_3=y -CONFIG_HISAX_AVM_A1=y -CONFIG_HISAX_IX1MICROR2=y -CONFIG_HISAX_ASUSCOM=y -CONFIG_HISAX_TELEINT=y -CONFIG_HISAX_HFCS=y -CONFIG_HISAX_SPORTSTER=y -CONFIG_HISAX_MIC=y -CONFIG_HISAX_ISURF=y -CONFIG_HISAX_HSTSAPHIR=y -CONFIG_HISAX_TELESPCI=y -CONFIG_HISAX_S0BOX=y -CONFIG_HISAX_FRITZPCI=y -CONFIG_HISAX_AVM_A1_PCMCIA=y -CONFIG_HISAX_ELSA=y -CONFIG_HISAX_DIEHLDIVA=y -CONFIG_HISAX_SEDLBAUER=y -CONFIG_HISAX_NETJET=y -CONFIG_HISAX_NETJET_U=y -CONFIG_HISAX_NICCY=y -CONFIG_HISAX_BKM_A4T=y -CONFIG_HISAX_SCT_QUADRO=y -CONFIG_HISAX_GAZEL=y -CONFIG_HISAX_HFC_PCI=y -CONFIG_HISAX_W6692=y -CONFIG_HISAX_HFC_SX=y -CONFIG_HISAX_ENTERNOW_PCI=y -CONFIG_HISAX_DEBUG=y -CONFIG_HISAX_SEDLBAUER_CS=m -CONFIG_HISAX_ELSA_CS=m -CONFIG_HISAX_AVM_A1_CS=m -CONFIG_HISAX_ST5481=m -CONFIG_HISAX_FRITZ_PCIPNP=m -CONFIG_USB_AUERISDN=m - -# -# Active ISDN cards -# -CONFIG_ISDN_DRV_ICN=m -CONFIG_ISDN_DRV_PCBIT=m -# CONFIG_ISDN_DRV_SC is not set -# CONFIG_ISDN_DRV_ACT2000 is not set -CONFIG_ISDN_DRV_EICON=y -CONFIG_ISDN_DRV_EICON_DIVAS=m -# CONFIG_ISDN_DRV_EICON_OLD is not set -CONFIG_ISDN_DRV_TPAM=m -CONFIG_ISDN_CAPI=m -CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y -CONFIG_ISDN_CAPI_MIDDLEWARE=y -CONFIG_ISDN_CAPI_CAPI20=m -CONFIG_ISDN_CAPI_CAPIFS_BOOL=y -CONFIG_ISDN_CAPI_CAPIFS=m -CONFIG_ISDN_CAPI_CAPIDRV=m -CONFIG_ISDN_DRV_AVMB1_B1ISA=m -CONFIG_ISDN_DRV_AVMB1_B1PCI=m -CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y -CONFIG_ISDN_DRV_AVMB1_T1ISA=m -CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m -CONFIG_ISDN_DRV_AVMB1_AVM_CS=m -CONFIG_ISDN_DRV_AVMB1_T1PCI=m -CONFIG_ISDN_DRV_AVMB1_C4=m -CONFIG_HYSDN=m -CONFIG_HYSDN_CAPI=y -CONFIG_KALLSYMS=y - -# -# Old CD-ROM drivers (not SCSI, not IDE) -# -# CONFIG_CD_NO_IDESCSI is not set - -# -# Input core support -# -CONFIG_INPUT=m -CONFIG_INPUT_KEYBDEV=m -CONFIG_INPUT_MOUSEDEV=m -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -CONFIG_INPUT_JOYDEV=m -CONFIG_INPUT_EVDEV=m - -# -# Character devices -# -CONFIG_VT=y -CONFIG_ECC=m -CONFIG_VT_CONSOLE=y -CONFIG_SERIAL=y -CONFIG_SERIAL_CONSOLE=y -CONFIG_SERIAL_EXTENDED=y -CONFIG_SERIAL_MANY_PORTS=y -CONFIG_SERIAL_SHARE_IRQ=y -# CONFIG_SERIAL_DETECT_IRQ is not set -CONFIG_SERIAL_MULTIPORT=y -# CONFIG_HUB6 is not set -CONFIG_SERIAL_NONSTANDARD=y -CONFIG_COMPUTONE=m -CONFIG_ROCKETPORT=m -CONFIG_CYCLADES=m -# CONFIG_CYZ_INTR is not set -CONFIG_DIGIEPCA=m -CONFIG_ESPSERIAL=m -CONFIG_MOXA_INTELLIO=m -CONFIG_MOXA_SMARTIO=m -CONFIG_ISI=m -CONFIG_SYNCLINK=m -# CONFIG_SYNCLINKMP is not set -CONFIG_N_HDLC=m -CONFIG_RISCOM8=m -CONFIG_SPECIALIX=m -CONFIG_SPECIALIX_RTSCTS=y -CONFIG_SX=m -# CONFIG_RIO is not set -CONFIG_STALDRV=y -CONFIG_STALLION=m -CONFIG_ISTALLION=m -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=2048 -CONFIG_PRINTER=m -CONFIG_LP_CONSOLE=y -CONFIG_PPDEV=m -CONFIG_TIPAR=m - -# -# I2C support -# -CONFIG_I2C=m -CONFIG_I2C_ALGOBIT=m -CONFIG_I2C_PHILIPSPAR=m -CONFIG_I2C_ELV=m -CONFIG_I2C_VELLEMAN=m -# CONFIG_SCx200_I2C is not set -# CONFIG_SCx200_ACB is not set -CONFIG_I2C_ALGOPCF=m -CONFIG_I2C_ELEKTOR=m -CONFIG_I2C_MAINBOARD=y -CONFIG_I2C_ALI1535=m -CONFIG_I2C_ALI15X3=m -CONFIG_I2C_HYDRA=m -CONFIG_I2C_AMD756=m -# CONFIG_I2C_TSUNAMI is not set -CONFIG_I2C_I801=m -# CONFIG_I2C_I810 is not set -CONFIG_I2C_PIIX4=m -CONFIG_I2C_SIS5595=m -CONFIG_I2C_VIA=m -CONFIG_I2C_VIAPRO=m -CONFIG_I2C_VOODOO3=m -CONFIG_I2C_ISA=m -CONFIG_I2C_CHARDEV=m -CONFIG_I2C_PROC=m - -# -# Hardware sensors support -# -CONFIG_SENSORS=y -CONFIG_SENSORS_ADM1021=m -CONFIG_SENSORS_ADM1024=m -CONFIG_SENSORS_ADM1025=m -CONFIG_SENSORS_ADM9240=m -CONFIG_SENSORS_DS1621=m -CONFIG_SENSORS_FSCPOS=m -CONFIG_SENSORS_FSCSCY=m -CONFIG_SENSORS_GL518SM=m -CONFIG_SENSORS_GL520SM=m -CONFIG_SENSORS_MAXILIFE=m -CONFIG_SENSORS_IT87=m -CONFIG_SENSORS_MTP008=m -CONFIG_SENSORS_LM75=m -CONFIG_SENSORS_LM78=m -CONFIG_SENSORS_LM80=m -CONFIG_SENSORS_LM87=m -CONFIG_SENSORS_LM92=m -CONFIG_SENSORS_SIS5595=m -CONFIG_SENSORS_SMSC47M1=m -CONFIG_SENSORS_THMC50=m -CONFIG_SENSORS_VIA686A=m -CONFIG_SENSORS_VT1211=m -CONFIG_SENSORS_VT8231=m -CONFIG_SENSORS_W83781D=m -CONFIG_SENSORS_OTHER=y -CONFIG_SENSORS_BT869=m -CONFIG_SENSORS_DDCMON=m -CONFIG_SENSORS_EEPROM=m -CONFIG_SENSORS_MATORB=m -CONFIG_SENSORS_PCF8574=m -CONFIG_SENSORS_PCF8591=m - -# -# Mice -# -CONFIG_BUSMOUSE=m -CONFIG_ATIXL_BUSMOUSE=m -CONFIG_LOGIBUSMOUSE=m -CONFIG_MS_BUSMOUSE=m -CONFIG_MOUSE=y -CONFIG_PSMOUSE=y -CONFIG_82C710_MOUSE=m -CONFIG_PC110_PAD=m -CONFIG_MK712_MOUSE=m - -# -# Joysticks -# -CONFIG_INPUT_GAMEPORT=m -CONFIG_INPUT_NS558=m -CONFIG_INPUT_LIGHTNING=m -CONFIG_INPUT_PCIGAME=m -CONFIG_INPUT_CS461X=m -CONFIG_INPUT_EMU10K1=m -CONFIG_INPUT_SERIO=m -CONFIG_INPUT_SERPORT=m -CONFIG_INPUT_ANALOG=m -CONFIG_INPUT_A3D=m -CONFIG_INPUT_ADI=m -CONFIG_INPUT_COBRA=m -CONFIG_INPUT_GF2K=m -CONFIG_INPUT_GRIP=m -CONFIG_INPUT_INTERACT=m -CONFIG_INPUT_TMDC=m -CONFIG_INPUT_SIDEWINDER=m -CONFIG_INPUT_IFORCE_USB=m -CONFIG_INPUT_IFORCE_232=m -CONFIG_INPUT_WARRIOR=m -CONFIG_INPUT_MAGELLAN=m -CONFIG_INPUT_SPACEORB=m -CONFIG_INPUT_SPACEBALL=m -CONFIG_INPUT_STINGER=m -CONFIG_INPUT_DB9=m -CONFIG_INPUT_GAMECON=m -CONFIG_INPUT_TURBOGRAFX=m -# CONFIG_QIC02_TAPE is not set -CONFIG_IPMI_HANDLER=m -# CONFIG_IPMI_PANIC_EVENT is not set -CONFIG_IPMI_DEVICE_INTERFACE=m -CONFIG_IPMI_KCS=m -CONFIG_IPMI_WATCHDOG=m - -# -# Watchdog Cards -# -CONFIG_WATCHDOG=y -# CONFIG_WATCHDOG_NOWAYOUT is not set -CONFIG_ACQUIRE_WDT=m -CONFIG_ADVANTECH_WDT=m -CONFIG_ALIM7101_WDT=m -CONFIG_SC520_WDT=m -CONFIG_PCWATCHDOG=m -CONFIG_EUROTECH_WDT=m -CONFIG_IB700_WDT=m -CONFIG_WAFER_WDT=m -CONFIG_I810_TCO=m -# CONFIG_MIXCOMWD is not set -# CONFIG_60XX_WDT is not set -CONFIG_SC1200_WDT=m -# CONFIG_SCx200_WDT is not set -CONFIG_SOFT_WATCHDOG=m -CONFIG_W83877F_WDT=m -CONFIG_WDT=m -CONFIG_WDTPCI=m -# CONFIG_WDT_501 is not set -CONFIG_MACHZ_WDT=m -CONFIG_AMD7XX_TCO=m -# CONFIG_SCx200_GPIO is not set -CONFIG_AMD_RNG=m -CONFIG_INTEL_RNG=m -CONFIG_AMD_PM768=m -CONFIG_NVRAM=m -CONFIG_RTC=y -CONFIG_DTLK=m -CONFIG_R3964=m -# CONFIG_APPLICOM is not set -CONFIG_SONYPI=m - -# -# Ftape, the floppy tape device driver -# -CONFIG_FTAPE=m -CONFIG_ZFTAPE=m -CONFIG_ZFT_DFLT_BLK_SZ=10240 -CONFIG_ZFT_COMPRESSOR=m -CONFIG_FT_NR_BUFFERS=3 -# CONFIG_FT_PROC_FS is not set -CONFIG_FT_NORMAL_DEBUG=y -# CONFIG_FT_FULL_DEBUG is not set -# CONFIG_FT_NO_TRACE is not set -# CONFIG_FT_NO_TRACE_AT_ALL is not set -CONFIG_FT_STD_FDC=y -# CONFIG_FT_MACH2 is not set -# CONFIG_FT_PROBE_FC10 is not set -# CONFIG_FT_ALT_FDC is not set -CONFIG_FT_FDC_THR=8 -CONFIG_FT_FDC_MAX_RATE=2000 -CONFIG_FT_ALPHA_CLOCK=0 -CONFIG_AGP=m -CONFIG_AGP_INTEL=y -CONFIG_AGP_I810=y -CONFIG_AGP_VIA=y -CONFIG_AGP_AMD=y -CONFIG_AGP_AMD_8151=y -CONFIG_AGP_SIS=y -CONFIG_AGP_ALI=y -CONFIG_AGP_SWORKS=y -CONFIG_DRM=y -# CONFIG_DRM_OLD is not set -CONFIG_DRM_NEW=y -CONFIG_DRM_TDFX=m -CONFIG_DRM_R128=m -CONFIG_DRM_RADEON=m -CONFIG_DRM_I810=m -# CONFIG_DRM_I810_XFREE_41 is not set -CONFIG_DRM_I830=m -CONFIG_DRM_MGA=m -# CONFIG_DRM_SIS is not set - -# -# PCMCIA character devices -# -CONFIG_PCMCIA_SERIAL_CS=m -CONFIG_SYNCLINK_CS=m -CONFIG_MWAVE=m -CONFIG_BATTERY_GERICOM=m - -# -# Multimedia devices -# -CONFIG_VIDEO_DEV=m - -# -# Video For Linux -# -CONFIG_VIDEO_PROC_FS=y -CONFIG_I2C_PARPORT=m -CONFIG_VIDEO_BT848=m -CONFIG_VIDEO_PMS=m -CONFIG_VIDEO_BWQCAM=m -CONFIG_VIDEO_CQCAM=m -CONFIG_VIDEO_W9966=m -CONFIG_VIDEO_CPIA=m -CONFIG_VIDEO_CPIA_PP=m -CONFIG_VIDEO_CPIA_USB=m -CONFIG_VIDEO_SAA5249=m -CONFIG_TUNER_3036=m -CONFIG_VIDEO_STRADIS=m -CONFIG_VIDEO_ZORAN=m -CONFIG_VIDEO_ZORAN_BUZ=m -CONFIG_VIDEO_ZORAN_DC10=m -CONFIG_VIDEO_ZORAN_LML33=m -CONFIG_VIDEO_ZR36120=m -CONFIG_VIDEO_MEYE=m - -# -# Radio Adapters -# -CONFIG_RADIO_CADET=m -CONFIG_RADIO_RTRACK=m -CONFIG_RADIO_RTRACK2=m -CONFIG_RADIO_AZTECH=m -CONFIG_RADIO_GEMTEK=m -CONFIG_RADIO_GEMTEK_PCI=m -CONFIG_RADIO_MAXIRADIO=m -CONFIG_RADIO_MAESTRO=m -CONFIG_RADIO_MIROPCM20=m -CONFIG_RADIO_MIROPCM20_RDS=m -CONFIG_RADIO_SF16FMI=m -CONFIG_RADIO_SF16FMR2=m -CONFIG_RADIO_TERRATEC=m -CONFIG_RADIO_TRUST=m -CONFIG_RADIO_TYPHOON=m -CONFIG_RADIO_TYPHOON_PROC_FS=y -CONFIG_RADIO_ZOLTRIX=m - -# -# Crypto Hardware support -# -CONFIG_CRYPTO=m -CONFIG_CRYPTO_BROADCOM=m - -# -# File systems -# -CONFIG_QUOTA=y -# CONFIG_QFMT_V1 is not set -CONFIG_QFMT_V2=y -# CONFIG_QIFACE_COMPAT is not set -CONFIG_AUTOFS_FS=m -CONFIG_AUTOFS4_FS=m -CONFIG_REISERFS_FS=m -# CONFIG_REISERFS_CHECK is not set -CONFIG_REISERFS_PROC_INFO=y -# CONFIG_ADFS_FS is not set -CONFIG_AFS_FS=m -# CONFIG_ADFS_FS_RW is not set -# CONFIG_AFFS_FS is not set -CONFIG_HFS_FS=m -CONFIG_BEFS_FS=m -# CONFIG_BEFS_DEBUG is not set -CONFIG_BFS_FS=m -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -CONFIG_EXT3_FS_XATTR_SHARING=y -CONFIG_EXT3_FS_XATTR_USER=y -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FAT_FS=m -CONFIG_MSDOS_FS=m -CONFIG_UMSDOS_FS=m -CONFIG_VFAT_FS=m -# CONFIG_EFS_FS is not set -# CONFIG_JFFS_FS is not set -# CONFIG_JFFS2_FS is not set -CONFIG_CRAMFS=m -CONFIG_TMPFS=y -CONFIG_RAMFS=y -CONFIG_ISO9660_FS=y -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_JFS_FS=m -# CONFIG_JFS_DEBUG is not set -# CONFIG_JFS_STATISTICS is not set -CONFIG_MINIX_FS=m -CONFIG_VXFS_FS=m -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_RW is not set -# CONFIG_HPFS_FS is not set -CONFIG_PROC_FS=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y -# CONFIG_QNX4FS_FS is not set -# CONFIG_QNX4FS_RW is not set -CONFIG_ROMFS_FS=m -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_XATTR_SHARING=y -CONFIG_EXT2_FS_XATTR_USER=y -CONFIG_SYSV_FS=m -CONFIG_UDF_FS=m -CONFIG_UDF_RW=y -CONFIG_UFS_FS=m -# CONFIG_UFS_FS_WRITE is not set - -# -# Network File Systems -# -CONFIG_CODA_FS=m -CONFIG_INTERMEZZO_FS=m -CONFIG_NFS_FS=m -CONFIG_NFS_V3=y -# CONFIG_ROOT_NFS is not set -CONFIG_NFSD=m -CONFIG_NFSD_V3=y -# CONFIG_NFSD_TCP is not set -CONFIG_SUNRPC=m -CONFIG_LOCKD=m -CONFIG_LOCKD_V4=y -CONFIG_SMB_FS=m -# CONFIG_SMB_NLS_DEFAULT is not set -CONFIG_NCP_FS=m -CONFIG_NCPFS_PACKET_SIGNING=y -CONFIG_NCPFS_IOCTL_LOCKING=y -CONFIG_NCPFS_STRONG=y -CONFIG_NCPFS_NFS_NS=y -CONFIG_NCPFS_OS2_NS=y -CONFIG_NCPFS_SMALLDOS=y -CONFIG_NCPFS_NLS=y -CONFIG_NCPFS_EXTRAS=y -CONFIG_ZISOFS_FS=y -CONFIG_FS_MBCACHE=y - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -CONFIG_OSF_PARTITION=y -# CONFIG_AMIGA_PARTITION is not set -# CONFIG_ATARI_PARTITION is not set -CONFIG_MAC_PARTITION=y -CONFIG_MSDOS_PARTITION=y -CONFIG_BSD_DISKLABEL=y -CONFIG_MINIX_SUBPARTITION=y -CONFIG_SOLARIS_X86_PARTITION=y -CONFIG_UNIXWARE_DISKLABEL=y -# CONFIG_LDM_PARTITION is not set -CONFIG_SGI_PARTITION=y -# CONFIG_ULTRIX_PARTITION is not set -CONFIG_SUN_PARTITION=y -# CONFIG_EFI_PARTITION is not set -CONFIG_SMB_NLS=y -CONFIG_NLS=y - -# -# Native Language Support -# -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_737=m -CONFIG_NLS_CODEPAGE_775=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_CODEPAGE_852=m -CONFIG_NLS_CODEPAGE_855=m -CONFIG_NLS_CODEPAGE_857=m -CONFIG_NLS_CODEPAGE_860=m -CONFIG_NLS_CODEPAGE_861=m -CONFIG_NLS_CODEPAGE_862=m -CONFIG_NLS_CODEPAGE_863=m -CONFIG_NLS_CODEPAGE_864=m -CONFIG_NLS_CODEPAGE_865=m -CONFIG_NLS_CODEPAGE_866=m -CONFIG_NLS_CODEPAGE_869=m -CONFIG_NLS_CODEPAGE_936=m -CONFIG_NLS_CODEPAGE_950=m -CONFIG_NLS_CODEPAGE_932=m -CONFIG_NLS_CODEPAGE_949=m -CONFIG_NLS_CODEPAGE_874=m -CONFIG_NLS_ISO8859_8=m -CONFIG_NLS_CODEPAGE_1250=m -CONFIG_NLS_CODEPAGE_1251=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_ISO8859_2=m -CONFIG_NLS_ISO8859_3=m -CONFIG_NLS_ISO8859_4=m -CONFIG_NLS_ISO8859_5=m -CONFIG_NLS_ISO8859_6=m -CONFIG_NLS_ISO8859_7=m -CONFIG_NLS_ISO8859_9=m -CONFIG_NLS_ISO8859_13=m -CONFIG_NLS_ISO8859_14=m -CONFIG_NLS_ISO8859_15=m -CONFIG_NLS_KOI8_R=m -CONFIG_NLS_KOI8_U=m -CONFIG_NLS_UTF8=m - -# -# Console drivers -# -CONFIG_VGA_CONSOLE=y -CONFIG_VIDEO_SELECT=y -# CONFIG_VIDEO_IGNORE_BAD_MODE is not set -CONFIG_MDA_CONSOLE=m - -# -# Frame-buffer support -# -CONFIG_FB=y -CONFIG_DUMMY_CONSOLE=y -CONFIG_FB_RIVA=m -CONFIG_FB_CLGEN=m -CONFIG_FB_PM2=m -# CONFIG_FB_PM2_FIFO_DISCONNECT is not set -CONFIG_FB_PM2_PCI=y -CONFIG_FB_PM3=m -# CONFIG_FB_CYBER2000 is not set -CONFIG_FB_VESA=y -CONFIG_FB_VGA16=m -CONFIG_FB_HGA=m -CONFIG_VIDEO_SELECT=y -CONFIG_FB_MATROX=m -CONFIG_FB_MATROX_MILLENIUM=y -CONFIG_FB_MATROX_MYSTIQUE=y -# CONFIG_FB_MATROX_G450 is not set -CONFIG_FB_MATROX_G100A=y -CONFIG_FB_MATROX_G100=y -CONFIG_FB_MATROX_I2C=m -CONFIG_FB_MATROX_MAVEN=m -# CONFIG_FB_MATROX_PROC is not set -CONFIG_FB_MATROX_MULTIHEAD=y -CONFIG_FB_ATY=m -CONFIG_FB_ATY_GX=y -CONFIG_FB_ATY_CT=y -CONFIG_FB_ATY_CT_VAIO_LCD=y -CONFIG_FB_RADEON=m -CONFIG_FB_ATY128=m -CONFIG_FB_SIS=m -CONFIG_FB_SIS_300=y -CONFIG_FB_SIS_315=y -CONFIG_FB_NEOMAGIC=m -CONFIG_FB_3DFX=m -CONFIG_FB_VOODOO1=m -# CONFIG_FB_TRIDENT is not set -# CONFIG_FB_VIRTUAL is not set -# CONFIG_FBCON_ADVANCED is not set -CONFIG_FBCON_MFB=m -CONFIG_FBCON_CFB8=y -CONFIG_FBCON_CFB16=y -CONFIG_FBCON_CFB24=y -CONFIG_FBCON_CFB32=y -CONFIG_FBCON_VGA_PLANES=m -CONFIG_FBCON_HGA=m -# CONFIG_FBCON_FONTWIDTH8_ONLY is not set -# CONFIG_FBCON_FONTS is not set -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y - -# -# Sound -# -CONFIG_SOUND=m -CONFIG_SOUND_ALI5455=m -CONFIG_SOUND_BT878=m -CONFIG_SOUND_CMPCI=m -CONFIG_SOUND_CMPCI_FM=y -CONFIG_SOUND_CMPCI_FMIO=388 -CONFIG_SOUND_CMPCI_FMIO=388 -CONFIG_SOUND_CMPCI_MIDI=y -CONFIG_SOUND_CMPCI_MPUIO=330 -CONFIG_SOUND_CMPCI_JOYSTICK=y -CONFIG_SOUND_CMPCI_CM8738=y -# CONFIG_SOUND_CMPCI_SPDIFINVERSE is not set -CONFIG_SOUND_CMPCI_SPDIFLOOP=y -CONFIG_SOUND_CMPCI_SPEAKERS=2 -CONFIG_SOUND_EMU10K1=m -CONFIG_MIDI_EMU10K1=y -CONFIG_SOUND_AUDIGY=m -CONFIG_SOUND_FUSION=m -CONFIG_SOUND_CS4281=m -CONFIG_SOUND_ES1370=m -CONFIG_SOUND_ES1371=m -CONFIG_SOUND_ESSSOLO1=m -CONFIG_SOUND_MAESTRO=m -CONFIG_SOUND_MAESTRO3=m -CONFIG_SOUND_FORTE=m -CONFIG_SOUND_ICH=m -CONFIG_SOUND_RME96XX=m -CONFIG_SOUND_SONICVIBES=m -CONFIG_SOUND_TRIDENT=m -CONFIG_SOUND_MSNDCLAS=m -# CONFIG_MSNDCLAS_HAVE_BOOT is not set -CONFIG_MSNDCLAS_INIT_FILE="/etc/sound/msndinit.bin" -CONFIG_MSNDCLAS_PERM_FILE="/etc/sound/msndperm.bin" -CONFIG_SOUND_MSNDPIN=m -# CONFIG_MSNDPIN_HAVE_BOOT is not set -CONFIG_MSNDPIN_INIT_FILE="/etc/sound/pndspini.bin" -CONFIG_MSNDPIN_PERM_FILE="/etc/sound/pndsperm.bin" -CONFIG_SOUND_VIA82CXXX=m -CONFIG_MIDI_VIA82CXXX=y -CONFIG_SOUND_OSS=m -# CONFIG_SOUND_TRACEINIT is not set -CONFIG_SOUND_DMAP=y -CONFIG_SOUND_AD1816=m -CONFIG_SOUND_AD1889=m -CONFIG_SOUND_SGALAXY=m -CONFIG_SOUND_ADLIB=m -CONFIG_SOUND_ACI_MIXER=m -CONFIG_SOUND_CS4232=m -CONFIG_SOUND_SSCAPE=m -CONFIG_SOUND_GUS=m -CONFIG_SOUND_GUS16=y -CONFIG_SOUND_GUSMAX=y -CONFIG_SOUND_VMIDI=m -CONFIG_SOUND_TRIX=m -CONFIG_SOUND_MSS=m -CONFIG_SOUND_MPU401=m -CONFIG_SOUND_NM256=m -CONFIG_SOUND_MAD16=m -CONFIG_MAD16_OLDCARD=y -CONFIG_SOUND_PAS=m -# CONFIG_PAS_JOYSTICK is not set -CONFIG_SOUND_PSS=m -# CONFIG_PSS_MIXER is not set -# CONFIG_PSS_HAVE_BOOT is not set -CONFIG_SOUND_SB=m -CONFIG_SOUND_AWE32_SYNTH=m -CONFIG_SOUND_KAHLUA=m -CONFIG_SOUND_WAVEFRONT=m -CONFIG_SOUND_MAUI=m -CONFIG_SOUND_YM3812=m -CONFIG_SOUND_OPL3SA1=m -CONFIG_SOUND_OPL3SA2=m -CONFIG_SOUND_YMFPCI=m -CONFIG_SOUND_YMFPCI_LEGACY=y -CONFIG_SOUND_UART6850=m -CONFIG_SOUND_AEDSP16=m -CONFIG_SC6600=y -CONFIG_SC6600_JOY=y -CONFIG_SC6600_CDROM=4 -CONFIG_SC6600_CDROMBASE=0 -CONFIG_AEDSP16_SBPRO=y -CONFIG_AEDSP16_MPU401=y -CONFIG_SOUND_TVMIXER=m - -# -# USB support -# -CONFIG_USB=m -# CONFIG_USB_DEBUG is not set -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_BANDWIDTH is not set -CONFIG_USB_EHCI_HCD=m -CONFIG_USB_UHCI=m -CONFIG_USB_UHCI_ALT=m -CONFIG_USB_OHCI=m -CONFIG_USB_AUDIO=m -# CONFIG_USB_EMI26 is not set -CONFIG_USB_MIDI=m -CONFIG_USB_STORAGE=m -# CONFIG_USB_STORAGE_DEBUG is not set -CONFIG_USB_STORAGE_DATAFAB=y -CONFIG_USB_STORAGE_FREECOM=y -CONFIG_USB_STORAGE_ISD200=y -CONFIG_USB_STORAGE_DPCM=y -CONFIG_USB_STORAGE_HP8200e=y -CONFIG_USB_STORAGE_SDDR09=y -CONFIG_USB_STORAGE_SDDR55=y -CONFIG_USB_STORAGE_JUMPSHOT=y -CONFIG_USB_ACM=m -CONFIG_USB_PRINTER=m -CONFIG_USB_HID=m -CONFIG_USB_HIDINPUT=y -CONFIG_USB_HIDDEV=y -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set -CONFIG_USB_AIPTEK=m -CONFIG_USB_WACOM=m -CONFIG_USB_KBTAB=m -CONFIG_USB_POWERMATE=m -# CONFIG_USB_DC2XX is not set -CONFIG_USB_MDC800=m -CONFIG_USB_SCANNER=m -CONFIG_USB_MICROTEK=m -CONFIG_USB_HPUSBSCSI=m -CONFIG_USB_IBMCAM=m -CONFIG_USB_KONICAWC=m -CONFIG_USB_OV511=m -CONFIG_USB_PWC=m -CONFIG_USB_SE401=m -CONFIG_USB_STV680=m -CONFIG_USB_VICAM=m -CONFIG_USB_DSBR=m -CONFIG_USB_DABUSB=m -CONFIG_USB_PEGASUS=m -CONFIG_USB_RTL8150=m -CONFIG_USB_KAWETH=m -CONFIG_USB_CATC=m -CONFIG_USB_CDCETHER=m -CONFIG_USB_USBNET=m -CONFIG_USB_USS720=m - -# -# USB Serial Converter support -# -CONFIG_USB_SERIAL=m -# CONFIG_USB_SERIAL_DEBUG is not set -CONFIG_USB_SERIAL_GENERIC=y -CONFIG_USB_SERIAL_BELKIN=m -CONFIG_USB_SERIAL_WHITEHEAT=m -CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m -CONFIG_USB_SERIAL_EMPEG=m -CONFIG_USB_SERIAL_FTDI_SIO=m -CONFIG_USB_SERIAL_VISOR=m -CONFIG_USB_SERIAL_IPAQ=m -CONFIG_USB_SERIAL_IR=m -CONFIG_USB_SERIAL_EDGEPORT=m -CONFIG_USB_SERIAL_EDGEPORT_TI=m -CONFIG_USB_SERIAL_KEYSPAN_PDA=m -CONFIG_USB_SERIAL_KEYSPAN=m -# CONFIG_USB_SERIAL_KEYSPAN_USA28 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA28X is not set -CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y -CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y -# CONFIG_USB_SERIAL_KEYSPAN_USA19 is not set -# CONFIG_USB_SERIAL_KEYSPAN_USA18X is not set -CONFIG_USB_SERIAL_KEYSPAN_USA19W=y -CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y -CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y -CONFIG_USB_SERIAL_KEYSPAN_MPR=y -CONFIG_USB_SERIAL_KEYSPAN_USA49W=y -CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y -CONFIG_USB_SERIAL_MCT_U232=m -CONFIG_USB_SERIAL_KLSI=m -CONFIG_USB_SERIAL_KOBIL_SCT=m -CONFIG_USB_SERIAL_PL2303=m -CONFIG_USB_SERIAL_CYBERJACK=m -CONFIG_USB_SERIAL_XIRCOM=m -CONFIG_USB_SERIAL_OMNINET=m -CONFIG_USB_RIO500=m -CONFIG_USB_AUERSWALD=m -CONFIG_USB_TIGL=m -CONFIG_USB_BRLVGER=m -CONFIG_USB_LCD=m - -# -# Additional device driver support -# -CONFIG_NET_BROADCOM=m -CONFIG_CIPE=m -CONFIG_CRYPTO_AEP=m -CONFIG_MEGARAC=m -CONFIG_FC_QLA2200=m -CONFIG_FC_QLA2300=m -CONFIG_SCSI_ISCSI=m - -# -# Bluetooth support -# -CONFIG_BLUEZ=m -CONFIG_BLUEZ_L2CAP=m -CONFIG_BLUEZ_SCO=m -CONFIG_BLUEZ_RFCOMM=m -CONFIG_BLUEZ_RFCOMM_TTY=y -CONFIG_BLUEZ_BNEP=m -CONFIG_BLUEZ_BNEP_MC_FILTER=y -CONFIG_BLUEZ_BNEP_PROTO_FILTER=y - -# -# Bluetooth device drivers -# -CONFIG_BLUEZ_HCIUSB=m -CONFIG_BLUEZ_USB_SCO=y -CONFIG_BLUEZ_USB_ZERO_PACKET=y -CONFIG_BLUEZ_HCIUART=m -CONFIG_BLUEZ_HCIUART_H4=y -CONFIG_BLUEZ_HCIUART_BCSP=y -CONFIG_BLUEZ_HCIUART_BCSP_TXCRC=y -CONFIG_BLUEZ_HCIDTL1=m -CONFIG_BLUEZ_HCIBT3C=m -CONFIG_BLUEZ_HCIBLUECARD=m -CONFIG_BLUEZ_HCIBTUART=m -CONFIG_BLUEZ_HCIVHCI=m - -# -# Profiling support -# -CONFIG_PROFILING=y -CONFIG_OPROFILE=m - -# -# Kernel hacking -# -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_STACKOVERFLOW is not set -# CONFIG_DEBUG_HIGHMEM is not set -# CONFIG_DEBUG_SLAB is not set -# CONFIG_DEBUG_IOVIRT is not set -CONFIG_MAGIC_SYSRQ=y -# CONFIG_DEBUG_SPINLOCK is not set -CONFIG_FRAME_POINTER=y -# CONFIG_MCL_COREDUMP is not set - -# -# Library routines -# -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=m diff --git a/lustre/kernel_patches/kernel_configs/kernel-2.4.21-suse-2.4.21-2-x86_64.config b/lustre/kernel_patches/kernel_configs/kernel-2.4.21-suse-2.4.21-2-x86_64.config deleted file mode 100644 index eca7425..0000000 --- a/lustre/kernel_patches/kernel_configs/kernel-2.4.21-suse-2.4.21-2-x86_64.config +++ /dev/null @@ -1,2036 +0,0 @@ -# -# Automatically generated by make menuconfig: don't edit -# -CONFIG_X86_64=y -CONFIG_X86=y -# CONFIG_ISA is not set -# CONFIG_SBUS is not set -CONFIG_UID16=y -CONFIG_X86_CMPXCHG=y -CONFIG_EARLY_PRINTK=y - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y - -# -# Loadable module support -# -CONFIG_MODULES=y -CONFIG_MODVERSIONS=y -CONFIG_KMOD=y - -# -# Processor type and features -# -CONFIG_MK8=y -# CONFIG_GENERIC_CPU is not set -CONFIG_X86_L1_CACHE_BYTES=64 -CONFIG_X86_L1_CACHE_SHIFT=6 -CONFIG_X86_TSC=y -CONFIG_X86_GOOD_APIC=y - -# -# CPU Frequency scaling -# -CONFIG_CPU_FREQ=y -CONFIG_CPU_FREQ_TABLE=y -CONFIG_CPU_FREQ_PROC_INTF=y -CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_24_API=y -CONFIG_X86_POWERNOW_K8=m -# CONFIG_X86_POWERNOW_K8_DBG is not set -CONFIG_X86_MSR=m -CONFIG_X86_CPUID=m -# CONFIG_MATH_EMULATION is not set -# CONFIG_MCA is not set -# CONFIG_EISA is not set -CONFIG_X86_IO_APIC=y -CONFIG_X86_LOCAL_APIC=y -CONFIG_MTRR=y -# CONFIG_SMP is not set -CONFIG_HPET_TIMER=y -CONFIG_GART_IOMMU=y -CONFIG_X86_UP_IOAPIC=y -CONFIG_MCE=y -# CONFIG_K8_NUMA is not set - -# -# General setup -# -# CONFIG_DESKTOP is not set -CONFIG_NET=y -CONFIG_EVLOG=y -CONFIG_EVLOG_BUFSIZE=128 -CONFIG_EVLOG_FWPRINTK=y -# CONFIG_EVLOG_PRINTKWLOC is not set -CONFIG_PCI=y -CONFIG_PCI_DIRECT=y -# CONFIG_PCI_NAMES is not set -CONFIG_HOTPLUG=y - -# -# PCMCIA/CardBus support -# -CONFIG_PCMCIA=m -CONFIG_CARDBUS=y -CONFIG_TCIC=y -CONFIG_I82092=y -CONFIG_I82365=y - -# -# PCI Hotplug Support -# -CONFIG_HOTPLUG_PCI=m -# CONFIG_HOTPLUG_PCI_COMPAQ is not set -# CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM is not set -# CONFIG_HOTPLUG_PCI_IBM is not set -CONFIG_HOTPLUG_PCI_ACPI=m -CONFIG_HOTPLUG_PCI_AMD=m -CONFIG_SYSVIPC=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_SYSCTL=y -CONFIG_MAX_USER_RT_PRIO=100 -CONFIG_MAX_RT_PRIO=0 -CONFIG_KCORE_ELF=y -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=m -CONFIG_PM=y -CONFIG_IA32_EMULATION=y - -# -# ACPI Support -# -CONFIG_ACPI=y -# CONFIG_ACPI_HT_ONLY is not set -CONFIG_ACPI_INITRD=y -CONFIG_ACPI_BOOT=y -CONFIG_ACPI_BUS=y -CONFIG_ACPI_INTERPRETER=y -CONFIG_ACPI_EC=y -CONFIG_ACPI_POWER=y -CONFIG_ACPI_PCI=y -CONFIG_ACPI_SLEEP=y -CONFIG_ACPI_SYSTEM=y -CONFIG_ACPI_AC=m -CONFIG_ACPI_BATTERY=m -CONFIG_ACPI_BUTTON=m -CONFIG_ACPI_FAN=m -CONFIG_ACPI_PROCESSOR=m -CONFIG_ACPI_THERMAL=m -CONFIG_ACPI_ASUS=m -CONFIG_ACPI_TOSHIBA=m -# CONFIG_ACPI_DEBUG is not set -CONFIG_ACPI_RELAXED_AML=y - -# -# Memory Technology Devices (MTD) -# -CONFIG_MTD=m -# CONFIG_MTD_DEBUG is not set -CONFIG_MTD_PARTITIONS=m -CONFIG_MTD_CONCAT=m -CONFIG_MTD_REDBOOT_PARTS=m -CONFIG_MTD_CMDLINE_PARTS=m -CONFIG_MTD_CHAR=m -CONFIG_MTD_BLOCK=m -CONFIG_MTD_BLOCK_RO=m -CONFIG_FTL=m -CONFIG_NFTL=m -# CONFIG_NFTL_RW is not set - -# -# RAM/ROM/Flash chip drivers -# -CONFIG_MTD_CFI=m -CONFIG_MTD_JEDECPROBE=m -CONFIG_MTD_GEN_PROBE=m -CONFIG_MTD_CFI_ADV_OPTIONS=y -CONFIG_MTD_CFI_NOSWAP=y -# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set -# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set -# CONFIG_MTD_CFI_GEOMETRY is not set -CONFIG_MTD_CFI_INTELEXT=m -CONFIG_MTD_CFI_AMDSTD=m -CONFIG_MTD_CFI_STAA=m -# CONFIG_MTD_RAM is not set -# CONFIG_MTD_ROM is not set -CONFIG_MTD_ABSENT=m -CONFIG_MTD_OBSOLETE_CHIPS=y -CONFIG_MTD_AMDSTD=m -CONFIG_MTD_SHARP=m -CONFIG_MTD_JEDEC=m - -# -# Mapping drivers for chip access -# -CONFIG_MTD_PHYSMAP=m -CONFIG_MTD_PHYSMAP_START=8000000 -CONFIG_MTD_PHYSMAP_LEN=4000000 -CONFIG_MTD_PHYSMAP_BUSWIDTH=2 -CONFIG_MTD_PNC2000=m -CONFIG_MTD_SC520CDP=m -CONFIG_MTD_NETSC520=m -CONFIG_MTD_SBC_GXX=m -CONFIG_MTD_ELAN_104NC=m -CONFIG_MTD_DILNETPC=m -CONFIG_MTD_DILNETPC_BOOTSIZE=80000 -CONFIG_MTD_MIXMEM=m -CONFIG_MTD_OCTAGON=m -CONFIG_MTD_VMAX=m -CONFIG_MTD_SCx200_DOCFLASH=m -CONFIG_MTD_L440GX=m -# CONFIG_MTD_AMD76XROM is not set -CONFIG_MTD_ICH2ROM=m -CONFIG_MTD_NETtel=m -# CONFIG_MTD_SCB2_FLASH is not set -CONFIG_MTD_PCI=m -CONFIG_MTD_PCMCIA=m - -# -# Self-contained MTD device drivers -# -CONFIG_MTD_PMC551=m -CONFIG_MTD_PMC551_BUGFIX=y -# CONFIG_MTD_PMC551_DEBUG is not set -CONFIG_MTD_SLRAM=m -CONFIG_MTD_MTDRAM=m -CONFIG_MTDRAM_TOTAL_SIZE=4096 -CONFIG_MTDRAM_ERASE_SIZE=128 -CONFIG_MTD_BLKMTD=m -CONFIG_MTD_DOC1000=m -CONFIG_MTD_DOC2000=m -CONFIG_MTD_DOC2001=m -CONFIG_MTD_DOCPROBE=m -CONFIG_MTD_DOCPROBE_ADVANCED=y -CONFIG_MTD_DOCPROBE_ADDRESS=0000 -CONFIG_MTD_DOCPROBE_HIGH=y -CONFIG_MTD_DOCPROBE_55AA=y - -# -# NAND Flash Device Drivers -# -CONFIG_MTD_NAND=m -# CONFIG_MTD_NAND_VERIFY_WRITE is not set -CONFIG_MTD_NAND_IDS=m - -# -# Parallel port support -# -CONFIG_PARPORT=m -CONFIG_PARPORT_PC=m -CONFIG_PARPORT_PC_CML1=m -CONFIG_PARPORT_SERIAL=m -CONFIG_PARPORT_PC_FIFO=y -CONFIG_PARPORT_PC_SUPERIO=y -CONFIG_PARPORT_PC_PCMCIA=m -# CONFIG_PARPORT_AMIGA is not set -# CONFIG_PARPORT_MFC3 is not set -# CONFIG_PARPORT_ATARI is not set -# CONFIG_PARPORT_GSC is not set -# CONFIG_PARPORT_SUNBPP is not set -CONFIG_PARPORT_OTHER=y -CONFIG_PARPORT_1284=y - -# -# Block devices -# -CONFIG_BLK_DEV_FD=y -# CONFIG_BLK_DEV_XD is not set -CONFIG_PARIDE=m -CONFIG_PARIDE_PARPORT=m -CONFIG_PARIDE_PD=m -CONFIG_PARIDE_PCD=m -CONFIG_PARIDE_PF=m -CONFIG_PARIDE_PT=m -CONFIG_PARIDE_PG=m -CONFIG_PARIDE_ATEN=m -CONFIG_PARIDE_BPCK=m -CONFIG_PARIDE_BPCK6=m -CONFIG_PARIDE_COMM=m -CONFIG_PARIDE_DSTR=m -CONFIG_PARIDE_FIT2=m -CONFIG_PARIDE_FIT3=m -CONFIG_PARIDE_EPAT=m -CONFIG_PARIDE_EPATC8=y -CONFIG_PARIDE_EPIA=m -CONFIG_PARIDE_FRIQ=m -CONFIG_PARIDE_FRPW=m -CONFIG_PARIDE_KBIC=m -CONFIG_PARIDE_KTTI=m -CONFIG_PARIDE_ON20=m -CONFIG_PARIDE_ON26=m -CONFIG_BLK_CPQ_DA=m -CONFIG_BLK_CPQ_CISS_DA=m -CONFIG_CISS_SCSI_TAPE=y -CONFIG_BLK_DEV_DAC960=m -CONFIG_BLK_DEV_UMEM=m -CONFIG_BLK_DEV_LOOP=y -CONFIG_CIPHER_TWOFISH=m -CONFIG_BLK_DEV_NBD=m -CONFIG_BLK_DEV_RAM=y -CONFIG_BLK_DEV_RAM_SIZE=128000 -CONFIG_BLK_DEV_INITRD=y -CONFIG_BLK_STATS=y - -# -# Multi-device support (RAID and LVM) -# -CONFIG_MD=y -CONFIG_BLK_DEV_MD=y -CONFIG_MD_LINEAR=m -CONFIG_MD_RAID0=m -CONFIG_MD_RAID1=m -CONFIG_MD_RAID5=m -CONFIG_MD_MULTIPATH=m -CONFIG_BLK_DEV_LVM=m -CONFIG_BLK_DEV_DM=m -CONFIG_BLK_DEV_DM_MIRROR=m - -# -# Cryptography support (CryptoAPI) -# -CONFIG_CRYPTO=y -CONFIG_CIPHERS=y -CONFIG_CIPHER_AES=m -CONFIG_CIPHER_3DES=m -CONFIG_CIPHER_NULL=m -CONFIG_CIPHER_DES=m -CONFIG_DIGESTS=y -CONFIG_DIGEST_MD5=m -CONFIG_DIGEST_SHA1=m -CONFIG_CRYPTODEV=y -CONFIG_CRYPTOLOOP=m -CONFIG_CRYPTOLOOP_ATOMIC=y -# CONFIG_CRYPTOLOOP_IV_HACK is not set -# CONFIG_CRYPTOLOOP_DEBUG is not set - -# -# Networking options -# -CONFIG_PACKET=m -CONFIG_PACKET_MMAP=y -CONFIG_NETLINK_DEV=m -CONFIG_NETFILTER=y -# CONFIG_NETFILTER_DEBUG is not set -CONFIG_FILTER=y -CONFIG_UNIX=y -CONFIG_INET=y -CONFIG_IPSEC=m -CONFIG_IPSEC_DEBUG=y -CONFIG_IPSEC_DEBUG_DISABLE_DEFAULT=y -CONFIG_IPSEC_TUNNEL=y -CONFIG_TUX=m -CONFIG_TUX_EXTCGI=y -CONFIG_TUX_EXTENDED_LOG=y -# CONFIG_TUX_DEBUG is not set -CONFIG_IP_MULTICAST=y -CONFIG_IP_ADVANCED_ROUTER=y -CONFIG_IP_MULTIPLE_TABLES=y -CONFIG_IP_ROUTE_FWMARK=y -CONFIG_IP_ROUTE_NAT=y -CONFIG_IP_ROUTE_MULTIPATH=y -CONFIG_IP_ROUTE_TOS=y -CONFIG_IP_ROUTE_VERBOSE=y -CONFIG_IP_ROUTE_LARGE_TABLES=y -CONFIG_IP_PNP=y -CONFIG_IP_PNP_DHCP=y -CONFIG_IP_PNP_BOOTP=y -CONFIG_IP_PNP_RARP=y -CONFIG_NET_IPIP=m -CONFIG_NET_IPGRE=m -CONFIG_NET_IPGRE_BROADCAST=y -CONFIG_IP_MROUTE=y -CONFIG_IP_PIMSM_V1=y -CONFIG_IP_PIMSM_V2=y -# CONFIG_ARPD is not set -CONFIG_INET_ECN=y -CONFIG_SYN_COOKIES=y -CONFIG_IP_IPSEC=m - -# -# IP: Netfilter Configuration -# -CONFIG_IP_NF_CONNTRACK=m -CONFIG_IP_NF_FTP=m -CONFIG_IP_NF_AMANDA=m -CONFIG_IP_NF_TFTP=m -CONFIG_IP_NF_IRC=m -CONFIG_IP_NF_QUEUE=m -CONFIG_IP_NF_IPTABLES=m -CONFIG_IP_NF_MATCH_LIMIT=m -CONFIG_IP_NF_MATCH_MAC=m -CONFIG_IP_NF_MATCH_PKTTYPE=m -CONFIG_IP_NF_MATCH_MARK=m -CONFIG_IP_NF_MATCH_MULTIPORT=m -CONFIG_IP_NF_MATCH_TOS=m -CONFIG_IP_NF_MATCH_PSD=m -CONFIG_IP_NF_MATCH_ECN=m -CONFIG_IP_NF_MATCH_DSCP=m -CONFIG_IP_NF_MATCH_AH_ESP=m -CONFIG_IP_NF_MATCH_LENGTH=m -CONFIG_IP_NF_MATCH_TTL=m -CONFIG_IP_NF_MATCH_TCPMSS=m -CONFIG_IP_NF_MATCH_HELPER=m -CONFIG_IP_NF_MATCH_STATE=m -CONFIG_IP_NF_MATCH_CONNTRACK=m -CONFIG_IP_NF_MATCH_IPLIMIT=m -CONFIG_IP_NF_MATCH_UNCLEAN=m -CONFIG_IP_NF_MATCH_STRING=m -CONFIG_IP_NF_MATCH_OWNER=m -CONFIG_IP_NF_FILTER=m -CONFIG_IP_NF_TARGET_REJECT=m -CONFIG_IP_NF_TARGET_MIRROR=m -CONFIG_IP_NF_NAT=m -CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IP_NF_TARGET_MASQUERADE=m -CONFIG_IP_NF_TARGET_REDIRECT=m -CONFIG_IP_NF_NAT_AMANDA=m -# CONFIG_IP_NF_NAT_LOCAL is not set -CONFIG_IP_NF_NAT_SNMP_BASIC=m -CONFIG_IP_NF_NAT_IRC=m -CONFIG_IP_NF_NAT_FTP=m -CONFIG_IP_NF_NAT_TFTP=m -CONFIG_IP_NF_MANGLE=m -CONFIG_IP_NF_TARGET_TOS=m -CONFIG_IP_NF_TARGET_ECN=m -CONFIG_IP_NF_TARGET_DSCP=m -CONFIG_IP_NF_TARGET_MARK=m -CONFIG_IP_NF_TARGET_LOG=m -CONFIG_IP_NF_TARGET_ULOG=m -CONFIG_IP_NF_TARGET_TCPMSS=m -CONFIG_IP_NF_ARPTABLES=m -CONFIG_IP_NF_ARPFILTER=m -CONFIG_IP_NF_COMPAT_IPCHAINS=m -CONFIG_IP_NF_NAT_NEEDED=y -CONFIG_IP_NF_COMPAT_IPFWADM=m -CONFIG_IP_NF_NAT_NEEDED=y - -# -# IP: Virtual Server Configuration -# -CONFIG_IP_VS=m -# CONFIG_IP_VS_DEBUG is not set -CONFIG_IP_VS_TAB_BITS=12 -CONFIG_IP_VS_RR=m -CONFIG_IP_VS_WRR=m -CONFIG_IP_VS_LC=m -CONFIG_IP_VS_WLC=m -CONFIG_IP_VS_LBLC=m -CONFIG_IP_VS_LBLCR=m -CONFIG_IP_VS_DH=m -CONFIG_IP_VS_SH=m -CONFIG_IP_VS_SED=m -CONFIG_IP_VS_NQ=m -CONFIG_IP_VS_FTP=m -CONFIG_IPV6=m -# CONFIG_IPV6_DEBUG is not set -CONFIG_IPV6_IM=y -CONFIG_IPV6_MODULE_IP_GRE=y -CONFIG_IPV6_ISATAP=y -CONFIG_IPV6_PREFIXLIST=y -CONFIG_IPV6_6TO4_NEXTHOP=y -CONFIG_IPV6_PRIVACY=y -CONFIG_IPV6_SUBTREES=y -# CONFIG_IPV6_MLD6_ALL_DONE is not set -# CONFIG_IPV6_NODEINFO is not set -# CONFIG_IPV6_ZONE is not set -CONFIG_IPV6_DROP_FAKE_V4MAPPED=y - -# -# IPv6: Netfilter Configuration -# -CONFIG_IP6_NF_QUEUE=m -CONFIG_IP6_NF_IPTABLES=m -CONFIG_IP6_NF_MATCH_LIMIT=m -CONFIG_IP6_NF_MATCH_MAC=m -CONFIG_IP6_NF_MATCH_RT=m -CONFIG_IP6_NF_MATCH_OPTS=m -CONFIG_IP6_NF_MATCH_FRAG=m -CONFIG_IP6_NF_MATCH_HL=m -CONFIG_IP6_NF_MATCH_MULTIPORT=m -CONFIG_IP6_NF_MATCH_OWNER=m -CONFIG_IP6_NF_MATCH_MARK=m -CONFIG_IP6_NF_MATCH_IPV6HEADER=m -CONFIG_IP6_NF_MATCH_AHESP=m -CONFIG_IP6_NF_MATCH_LENGTH=m -CONFIG_IP6_NF_MATCH_EUI64=m -CONFIG_IP6_NF_FILTER=m -CONFIG_IP6_NF_TARGET_REJECT=m -CONFIG_IP6_NF_TARGET_LOG=m -CONFIG_IP6_NF_MANGLE=m -CONFIG_IP6_NF_TARGET_MARK=m -CONFIG_IPV6_IPSEC=y -CONFIG_IPV6_IPSEC_TUNNEL=y -CONFIG_IPV6_IPV6_TUNNEL=m -CONFIG_IPV6_MOBILITY=m -CONFIG_IPV6_MOBILITY_CN=m -CONFIG_IPV6_MOBILITY_MN=m -CONFIG_IPV6_MOBILITY_HA=m -# CONFIG_IPV6_MOBILITY_DEBUG is not set -# CONFIG_SHARED_IPV6_CARDS is not set -CONFIG_KHTTPD=m -CONFIG_KHTTPD_IPV6=y -# CONFIG_ATM is not set -CONFIG_VLAN_8021Q=m -CONFIG_IPX=m -# CONFIG_IPX_INTERN is not set -CONFIG_ATALK=m - -# -# Appletalk devices -# -CONFIG_DEV_APPLETALK=y -CONFIG_COPS_DAYNA=y -CONFIG_COPS_TANGENT=y -CONFIG_IPDDP=m -CONFIG_IPDDP_ENCAP=y -CONFIG_IPDDP_DECAP=y -CONFIG_DECNET=m -CONFIG_DECNET_SIOCGIFCONF=y -# CONFIG_DECNET_ROUTER is not set -CONFIG_BRIDGE=m -CONFIG_X25=m -CONFIG_LAPB=m -# CONFIG_LLC is not set -# CONFIG_NET_DIVERT is not set -CONFIG_ECONET=m -# CONFIG_ECONET_AUNUDP is not set -# CONFIG_ECONET_NATIVE is not set -CONFIG_WAN_ROUTER=m -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set - -# -# QoS and/or fair queueing -# -CONFIG_NET_SCHED=y -CONFIG_NET_SCH_CBQ=m -CONFIG_NET_SCH_HTB=m -CONFIG_NET_SCH_CSZ=m -CONFIG_NET_SCH_PRIO=m -CONFIG_NET_SCH_RED=m -CONFIG_NET_SCH_SFQ=m -CONFIG_NET_SCH_TEQL=m -CONFIG_NET_SCH_TBF=m -CONFIG_NET_SCH_GRED=m -CONFIG_NET_SCH_DSMARK=m -CONFIG_NET_SCH_INGRESS=m -CONFIG_NET_QOS=y -CONFIG_NET_ESTIMATOR=y -CONFIG_NET_CLS=y -CONFIG_NET_CLS_TCINDEX=m -CONFIG_NET_CLS_ROUTE4=m -CONFIG_NET_CLS_ROUTE=y -CONFIG_NET_CLS_FW=m -CONFIG_NET_CLS_U32=m -CONFIG_NET_CLS_RSVP=m -CONFIG_NET_CLS_RSVP6=m -CONFIG_NET_CLS_POLICE=y - -# -# Network testing -# -CONFIG_NET_PKTGEN=m - -# -# Telephony Support -# -CONFIG_PHONE=m -CONFIG_PHONE_IXJ=m -CONFIG_PHONE_IXJ_PCMCIA=m - -# -# ATA/IDE/MFM/RLL support -# -CONFIG_IDE=y - -# -# IDE, ATA and ATAPI Block devices -# -CONFIG_BLK_DEV_IDE=y -# CONFIG_BLK_DEV_HD_IDE is not set -# CONFIG_BLK_DEV_HD is not set -CONFIG_BLK_DEV_IDEDISK=y -CONFIG_IDEDISK_MULTI_MODE=y -CONFIG_IDEDISK_STROKE=y -CONFIG_BLK_DEV_IDECS=m -CONFIG_BLK_DEV_IDECD=m -CONFIG_BLK_DEV_IDETAPE=m -CONFIG_BLK_DEV_IDEFLOPPY=y -CONFIG_BLK_DEV_IDESCSI=m -# CONFIG_IDE_TASK_IOCTL is not set -CONFIG_BLK_DEV_CMD640=y -CONFIG_BLK_DEV_CMD640_ENHANCED=y -# CONFIG_BLK_DEV_ISAPNP is not set -CONFIG_BLK_DEV_IDEPCI=y -CONFIG_BLK_DEV_GENERIC=y -CONFIG_IDEPCI_SHARE_IRQ=y -CONFIG_BLK_DEV_IDEDMA_PCI=y -CONFIG_BLK_DEV_OFFBOARD=y -# CONFIG_BLK_DEV_IDEDMA_FORCED is not set -CONFIG_IDEDMA_PCI_AUTO=y -CONFIG_IDEDMA_ONLYDISK=y -CONFIG_BLK_DEV_IDEDMA=y -# CONFIG_IDEDMA_PCI_WIP is not set -# CONFIG_BLK_DEV_ADMA100 is not set -CONFIG_BLK_DEV_AEC62XX=y -CONFIG_BLK_DEV_ALI15X3=y -# CONFIG_WDC_ALI15X3 is not set -CONFIG_BLK_DEV_AMD74XX=y -# CONFIG_AMD74XX_OVERRIDE is not set -CONFIG_BLK_DEV_CMD64X=y -CONFIG_BLK_DEV_TRIFLEX=y -CONFIG_BLK_DEV_CY82C693=y -CONFIG_BLK_DEV_CS5530=y -CONFIG_BLK_DEV_HPT34X=y -# CONFIG_HPT34X_AUTODMA is not set -CONFIG_BLK_DEV_HPT366=y -# CONFIG_BLK_DEV_PIIX is not set -CONFIG_BLK_DEV_NS87415=y -# CONFIG_BLK_DEV_OPTI621 is not set -CONFIG_BLK_DEV_PDC202XX_OLD=y -CONFIG_PDC202XX_BURST=y -CONFIG_BLK_DEV_PDC202XX_NEW=y -CONFIG_PDC202XX_FORCE=y -# CONFIG_BLK_DEV_RZ1000 is not set -CONFIG_BLK_DEV_SC1200=y -# CONFIG_BLK_DEV_SVWKS is not set -CONFIG_BLK_DEV_SIIMAGE=y -CONFIG_BLK_DEV_SIS5513=y -CONFIG_BLK_DEV_SLC90E66=y -CONFIG_BLK_DEV_TRM290=y -CONFIG_BLK_DEV_VIA82CXXX=y -CONFIG_BLK_DEV_CENATEK=y -# CONFIG_IDE_CHIPSETS is not set -CONFIG_IDEDMA_AUTO=y -# CONFIG_IDEDMA_IVB is not set -# CONFIG_DMA_NONPCI is not set -CONFIG_BLK_DEV_PDC202XX=y -CONFIG_BLK_DEV_IDE_MODES=y -CONFIG_BLK_DEV_ATARAID=m -CONFIG_BLK_DEV_ATARAID_PDC=m -CONFIG_BLK_DEV_ATARAID_HPT=m -CONFIG_BLK_DEV_ATARAID_SII=m - -# -# SCSI support -# -CONFIG_SCSI=m -CONFIG_BLK_DEV_SD=m -CONFIG_SD_MAX_MAJORS=144 -CONFIG_CHR_DEV_ST=m -CONFIG_CHR_DEV_OSST=m -CONFIG_BLK_DEV_SR=m -# CONFIG_BLK_DEV_SR_VENDOR is not set -CONFIG_SR_EXTRA_DEVS=4 -CONFIG_CHR_DEV_SCH=m -CONFIG_CHR_DEV_SG=m -# CONFIG_SCSI_DEBUG_QUEUES is not set -CONFIG_SCSI_MULTI_LUN=y -CONFIG_SCSI_CONSTANTS=y -CONFIG_SCSI_LOGGING=y - -# -# SCSI low-level drivers -# -CONFIG_BLK_DEV_3W_XXXX_RAID=m -# CONFIG_SCSI_7000FASST is not set -CONFIG_SCSI_ACARD=m -# CONFIG_SCSI_AHA152X is not set -# CONFIG_SCSI_AHA1542 is not set -# CONFIG_SCSI_AHA1740 is not set -CONFIG_SCSI_AACRAID=m -CONFIG_SCSI_AIC7XXX=m -CONFIG_AIC7XXX_CMDS_PER_DEVICE=32 -CONFIG_AIC7XXX_RESET_DELAY_MS=5000 -CONFIG_AIC7XXX_PROBE_EISA_VL=y -# CONFIG_AIC7XXX_BUILD_FIRMWARE is not set -# CONFIG_AIC7XXX_DEBUG_ENABLE is not set -CONFIG_AIC7XXX_DEBUG_MASK=0 -CONFIG_AIC7XXX_REG_PRETTY_PRINT=y -CONFIG_SCSI_AIC79XX=m -CONFIG_AIC79XX_CMDS_PER_DEVICE=32 -CONFIG_AIC79XX_RESET_DELAY_MS=15000 -# CONFIG_AIC79XX_BUILD_FIRMWARE is not set -# CONFIG_AIC79XX_ENABLE_RD_STRM is not set -# CONFIG_AIC79XX_DEBUG_ENABLE is not set -CONFIG_AIC79XX_DEBUG_MASK=0 -CONFIG_AIC79XX_REG_PRETTY_PRINT=y -CONFIG_SCSI_AIC7XXX_OLD=m -CONFIG_AIC7XXX_OLD_TCQ_ON_BY_DEFAULT=y -CONFIG_AIC7XXX_OLD_CMDS_PER_DEVICE=24 -CONFIG_AIC7XXX_OLD_PROC_STATS=y -CONFIG_SCSI_DPT_I2O=m -CONFIG_SCSI_ADVANSYS=m -CONFIG_SCSI_IN2000=m -CONFIG_SCSI_AM53C974=m -CONFIG_SCSI_MEGARAID=m -CONFIG_SCSI_MEGARAID2=m -CONFIG_SCSI_BUSLOGIC=m -# CONFIG_SCSI_OMIT_FLASHPOINT is not set -CONFIG_SCSI_CPQFCTS=m -CONFIG_SCSI_DMX3191D=m -# CONFIG_SCSI_DTC3280 is not set -CONFIG_SCSI_EATA=m -CONFIG_SCSI_EATA_TAGGED_QUEUE=y -CONFIG_SCSI_EATA_LINKED_COMMANDS=y -CONFIG_SCSI_EATA_MAX_TAGS=16 -CONFIG_SCSI_EATA_DMA=m -CONFIG_SCSI_EATA_PIO=m -CONFIG_SCSI_LPFC=m -CONFIG_SCSI_FUTURE_DOMAIN=m -CONFIG_SCSI_GDTH=m -CONFIG_SCSI_GENERIC_NCR5380=m -CONFIG_SCSI_GENERIC_NCR53C400=y -CONFIG_SCSI_G_NCR5380_PORT=y -# CONFIG_SCSI_G_NCR5380_MEM is not set -CONFIG_SCSI_IPS_OLD=m -CONFIG_SCSI_IPS=m -CONFIG_SCSI_INITIO=m -CONFIG_SCSI_INIA100=m -CONFIG_SCSI_PPA=m -CONFIG_SCSI_IMM=m -# CONFIG_SCSI_IZIP_EPP16 is not set -# CONFIG_SCSI_IZIP_SLOW_CTR is not set -CONFIG_PPSCSI=m -CONFIG_PPSCSI_T348=m -CONFIG_PPSCSI_T358=m -CONFIG_PPSCSI_VPI0=m -CONFIG_PPSCSI_VPI2=m -CONFIG_PPSCSI_ONSCSI=m -CONFIG_PPSCSI_SPARCSI=m -CONFIG_PPSCSI_EPSA2=m -CONFIG_PPSCSI_EPST=m -# CONFIG_SCSI_NCR53C406A is not set -CONFIG_SCSI_NCR53C7xx=m -# CONFIG_SCSI_NCR53C7xx_sync is not set -CONFIG_SCSI_NCR53C7xx_FAST=y -CONFIG_SCSI_NCR53C7xx_DISCONNECT=y -CONFIG_SCSI_SYM53C8XX_2=m -CONFIG_SCSI_SYM53C8XX_DMA_ADDRESSING_MODE=1 -CONFIG_SCSI_SYM53C8XX_DEFAULT_TAGS=16 -CONFIG_SCSI_SYM53C8XX_MAX_TAGS=64 -# CONFIG_SCSI_SYM53C8XX_IOMAPPED is not set -CONFIG_SCSI_NCR53C8XX=m -CONFIG_SCSI_SYM53C8XX=m -CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 -CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 -CONFIG_SCSI_NCR53C8XX_SYNC=80 -CONFIG_SCSI_NCR53C8XX_PROFILE=y -# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set -CONFIG_SCSI_NCR53C8XX_PQS_PDS=y -# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set -# CONFIG_SCSI_PAS16 is not set -CONFIG_SCSI_PCI2000=m -CONFIG_SCSI_PCI2220I=m -# CONFIG_SCSI_PSI240I is not set -# CONFIG_SCSI_QLOGIC_FAS is not set -CONFIG_SCSI_QLOGIC_ISP=m -CONFIG_SCSI_QLOGIC_FC=m -CONFIG_SCSI_QLOGIC_FC_FIRMWARE=y -CONFIG_SCSI_QLOGIC_1280=m -CONFIG_SCSI_QLOGIC_QLA2XXX=y -CONFIG_SCSI_QLOGIC_QLA2XXX_QLA2100=m -CONFIG_SCSI_QLOGIC_QLA2XXX_QLA2200=m -CONFIG_SCSI_QLOGIC_QLA2XXX_QLA2300=m -CONFIG_SCSI_SEAGATE=m -CONFIG_SCSI_SIM710=m -CONFIG_SCSI_SYM53C416=m -CONFIG_SCSI_DC395x_TRMS1040=m -CONFIG_SCSI_DC390T=m -# CONFIG_SCSI_DC390T_NOGENSUPP is not set -# CONFIG_SCSI_T128 is not set -CONFIG_SCSI_U14_34F=m -CONFIG_SCSI_U14_34F_LINKED_COMMANDS=y -CONFIG_SCSI_U14_34F_MAX_TAGS=8 -CONFIG_SCSI_ULTRASTOR=m -CONFIG_SCSI_NSP32=m -CONFIG_SCSI_DEBUG=m - -# -# PCMCIA SCSI adapter support -# -CONFIG_SCSI_PCMCIA=y -CONFIG_PCMCIA_AHA152X=m -CONFIG_PCMCIA_FDOMAIN=m -CONFIG_PCMCIA_NINJA_SCSI=m -CONFIG_PCMCIA_QLOGIC=m - -# -# Fusion MPT device support -# -CONFIG_FUSION=m -# CONFIG_FUSION_BOOT is not set -CONFIG_FUSION_MAX_SGE=40 -CONFIG_FUSION_ISENSE=m -CONFIG_FUSION_CTL=m -CONFIG_FUSION_LAN=m -CONFIG_NET_FC=y - -# -# IEEE 1394 (FireWire) support (EXPERIMENTAL) -# -CONFIG_IEEE1394=m -CONFIG_IEEE1394_PCILYNX=m -CONFIG_IEEE1394_OHCI1394=m -CONFIG_IEEE1394_VIDEO1394=m -CONFIG_IEEE1394_SBP2=m -# CONFIG_IEEE1394_SBP2_PHYS_DMA is not set -CONFIG_IEEE1394_ETH1394=m -CONFIG_IEEE1394_DV1394=m -CONFIG_IEEE1394_RAWIO=m -CONFIG_IEEE1394_CMP=m -CONFIG_IEEE1394_AMDTP=m -# CONFIG_IEEE1394_VERBOSEDEBUG is not set -# CONFIG_IEEE1394_OUI_DB is not set - -# -# Network device support -# -CONFIG_NETDEVICES=y - -# -# ARCnet devices -# -CONFIG_ARCNET=m -CONFIG_ARCNET_1201=m -CONFIG_ARCNET_1051=m -CONFIG_ARCNET_RAW=m -CONFIG_ARCNET_COM90xx=m -CONFIG_ARCNET_COM90xxIO=m -CONFIG_ARCNET_RIM_I=m -CONFIG_ARCNET_COM20020=m -# CONFIG_ARCNET_COM20020_ISA is not set -CONFIG_ARCNET_COM20020_PCI=m -CONFIG_DUMMY=m -CONFIG_BONDING=m -CONFIG_EQUALIZER=m -CONFIG_TUN=m -CONFIG_ETHERTAP=m - -# -# Ethernet (10 or 100Mbit) -# -CONFIG_NET_ETHERNET=y -# CONFIG_SUNLANCE is not set -CONFIG_HAPPYMEAL=m -# CONFIG_SUNBMAC is not set -# CONFIG_SUNQE is not set -CONFIG_SUNGEM=m -CONFIG_NET_VENDOR_3COM=y -# CONFIG_EL1 is not set -# CONFIG_EL2 is not set -# CONFIG_ELPLUS is not set -# CONFIG_EL16 is not set -# CONFIG_ELMC is not set -# CONFIG_ELMC_II is not set -CONFIG_VORTEX=m -CONFIG_TYPHOON=m -# CONFIG_LANCE is not set -CONFIG_NET_VENDOR_SMC=y -# CONFIG_WD80x3 is not set -# CONFIG_ULTRAMCA is not set -# CONFIG_ULTRA is not set -# CONFIG_ULTRA32 is not set -# CONFIG_SMC9194 is not set -CONFIG_NET_VENDOR_RACAL=y -# CONFIG_NI5010 is not set -# CONFIG_NI52 is not set -# CONFIG_NI65 is not set -CONFIG_HP100=m -# CONFIG_NET_ISA is not set -CONFIG_NET_PCI=y -CONFIG_PCNET32=m -CONFIG_PCNET32_OLD=m -CONFIG_AMD8111_ETH=m -CONFIG_ADAPTEC_STARFIRE=m -# CONFIG_APRICOT is not set -CONFIG_NET_BCM4400=m -# CONFIG_CS89x0 is not set -CONFIG_TULIP=m -# CONFIG_TULIP_MWI is not set -# CONFIG_TULIP_MMIO is not set -CONFIG_DE4X5=m -CONFIG_DGRS=m -CONFIG_DM9102=m -CONFIG_EEPRO100=m -# CONFIG_EEPRO100_PIO is not set -CONFIG_E100=m -# CONFIG_LNE390 is not set -CONFIG_FEALNX=m -CONFIG_NATSEMI=m -CONFIG_NETGEAR_GA621=m -CONFIG_NETGEAR_GA622=m -CONFIG_NE2K_PCI=m -# CONFIG_NE3210 is not set -# CONFIG_ES3210 is not set -CONFIG_8139CP=m -CONFIG_8139TOO=m -# CONFIG_8139TOO_PIO is not set -# CONFIG_8139TOO_TUNE_TWISTER is not set -CONFIG_8139TOO_8129=y -# CONFIG_8139_OLD_RX_RESET is not set -CONFIG_SIS900=m -CONFIG_EPIC100=m -CONFIG_SUNDANCE=m -# CONFIG_SUNDANCE_MMIO is not set -CONFIG_TLAN=m -CONFIG_TC35815=m -CONFIG_VIA_RHINE=m -# CONFIG_VIA_RHINE_MMIO is not set -CONFIG_WINBOND_840=m -CONFIG_NET_POCKET=y -# CONFIG_DE600 is not set -# CONFIG_DE620 is not set - -# -# Ethernet (1000 Mbit) -# -CONFIG_ACENIC=m -# CONFIG_ACENIC_OMIT_TIGON_I is not set -CONFIG_DL2K=m -CONFIG_E1000=m -# CONFIG_MYRI_SBUS is not set -CONFIG_NS83820=m -CONFIG_HAMACHI=m -CONFIG_YELLOWFIN=m -CONFIG_R8169=m -CONFIG_SK98LIN=m -CONFIG_SK98LIN_T1=y -CONFIG_SK98LIN_T3=y -CONFIG_SK98LIN_T8=y -CONFIG_SK98LIN_T6=y -CONFIG_SK98LIN_T9=y -CONFIG_SK98LIN_T4=y -CONFIG_SK98LIN_T7=y -CONFIG_SK98LIN_T2=y -CONFIG_SK98LIN_T5=y -CONFIG_SK9DLIN=m -CONFIG_TIGON3=m -CONFIG_NET_BROADCOM=m -CONFIG_FDDI=y -CONFIG_DEFXX=m -CONFIG_SKFP=m -CONFIG_NETCONSOLE=m -CONFIG_HIPPI=y -CONFIG_ROADRUNNER=m -CONFIG_ROADRUNNER_LARGE_RINGS=y -CONFIG_PLIP=m -CONFIG_PPP=m -CONFIG_PPP_MULTILINK=y -CONFIG_PPP_FILTER=y -CONFIG_PPP_ASYNC=m -CONFIG_PPP_SYNC_TTY=m -CONFIG_PPP_DEFLATE=m -CONFIG_PPP_BSDCOMP=m -CONFIG_PPPOE=m -CONFIG_SLIP=m -CONFIG_SLIP_COMPRESSED=y -CONFIG_SLIP_SMART=y -CONFIG_SLIP_MODE_SLIP6=y - -# -# Wireless LAN (non-hamradio) -# -CONFIG_NET_RADIO=y -CONFIG_STRIP=m -CONFIG_WAVELAN=m -CONFIG_AIRONET4500=m -CONFIG_AIRONET4500_NONCS=m -CONFIG_AIRONET4500_PNP=y -CONFIG_AIRONET4500_PCI=y -CONFIG_AIRONET4500_ISA=y -CONFIG_AIRONET4500_I365=y -CONFIG_AIRONET4500_PROC=m -CONFIG_AIRO=m -CONFIG_HERMES=m -CONFIG_PLX_HERMES=m -CONFIG_PCI_HERMES=m -CONFIG_PCMCIA_HERMES=m -CONFIG_AIRO_CS=m -CONFIG_NET_WIRELESS=y - -# -# Token Ring devices -# -# CONFIG_TR is not set -CONFIG_NET_FC=y -CONFIG_IPHASE5526=m -CONFIG_RCPCI=m -CONFIG_SHAPER=m - -# -# Wan interfaces -# -# CONFIG_WAN is not set - -# -# PCMCIA network device support -# -CONFIG_NET_PCMCIA=y -CONFIG_PCMCIA_3C589=m -CONFIG_PCMCIA_3C574=m -CONFIG_PCMCIA_FMVJ18X=m -CONFIG_PCMCIA_PCNET=m -CONFIG_PCMCIA_AXNET=m -CONFIG_PCMCIA_NMCLAN=m -CONFIG_PCMCIA_SMC91C92=m -CONFIG_PCMCIA_XIRC2PS=m -CONFIG_ARCNET_COM20020_CS=m -# CONFIG_PCMCIA_IBMTR is not set -CONFIG_PCMCIA_XIRCOM=m -CONFIG_PCMCIA_XIRTULIP=m -CONFIG_NET_PCMCIA_RADIO=y -CONFIG_PCMCIA_RAYCS=m -CONFIG_PCMCIA_NETWAVE=m -CONFIG_PCMCIA_WAVELAN=m -CONFIG_AIRONET4500_CS=m - -# -# Amateur Radio support -# -CONFIG_HAMRADIO=y -CONFIG_AX25=m -CONFIG_AX25_DAMA_SLAVE=y -CONFIG_NETROM=m -CONFIG_ROSE=m - -# -# AX.25 network device drivers -# -CONFIG_MKISS=m -CONFIG_6PACK=m -CONFIG_BPQETHER=m -CONFIG_SCC_DELAY=y -CONFIG_SCC_TRXECHO=y -CONFIG_BAYCOM_SER_FDX=m -CONFIG_BAYCOM_SER_HDX=m -CONFIG_BAYCOM_PAR=m -CONFIG_BAYCOM_EPP=m -CONFIG_SOUNDMODEM=m -CONFIG_SOUNDMODEM_SBC=y -CONFIG_SOUNDMODEM_WSS=y -CONFIG_SOUNDMODEM_AFSK1200=y -CONFIG_SOUNDMODEM_AFSK2400_7=y -CONFIG_SOUNDMODEM_AFSK2400_8=y -CONFIG_SOUNDMODEM_AFSK2666=y -CONFIG_SOUNDMODEM_HAPN4800=y -CONFIG_SOUNDMODEM_PSK4800=y -CONFIG_SOUNDMODEM_FSK9600=y -CONFIG_YAM=m - -# -# IrDA (infrared) support -# -CONFIG_IRDA=m -CONFIG_IRLAN=m -CONFIG_IRNET=m -CONFIG_IRCOMM=m -CONFIG_IRDA_ULTRA=y -CONFIG_IRDA_CACHE_LAST_LSAP=y -# CONFIG_IRDA_FAST_RR is not set -# CONFIG_IRDA_DEBUG is not set - -# -# Infrared-port device drivers -# -CONFIG_IRTTY_SIR=m -CONFIG_IRPORT_SIR=m -CONFIG_DONGLE=y -CONFIG_ESI_DONGLE=m -CONFIG_ACTISYS_DONGLE=m -CONFIG_TEKRAM_DONGLE=m -CONFIG_GIRBIL_DONGLE=m -CONFIG_LITELINK_DONGLE=m -CONFIG_MCP2120_DONGLE=m -CONFIG_OLD_BELKIN_DONGLE=m -CONFIG_ACT200L_DONGLE=m -CONFIG_MA600_DONGLE=m -CONFIG_USB_IRDA=m -CONFIG_NSC_FIR=m -CONFIG_WINBOND_FIR=m -# CONFIG_TOSHIBA_OLD is not set -CONFIG_TOSHIBA_FIR=m -CONFIG_SMC_IRCC_FIR=m -CONFIG_ALI_FIR=m -CONFIG_VLSI_FIR=m - -# -# ISDN subsystem -# -CONFIG_ISDN=m -CONFIG_ISDN_BOOL=y -CONFIG_ISDN_PPP=y -CONFIG_IPPP_FILTER=y -CONFIG_ISDN_PPP_VJ=y -CONFIG_ISDN_MPP=y -CONFIG_ISDN_PPP_BSDCOMP=m -CONFIG_ISDN_AUDIO=y -CONFIG_ISDN_TTY_FAX=y -CONFIG_ISDN_X25=y - -# -# ISDN feature submodules -# -CONFIG_ISDN_DRV_LOOP=m -CONFIG_ISDN_DIVERSION=m - -# -# Passive ISDN cards -# -CONFIG_ISDN_DRV_HISAX=m -CONFIG_ISDN_HISAX=y -CONFIG_HISAX_EURO=y -CONFIG_DE_AOC=y -# CONFIG_HISAX_NO_SENDCOMPLETE is not set -# CONFIG_HISAX_NO_LLC is not set -# CONFIG_HISAX_NO_KEYPAD is not set -CONFIG_HISAX_1TR6=y -CONFIG_HISAX_NI1=y -CONFIG_HISAX_MAX_CARDS=8 -CONFIG_HISAX_TELESPCI=y -CONFIG_HISAX_S0BOX=y -CONFIG_HISAX_FRITZPCI=y -CONFIG_HISAX_AVM_A1_PCMCIA=y -CONFIG_HISAX_ELSA=y -CONFIG_HISAX_DIEHLDIVA=y -CONFIG_HISAX_SEDLBAUER=y -CONFIG_HISAX_NETJET=y -CONFIG_HISAX_NETJET_U=y -CONFIG_HISAX_NICCY=y -CONFIG_HISAX_BKM_A4T=y -CONFIG_HISAX_SCT_QUADRO=y -CONFIG_HISAX_GAZEL=y -CONFIG_HISAX_HFC_PCI=y -CONFIG_HISAX_W6692=y -CONFIG_HISAX_HFC_SX=y -CONFIG_HISAX_ENTERNOW_PCI=y -# CONFIG_HISAX_DEBUG is not set -# CONFIG_HISAX_TELES_CS is not set -CONFIG_HISAX_SEDLBAUER_CS=m -CONFIG_HISAX_ELSA_CS=m -# CONFIG_HISAX_AVM_A1_CS is not set -CONFIG_HISAX_ST5481=m -CONFIG_HISAX_FRITZ_PCIPNP=m -CONFIG_USB_AUERISDN=m - -# -# Active ISDN cards -# -CONFIG_ISDN_DRV_ICN=m -CONFIG_ISDN_DRV_PCBIT=m -CONFIG_ISDN_DRV_SC=m -CONFIG_ISDN_DRV_ACT2000=m -CONFIG_ISDN_DRV_EICON=y -CONFIG_ISDN_DRV_EICON_DIVAS=m -CONFIG_ISDN_DRV_EICON_OLD=m -CONFIG_ISDN_DRV_EICON_PCI=y -CONFIG_ISDN_DRV_EICON_ISA=y -CONFIG_ISDN_DRV_TPAM=m -CONFIG_ISDN_CAPI=m -CONFIG_ISDN_DRV_AVMB1_VERBOSE_REASON=y -CONFIG_ISDN_CAPI_MIDDLEWARE=y -CONFIG_ISDN_CAPI_CAPI20=m -CONFIG_ISDN_CAPI_CAPIFS_BOOL=y -CONFIG_ISDN_CAPI_CAPIFS=m -CONFIG_ISDN_CAPI_CAPIDRV=m -# CONFIG_ISDN_DRV_AVMB1_B1ISA is not set -CONFIG_ISDN_DRV_AVMB1_B1PCI=m -CONFIG_ISDN_DRV_AVMB1_B1PCIV4=y -# CONFIG_ISDN_DRV_AVMB1_T1ISA is not set -CONFIG_ISDN_DRV_AVMB1_B1PCMCIA=m -CONFIG_ISDN_DRV_AVMB1_AVM_CS=m -CONFIG_ISDN_DRV_AVMB1_T1PCI=m -CONFIG_ISDN_DRV_AVMB1_C4=m -CONFIG_HYSDN=m -CONFIG_HYSDN_CAPI=y - -# -# Input core support -# -CONFIG_INPUT=m -CONFIG_INPUT_KEYBDEV=m -CONFIG_INPUT_MOUSEDEV=m -CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024 -CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768 -CONFIG_INPUT_JOYDEV=m -CONFIG_INPUT_EVDEV=m - -# -# Character devices -# -CONFIG_VT=y -CONFIG_ECC=m -CONFIG_VT_CONSOLE=y -CONFIG_SERIAL=y -CONFIG_SERIAL_CONSOLE=y -CONFIG_SERIAL_EXTENDED=y -CONFIG_SERIAL_MANY_PORTS=y -CONFIG_SERIAL_SHARE_IRQ=y -# CONFIG_SERIAL_DETECT_IRQ is not set -CONFIG_SERIAL_MULTIPORT=y -CONFIG_HUB6=y -CONFIG_SERIAL_NONSTANDARD=y -CONFIG_COMPUTONE=m -CONFIG_ROCKETPORT=m -CONFIG_CYCLADES=m -# CONFIG_CYZ_INTR is not set -# CONFIG_ESPSERIAL is not set -CONFIG_MOXA_INTELLIO=m -CONFIG_MOXA_SMARTIO=m -CONFIG_ISI=m -CONFIG_SYNCLINK=m -CONFIG_SYNCLINKMP=m -CONFIG_N_HDLC=m -CONFIG_RISCOM8=m -CONFIG_STALDRV=y -CONFIG_STALLION=m -CONFIG_ISTALLION=m -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 -CONFIG_PRINTER=m -# CONFIG_LP_CONSOLE is not set -CONFIG_PPDEV=m -CONFIG_TIPAR=m - -# -# I2C support -# -CONFIG_I2C=m -CONFIG_I2C_ALGOBIT=m -CONFIG_I2C_PHILIPSPAR=m -# CONFIG_I2C_ELV is not set -# CONFIG_I2C_VELLEMAN is not set -CONFIG_SCx200_I2C=m -CONFIG_SCx200_I2C_SCL=12 -CONFIG_SCx200_I2C_SDA=13 -CONFIG_SCx200_ACB=m -CONFIG_I2C_ALGOPCF=m -# CONFIG_I2C_ELEKTOR is not set -CONFIG_I2C_MAINBOARD=y -CONFIG_I2C_ALI1535=m -CONFIG_I2C_ALI15X3=m -CONFIG_I2C_HYDRA=m -CONFIG_I2C_AMD756=m -CONFIG_I2C_AMD8111=m -CONFIG_I2C_I801=m -# CONFIG_I2C_I810 is not set -CONFIG_I2C_PIIX4=m -CONFIG_I2C_SIS5595=m -CONFIG_I2C_SIS630=m -CONFIG_I2C_SIS645=m -CONFIG_I2C_SAVAGE4=m -CONFIG_I2C_VIA=m -CONFIG_I2C_VIAPRO=m -CONFIG_I2C_VOODOO3=m -CONFIG_I2C_ISA=m -CONFIG_I2C_CHARDEV=m -CONFIG_I2C_PROC=m - -# -# Hardware sensors support -# -CONFIG_SENSORS=y -CONFIG_SENSORS_ADM1021=m -CONFIG_SENSORS_ADM1024=m -CONFIG_SENSORS_ADM1025=m -CONFIG_SENSORS_ADM1026=m -CONFIG_SENSORS_ADM9240=m -CONFIG_SENSORS_DS1621=m -CONFIG_SENSORS_FSCPOS=m -CONFIG_SENSORS_FSCSCY=m -CONFIG_SENSORS_GL518SM=m -CONFIG_SENSORS_GL520SM=m -CONFIG_SENSORS_MAXILIFE=m -CONFIG_SENSORS_IT87=m -CONFIG_SENSORS_MTP008=m -CONFIG_SENSORS_LM75=m -CONFIG_SENSORS_LM78=m -CONFIG_SENSORS_LM80=m -CONFIG_SENSORS_LM85=m -CONFIG_SENSORS_LM87=m -# CONFIG_SENSORS_LM92 is not set -CONFIG_SENSORS_SIS5595=m -# CONFIG_SENSORS_SMSC47M1 is not set -CONFIG_SENSORS_THMC50=m -CONFIG_SENSORS_VIA686A=m -CONFIG_SENSORS_VT1211=m -CONFIG_SENSORS_VT8231=m -CONFIG_SENSORS_W83781D=m -CONFIG_SENSORS_OTHER=y -CONFIG_SENSORS_BT869=m -CONFIG_SENSORS_DDCMON=m -CONFIG_SENSORS_EEPROM=m -CONFIG_SENSORS_MATORB=m -# CONFIG_SENSORS_PCF8574 is not set -# CONFIG_SENSORS_PCF8591 is not set - -# -# Mice -# -CONFIG_BUSMOUSE=m -CONFIG_ATIXL_BUSMOUSE=m -CONFIG_LOGIBUSMOUSE=m -CONFIG_MS_BUSMOUSE=m -CONFIG_MOUSE=y -CONFIG_PSMOUSE=y -CONFIG_82C710_MOUSE=y -CONFIG_PC110_PAD=m -CONFIG_MK712_MOUSE=m - -# -# Joysticks -# -CONFIG_INPUT_GAMEPORT=m -CONFIG_INPUT_NS558=m -CONFIG_INPUT_LIGHTNING=m -CONFIG_INPUT_PCIGAME=m -CONFIG_INPUT_CS461X=m -CONFIG_INPUT_EMU10K1=m -CONFIG_INPUT_FM801=m -CONFIG_INPUT_SERIO=m -CONFIG_INPUT_SERPORT=m -CONFIG_INPUT_ANALOG=m -CONFIG_INPUT_A3D=m -CONFIG_INPUT_ADI=m -CONFIG_INPUT_COBRA=m -CONFIG_INPUT_GF2K=m -CONFIG_INPUT_GRIP=m -CONFIG_INPUT_INTERACT=m -CONFIG_INPUT_TMDC=m -CONFIG_INPUT_SIDEWINDER=m -CONFIG_INPUT_IFORCE_USB=m -CONFIG_INPUT_IFORCE_232=m -CONFIG_INPUT_WARRIOR=m -CONFIG_INPUT_MAGELLAN=m -CONFIG_INPUT_SPACEORB=m -CONFIG_INPUT_SPACEBALL=m -CONFIG_INPUT_STINGER=m -CONFIG_INPUT_DB9=m -CONFIG_INPUT_GAMECON=m -CONFIG_INPUT_TURBOGRAFX=m -CONFIG_QIC02_TAPE=m -CONFIG_QIC02_DYNCONF=y -CONFIG_IPMI_HANDLER=m -CONFIG_IPMI_PANIC_EVENT=y -CONFIG_IPMI_DEVICE_INTERFACE=m -CONFIG_IPMI_KCS=m -CONFIG_IPMI_WATCHDOG=m - -# -# Watchdog Cards -# -CONFIG_WATCHDOG=y -CONFIG_WATCHDOG_NOWAYOUT=y -CONFIG_ACQUIRE_WDT=m -CONFIG_ADVANTECH_WDT=m -CONFIG_ALIM1535_WDT=m -CONFIG_ALIM7101_WDT=m -CONFIG_SC520_WDT=m -CONFIG_PCWATCHDOG=m -CONFIG_EUROTECH_WDT=m -CONFIG_IB700_WDT=m -CONFIG_WAFER_WDT=m -# CONFIG_I810_TCO is not set -CONFIG_MIXCOMWD=m -CONFIG_60XX_WDT=m -CONFIG_SC1200_WDT=m -CONFIG_SCx200_WDT=m -CONFIG_SOFT_WATCHDOG=m -CONFIG_W83877F_WDT=m -CONFIG_WDT=m -CONFIG_WDTPCI=m -CONFIG_WDT_501=y -CONFIG_WDT_501_FAN=y -CONFIG_MACHZ_WDT=m -CONFIG_DEADMAN=m -CONFIG_HANGCHECK_TIMER=m -CONFIG_AMD7XX_TCO=m -CONFIG_SCx200_GPIO=m -CONFIG_AMD_RNG=m -CONFIG_INTEL_RNG=m -CONFIG_AMD_PM768=m -CONFIG_NVRAM=m -CONFIG_RTC=y -CONFIG_DTLK=m -CONFIG_R3964=m -CONFIG_APPLICOM=m - -# -# Ftape, the floppy tape device driver -# -CONFIG_FTAPE=m -CONFIG_ZFTAPE=m -CONFIG_ZFT_DFLT_BLK_SZ=10240 -CONFIG_ZFT_COMPRESSOR=m -CONFIG_FT_NR_BUFFERS=3 -CONFIG_FT_PROC_FS=y -CONFIG_FT_NORMAL_DEBUG=y -# CONFIG_FT_FULL_DEBUG is not set -# CONFIG_FT_NO_TRACE is not set -# CONFIG_FT_NO_TRACE_AT_ALL is not set -CONFIG_FT_STD_FDC=y -# CONFIG_FT_MACH2 is not set -# CONFIG_FT_PROBE_FC10 is not set -# CONFIG_FT_ALT_FDC is not set -CONFIG_FT_FDC_THR=8 -CONFIG_FT_FDC_MAX_RATE=2000 -CONFIG_FT_ALPHA_CLOCK=0 -CONFIG_AGP=y -CONFIG_AGP_AMD_8151=y -# CONFIG_AGP_INTEL is not set -# CONFIG_AGP_I810 is not set -# CONFIG_AGP_VIA is not set -# CONFIG_AGP_AMD is not set -# CONFIG_AGP_SIS is not set -# CONFIG_AGP_ALI is not set -# CONFIG_AGP_SWORKS is not set -# CONFIG_AGP_NVIDIA is not set -CONFIG_DRM=y -# CONFIG_DRM_OLD is not set -CONFIG_DRM_NEW=y -CONFIG_DRM_TDFX=m -CONFIG_DRM_R128=m -CONFIG_DRM_RADEON=m -CONFIG_DRM_I810=m -# CONFIG_DRM_I810_XFREE_41 is not set -CONFIG_DRM_I830=m -CONFIG_DRM_MGA=m -# CONFIG_DRM_SIS is not set - -# -# PCMCIA character devices -# -CONFIG_PCMCIA_SERIAL_CS=m -CONFIG_SYNCLINK_CS=m -CONFIG_MWAVE=m - -# -# Multimedia devices -# -CONFIG_VIDEO_DEV=m - -# -# Video For Linux -# -CONFIG_VIDEO_PROC_FS=y -CONFIG_I2C_PARPORT=m -CONFIG_VIDEO_BT848=m -CONFIG_VIDEO_PMS=m -CONFIG_VIDEO_BWQCAM=m -CONFIG_VIDEO_CQCAM=m -CONFIG_VIDEO_W9966=m -CONFIG_VIDEO_CPIA=m -CONFIG_VIDEO_CPIA_PP=m -CONFIG_VIDEO_CPIA_USB=m -CONFIG_VIDEO_SAA5249=m -CONFIG_TUNER_3036=m -CONFIG_VIDEO_STRADIS=m -CONFIG_VIDEO_ZORAN=m -CONFIG_VIDEO_ZORAN_BUZ=m -CONFIG_VIDEO_ZORAN_DC10=m -CONFIG_VIDEO_ZORAN_LML33=m -CONFIG_VIDEO_ZR36120=m -# CONFIG_VIDEO_MEYE is not set - -# -# Radio Adapters -# -CONFIG_RADIO_GEMTEK_PCI=m -CONFIG_RADIO_MAXIRADIO=m -CONFIG_RADIO_MAESTRO=m -CONFIG_RADIO_MIROPCM20=m -# CONFIG_DXR3 is not set - -# -# File systems -# -CONFIG_QUOTA=y -CONFIG_QFMT_V1=m -CONFIG_QFMT_V2=m -CONFIG_QIFACE_COMPAT=y -# CONFIG_QIFACE_V1 is not set -CONFIG_QIFACE_V2=y -CONFIG_AUTOFS_FS=m -CONFIG_AUTOFS4_FS=m -CONFIG_REISERFS_FS=m -# CONFIG_REISERFS_CHECK is not set -CONFIG_REISERFS_PROC_INFO=y -CONFIG_REISERFS_FS_XATTR=y -CONFIG_REISERFS_FS_XATTR_USER=y -CONFIG_REISERFS_FS_XATTR_TRUSTED=y -CONFIG_REISERFS_FS_POSIX_ACL=y -CONFIG_ADFS_FS=m -# CONFIG_ADFS_FS_RW is not set -CONFIG_AFFS_FS=m -CONFIG_HFS_FS=m -CONFIG_HFSPLUS_FS=m -CONFIG_BEFS_FS=m -# CONFIG_BEFS_DEBUG is not set -CONFIG_BFS_FS=m -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -CONFIG_EXT3_FS_XATTR_SHARING=y -CONFIG_EXT3_FS_XATTR_USER=y -CONFIG_EXT3_FS_XATTR_TRUSTED=y -CONFIG_EXT3_FS_POSIX_ACL=y -CONFIG_JBD=y -CONFIG_JBD_DEBUG=y -CONFIG_FAT_FS=m -CONFIG_MSDOS_FS=m -CONFIG_UMSDOS_FS=m -CONFIG_VFAT_FS=m -CONFIG_FATX_FS=m -CONFIG_EFS_FS=m -CONFIG_JFFS_FS=m -CONFIG_JFFS_FS_VERBOSE=0 -CONFIG_JFFS_PROC_FS=y -CONFIG_JFFS2_FS=m -CONFIG_JFFS2_FS_DEBUG=0 -CONFIG_CRAMFS=m -CONFIG_TMPFS=y -CONFIG_RAMFS=y -CONFIG_ISO9660_FS=y -CONFIG_JOLIET=y -CONFIG_ZISOFS=y -CONFIG_JFS_FS=m -CONFIG_JFS_POSIX_ACL=y -# CONFIG_JFS_DEBUG is not set -CONFIG_JFS_STATISTICS=y -CONFIG_MINIX_FS=y -CONFIG_VXFS_FS=m -# CONFIG_NTFS_FS is not set -# CONFIG_NTFS_DEBUG is not set -# CONFIG_NTFS_RW is not set -CONFIG_HPFS_FS=m -CONFIG_PROC_FS=y -CONFIG_PROC_CONFIG=y -# CONFIG_DEVFS_FS is not set -# CONFIG_DEVFS_MOUNT is not set -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y -CONFIG_QNX4FS_FS=m -# CONFIG_QNX4FS_RW is not set -CONFIG_ROMFS_FS=m -CONFIG_EXT2_FS=y -CONFIG_EXT2_FS_XATTR=y -CONFIG_EXT2_FS_XATTR_SHARING=y -CONFIG_EXT2_FS_XATTR_USER=y -CONFIG_EXT2_FS_XATTR_TRUSTED=y -CONFIG_EXT2_FS_POSIX_ACL=y -CONFIG_SYSV_FS=m -CONFIG_UDF_FS=m -CONFIG_UDF_RW=y -CONFIG_UFS_FS=m -# CONFIG_UFS_FS_WRITE is not set -CONFIG_XFS_FS=m -CONFIG_XFS_POSIX_ACL=y -# CONFIG_XFS_RT is not set -CONFIG_XFS_QUOTA=y -CONFIG_XFS_DMAPI=y -# CONFIG_XFS_DEBUG is not set -# CONFIG_PAGEBUF_DEBUG is not set -# CONFIG_OCFS_FS is not set - -# -# Network File Systems -# -CONFIG_CODA_FS=m -CONFIG_INTERMEZZO_FS=m -CONFIG_NFS_FS=y -CONFIG_NFS_V3=y -CONFIG_NFS_ACL=y -CONFIG_NFS_DIRECTIO=y -CONFIG_ROOT_NFS=y -CONFIG_NFSD=m -CONFIG_NFSD_V3=y -CONFIG_NFSD_ACL=y -CONFIG_NFSD_TCP=y -CONFIG_NFSD_FHALIAS=y -CONFIG_SUNRPC=y -CONFIG_LOCKD=y -CONFIG_LOCKD_V4=y -CONFIG_CIFS=m -CONFIG_SMB_FS=m -CONFIG_SMB_NLS_DEFAULT=y -CONFIG_SMB_NLS_REMOTE="cp437" -CONFIG_NCP_FS=m -CONFIG_NCPFS_PACKET_SIGNING=y -CONFIG_NCPFS_IOCTL_LOCKING=y -CONFIG_NCPFS_STRONG=y -CONFIG_NCPFS_NFS_NS=y -CONFIG_NCPFS_OS2_NS=y -CONFIG_NCPFS_SMALLDOS=y -CONFIG_NCPFS_NLS=y -CONFIG_NCPFS_EXTRAS=y -CONFIG_ZISOFS_FS=y -CONFIG_FS_MBCACHE=y -CONFIG_FS_POSIX_ACL=y - -# -# Partition Types -# -CONFIG_PARTITION_ADVANCED=y -# CONFIG_ACORN_PARTITION is not set -CONFIG_OSF_PARTITION=y -# CONFIG_AMIGA_PARTITION is not set -CONFIG_ATARI_PARTITION=y -CONFIG_MAC_PARTITION=y -CONFIG_XBOX_PARTITION=y -CONFIG_MSDOS_PARTITION=y -CONFIG_BSD_DISKLABEL=y -# CONFIG_MINIX_SUBPARTITION is not set -CONFIG_SOLARIS_X86_PARTITION=y -CONFIG_UNIXWARE_DISKLABEL=y -# CONFIG_LDM_PARTITION is not set -CONFIG_SGI_PARTITION=y -CONFIG_ULTRIX_PARTITION=y -CONFIG_SUN_PARTITION=y -CONFIG_EFI_PARTITION=y -CONFIG_SMB_NLS=y -CONFIG_NLS=y - -# -# Native Language Support -# -CONFIG_NLS_DEFAULT="iso8859-1" -CONFIG_NLS_CODEPAGE_437=m -CONFIG_NLS_CODEPAGE_737=m -CONFIG_NLS_CODEPAGE_775=m -CONFIG_NLS_CODEPAGE_850=m -CONFIG_NLS_CODEPAGE_852=m -CONFIG_NLS_CODEPAGE_855=m -CONFIG_NLS_CODEPAGE_857=m -CONFIG_NLS_CODEPAGE_860=m -CONFIG_NLS_CODEPAGE_861=m -CONFIG_NLS_CODEPAGE_862=m -CONFIG_NLS_CODEPAGE_863=m -CONFIG_NLS_CODEPAGE_864=m -CONFIG_NLS_CODEPAGE_865=m -CONFIG_NLS_CODEPAGE_866=m -CONFIG_NLS_CODEPAGE_869=m -CONFIG_NLS_CODEPAGE_936=m -CONFIG_NLS_CODEPAGE_950=m -CONFIG_NLS_CODEPAGE_932=m -CONFIG_NLS_CODEPAGE_949=m -CONFIG_NLS_CODEPAGE_874=m -CONFIG_NLS_ISO8859_8=m -CONFIG_NLS_CODEPAGE_1250=m -CONFIG_NLS_CODEPAGE_1251=m -CONFIG_NLS_ISO8859_1=m -CONFIG_NLS_ISO8859_2=m -CONFIG_NLS_ISO8859_3=m -CONFIG_NLS_ISO8859_4=m -CONFIG_NLS_ISO8859_5=m -CONFIG_NLS_ISO8859_6=m -CONFIG_NLS_ISO8859_7=m -CONFIG_NLS_ISO8859_9=m -CONFIG_NLS_ISO8859_13=m -CONFIG_NLS_ISO8859_14=m -CONFIG_NLS_ISO8859_15=m -CONFIG_NLS_KOI8_R=m -CONFIG_NLS_KOI8_U=m -CONFIG_NLS_UTF8=m - -# -# Console drivers -# -CONFIG_VGA_CONSOLE=y -CONFIG_VIDEO_SELECT=y -CONFIG_MDA_CONSOLE=m - -# -# Frame-buffer support -# -CONFIG_FB=y -CONFIG_DUMMY_CONSOLE=y -CONFIG_FB_RIVA=m -CONFIG_FB_CLGEN=m -CONFIG_FB_PM2=m -CONFIG_FB_PM2_FIFO_DISCONNECT=y -CONFIG_FB_PM2_PCI=y -CONFIG_FB_PM3=m -# CONFIG_UNICON is not set -# CONFIG_UNICON_GB is not set -# CONFIG_UNICON_GBK is not set -# CONFIG_UNICON_BIG5 is not set -# CONFIG_UNICON_JIS is not set -# CONFIG_UNICON_KSCM is not set -CONFIG_FB_CYBER2000=m -CONFIG_FB_VESA=y -CONFIG_FB_VGA16=m -CONFIG_FB_HGA=m -CONFIG_VIDEO_SELECT=y -CONFIG_FB_MATROX=m -CONFIG_FB_MATROX_MILLENIUM=y -CONFIG_FB_MATROX_MYSTIQUE=y -CONFIG_FB_MATROX_G450=y -CONFIG_FB_MATROX_G100=y -CONFIG_FB_MATROX_I2C=m -CONFIG_FB_MATROX_MAVEN=m -CONFIG_FB_MATROX_PROC=m -CONFIG_FB_MATROX_MULTIHEAD=y -CONFIG_FB_ATY=m -CONFIG_FB_ATY_GX=y -CONFIG_FB_ATY_CT=y -CONFIG_FB_RADEON=m -CONFIG_FB_ATY128=m -# CONFIG_FB_INTEL is not set -# CONFIG_FB_SIS is not set -CONFIG_FB_NEOMAGIC=m -CONFIG_FB_VMWARE_SVGA=m -CONFIG_FB_3DFX=m -CONFIG_FB_VOODOO1=m -CONFIG_FB_TRIDENT=m -# CONFIG_FB_VIRTUAL is not set -CONFIG_FBCON_SPLASHSCREEN=y -CONFIG_FBCON_CFB16=y -CONFIG_FBCON_ADVANCED=y -CONFIG_FBCON_MFB=m -CONFIG_FBCON_CFB2=m -CONFIG_FBCON_CFB4=m -CONFIG_FBCON_CFB8=y -CONFIG_FBCON_CFB24=y -CONFIG_FBCON_CFB32=y -CONFIG_FBCON_AFB=m -CONFIG_FBCON_ILBM=m -CONFIG_FBCON_IPLAN2P2=m -CONFIG_FBCON_IPLAN2P4=m -CONFIG_FBCON_IPLAN2P8=m -CONFIG_FBCON_MAC=m -CONFIG_FBCON_VGA_PLANES=m -CONFIG_FBCON_VGA=m -CONFIG_FBCON_HGA=m -# CONFIG_FBCON_FONTWIDTH8_ONLY is not set -CONFIG_FBCON_FONTS=y -CONFIG_FONT_8x8=y -CONFIG_FONT_8x16=y -# CONFIG_FONT_SUN8x16 is not set -# CONFIG_FONT_SUN12x22 is not set -# CONFIG_FONT_6x11 is not set -# CONFIG_FONT_PEARL_8x8 is not set -# CONFIG_FONT_ACORN_8x8 is not set - -# -# Sound -# -CONFIG_SOUND=m -CONFIG_SOUND_ALI5455=m -CONFIG_SOUND_BT878=m -CONFIG_SOUND_CMPCI=m -CONFIG_SOUND_CMPCI_FM=y -CONFIG_SOUND_CMPCI_FMIO=388 -CONFIG_SOUND_CMPCI_FMIO=388 -CONFIG_SOUND_CMPCI_MIDI=y -CONFIG_SOUND_CMPCI_MPUIO=330 -CONFIG_SOUND_CMPCI_JOYSTICK=y -CONFIG_SOUND_CMPCI_CM8738=y -# CONFIG_SOUND_CMPCI_SPDIFINVERSE is not set -CONFIG_SOUND_CMPCI_SPDIFLOOP=y -CONFIG_SOUND_CMPCI_SPEAKERS=2 -CONFIG_SOUND_EMU10K1=m -CONFIG_MIDI_EMU10K1=y -CONFIG_SOUND_FUSION=m -CONFIG_SOUND_CS4281=m -CONFIG_SOUND_ES1370=m -CONFIG_SOUND_ES1371=m -CONFIG_SOUND_ESSSOLO1=m -CONFIG_SOUND_MAESTRO=m -CONFIG_SOUND_MAESTRO3=m -CONFIG_SOUND_FORTE=m -CONFIG_SOUND_ICH=m -CONFIG_SOUND_RME96XX=m -CONFIG_SOUND_SONICVIBES=m -CONFIG_SOUND_TRIDENT=m -# CONFIG_SOUND_MSNDCLAS is not set -# CONFIG_SOUND_MSNDPIN is not set -CONFIG_SOUND_VIA82CXXX=m -CONFIG_MIDI_VIA82CXXX=y -CONFIG_SOUND_OSS=m -CONFIG_SOUND_TRACEINIT=y -CONFIG_SOUND_DMAP=y -CONFIG_SOUND_AD1816=m -CONFIG_SOUND_AD1889=m -CONFIG_SOUND_SGALAXY=m -CONFIG_SOUND_ADLIB=m -CONFIG_SOUND_ACI_MIXER=m -CONFIG_SOUND_CS4232=m -CONFIG_SOUND_SSCAPE=m -CONFIG_SOUND_GUS=m -# CONFIG_SOUND_GUS16 is not set -CONFIG_SOUND_GUSMAX=y -CONFIG_SOUND_VMIDI=m -CONFIG_SOUND_TRIX=m -CONFIG_SOUND_MSS=m -CONFIG_SOUND_MPU401=m -CONFIG_SOUND_NM256=m -CONFIG_SOUND_MAD16=m -CONFIG_MAD16_OLDCARD=y -CONFIG_SOUND_PAS=m -# CONFIG_PAS_JOYSTICK is not set -CONFIG_SOUND_PSS=m -CONFIG_PSS_MIXER=y -# CONFIG_PSS_HAVE_BOOT is not set -CONFIG_SOUND_SB=m -CONFIG_SOUND_AWE32_SYNTH=m -CONFIG_SOUND_KAHLUA=m -CONFIG_SOUND_WAVEFRONT=m -CONFIG_SOUND_MAUI=m -CONFIG_SOUND_YM3812=m -CONFIG_SOUND_OPL3SA1=m -CONFIG_SOUND_OPL3SA2=m -CONFIG_SOUND_YMFPCI=m -CONFIG_SOUND_YMFPCI_LEGACY=y -CONFIG_SOUND_UART6850=m -CONFIG_SOUND_AEDSP16=m -CONFIG_SC6600=y -CONFIG_SC6600_JOY=y -CONFIG_SC6600_CDROM=4 -CONFIG_SC6600_CDROMBASE=0 -CONFIG_AEDSP16_SBPRO=y -CONFIG_AEDSP16_MPU401=y -CONFIG_SOUND_TVMIXER=m - -# -# Advanced Linux Sound Architecture -# -CONFIG_SND=m -CONFIG_SND_BIT32_EMUL=m -CONFIG_SND_SEQUENCER=m -CONFIG_SND_SEQ_DUMMY=m -CONFIG_SND_OSSEMUL=y -CONFIG_SND_MIXER_OSS=m -CONFIG_SND_PCM_OSS=m -CONFIG_SND_SEQUENCER_OSS=y -CONFIG_SND_VERBOSE_PRINTK=y -CONFIG_SND_DEBUG=y -CONFIG_SND_DEBUG_MEMORY=y -# CONFIG_SND_DEBUG_DETECT is not set - -# -# Generic devices -# -CONFIG_SND_DUMMY=m -CONFIG_SND_VIRMIDI=m -CONFIG_SND_MTPAV=m -CONFIG_SND_SERIAL_U16550=m -CONFIG_SND_MPU401=m -CONFIG_SND_SERIALMIDI=m - -# -# PCI devices -# -CONFIG_SND_ALI5451=m -CONFIG_SND_CS46XX=m -CONFIG_SND_CS46XX_NEW_DSP=y -CONFIG_SND_CS4281=m -CONFIG_SND_EMU10K1=m -CONFIG_SND_PDPLUS=m -CONFIG_SND_KORG1212=m -CONFIG_SND_NM256=m -CONFIG_SND_RME32=m -CONFIG_SND_RME96=m -CONFIG_SND_RME9652=m -CONFIG_SND_HDSP=m -CONFIG_SND_TRIDENT=m -CONFIG_SND_YMFPCI=m -CONFIG_SND_ALS4000=m -CONFIG_SND_CMIPCI=m -CONFIG_SND_ENS1370=m -CONFIG_SND_ENS1371=m -CONFIG_SND_ES1938=m -CONFIG_SND_ES1968=m -CONFIG_SND_MAESTRO3=m -CONFIG_SND_FM801=m -CONFIG_SND_ICE1712=m -CONFIG_SND_ICE1724=m -CONFIG_SND_INTEL8X0=m -CONFIG_SND_SONICVIBES=m -CONFIG_SND_VIA82XX=m -CONFIG_SND_VX222=m -CONFIG_SND_MIXART=m -CONFIG_SND_AZT3328=m - -# -# ALSA USB devices -# -CONFIG_SND_USB_AUDIO=m - -# -# ALSA PCMCIA devices -# -CONFIG_SND_VXPOCKET=m -CONFIG_SND_VXP440=m - -# -# USB support -# -CONFIG_USB=m -# CONFIG_USB_DEBUG is not set -CONFIG_USB_DEVICEFS=y -# CONFIG_USB_BANDWIDTH is not set -CONFIG_USB_EHCI_HCD=m -CONFIG_USB_UHCI=m -CONFIG_USB_UHCI_ALT=m -CONFIG_USB_OHCI=m -CONFIG_USB_AUDIO=m -CONFIG_USB_EMI26=m -CONFIG_USB_MIDI=m -CONFIG_USB_STORAGE=m -# CONFIG_USB_STORAGE_DEBUG is not set -CONFIG_USB_STORAGE_DATAFAB=y -CONFIG_USB_STORAGE_FREECOM=y -CONFIG_USB_STORAGE_ISD200=y -CONFIG_USB_STORAGE_DPCM=y -CONFIG_USB_STORAGE_HP8200e=y -CONFIG_USB_STORAGE_SDDR09=y -CONFIG_USB_STORAGE_SDDR55=y -CONFIG_USB_STORAGE_JUMPSHOT=y -CONFIG_USB_ACM=m -CONFIG_USB_PRINTER=m -CONFIG_USB_HID=m -CONFIG_USB_HIDINPUT=y -CONFIG_USB_HIDDEV=y -# CONFIG_USB_KBD is not set -# CONFIG_USB_MOUSE is not set -CONFIG_USB_AIPTEK=m -CONFIG_USB_WACOM=m -CONFIG_USB_KBTAB=m -CONFIG_USB_POWERMATE=m -CONFIG_USB_DC2XX=m -CONFIG_USB_MDC800=m -CONFIG_USB_SCANNER=m -CONFIG_USB_MICROTEK=m -CONFIG_USB_HPUSBSCSI=m -CONFIG_USB_IBMCAM=m -CONFIG_USB_KONICAWC=m -CONFIG_USB_OV511=m -CONFIG_USB_PWC=m -CONFIG_USB_SE401=m -CONFIG_USB_STV680=m -CONFIG_USB_VICAM=m -CONFIG_USB_DSBR=m -CONFIG_USB_DABUSB=m -# CONFIG_USB_LOGITECH_CAM is not set -CONFIG_USB_PEGASUS=m -CONFIG_USB_RTL8150=m -CONFIG_USB_KAWETH=m -CONFIG_USB_CATC=m -CONFIG_USB_AX8817X=m -CONFIG_USB_CDCETHER=m -CONFIG_USB_USBNET=m -CONFIG_USB_USBDNET=m -CONFIG_USB_USBDNET_VENDOR=0000 -CONFIG_USB_USBDNET_PRODUCT=0000 -CONFIG_USB_USBDNET_CLASS=0000 -CONFIG_USB_USBDNET_SUBCLASS=0000 -CONFIG_USB_USS720=m - -# -# USB Serial Converter support -# -CONFIG_USB_SERIAL=m -# CONFIG_USB_SERIAL_DEBUG is not set -CONFIG_USB_SERIAL_GENERIC=y -CONFIG_USB_SERIAL_BELKIN=m -CONFIG_USB_SERIAL_WHITEHEAT=m -CONFIG_USB_SERIAL_DIGI_ACCELEPORT=m -CONFIG_USB_SERIAL_EMPEG=m -CONFIG_USB_SERIAL_FTDI_SIO=m -CONFIG_USB_SERIAL_VISOR=m -CONFIG_USB_SERIAL_IPAQ=m -CONFIG_USB_SERIAL_IR=m -CONFIG_USB_SERIAL_EDGEPORT=m -CONFIG_USB_SERIAL_EDGEPORT_TI=m -CONFIG_USB_SERIAL_KEYSPAN_PDA=m -CONFIG_USB_SERIAL_KEYSPAN=m -CONFIG_USB_SERIAL_KEYSPAN_USA28=y -CONFIG_USB_SERIAL_KEYSPAN_USA28X=y -CONFIG_USB_SERIAL_KEYSPAN_USA28XA=y -CONFIG_USB_SERIAL_KEYSPAN_USA28XB=y -CONFIG_USB_SERIAL_KEYSPAN_USA19=y -CONFIG_USB_SERIAL_KEYSPAN_USA18X=y -CONFIG_USB_SERIAL_KEYSPAN_USA19W=y -CONFIG_USB_SERIAL_KEYSPAN_USA19QW=y -CONFIG_USB_SERIAL_KEYSPAN_USA19QI=y -CONFIG_USB_SERIAL_KEYSPAN_MPR=y -CONFIG_USB_SERIAL_KEYSPAN_USA49W=y -CONFIG_USB_SERIAL_KEYSPAN_USA49WLC=y -CONFIG_USB_SERIAL_MCT_U232=m -CONFIG_USB_SERIAL_KLSI=m -CONFIG_USB_SERIAL_KOBIL_SCT=m -CONFIG_USB_SERIAL_PL2303=m -CONFIG_USB_SERIAL_CYBERJACK=m -CONFIG_USB_SERIAL_XIRCOM=m -CONFIG_USB_SERIAL_OMNINET=m -CONFIG_USB_SERIAL_SAFE_PADDED=y -CONFIG_USB_SAFE_SERIAL_VENDOR=0000 -CONFIG_USB_SAFE_SERIAL_PRODUCT=0000 -CONFIG_USB_RIO500=m -CONFIG_USB_AUERSWALD=m -CONFIG_USB_TIGL=m -CONFIG_USB_BRLVGER=m -CONFIG_USB_LCD=m -# CONFIG_USB_SPEEDTOUCH is not set - -# -# Bluetooth support -# -CONFIG_BLUEZ=m -CONFIG_BLUEZ_L2CAP=m -CONFIG_BLUEZ_SCO=m -CONFIG_BLUEZ_RFCOMM=m -CONFIG_BLUEZ_RFCOMM_TTY=y -CONFIG_BLUEZ_BNEP=m -CONFIG_BLUEZ_BNEP_MC_FILTER=y -CONFIG_BLUEZ_BNEP_PROTO_FILTER=y -CONFIG_BLUEZ_CMTP=m - -# -# Bluetooth device drivers -# -CONFIG_BLUEZ_HCIUSB=m -CONFIG_BLUEZ_USB_SCO=y -# CONFIG_BLUEZ_USB_ZERO_PACKET is not set -CONFIG_BLUEZ_HCIUART=m -CONFIG_BLUEZ_HCIUART_H4=y -CONFIG_BLUEZ_HCIUART_BCSP=y -CONFIG_BLUEZ_HCIUART_BCSP_TXCRC=y -CONFIG_BLUEZ_HCIBFUSB=m -CONFIG_BLUEZ_HCIDTL1=m -CONFIG_BLUEZ_HCIBT3C=m -CONFIG_BLUEZ_HCIBLUECARD=m -CONFIG_BLUEZ_HCIBTUART=m -CONFIG_BLUEZ_HCIVHCI=m - -# -# Kernel hacking -# -CONFIG_DEBUG_KERNEL=y -# CONFIG_DEBUG_SLAB is not set -CONFIG_MAGIC_SYSRQ=y -# CONFIG_DEBUG_SPINLOCK is not set -# CONFIG_CHECKING is not set -# CONFIG_INIT_DEBUG is not set -# CONFIG_X86_REMOTE_DEBUG is not set -# CONFIG_IOMMU_DEBUG is not set -# CONFIG_IOMMU_LEAK is not set -CONFIG_DEBUG_STACKOVERFLOW=y -CONFIG_KALLSYMS=y - -# -# Library routines -# -CONFIG_ZLIB_INFLATE=y -CONFIG_ZLIB_DEFLATE=m -CONFIG_QSORT=y -CONFIG_FW_LOADER=m - -# -# Build options -# -CONFIG_SUSE_KERNEL=y -CONFIG_CFGNAME="default" -CONFIG_RELEASE=171 diff --git a/lustre/kernel_patches/kernel_configs/uml_2.6.0_test3.config b/lustre/kernel_patches/kernel_configs/uml_2.6.0_test3.config deleted file mode 100644 index f933188..0000000 --- a/lustre/kernel_patches/kernel_configs/uml_2.6.0_test3.config +++ /dev/null @@ -1,325 +0,0 @@ -# -# Automatically generated make config: don't edit -# -CONFIG_USERMODE=y -CONFIG_MMU=y -CONFIG_UID16=y -CONFIG_RWSEM_GENERIC_SPINLOCK=y - -# -# UML-specific options -# -CONFIG_MODE_TT=y -# CONFIG_MODE_SKAS is not set -CONFIG_NET=y -CONFIG_BINFMT_ELF=y -CONFIG_BINFMT_MISC=y -CONFIG_HOSTFS=y -# CONFIG_HPPFS is not set -CONFIG_MCONSOLE=y -CONFIG_MAGIC_SYSRQ=y -# CONFIG_HOST_2G_2G is not set -# CONFIG_UML_SMP is not set -# CONFIG_SMP is not set -CONFIG_NEST_LEVEL=0 -CONFIG_KERNEL_HALF_GIGS=1 -# CONFIG_HIGHMEM is not set -# CONFIG_PROC_MM is not set -CONFIG_KERNEL_STACK_ORDER=2 - -# -# Code maturity level options -# -CONFIG_EXPERIMENTAL=y - -# -# General setup -# -CONFIG_SWAP=y -CONFIG_SYSVIPC=y -CONFIG_BSD_PROCESS_ACCT=y -CONFIG_SYSCTL=y -CONFIG_LOG_BUF_SHIFT=14 -# CONFIG_EMBEDDED is not set -CONFIG_KALLSYMS=y -CONFIG_FUTEX=y -CONFIG_EPOLL=y -CONFIG_IOSCHED_AS=y -CONFIG_IOSCHED_DEADLINE=y - -# -# Loadable module support -# -# CONFIG_MODULES is not set - -# -# Generic Driver Options -# -# CONFIG_FW_LOADER is not set - -# -# Character Devices -# -CONFIG_STDIO_CONSOLE=y -CONFIG_SSL=y -CONFIG_FD_CHAN=y -# CONFIG_NULL_CHAN is not set -CONFIG_PORT_CHAN=y -CONFIG_PTY_CHAN=y -CONFIG_TTY_CHAN=y -CONFIG_XTERM_CHAN=y -CONFIG_CON_ZERO_CHAN="fd:0,fd:1" -CONFIG_CON_CHAN="xterm" -CONFIG_SSL_CHAN="pty" -CONFIG_UNIX98_PTYS=y -CONFIG_UNIX98_PTY_COUNT=256 -# CONFIG_WATCHDOG is not set -# CONFIG_UML_SOUND is not set -# CONFIG_SOUND is not set -# CONFIG_HOSTAUDIO is not set - -# -# Block Devices -# -CONFIG_BLK_DEV_UBD=y -# CONFIG_BLK_DEV_UBD_SYNC is not set -CONFIG_BLK_DEV_COW_COMMON=y -CONFIG_BLK_DEV_LOOP=y -# CONFIG_BLK_DEV_NBD is not set -# CONFIG_BLK_DEV_RAM is not set -# CONFIG_MMAPPER is not set -CONFIG_NETDEVICES=y - -# -# UML Network Devices -# -CONFIG_UML_NET=y -CONFIG_UML_NET_ETHERTAP=y -CONFIG_UML_NET_TUNTAP=y -CONFIG_UML_NET_SLIP=y -CONFIG_UML_NET_DAEMON=y -CONFIG_UML_NET_MCAST=y -# CONFIG_UML_NET_PCAP is not set -# CONFIG_UML_NET_SLIRP is not set - -# -# Networking support -# - -# -# Networking options -# -CONFIG_PACKET=y -CONFIG_PACKET_MMAP=y -# CONFIG_NETLINK_DEV is not set -CONFIG_UNIX=y -# CONFIG_NET_KEY is not set -CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set -# CONFIG_IP_ADVANCED_ROUTER is not set -# CONFIG_IP_PNP is not set -# CONFIG_NET_IPIP is not set -# CONFIG_NET_IPGRE is not set -# CONFIG_ARPD is not set -# CONFIG_INET_ECN is not set -# CONFIG_SYN_COOKIES is not set -# CONFIG_INET_AH is not set -# CONFIG_INET_ESP is not set -# CONFIG_INET_IPCOMP is not set -# CONFIG_IPV6 is not set -# CONFIG_DECNET is not set -# CONFIG_BRIDGE is not set -# CONFIG_NETFILTER is not set -# CONFIG_XFRM_USER is not set - -# -# SCTP Configuration (EXPERIMENTAL) -# -CONFIG_IPV6_SCTP__=y -# CONFIG_IP_SCTP is not set -# CONFIG_ATM is not set -# CONFIG_VLAN_8021Q is not set -# CONFIG_LLC is not set -# CONFIG_X25 is not set -# CONFIG_LAPB is not set -# CONFIG_NET_DIVERT is not set -# CONFIG_ECONET is not set -# CONFIG_WAN_ROUTER is not set -# CONFIG_NET_FASTROUTE is not set -# CONFIG_NET_HW_FLOWCONTROL is not set - -# -# QoS and/or fair queueing -# -# CONFIG_NET_SCHED is not set - -# -# Network testing -# -# CONFIG_NET_PKTGEN is not set -CONFIG_DUMMY=y -# CONFIG_BONDING is not set -# CONFIG_EQUALIZER is not set -CONFIG_TUN=y -# CONFIG_ETHERTAP is not set - -# -# Ethernet (10 or 100Mbit) -# -# CONFIG_NET_ETHERNET is not set - -# -# Ethernet (1000 Mbit) -# - -# -# Ethernet (10000 Mbit) -# -CONFIG_PPP=y -# CONFIG_PPP_MULTILINK is not set -# CONFIG_PPP_FILTER is not set -# CONFIG_PPP_ASYNC is not set -# CONFIG_PPP_SYNC_TTY is not set -# CONFIG_PPP_DEFLATE is not set -# CONFIG_PPP_BSDCOMP is not set -# CONFIG_PPPOE is not set -CONFIG_SLIP=y -# CONFIG_SLIP_COMPRESSED is not set -# CONFIG_SLIP_SMART is not set -# CONFIG_SLIP_MODE_SLIP6 is not set - -# -# Wireless LAN (non-hamradio) -# -# CONFIG_NET_RADIO is not set - -# -# Token Ring devices (depends on LLC=y) -# -# CONFIG_SHAPER is not set - -# -# Wan interfaces -# -# CONFIG_WAN is not set - -# -# File systems -# -CONFIG_EXT2_FS=y -# CONFIG_EXT2_FS_XATTR is not set -CONFIG_EXT3_FS=y -CONFIG_EXT3_FS_XATTR=y -# CONFIG_EXT3_FS_POSIX_ACL is not set -# CONFIG_EXT3_FS_SECURITY is not set -CONFIG_JBD=y -# CONFIG_JBD_DEBUG is not set -CONFIG_FS_MBCACHE=y -# CONFIG_REISERFS_FS is not set -# CONFIG_JFS_FS is not set -# CONFIG_XFS_FS is not set -# CONFIG_MINIX_FS is not set -# CONFIG_ROMFS_FS is not set -# CONFIG_QUOTA is not set -# CONFIG_AUTOFS_FS is not set -# CONFIG_AUTOFS4_FS is not set - -# -# CD-ROM/DVD Filesystems -# -# CONFIG_ISO9660_FS is not set -# CONFIG_UDF_FS is not set - -# -# DOS/FAT/NT Filesystems -# -# CONFIG_FAT_FS is not set -# CONFIG_NTFS_FS is not set - -# -# Pseudo filesystems -# -CONFIG_PROC_FS=y -CONFIG_DEVFS_FS=y -CONFIG_DEVFS_MOUNT=y -# CONFIG_DEVFS_DEBUG is not set -CONFIG_DEVPTS_FS=y -# CONFIG_DEVPTS_FS_XATTR is not set -CONFIG_TMPFS=y -CONFIG_RAMFS=y - -# -# Miscellaneous filesystems -# -# CONFIG_ADFS_FS is not set -# CONFIG_AFFS_FS is not set -# CONFIG_HFS_FS is not set -# CONFIG_BEFS_FS is not set -# CONFIG_BFS_FS is not set -# CONFIG_EFS_FS is not set -# CONFIG_CRAMFS is not set -# CONFIG_VXFS_FS is not set -# CONFIG_HPFS_FS is not set -# CONFIG_QNX4FS_FS is not set -# CONFIG_SYSV_FS is not set -# CONFIG_UFS_FS is not set - -# -# Network File Systems -# -# CONFIG_NFS_FS is not set -# CONFIG_NFSD is not set -# CONFIG_EXPORTFS is not set -# CONFIG_SMB_FS is not set -# CONFIG_CIFS is not set -# CONFIG_NCP_FS is not set -# CONFIG_CODA_FS is not set -# CONFIG_INTERMEZZO_FS is not set -# CONFIG_AFS_FS is not set - -# -# Partition Types -# -# CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y - -# -# Security options -# -# CONFIG_SECURITY is not set - -# -# Cryptographic options -# -# CONFIG_CRYPTO is not set - -# -# Library routines -# -# CONFIG_CRC32 is not set - -# -# SCSI support -# -# CONFIG_SCSI is not set - -# -# Multi-device support (RAID and LVM) -# -# CONFIG_MD is not set - -# -# Memory Technology Devices (MTD) -# -# CONFIG_MTD is not set - -# -# Kernel hacking -# -CONFIG_DEBUG_SLAB=y -# CONFIG_DEBUG_SPINLOCK is not set -CONFIG_DEBUG_INFO=y -CONFIG_FRAME_POINTER=y -CONFIG_PT_PROXY=y -# CONFIG_GPROF is not set -# CONFIG_GCOV is not set diff --git a/lustre/kernel_patches/patches/3.5G-address-space-2.4.24-vanilla.patch b/lustre/kernel_patches/patches/3.5G-address-space-2.4.24-vanilla.patch deleted file mode 100644 index 0276131..0000000 --- a/lustre/kernel_patches/patches/3.5G-address-space-2.4.24-vanilla.patch +++ /dev/null @@ -1,352 +0,0 @@ - Rules.make | 17 +++++++ - arch/i386/Makefile | 4 + - arch/i386/config.in | 10 ++++ - arch/i386/vmlinux.lds | 99 ----------------------------------------- - arch/i386/vmlinux.lds.S | 99 +++++++++++++++++++++++++++++++++++++++++ - include/asm-i386/page.h | 4 + - include/asm-i386/page_offset.h | 10 ++++ - include/asm-i386/processor.h | 4 + - mm/memory.c | 23 +++++++-- - 9 files changed, 165 insertions(+), 105 deletions(-) - -Index: linux-2.4.22-vanilla/arch/i386/config.in -=================================================================== ---- linux-2.4.22-vanilla.orig/arch/i386/config.in 2003-12-02 23:55:28.000000000 +0300 -+++ linux-2.4.22-vanilla/arch/i386/config.in 2003-12-15 23:09:28.000000000 +0300 -@@ -212,6 +212,16 @@ - fi - if [ "$CONFIG_HIGHMEM64G" = "y" ]; then - define_bool CONFIG_X86_PAE y -+ choice 'User address space size' \ -+ "3GB CONFIG_1GB \ -+ 2GB CONFIG_2GB \ -+ 1GB CONFIG_3GB" 3GB -+else -+ choice 'User address space size' \ -+ "3GB CONFIG_1GB \ -+ 2GB CONFIG_2GB \ -+ 1GB CONFIG_3GB \ -+ 3.5GB CONFIG_05GB" 3GB - fi - - if [ "$CONFIG_HIGHMEM" = "y" ]; then -Index: linux-2.4.22-vanilla/arch/i386/Makefile -=================================================================== ---- linux-2.4.22-vanilla.orig/arch/i386/Makefile 2003-11-03 22:50:58.000000000 +0300 -+++ linux-2.4.22-vanilla/arch/i386/Makefile 2003-12-15 23:09:28.000000000 +0300 -@@ -114,6 +114,9 @@ - - MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot - -+arch/i386/vmlinux.lds: arch/i386/vmlinux.lds.S FORCE -+ $(CPP) -C -P -I$(HPATH) -imacros $(HPATH)/asm-i386/page_offset.h -Ui386 arch/i386/vmlinux.lds.S >arch/i386/vmlinux.lds -+ - vmlinux: arch/i386/vmlinux.lds - - FORCE: ; -@@ -150,6 +153,7 @@ - @$(MAKEBOOT) clean - - archmrproper: -+ rm -f arch/i386/vmlinux.lds - - archdep: - @$(MAKEBOOT) dep -Index: linux-2.4.22-vanilla/arch/i386/vmlinux.lds.S -=================================================================== ---- linux-2.4.22-vanilla.orig/arch/i386/vmlinux.lds.S 2003-01-30 13:24:37.000000000 +0300 -+++ linux-2.4.22-vanilla/arch/i386/vmlinux.lds.S 2003-12-15 23:10:46.000000000 +0300 -@@ -0,0 +1,83 @@ -+/* ld script to make i386 Linux kernel -+ * Written by Martin Mares ; -+ */ -+OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") -+OUTPUT_ARCH(i386) -+ENTRY(_start) -+SECTIONS -+{ -+ . = PAGE_OFFSET_RAW + 0x100000; -+ _text = .; /* Text and read-only data */ -+ .text : { -+ *(.text) -+ *(.fixup) -+ *(.gnu.warning) -+ } = 0x9090 -+ -+ _etext = .; /* End of text section */ -+ -+ .rodata : { *(.rodata) *(.rodata.*) } -+ .kstrtab : { *(.kstrtab) } -+ -+ . = ALIGN(16); /* Exception table */ -+ __start___ex_table = .; -+ __ex_table : { *(__ex_table) } -+ __stop___ex_table = .; -+ -+ __start___ksymtab = .; /* Kernel symbol table */ -+ __ksymtab : { *(__ksymtab) } -+ __stop___ksymtab = .; -+ -+ .data : { /* Data */ -+ *(.data) -+ CONSTRUCTORS -+ } -+ -+ _edata = .; /* End of data section */ -+ -+/* chose the biggest of the possible stack sizes here? */ -+ . = ALIGN(65536); /* init_task */ -+ .data.init_task : { *(.data.init_task) } -+ -+ . = ALIGN(4096); /* Init code and data */ -+ __init_begin = .; -+ .text.init : { *(.text.init) } -+ .data.init : { *(.data.init) } -+ . = ALIGN(16); -+ __setup_start = .; -+ .setup.init : { *(.setup.init) } -+ __setup_end = .; -+ __initcall_start = .; -+ .initcall.init : { *(.initcall.init) } -+ __initcall_end = .; -+ . = ALIGN(4096); -+ __init_end = .; -+ -+ . = ALIGN(4096); -+ .data.page_aligned : { *(.data.idt) } -+ -+ . = ALIGN(32); -+ .data.cacheline_aligned : { *(.data.cacheline_aligned) } -+ -+ __bss_start = .; /* BSS */ -+ .bss : { -+ *(.bss) -+ } -+ _end = . ; -+ -+ /* Sections to be discarded */ -+ /DISCARD/ : { -+ *(.text.exit) -+ *(.data.exit) -+ *(.exitcall.exit) -+ } -+ -+ /* Stabs debugging sections. */ -+ .stab 0 : { *(.stab) } -+ .stabstr 0 : { *(.stabstr) } -+ .stab.excl 0 : { *(.stab.excl) } -+ .stab.exclstr 0 : { *(.stab.exclstr) } -+ .stab.index 0 : { *(.stab.index) } -+ .stab.indexstr 0 : { *(.stab.indexstr) } -+ .comment 0 : { *(.comment) } -+} -Index: linux-2.4.22-vanilla/arch/i386/vmlinux.lds -=================================================================== ---- linux-2.4.22-vanilla.orig/arch/i386/vmlinux.lds 2003-12-15 23:17:09.000000000 +0300 -+++ linux-2.4.22-vanilla/arch/i386/vmlinux.lds 2003-01-30 13:24:37.000000000 +0300 -@@ -1,83 +0,0 @@ --/* ld script to make i386 Linux kernel -- * Written by Martin Mares ; -- */ --OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386") --OUTPUT_ARCH(i386) --ENTRY(_start) --SECTIONS --{ -- . = 0xC0000000 + 0x100000; -- _text = .; /* Text and read-only data */ -- .text : { -- *(.text) -- *(.fixup) -- *(.gnu.warning) -- } = 0x9090 -- -- _etext = .; /* End of text section */ -- -- .rodata : { *(.rodata) *(.rodata.*) } -- .kstrtab : { *(.kstrtab) } -- -- . = ALIGN(16); /* Exception table */ -- __start___ex_table = .; -- __ex_table : { *(__ex_table) } -- __stop___ex_table = .; -- -- __start___ksymtab = .; /* Kernel symbol table */ -- __ksymtab : { *(__ksymtab) } -- __stop___ksymtab = .; -- -- .data : { /* Data */ -- *(.data) -- CONSTRUCTORS -- } -- -- _edata = .; /* End of data section */ -- --/* chose the biggest of the possible stack sizes here? */ -- . = ALIGN(65536); /* init_task */ -- .data.init_task : { *(.data.init_task) } -- -- . = ALIGN(4096); /* Init code and data */ -- __init_begin = .; -- .text.init : { *(.text.init) } -- .data.init : { *(.data.init) } -- . = ALIGN(16); -- __setup_start = .; -- .setup.init : { *(.setup.init) } -- __setup_end = .; -- __initcall_start = .; -- .initcall.init : { *(.initcall.init) } -- __initcall_end = .; -- . = ALIGN(4096); -- __init_end = .; -- -- . = ALIGN(4096); -- .data.page_aligned : { *(.data.idt) } -- -- . = ALIGN(32); -- .data.cacheline_aligned : { *(.data.cacheline_aligned) } -- -- __bss_start = .; /* BSS */ -- .bss : { -- *(.bss) -- } -- _end = . ; -- -- /* Sections to be discarded */ -- /DISCARD/ : { -- *(.text.exit) -- *(.data.exit) -- *(.exitcall.exit) -- } -- -- /* Stabs debugging sections. */ -- .stab 0 : { *(.stab) } -- .stabstr 0 : { *(.stabstr) } -- .stab.excl 0 : { *(.stab.excl) } -- .stab.exclstr 0 : { *(.stab.exclstr) } -- .stab.index 0 : { *(.stab.index) } -- .stab.indexstr 0 : { *(.stab.indexstr) } -- .comment 0 : { *(.comment) } --} -Index: linux-2.4.22-vanilla/include/asm-i386/page.h -=================================================================== ---- linux-2.4.22-vanilla.orig/include/asm-i386/page.h 2003-11-03 23:51:46.000000000 +0300 -+++ linux-2.4.22-vanilla/include/asm-i386/page.h 2003-12-15 23:09:28.000000000 +0300 -@@ -78,7 +78,9 @@ - * and CONFIG_HIGHMEM64G options in the kernel configuration. - */ - --#define __PAGE_OFFSET (0xC0000000) -+#include -+ -+#define __PAGE_OFFSET (PAGE_OFFSET_RAW) - - /* - * This much address space is reserved for vmalloc() and iomap() -Index: linux-2.4.22-vanilla/include/asm-i386/page_offset.h -=================================================================== ---- linux-2.4.22-vanilla.orig/include/asm-i386/page_offset.h 2003-01-30 13:24:37.000000000 +0300 -+++ linux-2.4.22-vanilla/include/asm-i386/page_offset.h 2003-12-15 23:09:28.000000000 +0300 -@@ -0,0 +1,10 @@ -+#include -+#ifdef CONFIG_05GB -+#define PAGE_OFFSET_RAW 0xE0000000 -+#elif defined(CONFIG_1GB) -+#define PAGE_OFFSET_RAW 0xC0000000 -+#elif defined(CONFIG_2GB) -+#define PAGE_OFFSET_RAW 0x80000000 -+#elif defined(CONFIG_3GB) -+#define PAGE_OFFSET_RAW 0x40000000 -+#endif -Index: linux-2.4.22-vanilla/include/asm-i386/processor.h -=================================================================== ---- linux-2.4.22-vanilla.orig/include/asm-i386/processor.h 2003-12-02 23:55:28.000000000 +0300 -+++ linux-2.4.22-vanilla/include/asm-i386/processor.h 2003-12-15 23:09:28.000000000 +0300 -@@ -265,7 +265,11 @@ - /* This decides where the kernel will search for a free chunk of vm - * space during mmap's. - */ -+#ifndef CONFIG_05GB - #define TASK_UNMAPPED_BASE (TASK_SIZE / 3) -+#else -+#define TASK_UNMAPPED_BASE (TASK_SIZE / 16) -+#endif - - /* - * Size of io_bitmap in longwords: 32 is ports 0-0x3ff. -Index: linux-2.4.22-vanilla/mm/memory.c -=================================================================== ---- linux-2.4.22-vanilla.orig/mm/memory.c 2003-05-16 05:29:15.000000000 +0400 -+++ linux-2.4.22-vanilla/mm/memory.c 2003-12-15 23:09:28.000000000 +0300 -@@ -108,8 +108,7 @@ - - static inline void free_one_pgd(pgd_t * dir) - { -- int j; -- pmd_t * pmd; -+ pmd_t * pmd, * md, * emd; - - if (pgd_none(*dir)) - return; -@@ -120,9 +119,23 @@ - } - pmd = pmd_offset(dir, 0); - pgd_clear(dir); -- for (j = 0; j < PTRS_PER_PMD ; j++) { -- prefetchw(pmd+j+(PREFETCH_STRIDE/16)); -- free_one_pmd(pmd+j); -+ -+ /* -+ * Beware if changing the loop below. It once used int j, -+ * for (j = 0; j < PTRS_PER_PMD; j++) -+ * free_one_pmd(pmd+j); -+ * but some older i386 compilers (e.g. egcs-2.91.66, gcc-2.95.3) -+ * terminated the loop with a _signed_ address comparison -+ * using "jle", when configured for HIGHMEM64GB (X86_PAE). -+ * If also configured for 3GB of kernel virtual address space, -+ * if page at physical 0x3ffff000 virtual 0x7ffff000 is used as -+ * a pmd, when that mm exits the loop goes on to free "entries" -+ * found at 0x80000000 onwards. The loop below compiles instead -+ * to be terminated by unsigned address comparison using "jb". -+ */ -+ for (md = pmd, emd = pmd + PTRS_PER_PMD; md < emd; md++) { -+ prefetchw(md+(PREFETCH_STRIDE/16)); -+ free_one_pmd(md); - } - pmd_free(pmd); - } -Index: linux-2.4.22-vanilla/Rules.make -=================================================================== ---- linux-2.4.22-vanilla.orig/Rules.make 2003-05-16 05:28:27.000000000 +0400 -+++ linux-2.4.22-vanilla/Rules.make 2003-12-15 23:09:28.000000000 +0300 -@@ -215,6 +215,7 @@ - # - # Added the SMP separator to stop module accidents between uniprocessor - # and SMP Intel boxes - AC - from bits by Michael Chastain -+# Added separator for different PAGE_OFFSET memory models - Ingo. - # - - ifdef CONFIG_SMP -@@ -223,6 +224,22 @@ - genksyms_smp_prefix := - endif - -+ifdef CONFIG_2GB -+ifdef CONFIG_SMP -+ genksyms_smp_prefix := -p smp_2gig_ -+else -+ genksyms_smp_prefix := -p 2gig_ -+endif -+endif -+ -+ifdef CONFIG_3GB -+ifdef CONFIG_SMP -+ genksyms_smp_prefix := -p smp_3gig_ -+else -+ genksyms_smp_prefix := -p 3gig_ -+endif -+endif -+ - $(MODINCL)/%.ver: %.c - @if [ ! -r $(MODINCL)/$*.stamp -o $(MODINCL)/$*.stamp -ot $< ]; then \ - echo '$(CC) $(CFLAGS) $(EXTRA_CFLAGS_nostdinc) -E -D__GENKSYMS__ $<'; \ diff --git a/lustre/kernel_patches/patches/add_page_private-2.4.24.patch b/lustre/kernel_patches/patches/add_page_private-2.4.24.patch deleted file mode 100644 index f7cc567..0000000 --- a/lustre/kernel_patches/patches/add_page_private-2.4.24.patch +++ /dev/null @@ -1,23 +0,0 @@ -Index: linux-ia64/include/linux/mm.h -=================================================================== ---- linux-ia64.orig/include/linux/mm.h 2004-04-27 12:39:16.000000000 -0700 -+++ linux-ia64/include/linux/mm.h 2004-04-27 12:42:10.000000000 -0700 -@@ -205,6 +205,7 @@ typedef struct page { - struct page **pprev_hash; /* Complement to *next_hash. */ - struct buffer_head * buffers; /* Buffer maps us to a disk block. */ -+ unsigned long private; - - /* - * On machines where all RAM is mapped into kernel address space, - -_ -Index: linux-ia64/mm/filemap.c -=================================================================== ---- linux-ia64.orig/mm/filemap.c 2004-04-27 12:35:18.000000000 -0700 -+++ linux-ia64/mm/filemap.c 2004-04-27 12:42:47.000000000 -0700 -@@ -676,6 +676,7 @@ static inline void __add_to_page_cache(s - page_cache_get(page); - page->index = offset; -+ page->private = 0; - add_page_to_inode_queue(mapping, page); - add_page_to_hash_queue(page, hash); diff --git a/lustre/kernel_patches/patches/configurable-x86-stack-2.4.24.patch b/lustre/kernel_patches/patches/configurable-x86-stack-2.4.24.patch deleted file mode 100644 index a538239..0000000 --- a/lustre/kernel_patches/patches/configurable-x86-stack-2.4.24.patch +++ /dev/null @@ -1,330 +0,0 @@ -Index: kernel-2.4.21/arch/i386/kernel/entry.S -=================================================================== ---- kernel-2.4.21.orig/arch/i386/kernel/entry.S 2003-06-13 07:51:29.000000000 -0700 -+++ kernel-2.4.21/arch/i386/kernel/entry.S 2003-12-04 11:57:01.000000000 -0800 -@@ -45,6 +45,7 @@ - #include - #include - #include -+#include - - EBX = 0x00 - ECX = 0x04 -@@ -130,10 +131,6 @@ - .long 3b,6b; \ - .previous - --#define GET_CURRENT(reg) \ -- movl $-8192, reg; \ -- andl %esp, reg -- - ENTRY(lcall7) - pushfl # We get a different stack layout with call gates, - pushl %eax # which has to be cleaned up later.. -@@ -149,7 +146,7 @@ - movl %ecx,CS(%esp) # - movl %esp,%ebx - pushl %ebx -- andl $-8192,%ebx # GET_CURRENT -+ andl $-THREAD_SIZE,%ebx # GET_CURRENT - movl exec_domain(%ebx),%edx # Get the execution domain - movl 4(%edx),%edx # Get the lcall7 handler for the domain - pushl $0x7 -@@ -173,7 +170,7 @@ - movl %ecx,CS(%esp) # - movl %esp,%ebx - pushl %ebx -- andl $-8192,%ebx # GET_CURRENT -+ andl $-THREAD_SIZE,%ebx # GET_CURRENT - movl exec_domain(%ebx),%edx # Get the execution domain - movl 4(%edx),%edx # Get the lcall7 handler for the domain - pushl $0x27 -Index: kernel-2.4.21/arch/i386/kernel/smpboot.c -=================================================================== ---- kernel-2.4.21.orig/arch/i386/kernel/smpboot.c 2003-06-13 07:51:29.000000000 -0700 -+++ kernel-2.4.21/arch/i386/kernel/smpboot.c 2003-12-04 11:57:01.000000000 -0800 -@@ -819,7 +819,7 @@ - - /* So we see what's up */ - printk("Booting processor %d/%d eip %lx\n", cpu, apicid, start_eip); -- stack_start.esp = (void *) (1024 + PAGE_SIZE + (char *)idle); -+ stack_start.esp = (void *)idle->thread.esp; - - /* - * This grunge runs the startup process for -@@ -892,7 +892,7 @@ - Dprintk("CPU has booted.\n"); - } else { - boot_error= 1; -- if (*((volatile unsigned char *)phys_to_virt(8192)) -+ if (*((volatile unsigned char *)phys_to_virt(THREAD_SIZE)) - == 0xA5) - /* trampoline started but...? */ - printk("Stuck ??\n"); -@@ -915,7 +915,7 @@ - } - - /* mark "stuck" area as not stuck */ -- *((volatile unsigned long *)phys_to_virt(8192)) = 0; -+ *((volatile unsigned long *)phys_to_virt(THREAD_SIZE)) = 0; - - if(clustered_apic_mode == CLUSTERED_APIC_NUMAQ) { - printk("Restoring NMI vector\n"); -Index: kernel-2.4.21/arch/i386/kernel/traps.c -=================================================================== ---- kernel-2.4.21.orig/arch/i386/kernel/traps.c 2002-11-28 15:53:09.000000000 -0800 -+++ kernel-2.4.21/arch/i386/kernel/traps.c 2003-12-04 11:57:01.000000000 -0800 -@@ -158,7 +158,7 @@ - unsigned long esp = tsk->thread.esp; - - /* User space on another CPU? */ -- if ((esp ^ (unsigned long)tsk) & (PAGE_MASK<<1)) -+ if ((esp ^ (unsigned long)tsk) & ~(THREAD_SIZE - 1)) - return; - show_trace((unsigned long *)esp); - } -Index: kernel-2.4.21/arch/i386/kernel/head.S -=================================================================== ---- kernel-2.4.21.orig/arch/i386/kernel/head.S 2003-06-13 07:51:29.000000000 -0700 -+++ kernel-2.4.21/arch/i386/kernel/head.S 2003-12-04 11:57:01.000000000 -0800 -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - - #define OLD_CL_MAGIC_ADDR 0x90020 - #define OLD_CL_MAGIC 0xA33F -@@ -320,7 +321,7 @@ - ret - - ENTRY(stack_start) -- .long SYMBOL_NAME(init_task_union)+8192 -+ .long SYMBOL_NAME(init_task_union)+THREAD_SIZE - .long __KERNEL_DS - - /* This is the default interrupt "handler" :-) */ -Index: kernel-2.4.21/arch/i386/kernel/irq.c -=================================================================== ---- kernel-2.4.21.orig/arch/i386/kernel/irq.c 2002-11-28 15:53:09.000000000 -0800 -+++ kernel-2.4.21/arch/i386/kernel/irq.c 2003-12-04 11:57:01.000000000 -0800 -@@ -581,7 +581,10 @@ - long esp; - - /* Debugging check for stack overflow: is there less than 1KB free? */ -- __asm__ __volatile__("andl %%esp,%0" : "=r" (esp) : "0" (8191)); -+ __asm__ __volatile__( -+ "andl %%esp,%0" -+ : "=r" (esp) : "0" (THREAD_SIZE-1)); -+ - if (unlikely(esp < (sizeof(struct task_struct) + 1024))) { - extern void show_stack(unsigned long *); - -Index: kernel-2.4.21/arch/i386/lib/getuser.S -=================================================================== ---- kernel-2.4.21.orig/arch/i386/lib/getuser.S 1998-01-12 13:42:52.000000000 -0800 -+++ kernel-2.4.21/arch/i386/lib/getuser.S 2003-12-04 11:57:01.000000000 -0800 -@@ -21,6 +21,10 @@ - * as they get called from within inline assembly. - */ - -+/* Duplicated from asm/processor.h */ -+#include -+#include -+ - addr_limit = 12 - - .text -@@ -28,7 +32,7 @@ - .globl __get_user_1 - __get_user_1: - movl %esp,%edx -- andl $0xffffe000,%edx -+ andl $~(THREAD_SIZE - 1),%edx - cmpl addr_limit(%edx),%eax - jae bad_get_user - 1: movzbl (%eax),%edx -@@ -41,7 +45,7 @@ - addl $1,%eax - movl %esp,%edx - jc bad_get_user -- andl $0xffffe000,%edx -+ andl $~(THREAD_SIZE - 1),%edx - cmpl addr_limit(%edx),%eax - jae bad_get_user - 2: movzwl -1(%eax),%edx -@@ -54,7 +58,7 @@ - addl $3,%eax - movl %esp,%edx - jc bad_get_user -- andl $0xffffe000,%edx -+ andl $~(THREAD_SIZE - 1),%edx - cmpl addr_limit(%edx),%eax - jae bad_get_user - 3: movl -3(%eax),%edx -Index: kernel-2.4.21/arch/i386/config.in -=================================================================== ---- kernel-2.4.21.orig/arch/i386/config.in 2003-06-13 07:51:29.000000000 -0700 -+++ kernel-2.4.21/arch/i386/config.in 2003-12-04 11:57:01.000000000 -0800 -@@ -256,6 +256,29 @@ - if [ "$CONFIG_SMP" = "y" -a "$CONFIG_X86_CMPXCHG" = "y" ]; then - define_bool CONFIG_HAVE_DEC_LOCK y - fi -+ -+choice 'Bigger Stack Size Support' \ -+ "off CONFIG_NOBIGSTACK \ -+ 16KB CONFIG_STACK_SIZE_16KB \ -+ 32KB CONFIG_STACK_SIZE_32KB \ -+ 64KB CONFIG_STACK_SIZE_64KB" off -+ -+if [ "$CONFIG_NOBIGSTACK" = "y" ]; then -+ define_int CONFIG_STACK_SIZE_SHIFT 1 -+else -+ if [ "$CONFIG_STACK_SIZE_16KB" = "y" ]; then -+ define_int CONFIG_STACK_SIZE_SHIFT 2 -+ else -+ if [ "$CONFIG_STACK_SIZE_32KB" = "y" ]; then -+ define_int CONFIG_STACK_SIZE_SHIFT 3 -+ else -+ if [ "$CONFIG_STACK_SIZE_64KB" = "y" ]; then -+ define_int CONFIG_STACK_SIZE_SHIFT 4 -+ fi -+ fi -+ fi -+fi -+ - endmenu - - mainmenu_option next_comment -Index: kernel-2.4.21/arch/i386/vmlinux.lds -=================================================================== ---- kernel-2.4.21.orig/arch/i386/vmlinux.lds 2002-02-25 11:37:53.000000000 -0800 -+++ kernel-2.4.21/arch/i386/vmlinux.lds 2003-12-04 11:57:01.000000000 -0800 -@@ -35,7 +35,8 @@ - - _edata = .; /* End of data section */ - -- . = ALIGN(8192); /* init_task */ -+/* chose the biggest of the possible stack sizes here? */ -+ . = ALIGN(65536); /* init_task */ - .data.init_task : { *(.data.init_task) } - - . = ALIGN(4096); /* Init code and data */ -Index: kernel-2.4.21/include/asm-i386/current.h -=================================================================== ---- kernel-2.4.21.orig/include/asm-i386/current.h 1998-08-14 16:35:22.000000000 -0700 -+++ kernel-2.4.21/include/asm-i386/current.h 2003-12-04 11:57:01.000000000 -0800 -@@ -1,15 +1,43 @@ - #ifndef _I386_CURRENT_H - #define _I386_CURRENT_H -+#include -+ -+/* -+ * Configurable page sizes on i386, mainly for debugging purposes. -+ * (c) Balbir Singh -+ */ -+ -+#ifdef __ASSEMBLY__ -+ -+#define PAGE_SIZE 4096 /* as cannot handle 1UL << 12 */ -+#define THREAD_SIZE ((1 << CONFIG_STACK_SIZE_SHIFT) * PAGE_SIZE) -+ -+#define GET_CURRENT(reg) \ -+ movl $-THREAD_SIZE, reg; \ -+ andl %esp, reg -+ -+#else /* __ASSEMBLY__ */ -+ -+#define THREAD_SIZE ((1 << CONFIG_STACK_SIZE_SHIFT) * PAGE_SIZE) -+#define alloc_task_struct() \ -+ ((struct task_struct *) __get_free_pages(GFP_KERNEL,CONFIG_STACK_SIZE_SHIFT)) -+ -+#define free_task_struct(p) \ -+ free_pages((unsigned long) (p), CONFIG_STACK_SIZE_SHIFT) -+ -+#define INIT_TASK_SIZE THREAD_SIZE - - struct task_struct; - - static inline struct task_struct * get_current(void) - { - struct task_struct *current; -- __asm__("andl %%esp,%0; ":"=r" (current) : "0" (~8191UL)); -+ __asm__("andl %%esp,%0; ":"=r" (current) : "0" (~(THREAD_SIZE - 1))); - return current; - } - - #define current get_current() - -+#endif /* __ASSEMBLY__ */ -+ - #endif /* !(_I386_CURRENT_H) */ -Index: kernel-2.4.21/include/asm-i386/hw_irq.h -=================================================================== ---- kernel-2.4.21.orig/include/asm-i386/hw_irq.h 2001-11-22 11:46:18.000000000 -0800 -+++ kernel-2.4.21/include/asm-i386/hw_irq.h 2003-12-04 11:57:01.000000000 -0800 -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - - /* - * IDT vectors usable for external interrupt sources start -@@ -113,10 +114,6 @@ - #define IRQ_NAME2(nr) nr##_interrupt(void) - #define IRQ_NAME(nr) IRQ_NAME2(IRQ##nr) - --#define GET_CURRENT \ -- "movl %esp, %ebx\n\t" \ -- "andl $-8192, %ebx\n\t" -- - /* - * SMP has a few special interrupts for IPI messages - */ -Index: kernel-2.4.21/include/asm-i386/processor.h -=================================================================== ---- kernel-2.4.21.orig/include/asm-i386/processor.h 2003-06-13 07:51:38.000000000 -0700 -+++ kernel-2.4.21/include/asm-i386/processor.h 2003-12-04 11:57:01.000000000 -0800 -@@ -14,6 +14,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -453,9 +454,6 @@ - #define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1019]) - #define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1022]) - --#define THREAD_SIZE (2*PAGE_SIZE) --#define alloc_task_struct() ((struct task_struct *) __get_free_pages(GFP_KERNEL,1)) --#define free_task_struct(p) free_pages((unsigned long) (p), 1) - #define get_task_struct(tsk) atomic_inc(&virt_to_page(tsk)->count) - - #define init_task (init_task_union.task) -Index: kernel-2.4.21/include/linux/sched.h -=================================================================== ---- kernel-2.4.21.orig/include/linux/sched.h 2003-06-13 15:26:52.000000000 -0700 -+++ kernel-2.4.21/include/linux/sched.h 2003-12-04 12:00:14.000000000 -0800 -@@ -2,6 +2,7 @@ - #define _LINUX_SCHED_H - - #include /* for HZ */ -+#include /* maybe for INIT_TASK_SIZE */ - - extern unsigned long event; - -Index: kernel-2.4.21/include/asm-x86_64/current.h -=================================================================== ---- kernel-2.4.21.orig/include/asm-x86_64/current.h 2003-06-13 15:26:52.000000000 -0700 -+++ kernel-2.4.21/include/asm-x86_64/current.h 2003-12-04 12:00:13.000000000 -0800 -@@ -5,6 +5,7 @@ - struct task_struct; - - #include -+#include - - static inline struct task_struct *get_current(void) - { diff --git a/lustre/kernel_patches/patches/dev_read_only-2.4.24.patch b/lustre/kernel_patches/patches/dev_read_only-2.4.24.patch deleted file mode 100644 index d3fa230..0000000 --- a/lustre/kernel_patches/patches/dev_read_only-2.4.24.patch +++ /dev/null @@ -1,58 +0,0 @@ -Index: linux-2.4.20-rh/drivers/block/blkpg.c -=================================================================== ---- linux-2.4.20-rh.orig/drivers/block/blkpg.c 2003-07-22 16:02:29.000000000 +0800 -+++ linux-2.4.20-rh/drivers/block/blkpg.c 2003-12-09 17:33:09.000000000 +0800 -@@ -297,3 +297,38 @@ - } - - EXPORT_SYMBOL(blk_ioctl); -+ -+#define NUM_DEV_NO_WRITE 16 -+static int dev_no_write[NUM_DEV_NO_WRITE]; -+ -+/* -+ * Debug code for turning block devices "read-only" (will discard writes -+ * silently). This is for filesystem crash/recovery testing. -+ */ -+void dev_set_rdonly(kdev_t dev, int no_write) -+{ -+ if (dev) { -+ printk(KERN_WARNING "Turning device %s read-only\n", -+ bdevname(dev)); -+ dev_no_write[no_write] = 0xdead0000 + dev; -+ } -+} -+ -+int dev_check_rdonly(kdev_t dev) { -+ int i; -+ -+ for (i = 0; i < NUM_DEV_NO_WRITE; i++) { -+ if ((dev_no_write[i] & 0xffff0000) == 0xdead0000 && -+ dev == (dev_no_write[i] & 0xffff)) -+ return 1; -+ } -+ return 0; -+} -+ -+void dev_clear_rdonly(int no_write) { -+ dev_no_write[no_write] = 0; -+} -+ -+EXPORT_SYMBOL(dev_set_rdonly); -+EXPORT_SYMBOL(dev_check_rdonly); -+EXPORT_SYMBOL(dev_clear_rdonly); -Index: linux-2.4.20-rh/drivers/block/ll_rw_blk.c -=================================================================== ---- linux-2.4.20-rh.orig/drivers/block/ll_rw_blk.c 2003-07-22 16:02:34.000000000 +0800 -+++ linux-2.4.20-rh/drivers/block/ll_rw_blk.c 2003-12-09 17:39:38.000000000 +0800 -@@ -1183,6 +1183,10 @@ - buffer_IO_error(bh); - break; - } -+ if ((rw & WRITE)&&(dev_check_rdonly(bh->b_rdev))) { -+ bh->b_end_io(bh, 0); -+ break; -+ } - } while (q->make_request_fn(q, rw, bh)); - } - diff --git a/lustre/kernel_patches/patches/directio-2.4.24.patch b/lustre/kernel_patches/patches/directio-2.4.24.patch deleted file mode 100644 index ba63e78..0000000 --- a/lustre/kernel_patches/patches/directio-2.4.24.patch +++ /dev/null @@ -1,15 +0,0 @@ -Index: lum/mm/filemap.c -=================================================================== ---- lum.orig/mm/filemap.c 2004-04-25 14:58:10.000000000 -0400 -+++ lum/mm/filemap.c 2004-04-25 16:23:32.000000000 -0400 -@@ -1614,8 +1614,8 @@ - new_iobuf = 1; - } - -- blocksize = 1 << inode->i_blkbits; -- blocksize_bits = inode->i_blkbits; -+ blocksize = 512 /*1 << inode->i_blkbits*/; -+ blocksize_bits = 9 /*inode->i_blkbits*/; - blocksize_mask = blocksize - 1; - chunk_size = KIO_MAX_ATOMIC_IO << 10; - diff --git a/lustre/kernel_patches/patches/dsp.patch b/lustre/kernel_patches/patches/dsp.patch deleted file mode 100644 index d072af9..0000000 --- a/lustre/kernel_patches/patches/dsp.patch +++ /dev/null @@ -1,142 +0,0 @@ - arch/i386/kernel/crash.c | 24 +++++++++++++++++------- - arch/i386/kernel/nmi.c | 2 +- - include/asm-i386/apic.h | 1 + - include/linux/crash.h | 2 +- - kernel/bootimg.c | 13 ++++++++++++- - kernel/bootimg_pic.c | 6 ++++-- - 6 files changed, 36 insertions(+), 12 deletions(-) - -Index: linux-2.4.20-rh/kernel/bootimg.c -=================================================================== ---- linux-2.4.20-rh.orig/kernel/bootimg.c 2003-10-29 23:56:02.000000000 +0800 -+++ linux-2.4.20-rh/kernel/bootimg.c 2003-10-29 23:56:17.000000000 +0800 -@@ -238,9 +238,20 @@ - int error = -ENOMEM; - - if (bootimg_checksum(__va(bootimg_dsc.page_dir),bootimg_dsc.pages) -- != bootimg_dsc.csum) -+ != bootimg_dsc.csum) { - printk("Checksum of kernel image failed. Rebooting via BIOS\n"); - -+ /* Before calling machine_restart(), make sure it will not -+ * simply call this function recursively. -+ */ -+ bootimg_dsc.page_dir = NULL; -+ machine_restart(NULL); -+ -+ /* We should never get here, but just in case... */ -+ for (; ; ) -+ __asm__ __volatile__ ("hlt"); -+ } -+ - code_page = get_identity_mapped_page(); - if (!code_page) goto out3; - code = (relocate_and_jump_t) virt_to_phys((void *) code_page); -Index: linux-2.4.20-rh/kernel/bootimg_pic.c -=================================================================== ---- linux-2.4.20-rh.orig/kernel/bootimg_pic.c 2003-10-29 23:56:02.000000000 +0800 -+++ linux-2.4.20-rh/kernel/bootimg_pic.c 2003-10-29 23:56:17.000000000 +0800 -@@ -69,7 +69,8 @@ - for (j = i+1; j < dsc.pages; j++) { - table = dsc.page_dir+FROM_TABLE(j); - if (((unsigned long) *table) == to) { -- copy_and_swap(*table,dsc.scratch); -+ copy_and_swap((unsigned long) (*table), -+ dsc.scratch); - break; - } - if ((*table)[PAGE_NR(j)] == to) { -@@ -79,7 +80,8 @@ - } - table = dsc.page_dir+TO_TABLE(j); - if (((unsigned long) *table) == to) { -- copy_and_swap(*table,dsc.scratch); -+ copy_and_swap((unsigned long) (*table), -+ dsc.scratch); - break; - } - } -Index: linux-2.4.20-rh/include/asm-i386/apic.h -=================================================================== ---- linux-2.4.20-rh.orig/include/asm-i386/apic.h 2003-10-29 23:58:49.000000000 +0800 -+++ linux-2.4.20-rh/include/asm-i386/apic.h 2003-10-29 23:59:40.000000000 +0800 -@@ -86,6 +86,9 @@ - extern void apic_pm_unregister(struct pm_dev*); - - extern int check_nmi_watchdog (void); -+extern void disable_apic_nmi_watchdog(void); -+ -+ - - extern unsigned int nmi_watchdog; - #define NMI_NONE 0 -Index: linux-2.4.20-rh/include/linux/crash.h -=================================================================== ---- linux-2.4.20-rh.orig/include/linux/crash.h 2003-10-29 23:56:02.000000000 +0800 -+++ linux-2.4.20-rh/include/linux/crash.h 2003-10-29 23:56:17.000000000 +0800 -@@ -71,7 +71,7 @@ - #define CRASH_ZALLOC_PAGES 16*5*2 /* 2 to handle crash in crash */ - #define CRASH_LOW_WATER_PAGES 100 - --#define CRASH_CPU_TIMEOUT 5000 /* 5 sec wait for other cpus to stop */ -+#define CRASH_CPU_TIMEOUT 15000 /* 15 sec wait for other cpus to stop */ - - #define CRASH_MARK_RESERVED(addr) (set_bit(PG_reserved,&mem_map[MAP_NR(addr)].flags)) - #define CRASH_CLEAR_RESERVED(addr) (clear_bit(PG_reserved,&mem_map[MAP_NR(addr)].flags)) -Index: linux-2.4.20-rh/arch/i386/kernel/crash.c -=================================================================== ---- linux-2.4.20-rh.orig/arch/i386/kernel/crash.c 2003-10-29 23:56:02.000000000 +0800 -+++ linux-2.4.20-rh/arch/i386/kernel/crash.c 2003-10-29 23:56:17.000000000 +0800 -@@ -9,6 +9,8 @@ - #include - #include - #include -+#include -+#include - - inline void crash_save_regs(void) { - static unsigned long regs[8]; -@@ -30,15 +32,23 @@ - */ - void crash_save_current_state(struct task_struct *tp) - { -+ if (tp != NULL) { -+ /* -+ * Here we save ebp instead of esp just in case the compiler -+ * decides to put an extra push in before we execute this -+ * instruction (thus invalidating our frame pointer). -+ */ -+ asm volatile("movl %%ebp,%0":"=m" (*(u_long *)&tp->thread.esp)); -+ tp->thread.eip = (u_long)crash_save_current_state; -+ panic_ksp[smp_processor_id()] = tp->thread.esp; -+ mb(); -+ } -+ - /* -- * Here we save ebp instead of esp just in case the compiler -- * decides to put an extra push in before we execute this -- * instruction (thus invalidating our frame pointer). -+ * Just to be safe, disable the NMI watchdog on the calling CPU so it -+ * doesn't get in the way while we are trying to save a dump. - */ -- asm volatile("movl %%ebp,%0":"=m" (*(u_long *)&tp->thread.esp)); -- tp->thread.eip = (u_long)crash_save_current_state; -- panic_ksp[smp_processor_id()] = tp->thread.esp; -- mb(); -+ disable_apic_nmi_watchdog(); - - save_core(); - -Index: linux-2.4.20-rh/arch/i386/kernel/nmi.c -=================================================================== ---- linux-2.4.20-rh.orig/arch/i386/kernel/nmi.c 2003-10-29 23:56:02.000000000 +0800 -+++ linux-2.4.20-rh/arch/i386/kernel/nmi.c 2003-10-29 23:56:17.000000000 +0800 -@@ -138,7 +138,7 @@ - - struct pm_dev *nmi_pmdev; - --static void disable_apic_nmi_watchdog(void) -+void disable_apic_nmi_watchdog(void) - { - switch (boot_cpu_data.x86_vendor) { - case X86_VENDOR_AMD: diff --git a/lustre/kernel_patches/patches/dynamic-locks-2.4.24.patch b/lustre/kernel_patches/patches/dynamic-locks-2.4.24.patch deleted file mode 100644 index 2da0974..0000000 --- a/lustre/kernel_patches/patches/dynamic-locks-2.4.24.patch +++ /dev/null @@ -1,281 +0,0 @@ - include/linux/dynlocks.h | 33 ++++++++++ - lib/Makefile | 4 - - lib/dynlocks.c | 152 +++++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 187 insertions(+), 2 deletions(-) - -Index: linux-2.4.24/include/linux/dynlocks.h -=================================================================== ---- linux-2.4.24.orig/include/linux/dynlocks.h 2003-01-30 13:24:37.000000000 +0300 -+++ linux-2.4.24/include/linux/dynlocks.h 2004-07-18 11:09:33.000000000 +0400 -@@ -0,0 +1,43 @@ -+#ifndef _LINUX_DYNLOCKS_H -+#define _LINUX_DYNLOCKS_H -+ -+#include -+#include -+ -+#define DYNLOCK_MAGIC 0xd19a10c -+#define DYNLOCK_MAGIC2 0xd1956ee -+ -+struct dynlock; -+ -+struct dynlock_member { -+ unsigned dl_magic; -+ struct list_head dl_list; -+ unsigned long dl_value; /* lock value */ -+ int dl_refcount; /* number of users */ -+ int dl_readers; -+ int dl_writers; -+ int dl_pid; /* holder of the lock */ -+ wait_queue_head_t dl_wait; -+}; -+ -+/* -+ * lock's namespace: -+ * - list of locks -+ * - lock to protect this list -+ */ -+ -+#define DYNLOCK_LIST_MAGIC 0x11ee91e6 -+ -+struct dynlock { -+ unsigned dl_magic; -+ struct list_head dl_list; -+ spinlock_t dl_list_lock; -+}; -+ -+void dynlock_init(struct dynlock *dl); -+void *dynlock_lock(struct dynlock *dl, unsigned long value, int rw, int gfp); -+void dynlock_unlock(struct dynlock *dl, void *lock); -+ -+ -+#endif -+ -Index: linux-2.4.24/lib/dynlocks.c -=================================================================== ---- linux-2.4.24.orig/lib/dynlocks.c 2003-01-30 13:24:37.000000000 +0300 -+++ linux-2.4.24/lib/dynlocks.c 2004-07-18 11:23:01.000000000 +0400 -@@ -0,0 +1,188 @@ -+/* -+ * Dynamic Locks -+ * -+ * struct dynlock is lockspace -+ * one may request lock (exclusive or shared) for some value -+ * in that lockspace -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+static kmem_cache_t * dynlock_cachep = NULL; -+ -+void __init dynlock_cache_init(void) -+{ -+ printk(KERN_INFO "init dynlocks cache\n"); -+ dynlock_cachep = kmem_cache_create("dynlock_cache", -+ sizeof(struct dynlock_member), -+ 0, -+ SLAB_HWCACHE_ALIGN, -+ NULL, NULL); -+ if (dynlock_cachep == NULL) -+ panic("Can't create dynlock cache"); -+} -+ -+/* -+ * dynlock_init -+ * -+ * initialize lockspace -+ * -+ */ -+void dynlock_init(struct dynlock *dl) -+{ -+ spin_lock_init(&dl->dl_list_lock); -+ INIT_LIST_HEAD(&dl->dl_list); -+ dl->dl_magic = DYNLOCK_LIST_MAGIC; -+} -+ -+/* -+ * dynlock_lock -+ * -+ * acquires lock (exclusive or shared) in specified lockspace -+ * each lock in lockspace is allocated separately, so user have -+ * to specify GFP flags. -+ * routine returns pointer to lock. this pointer is intended to -+ * be passed to dynlock_unlock -+ * -+ */ -+void *dynlock_lock(struct dynlock *dl, unsigned long value, int rw, int gfp) -+{ -+ struct dynlock_member *nhl = NULL; -+ struct dynlock_member *hl; -+ struct list_head *cur; -+ int num = 0; -+ -+ BUG_ON(dl == NULL); -+ BUG_ON(dl->dl_magic != DYNLOCK_LIST_MAGIC); -+repeat: -+ /* find requested lock in lockspace */ -+ spin_lock(&dl->dl_list_lock); -+ BUG_ON(dl->dl_list.next == NULL); -+ BUG_ON(dl->dl_list.prev == NULL); -+ list_for_each(cur, &dl->dl_list) { -+ BUG_ON(cur->next == NULL); -+ BUG_ON(cur->prev == NULL); -+ hl = list_entry(cur, struct dynlock_member, dl_list); -+ BUG_ON(hl->dl_magic != DYNLOCK_MAGIC); -+ if (hl->dl_value == value) { -+ /* lock is found */ -+ if (nhl) { -+ /* someone else just allocated -+ * lock we didn't find and just created -+ * so, we drop our lock -+ */ -+ kmem_cache_free(dynlock_cachep, nhl); -+ nhl = NULL; -+ } -+ hl->dl_refcount++; -+ goto found; -+ } -+ num++; -+ } -+ /* lock not found */ -+ if (nhl) { -+ /* we already have allocated lock. use it */ -+ hl = nhl; -+ nhl = NULL; -+ list_add(&hl->dl_list, &dl->dl_list); -+ goto found; -+ } -+ spin_unlock(&dl->dl_list_lock); -+ -+ /* lock not found and we haven't allocated lock yet. allocate it */ -+ nhl = kmem_cache_alloc(dynlock_cachep, gfp); -+ if (nhl == NULL) -+ return NULL; -+ nhl->dl_refcount = 1; -+ nhl->dl_value = value; -+ nhl->dl_readers = 0; -+ nhl->dl_writers = 0; -+ nhl->dl_magic = DYNLOCK_MAGIC; -+ init_waitqueue_head(&nhl->dl_wait); -+ -+ /* while lock is being allocated, someone else may allocate it -+ * and put onto to list. check this situation -+ */ -+ goto repeat; -+ -+found: -+ if (rw) { -+ /* exclusive lock: user don't want to share lock at all -+ * NOTE: one process may take the same lock several times -+ * this functionaly is useful for rename operations */ -+ while ((hl->dl_writers && hl->dl_pid != current->pid) || -+ hl->dl_readers) { -+ spin_unlock(&dl->dl_list_lock); -+ wait_event(hl->dl_wait, -+ hl->dl_writers == 0 && hl->dl_readers == 0); -+ spin_lock(&dl->dl_list_lock); -+ } -+ hl->dl_writers++; -+ } else { -+ /* shared lock: user do not want to share lock with writer */ -+ while (hl->dl_writers) { -+ spin_unlock(&dl->dl_list_lock); -+ wait_event(hl->dl_wait, hl->dl_writers == 0); -+ spin_lock(&dl->dl_list_lock); -+ } -+ hl->dl_readers++; -+ } -+ hl->dl_pid = current->pid; -+ spin_unlock(&dl->dl_list_lock); -+ -+ return hl; -+} -+ -+ -+/* -+ * dynlock_unlock -+ * -+ * user have to specify lockspace (dl) and pointer to lock structure -+ * returned by dynlock_lock() -+ * -+ */ -+void dynlock_unlock(struct dynlock *dl, void *lock) -+{ -+ struct dynlock_member *hl = lock; -+ int wakeup = 0; -+ -+ BUG_ON(dl == NULL); -+ BUG_ON(hl == NULL); -+ BUG_ON(dl->dl_magic != DYNLOCK_LIST_MAGIC); -+ BUG_ON(hl->dl_magic != DYNLOCK_MAGIC); -+ BUG_ON(current->pid != hl->dl_pid); -+ -+ spin_lock(&dl->dl_list_lock); -+ if (hl->dl_writers) { -+ BUG_ON(hl->dl_readers > 0 || hl->dl_readers < 0); -+ hl->dl_writers--; -+ if (hl->dl_writers == 0) -+ wakeup = 1; -+ } else if (hl->dl_readers) { -+ hl->dl_readers--; -+ if (hl->dl_readers == 0) -+ wakeup = 1; -+ } else { -+ BUG_ON(1); -+ } -+ if (wakeup) { -+ hl->dl_pid = 0; -+ wake_up(&hl->dl_wait); -+ } -+ if (--(hl->dl_refcount) == 0) { -+ hl->dl_magic = DYNLOCK_MAGIC2; -+ list_del(&hl->dl_list); -+ kmem_cache_free(dynlock_cachep, hl); -+ } -+ spin_unlock(&dl->dl_list_lock); -+} -+ -+EXPORT_SYMBOL(dynlock_init); -+EXPORT_SYMBOL(dynlock_lock); -+EXPORT_SYMBOL(dynlock_unlock); -+ -Index: linux-2.4.24/lib/Makefile -=================================================================== ---- linux-2.4.24.orig/lib/Makefile 2004-06-24 09:06:32.000000000 +0400 -+++ linux-2.4.24/lib/Makefile 2004-07-16 15:54:06.000000000 +0400 -@@ -9,10 +9,10 @@ - L_TARGET := lib.a - - export-objs := cmdline.o dec_and_lock.o rwsem-spinlock.o rwsem.o \ -- rbtree.o crc32.o firmware_class.o -+ rbtree.o crc32.o firmware_class.o dynlocks.o - - obj-y := errno.o ctype.o string.o vsprintf.o brlock.o cmdline.o \ -- bust_spinlocks.o rbtree.o dump_stack.o -+ bust_spinlocks.o rbtree.o dump_stack.o dynlocks.o - - obj-$(CONFIG_FW_LOADER) += firmware_class.o - obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o -Index: linux-2.4.24/fs/dcache.c -=================================================================== ---- linux-2.4.24.orig/fs/dcache.c 2004-07-16 12:35:54.000000000 +0400 -+++ linux-2.4.24/fs/dcache.c 2004-07-16 15:54:06.000000000 +0400 -@@ -1274,6 +1274,7 @@ - extern void bdev_cache_init(void); - extern void cdev_cache_init(void); - extern void iobuf_cache_init(void); -+extern void dynlock_cache_init(void); - - void __init vfs_caches_init(unsigned long mempages) - { -@@ -1310,4 +1311,5 @@ - bdev_cache_init(); - cdev_cache_init(); - iobuf_cache_init(); -+ dynlock_cache_init(); - } diff --git a/lustre/kernel_patches/patches/export-add_to_page_cache.patch b/lustre/kernel_patches/patches/export-add_to_page_cache.patch deleted file mode 100644 index 0d3b5da..0000000 --- a/lustre/kernel_patches/patches/export-add_to_page_cache.patch +++ /dev/null @@ -1,23 +0,0 @@ - mm/filemap.c | 2 ++ - 1 files changed, 2 insertions(+) - ---- linux-2.4.20-l19/mm/filemap.c~export-add_to_page_cache 2003-07-15 03:05:47.000000000 -0500 -+++ linux-2.4.20-l19-zab/mm/filemap.c 2003-07-15 15:33:01.000000000 -0500 -@@ -670,6 +670,7 @@ void add_to_page_cache(struct page * pag - spin_unlock(&pagecache_lock); - lru_cache_add(page); - } -+EXPORT_SYMBOL_GPL(add_to_page_cache); - - int add_to_page_cache_unique(struct page * page, - struct address_space *mapping, unsigned long offset, -@@ -692,6 +693,7 @@ int add_to_page_cache_unique(struct page - lru_cache_add(page); - return err; - } -+EXPORT_SYMBOL_GPL(add_to_page_cache_unique); - - /* - * This adds the requested page to the page cache if it isn't already there, - -_ diff --git a/lustre/kernel_patches/patches/export-truncate-2.4.24.patch b/lustre/kernel_patches/patches/export-truncate-2.4.24.patch deleted file mode 100644 index 2cd96b9..0000000 --- a/lustre/kernel_patches/patches/export-truncate-2.4.24.patch +++ /dev/null @@ -1,35 +0,0 @@ - include/linux/mm.h | 1 + - mm/filemap.c | 3 ++- - 2 files changed, 3 insertions(+), 1 deletion(-) - ---- linux-2.4.18-18/include/linux/mm.h~export-truncate 2003-04-05 02:54:55.000000000 -0700 -+++ linux-2.4.18-18-braam/include/linux/mm.h 2003-04-09 17:37:46.000000000 -0600 -@@ -650,6 +650,7 @@ struct zone_t; - /* filemap.c */ - extern void remove_inode_page(struct page *); - extern unsigned long page_unuse(struct page *); -+extern void truncate_complete_page(struct page *); - extern void truncate_inode_pages(struct address_space *, loff_t); - - /* generic vm_area_ops exported for stackable file systems */ ---- linux-2.4.18-18/mm/filemap.c~export-truncate 2003-04-05 02:54:55.000000000 -0700 -+++ linux-2.4.18-18-braam/mm/filemap.c 2003-04-09 17:37:46.000000000 -0600 -@@ -245,7 +245,7 @@ static inline void truncate_partial_page - do_flushpage(page, partial); - } - --static void truncate_complete_page(struct page *page) -+void truncate_complete_page(struct page *page) - { - /* - * Leave it on the LRU if it gets converted into anonymous buffers -@@ -266,6 +266,7 @@ static void truncate_complete_page(struc - remove_inode_page(page); - page_cache_release(page); - } -+EXPORT_SYMBOL_GPL(truncate_complete_page); - - static int FASTCALL(truncate_list_pages(struct list_head *, unsigned long, unsigned *)); - static int truncate_list_pages(struct list_head *head, unsigned long start, unsigned *partial) - -_ diff --git a/lustre/kernel_patches/patches/export-zap-page-range-2.4.24.patch b/lustre/kernel_patches/patches/export-zap-page-range-2.4.24.patch deleted file mode 100644 index 9b9d48f..0000000 --- a/lustre/kernel_patches/patches/export-zap-page-range-2.4.24.patch +++ /dev/null @@ -1,12 +0,0 @@ -Index: linux-2.4.24-l36mmap/mm/memory.c -=================================================================== ---- linux-2.4.24-l36mmap.orig/mm/memory.c 2004-05-27 17:44:13.000000000 -0700 -+++ linux-2.4.24-l36mmap/mm/memory.c 2004-05-27 17:45:07.000000000 -0700 -@@ -411,6 +411,7 @@ - mm->rss = 0; - spin_unlock(&mm->page_table_lock); - } -+EXPORT_SYMBOL_GPL(zap_page_range); - - /* - * Do a quick page-table lookup for a single page. diff --git a/lustre/kernel_patches/patches/export_lookup_create-2.4.24.patch b/lustre/kernel_patches/patches/export_lookup_create-2.4.24.patch deleted file mode 100644 index 02aaee1..0000000 --- a/lustre/kernel_patches/patches/export_lookup_create-2.4.24.patch +++ /dev/null @@ -1,34 +0,0 @@ -diff -rupN linux-2.4.24/fs/namei.c linux-2.4.24.new/fs/namei.c ---- linux-2.4.24/fs/namei.c 2004-05-19 10:58:50.000000000 +0300 -+++ linux-2.4.24.new/fs/namei.c 2004-05-19 11:04:05.725450928 +0300 -@@ -1391,8 +1391,8 @@ int open_namei(const char *pathname, int - - - /* SMP-safe */ --static struct dentry *lookup_create(struct nameidata *nd, int is_dir, -- struct lookup_intent *it) -+struct dentry *lookup_create(struct nameidata *nd, int is_dir, -+ struct lookup_intent *it) - { - struct dentry *dentry; - -@@ -1412,6 +1412,7 @@ enoent: - fail: - return dentry; - } -+EXPORT_SYMBOL(lookup_create); - - int vfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev) - { -diff -rupN linux-2.4.24/include/linux/fs.h linux-2.4.24.new/include/linux/fs.h ---- linux-2.4.24/include/linux/fs.h 2004-05-19 10:58:50.178421368 +0300 -+++ linux-2.4.24.new/include/linux/fs.h 2004-05-19 11:04:35.373943672 +0300 -@@ -1129,6 +1129,8 @@ extern struct file *filp_open(const char - extern struct file * dentry_open(struct dentry *, struct vfsmount *, int); - extern int open_namei_it(const char *filename, int namei_flags, int mode, - struct nameidata *nd, struct lookup_intent *it); -+extern struct dentry *lookup_create(struct nameidata *nd, int is_dir, -+ struct lookup_intent *it); - extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, - int flags, struct lookup_intent *it); - extern int revalidate_it(struct dentry *dentry, struct lookup_intent *it); diff --git a/lustre/kernel_patches/patches/export_num_siblings-2.4.24.patch b/lustre/kernel_patches/patches/export_num_siblings-2.4.24.patch deleted file mode 100644 index 0fdefb5..0000000 --- a/lustre/kernel_patches/patches/export_num_siblings-2.4.24.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- linux/arch/i386/kernel/i386_ksyms.c.orig 2003-11-28 11:26:19.000000000 -0700 -+++ linux/arch/i386/kernel/i386_ksyms.c 2004-08-13 11:31:33.000000000 -0600 -@@ -131,6 +131,7 @@ - EXPORT_SYMBOL(cpu_data); - EXPORT_SYMBOL(kernel_flag_cacheline); - EXPORT_SYMBOL(smp_num_cpus); -+EXPORT_SYMBOL(smp_num_siblings); - EXPORT_SYMBOL(cpu_online_map); - EXPORT_SYMBOL_NOVERS(__write_lock_failed); - EXPORT_SYMBOL_NOVERS(__read_lock_failed); diff --git a/lustre/kernel_patches/patches/exports-2.4.24.patch b/lustre/kernel_patches/patches/exports-2.4.24.patch deleted file mode 100644 index feaeec6..0000000 --- a/lustre/kernel_patches/patches/exports-2.4.24.patch +++ /dev/null @@ -1,53 +0,0 @@ - fs/ext3/Makefile | 2 ++ - fs/ext3/super.c | 2 +- - include/linux/fs.h | 1 + - kernel/ksyms.c | 4 ++++ - 4 files changed, 8 insertions(+), 1 deletion(-) - ---- linux/fs/ext3/Makefile~exports_2.4.20 Wed Apr 9 10:07:14 2003 -+++ linux-mmonroe/fs/ext3/Makefile Wed Apr 9 10:19:53 2003 -@@ -9,6 +9,8 @@ - - O_TARGET := ext3.o - -+export-objs := super.o inode.o -+ - obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ - ioctl.o namei.o super.o symlink.o - obj-m := $(O_TARGET) ---- linux/fs/ext3/super.c~exports_2.4.20 Wed Apr 9 10:07:14 2003 -+++ linux-mmonroe/fs/ext3/super.c Wed Apr 9 10:19:53 2003 -@@ -1769,7 +1769,7 @@ static void __exit exit_ext3_fs(void) - unregister_filesystem(&ext3_fs_type); - } - --EXPORT_NO_SYMBOLS; -+EXPORT_SYMBOL(ext3_bread); - - MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); - MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions"); ---- linux/include/linux/fs.h~exports_2.4.20 Wed Apr 9 10:07:14 2003 -+++ linux-mmonroe/include/linux/fs.h Wed Apr 9 10:19:53 2003 -@@ -1020,6 +1020,7 @@ extern int unregister_filesystem(struct - extern struct vfsmount *kern_mount(struct file_system_type *); - extern int may_umount(struct vfsmount *); - extern long do_mount(char *, char *, char *, unsigned long, void *); -+struct vfsmount *do_kern_mount(const char *type, int flags, char *name, void *data); - - #define kern_umount mntput - ---- linux/kernel/ksyms.c~exports_2.4.20 Wed Apr 9 10:07:14 2003 -+++ linux-mmonroe/kernel/ksyms.c Wed Apr 9 10:19:53 2003 -@@ -308,6 +308,10 @@ EXPORT_SYMBOL(dcache_dir_fsync); - EXPORT_SYMBOL(dcache_readdir); - EXPORT_SYMBOL(dcache_dir_ops); - -+/* lustre */ -+EXPORT_SYMBOL(pagecache_lock_cacheline); -+EXPORT_SYMBOL(do_kern_mount); -+ - /* for stackable file systems (lofs, wrapfs, cryptfs, etc.) */ - EXPORT_SYMBOL(default_llseek); - EXPORT_SYMBOL(dentry_open); - -_ diff --git a/lustre/kernel_patches/patches/ext3-2.4-ino_t.patch b/lustre/kernel_patches/patches/ext3-2.4-ino_t.patch deleted file mode 100644 index 1786d0f..0000000 --- a/lustre/kernel_patches/patches/ext3-2.4-ino_t.patch +++ /dev/null @@ -1,144 +0,0 @@ - fs/ext3/ialloc.c | 20 ++++++++++---------- - fs/ext3/namei.c | 16 ++++++++-------- - include/linux/ext3_fs.h | 2 +- - 3 files changed, 19 insertions(+), 19 deletions(-) - ---- linux-2.4.20/fs/ext3/ialloc.c~ext3-2.4-ino_t 2003-04-08 23:35:24.000000000 -0600 -+++ linux-2.4.20-braam/fs/ext3/ialloc.c 2003-04-08 23:35:24.000000000 -0600 -@@ -65,8 +65,8 @@ static int read_inode_bitmap (struct sup - if (!bh) { - ext3_error (sb, "read_inode_bitmap", - "Cannot read inode bitmap - " -- "block_group = %lu, inode_bitmap = %lu", -- block_group, (unsigned long) gdp->bg_inode_bitmap); -+ "block_group = %lu, inode_bitmap = %u", -+ block_group, gdp->bg_inode_bitmap); - retval = -EIO; - } - /* -@@ -533,19 +533,19 @@ out: - } - - /* Verify that we are loading a valid orphan from disk */ --struct inode *ext3_orphan_get (struct super_block * sb, ino_t ino) -+struct inode *ext3_orphan_get(struct super_block *sb, unsigned long ino) - { -- ino_t max_ino = le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count); -+ unsigned long max_ino = le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count); - unsigned long block_group; - int bit; - int bitmap_nr; - struct buffer_head *bh; - struct inode *inode = NULL; -- -+ - /* Error cases - e2fsck has already cleaned up for us */ - if (ino > max_ino) { - ext3_warning(sb, __FUNCTION__, -- "bad orphan ino %ld! e2fsck was run?\n", ino); -+ "bad orphan ino %lu! e2fsck was run?\n", ino); - return NULL; - } - -@@ -554,7 +554,7 @@ struct inode *ext3_orphan_get (struct su - if ((bitmap_nr = load_inode_bitmap(sb, block_group)) < 0 || - !(bh = EXT3_SB(sb)->s_inode_bitmap[bitmap_nr])) { - ext3_warning(sb, __FUNCTION__, -- "inode bitmap error for orphan %ld\n", ino); -+ "inode bitmap error for orphan %lu\n", ino); - return NULL; - } - -@@ -565,16 +565,16 @@ struct inode *ext3_orphan_get (struct su - if (!ext3_test_bit(bit, bh->b_data) || !(inode = iget(sb, ino)) || - is_bad_inode(inode) || NEXT_ORPHAN(inode) > max_ino) { - ext3_warning(sb, __FUNCTION__, -- "bad orphan inode %ld! e2fsck was run?\n", ino); -+ "bad orphan inode %lu! e2fsck was run?\n", ino); - printk(KERN_NOTICE "ext3_test_bit(bit=%d, block=%ld) = %d\n", - bit, bh->b_blocknr, ext3_test_bit(bit, bh->b_data)); - printk(KERN_NOTICE "inode=%p\n", inode); - if (inode) { - printk(KERN_NOTICE "is_bad_inode(inode)=%d\n", - is_bad_inode(inode)); -- printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%d\n", -+ printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%u\n", - NEXT_ORPHAN(inode)); -- printk(KERN_NOTICE "max_ino=%ld\n", max_ino); -+ printk(KERN_NOTICE "max_ino=%lu\n", max_ino); - } - /* Avoid freeing blocks if we got a bad deleted inode */ - if (inode && inode->i_nlink == 0) ---- linux-2.4.20/fs/ext3/namei.c~ext3-2.4-ino_t 2003-04-08 23:35:24.000000000 -0600 -+++ linux-2.4.20-braam/fs/ext3/namei.c 2003-04-08 23:35:24.000000000 -0600 -@@ -1808,10 +1808,10 @@ int ext3_orphan_del(handle_t *handle, st - struct list_head *prev; - struct ext3_inode_info *ei = EXT3_I(inode); - struct ext3_sb_info *sbi; -- ino_t ino_next; -+ unsigned long ino_next; - struct ext3_iloc iloc; - int err = 0; -- -+ - lock_super(inode->i_sb); - if (list_empty(&ei->i_orphan)) { - unlock_super(inode->i_sb); -@@ -1822,7 +1822,7 @@ int ext3_orphan_del(handle_t *handle, st - prev = ei->i_orphan.prev; - sbi = EXT3_SB(inode->i_sb); - -- jbd_debug(4, "remove inode %ld from orphan list\n", inode->i_ino); -+ jbd_debug(4, "remove inode %lu from orphan list\n", inode->i_ino); - - list_del(&ei->i_orphan); - INIT_LIST_HEAD(&ei->i_orphan); -@@ -1833,13 +1833,13 @@ int ext3_orphan_del(handle_t *handle, st - * list in memory. */ - if (!handle) - goto out; -- -+ - err = ext3_reserve_inode_write(handle, inode, &iloc); - if (err) - goto out_err; - - if (prev == &sbi->s_orphan) { -- jbd_debug(4, "superblock will point to %ld\n", ino_next); -+ jbd_debug(4, "superblock will point to %lu\n", ino_next); - BUFFER_TRACE(sbi->s_sbh, "get_write_access"); - err = ext3_journal_get_write_access(handle, sbi->s_sbh); - if (err) -@@ -1850,8 +1850,8 @@ int ext3_orphan_del(handle_t *handle, st - struct ext3_iloc iloc2; - struct inode *i_prev = - list_entry(prev, struct inode, u.ext3_i.i_orphan); -- -- jbd_debug(4, "orphan inode %ld will point to %ld\n", -+ -+ jbd_debug(4, "orphan inode %lu will point to %lu\n", - i_prev->i_ino, ino_next); - err = ext3_reserve_inode_write(handle, i_prev, &iloc2); - if (err) -@@ -1866,7 +1866,7 @@ int ext3_orphan_del(handle_t *handle, st - if (err) - goto out_brelse; - --out_err: -+out_err: - ext3_std_error(inode->i_sb, err); - out: - unlock_super(inode->i_sb); ---- linux-2.4.20/include/linux/ext3_fs.h~ext3-2.4-ino_t 2003-04-08 23:35:24.000000000 -0600 -+++ linux-2.4.20-braam/include/linux/ext3_fs.h 2003-04-08 23:35:24.000000000 -0600 -@@ -673,7 +673,7 @@ extern int ext3fs_dirhash(const char *na - /* ialloc.c */ - extern struct inode * ext3_new_inode (handle_t *, const struct inode *, int); - extern void ext3_free_inode (handle_t *, struct inode *); --extern struct inode * ext3_orphan_get (struct super_block *, ino_t); -+extern struct inode * ext3_orphan_get (struct super_block *, unsigned long); - extern unsigned long ext3_count_free_inodes (struct super_block *); - extern void ext3_check_inodes_bitmap (struct super_block *); - extern unsigned long ext3_count_free (struct buffer_head *, unsigned); - -_ diff --git a/lustre/kernel_patches/patches/ext3-delete_thread-2.4.24.patch b/lustre/kernel_patches/patches/ext3-delete_thread-2.4.24.patch deleted file mode 100644 index 6059aba..0000000 --- a/lustre/kernel_patches/patches/ext3-delete_thread-2.4.24.patch +++ /dev/null @@ -1,444 +0,0 @@ - fs/ext3/file.c | 4 - fs/ext3/inode.c | 116 ++++++++++++++++++++++ - fs/ext3/super.c | 230 +++++++++++++++++++++++++++++++++++++++++++++ - include/linux/ext3_fs.h | 5 - include/linux/ext3_fs_sb.h | 10 + - 5 files changed, 365 insertions(+) - -Index: linux-2.4.24/fs/ext3/super.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/super.c 2004-01-12 20:36:31.000000000 +0300 -+++ linux-2.4.24/fs/ext3/super.c 2004-01-13 16:27:43.000000000 +0300 -@@ -400,6 +400,128 @@ - } - } - -+#ifdef EXT3_DELETE_THREAD -+/* -+ * Delete inodes in a loop until there are no more to be deleted. -+ * Normally, we run in the background doing the deletes and sleeping again, -+ * and clients just add new inodes to be deleted onto the end of the list. -+ * If someone is concerned about free space (e.g. block allocation or similar) -+ * then they can sleep on s_delete_waiter_queue and be woken up when space -+ * has been freed. -+ */ -+int ext3_delete_thread(void *data) -+{ -+ struct super_block *sb = data; -+ struct ext3_sb_info *sbi = EXT3_SB(sb); -+ struct task_struct *tsk = current; -+ struct inode *inode; -+ unsigned long blocks; -+ -+ /* Almost like daemonize, but not quite */ -+ exit_mm(current); -+ tsk->session = 1; -+ tsk->pgrp = 1; -+ tsk->tty = NULL; -+ exit_files(current); -+ reparent_to_init(); -+ -+ sprintf(tsk->comm, "kdelext3-%s", kdevname(sb->s_dev)); -+ sigfillset(&tsk->blocked); -+ -+ /*tsk->flags |= PF_KERNTHREAD;*/ -+ -+ INIT_LIST_HEAD(&sbi->s_delete_list); -+ wake_up(&sbi->s_delete_waiter_queue); -+ ext3_debug("delete thread on %s started\n", kdevname(sb->s_dev)); -+ -+ /* main loop */ -+ for (;;) { -+ wait_event_interruptible(sbi->s_delete_thread_queue, -+ !list_empty(&sbi->s_delete_list) || -+ !test_opt(sb, ASYNCDEL)); -+ ext3_debug("%s woken up: %lu inodes, %lu blocks\n", -+ tsk->comm,sbi->s_delete_inodes,sbi->s_delete_blocks); -+ -+ spin_lock(&sbi->s_delete_lock); -+ if (list_empty(&sbi->s_delete_list)) { -+ clear_opt(sbi->s_mount_opt, ASYNCDEL); -+ memset(&sbi->s_delete_list, 0, -+ sizeof(sbi->s_delete_list)); -+ spin_unlock(&sbi->s_delete_lock); -+ ext3_debug("delete thread on %s exiting\n", -+ kdevname(sb->s_dev)); -+ wake_up(&sbi->s_delete_waiter_queue); -+ break; -+ } -+ -+ while (!list_empty(&sbi->s_delete_list)) { -+ inode = list_entry(sbi->s_delete_list.next, -+ struct inode, i_devices); -+ blocks = inode->i_blocks >> (inode->i_blkbits - 9); -+ -+ list_del_init(&inode->i_devices); -+ spin_unlock(&sbi->s_delete_lock); -+ ext3_debug("%s delete ino %lu blk %lu\n", -+ tsk->comm, inode->i_ino, blocks); -+ -+ J_ASSERT(EXT3_I(inode)->i_state & EXT3_STATE_DELETE); -+ J_ASSERT(inode->i_nlink == 1); -+ inode->i_nlink = 0; -+ iput(inode); -+ -+ spin_lock(&sbi->s_delete_lock); -+ sbi->s_delete_blocks -= blocks; -+ sbi->s_delete_inodes--; -+ } -+ if (sbi->s_delete_blocks != 0 || sbi->s_delete_inodes != 0) { -+ ext3_warning(sb, __FUNCTION__, -+ "%lu blocks, %lu inodes on list?\n", -+ sbi->s_delete_blocks,sbi->s_delete_inodes); -+ sbi->s_delete_blocks = 0; -+ sbi->s_delete_inodes = 0; -+ } -+ spin_unlock(&sbi->s_delete_lock); -+ wake_up(&sbi->s_delete_waiter_queue); -+ } -+ -+ return 0; -+} -+ -+static void ext3_start_delete_thread(struct super_block *sb) -+{ -+ struct ext3_sb_info *sbi = EXT3_SB(sb); -+ int rc; -+ -+ spin_lock_init(&sbi->s_delete_lock); -+ init_waitqueue_head(&sbi->s_delete_thread_queue); -+ init_waitqueue_head(&sbi->s_delete_waiter_queue); -+ -+ if (!test_opt(sb, ASYNCDEL)) -+ return; -+ -+ rc = kernel_thread(ext3_delete_thread, sb, CLONE_VM | CLONE_FILES); -+ if (rc < 0) -+ printk(KERN_ERR "EXT3-fs: cannot start delete thread: rc %d\n", -+ rc); -+ else -+ wait_event(sbi->s_delete_waiter_queue, sbi->s_delete_list.next); -+} -+ -+static void ext3_stop_delete_thread(struct ext3_sb_info *sbi) -+{ -+ if (sbi->s_delete_list.next == 0) /* thread never started */ -+ return; -+ -+ clear_opt(sbi->s_mount_opt, ASYNCDEL); -+ wake_up(&sbi->s_delete_thread_queue); -+ wait_event(sbi->s_delete_waiter_queue, -+ sbi->s_delete_list.next == 0 && sbi->s_delete_inodes == 0); -+} -+#else -+#define ext3_start_delete_thread(sbi) do {} while(0) -+#define ext3_stop_delete_thread(sbi) do {} while(0) -+#endif /* EXT3_DELETE_THREAD */ -+ - void ext3_put_super (struct super_block * sb) - { - struct ext3_sb_info *sbi = EXT3_SB(sb); -@@ -407,6 +529,7 @@ - kdev_t j_dev = sbi->s_journal->j_dev; - int i; - -+ J_ASSERT(sbi->s_delete_inodes == 0); - ext3_xattr_put_super(sb); - journal_destroy(sbi->s_journal); - if (!(sb->s_flags & MS_RDONLY)) { -@@ -527,6 +650,13 @@ - clear_opt (*mount_options, XATTR_USER); - else - #endif -+#ifdef EXT3_DELETE_THREAD -+ if (!strcmp(this_char, "asyncdel")) -+ set_opt(*mount_options, ASYNCDEL); -+ else if (!strcmp(this_char, "noasyncdel")) -+ clear_opt(*mount_options, ASYNCDEL); -+ else -+#endif - if (!strcmp (this_char, "bsddf")) - clear_opt (*mount_options, MINIX_DF); - else if (!strcmp (this_char, "nouid32")) { -@@ -1227,6 +1357,7 @@ - } - - ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY); -+ ext3_start_delete_thread(sb); - /* - * akpm: core read_super() calls in here with the superblock locked. - * That deadlocks, because orphan cleanup needs to lock the superblock -@@ -1618,7 +1749,12 @@ - static int ext3_sync_fs(struct super_block *sb) - { - tid_t target; -- -+ -+ if (atomic_read(&sb->s_active) == 0) { -+ /* fs is being umounted: time to stop delete thread */ -+ ext3_stop_delete_thread(EXT3_SB(sb)); -+ } -+ - sb->s_dirt = 0; - target = log_start_commit(EXT3_SB(sb)->s_journal, NULL); - log_wait_commit(EXT3_SB(sb)->s_journal, target); -@@ -1682,6 +1818,9 @@ - if (!parse_options(data, &tmp, sbi, &tmp, 1)) - return -EINVAL; - -+ if (!test_opt(sb, ASYNCDEL) || (*flags & MS_RDONLY)) -+ ext3_stop_delete_thread(sbi); -+ - if (sbi->s_mount_opt & EXT3_MOUNT_ABORT) - ext3_abort(sb, __FUNCTION__, "Abort forced by user"); - -Index: linux-2.4.24/fs/ext3/inode.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/inode.c 2004-01-12 20:36:31.000000000 +0300 -+++ linux-2.4.24/fs/ext3/inode.c 2004-01-12 20:36:32.000000000 +0300 -@@ -2551,6 +2551,118 @@ - return err; - } - -+#ifdef EXT3_DELETE_THREAD -+/* Move blocks from to-be-truncated inode over to a new inode, and delete -+ * that one from the delete thread instead. This avoids a lot of latency -+ * when truncating large files. -+ * -+ * If we have any problem deferring the truncate, just truncate it right away. -+ * If we defer it, we also mark how many blocks it would free, so that we -+ * can keep the statfs data correct, and we know if we should sleep on the -+ * delete thread when we run out of space. -+ */ -+void ext3_truncate_thread(struct inode *old_inode) -+{ -+ struct ext3_sb_info *sbi = EXT3_SB(old_inode->i_sb); -+ struct ext3_inode_info *nei, *oei = EXT3_I(old_inode); -+ struct inode *new_inode; -+ handle_t *handle; -+ unsigned long blocks = old_inode->i_blocks >> (old_inode->i_blkbits-9); -+ -+ if (!test_opt(old_inode->i_sb, ASYNCDEL) || !sbi->s_delete_list.next) -+ goto out_truncate; -+ -+ /* XXX This is a temporary limitation for code simplicity. -+ * We could truncate to arbitrary sizes at some later time. -+ */ -+ if (old_inode->i_size != 0) -+ goto out_truncate; -+ -+ /* We may want to truncate the inode immediately and not defer it */ -+ if (IS_SYNC(old_inode) || blocks <= EXT3_NDIR_BLOCKS || -+ old_inode->i_size > oei->i_disksize) -+ goto out_truncate; -+ -+ /* We can't use the delete thread as-is during real orphan recovery, -+ * as we add to the orphan list here, causing ext3_orphan_cleanup() -+ * to loop endlessly. It would be nice to do so, but needs work. -+ */ -+ if (oei->i_state & EXT3_STATE_DELETE || -+ sbi->s_mount_state & EXT3_ORPHAN_FS) { -+ ext3_debug("doing deferred inode %lu delete (%lu blocks)\n", -+ old_inode->i_ino, blocks); -+ goto out_truncate; -+ } -+ -+ ext3_discard_prealloc(old_inode); -+ -+ /* old_inode = 1 -+ * new_inode = sb + GDT + ibitmap -+ * orphan list = 1 inode/superblock for add, 2 inodes for del -+ * quota files = 2 * EXT3_SINGLEDATA_TRANS_BLOCKS -+ */ -+ handle = ext3_journal_start(old_inode, 7); -+ if (IS_ERR(handle)) -+ goto out_truncate; -+ -+ new_inode = ext3_new_inode(handle, old_inode, old_inode->i_mode); -+ if (IS_ERR(new_inode)) { -+ ext3_debug("truncate inode %lu directly (no new inodes)\n", -+ old_inode->i_ino); -+ goto out_journal; -+ } -+ -+ nei = EXT3_I(new_inode); -+ -+ down_write(&oei->truncate_sem); -+ new_inode->i_size = old_inode->i_size; -+ new_inode->i_blocks = old_inode->i_blocks; -+ new_inode->i_uid = old_inode->i_uid; -+ new_inode->i_gid = old_inode->i_gid; -+ new_inode->i_nlink = 1; -+ -+ /* FIXME when we do arbitrary truncates */ -+ old_inode->i_blocks = oei->i_file_acl ? old_inode->i_blksize / 512 : 0; -+ old_inode->i_mtime = old_inode->i_ctime = CURRENT_TIME; -+ -+ memcpy(nei->i_data, oei->i_data, sizeof(nei->i_data)); -+ memset(oei->i_data, 0, sizeof(oei->i_data)); -+ -+ nei->i_disksize = oei->i_disksize; -+ nei->i_state |= EXT3_STATE_DELETE; -+ up_write(&oei->truncate_sem); -+ -+ if (ext3_orphan_add(handle, new_inode) < 0) -+ goto out_journal; -+ -+ if (ext3_orphan_del(handle, old_inode) < 0) { -+ ext3_orphan_del(handle, new_inode); -+ iput(new_inode); -+ goto out_journal; -+ } -+ -+ ext3_journal_stop(handle, old_inode); -+ -+ spin_lock(&sbi->s_delete_lock); -+ J_ASSERT(list_empty(&new_inode->i_devices)); -+ list_add_tail(&new_inode->i_devices, &sbi->s_delete_list); -+ sbi->s_delete_blocks += blocks; -+ sbi->s_delete_inodes++; -+ spin_unlock(&sbi->s_delete_lock); -+ -+ ext3_debug("delete inode %lu (%lu blocks) by thread\n", -+ new_inode->i_ino, blocks); -+ -+ wake_up(&sbi->s_delete_thread_queue); -+ return; -+ -+out_journal: -+ ext3_journal_stop(handle, old_inode); -+out_truncate: -+ ext3_truncate(old_inode); -+} -+#endif /* EXT3_DELETE_THREAD */ -+ - /* - * On success, We end up with an outstanding reference count against - * iloc->bh. This _must_ be cleaned up later. -Index: linux-2.4.24/fs/ext3/file.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/file.c 2004-01-12 20:36:29.000000000 +0300 -+++ linux-2.4.24/fs/ext3/file.c 2004-01-12 20:36:32.000000000 +0300 -@@ -126,7 +126,11 @@ - }; - - struct inode_operations ext3_file_inode_operations = { -+#ifdef EXT3_DELETE_THREAD -+ truncate: ext3_truncate_thread, /* BKL held */ -+#else - truncate: ext3_truncate, /* BKL held */ -+#endif - setattr: ext3_setattr, /* BKL held */ - setxattr: ext3_setxattr, /* BKL held */ - getxattr: ext3_getxattr, /* BKL held */ -Index: linux-2.4.24/fs/ext3/namei.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/namei.c 2004-01-12 20:36:31.000000000 +0300 -+++ linux-2.4.24/fs/ext3/namei.c 2004-01-12 20:36:32.000000000 +0300 -@@ -1936,6 +1936,36 @@ - return retval; - } - -+static int ext3_try_to_delay_deletion(struct inode *inode) -+{ -+ struct ext3_sb_info *sbi = EXT3_SB(inode->i_sb); -+ struct ext3_inode_info *ei = EXT3_I(inode); -+ unsigned long blocks; -+ -+ if (!test_opt(inode->i_sb, ASYNCDEL)) -+ return 0; -+ -+ /* We may want to delete the inode immediately and not defer it */ -+ blocks = inode->i_blocks >> (inode->i_blkbits - 9); -+ if (IS_SYNC(inode) || blocks <= EXT3_NDIR_BLOCKS) -+ return 0; -+ -+ inode->i_nlink = 1; -+ atomic_inc(&inode->i_count); -+ ei->i_state |= EXT3_STATE_DELETE; -+ -+ spin_lock(&sbi->s_delete_lock); -+ J_ASSERT(list_empty(&inode->i_devices)); -+ list_add_tail(&inode->i_devices, &sbi->s_delete_list); -+ sbi->s_delete_blocks += blocks; -+ sbi->s_delete_inodes++; -+ spin_unlock(&sbi->s_delete_lock); -+ -+ wake_up(&sbi->s_delete_thread_queue); -+ -+ return 0; -+} -+ - static int ext3_unlink(struct inode * dir, struct dentry *dentry) - { - int retval; -@@ -1977,8 +2007,10 @@ - ext3_update_dx_flag(dir); - ext3_mark_inode_dirty(handle, dir); - inode->i_nlink--; -- if (!inode->i_nlink) -+ if (!inode->i_nlink) { -+ ext3_try_to_delay_deletion(inode); - ext3_orphan_add(handle, inode); -+ } - inode->i_ctime = dir->i_ctime; - ext3_mark_inode_dirty(handle, inode); - retval = 0; -Index: linux-2.4.24/include/linux/ext3_fs.h -=================================================================== ---- linux-2.4.24.orig/include/linux/ext3_fs.h 2004-01-12 20:36:31.000000000 +0300 -+++ linux-2.4.24/include/linux/ext3_fs.h 2004-01-12 20:36:32.000000000 +0300 -@@ -193,6 +193,7 @@ - */ - #define EXT3_STATE_JDATA 0x00000001 /* journaled data exists */ - #define EXT3_STATE_NEW 0x00000002 /* inode is newly created */ -+#define EXT3_STATE_DELETE 0x00000010 /* deferred delete inode */ - - /* - * ioctl commands -@@ -320,6 +321,7 @@ - #define EXT3_MOUNT_UPDATE_JOURNAL 0x1000 /* Update the journal format */ - #define EXT3_MOUNT_NO_UID32 0x2000 /* Disable 32-bit UIDs */ - #define EXT3_MOUNT_XATTR_USER 0x4000 /* Extended user attributes */ -+#define EXT3_MOUNT_ASYNCDEL 0x20000 /* Delayed deletion */ - - /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ - #ifndef _LINUX_EXT2_FS_H -@@ -697,6 +699,9 @@ - extern void ext3_dirty_inode(struct inode *); - extern int ext3_change_inode_journal_flag(struct inode *, int); - extern void ext3_truncate (struct inode *); -+#ifdef EXT3_DELETE_THREAD -+extern void ext3_truncate_thread(struct inode *inode); -+#endif - extern void ext3_set_inode_flags(struct inode *); - - /* ioctl.c */ -Index: linux-2.4.24/include/linux/ext3_fs_sb.h -=================================================================== ---- linux-2.4.24.orig/include/linux/ext3_fs_sb.h 2004-01-12 20:36:31.000000000 +0300 -+++ linux-2.4.24/include/linux/ext3_fs_sb.h 2004-01-12 20:36:32.000000000 +0300 -@@ -29,6 +29,8 @@ - - #define EXT3_MAX_GROUP_LOADED 8 - -+#define EXT3_DELETE_THREAD -+ - /* - * third extended-fs super-block data in memory - */ -@@ -76,6 +78,14 @@ - struct timer_list turn_ro_timer; /* For turning read-only (crash simulation) */ - wait_queue_head_t ro_wait_queue; /* For people waiting for the fs to go read-only */ - #endif -+#ifdef EXT3_DELETE_THREAD -+ spinlock_t s_delete_lock; -+ struct list_head s_delete_list; -+ unsigned long s_delete_blocks; -+ unsigned long s_delete_inodes; -+ wait_queue_head_t s_delete_thread_queue; -+ wait_queue_head_t s_delete_waiter_queue; -+#endif - }; - - #endif /* _LINUX_EXT3_FS_SB */ diff --git a/lustre/kernel_patches/patches/ext3-delete_thread-suse.patch b/lustre/kernel_patches/patches/ext3-delete_thread-suse.patch deleted file mode 100644 index f3d7f3c..0000000 --- a/lustre/kernel_patches/patches/ext3-delete_thread-suse.patch +++ /dev/null @@ -1,496 +0,0 @@ - fs/ext3/file.c | 4 - fs/ext3/inode.c | 116 ++++++++++++++++++++++ - fs/ext3/super.c | 230 +++++++++++++++++++++++++++++++++++++++++++++ - include/linux/ext3_fs.h | 5 - include/linux/ext3_fs_sb.h | 10 + - 5 files changed, 365 insertions(+) - -Index: linux-2.4.21-suse/fs/ext3/super.c -=================================================================== ---- linux-2.4.21-suse.orig/fs/ext3/super.c 2004-01-12 19:49:25.000000000 +0300 -+++ linux-2.4.21-suse/fs/ext3/super.c 2004-01-13 17:39:59.000000000 +0300 -@@ -400,6 +400,221 @@ - } - } - -+#ifdef EXT3_DELETE_THREAD -+/* -+ * Delete inodes in a loop until there are no more to be deleted. -+ * Normally, we run in the background doing the deletes and sleeping again, -+ * and clients just add new inodes to be deleted onto the end of the list. -+ * If someone is concerned about free space (e.g. block allocation or similar) -+ * then they can sleep on s_delete_waiter_queue and be woken up when space -+ * has been freed. -+ */ -+int ext3_delete_thread(void *data) -+{ -+ struct super_block *sb = data; -+ struct ext3_sb_info *sbi = EXT3_SB(sb); -+ struct task_struct *tsk = current; -+ -+ /* Almost like daemonize, but not quite */ -+ exit_mm(current); -+ tsk->session = 1; -+ tsk->pgrp = 1; -+ tsk->tty = NULL; -+ exit_files(current); -+ reparent_to_init(); -+ -+ sprintf(tsk->comm, "kdelext3-%s", kdevname(sb->s_dev)); -+ sigfillset(&tsk->blocked); -+ -+ /*tsk->flags |= PF_KERNTHREAD;*/ -+ -+ INIT_LIST_HEAD(&sbi->s_delete_list); -+ wake_up(&sbi->s_delete_waiter_queue); -+ ext3_debug("delete thread on %s started\n", kdevname(sb->s_dev)); -+ -+ /* main loop */ -+ for (;;) { -+ wait_event_interruptible(sbi->s_delete_thread_queue, -+ !list_empty(&sbi->s_delete_list) || -+ !test_opt(sb, ASYNCDEL)); -+ ext3_debug("%s woken up: %lu inodes, %lu blocks\n", -+ tsk->comm,sbi->s_delete_inodes,sbi->s_delete_blocks); -+ -+ spin_lock(&sbi->s_delete_lock); -+ if (list_empty(&sbi->s_delete_list)) { -+ clear_opt(sbi->s_mount_opt, ASYNCDEL); -+ memset(&sbi->s_delete_list, 0, -+ sizeof(sbi->s_delete_list)); -+ spin_unlock(&sbi->s_delete_lock); -+ ext3_debug("delete thread on %s exiting\n", -+ kdevname(sb->s_dev)); -+ wake_up(&sbi->s_delete_waiter_queue); -+ break; -+ } -+ -+ while (!list_empty(&sbi->s_delete_list)) { -+ struct inode *inode=list_entry(sbi->s_delete_list.next, -+ struct inode, i_dentry); -+ unsigned long blocks = inode->i_blocks >> -+ (inode->i_blkbits - 9); -+ -+ list_del_init(&inode->i_dentry); -+ spin_unlock(&sbi->s_delete_lock); -+ ext3_debug("%s delete ino %lu blk %lu\n", -+ tsk->comm, inode->i_ino, blocks); -+ -+ iput(inode); -+ -+ spin_lock(&sbi->s_delete_lock); -+ sbi->s_delete_blocks -= blocks; -+ sbi->s_delete_inodes--; -+ } -+ if (sbi->s_delete_blocks != 0 || sbi->s_delete_inodes != 0) { -+ ext3_warning(sb, __FUNCTION__, -+ "%lu blocks, %lu inodes on list?\n", -+ sbi->s_delete_blocks,sbi->s_delete_inodes); -+ sbi->s_delete_blocks = 0; -+ sbi->s_delete_inodes = 0; -+ } -+ spin_unlock(&sbi->s_delete_lock); -+ wake_up(&sbi->s_delete_waiter_queue); -+ } -+ -+ return 0; -+} -+ -+static void ext3_start_delete_thread(struct super_block *sb) -+{ -+ struct ext3_sb_info *sbi = EXT3_SB(sb); -+ int rc; -+ -+ spin_lock_init(&sbi->s_delete_lock); -+ init_waitqueue_head(&sbi->s_delete_thread_queue); -+ init_waitqueue_head(&sbi->s_delete_waiter_queue); -+ -+ if (!test_opt(sb, ASYNCDEL)) -+ return; -+ -+ rc = kernel_thread(ext3_delete_thread, sb, CLONE_VM | CLONE_FILES); -+ if (rc < 0) -+ printk(KERN_ERR "EXT3-fs: cannot start delete thread: rc %d\n", -+ rc); -+ else -+ wait_event(sbi->s_delete_waiter_queue, sbi->s_delete_list.next); -+} -+ -+static void ext3_stop_delete_thread(struct ext3_sb_info *sbi) -+{ -+ if (sbi->s_delete_list.next == 0) /* thread never started */ -+ return; -+ -+ clear_opt(sbi->s_mount_opt, ASYNCDEL); -+ wake_up(&sbi->s_delete_thread_queue); -+ wait_event(sbi->s_delete_waiter_queue, -+ sbi->s_delete_list.next == 0 && sbi->s_delete_inodes == 0); -+} -+ -+/* Instead of playing games with the inode flags, destruction, etc we just -+ * create a new inode locally and put it on a list for the truncate thread. -+ * We need large parts of the inode struct in order to complete the -+ * truncate and unlink, so we may as well just have a real inode to do it. -+ * -+ * If we have any problem deferring the delete, just delete it right away. -+ * If we defer it, we also mark how many blocks it would free, so that we -+ * can keep the statfs data correct, and we know if we should sleep on the -+ * delete thread when we run out of space. -+ */ -+static void ext3_delete_inode_thread(struct inode *old_inode) -+{ -+ struct ext3_sb_info *sbi = EXT3_SB(old_inode->i_sb); -+ struct ext3_inode_info *nei, *oei = EXT3_I(old_inode); -+ struct inode *new_inode; -+ unsigned long blocks = old_inode->i_blocks >> (old_inode->i_blkbits-9); -+ -+ if (is_bad_inode(old_inode)) { -+ clear_inode(old_inode); -+ return; -+ } -+ -+ if (!test_opt(old_inode->i_sb, ASYNCDEL) || !sbi->s_delete_list.next) -+ goto out_delete; -+ -+ /* We may want to delete the inode immediately and not defer it */ -+ if (IS_SYNC(old_inode) || blocks <= EXT3_NDIR_BLOCKS) -+ goto out_delete; -+ -+ /* We can't use the delete thread as-is during real orphan recovery, -+ * as we add to the orphan list here, causing ext3_orphan_cleanup() -+ * to loop endlessly. It would be nice to do so, but needs work. -+ */ -+ if (oei->i_state & EXT3_STATE_DELETE || -+ sbi->s_mount_state & EXT3_ORPHAN_FS) { -+ ext3_debug("doing deferred inode %lu delete (%lu blocks)\n", -+ old_inode->i_ino, blocks); -+ goto out_delete; -+ } -+ -+ /* We can iget this inode again here, because our caller has unhashed -+ * old_inode, so new_inode will be in a different inode struct. -+ * -+ * We need to ensure that the i_orphan pointers in the other inodes -+ * point at the new inode copy instead of the old one so the orphan -+ * list doesn't get corrupted when the old orphan inode is freed. -+ */ -+ down(&sbi->s_orphan_lock); -+ -+ sbi->s_mount_state |= EXT3_ORPHAN_FS; -+ new_inode = iget(old_inode->i_sb, old_inode->i_ino); -+ sbi->s_mount_state &= ~EXT3_ORPHAN_FS; -+ if (is_bad_inode(new_inode)) { -+ printk(KERN_WARNING "read bad inode %lu\n", old_inode->i_ino); -+ iput(new_inode); -+ new_inode = NULL; -+ } -+ if (!new_inode) { -+ up(&sbi->s_orphan_lock); -+ ext3_debug("delete inode %lu directly (bad read)\n", -+ old_inode->i_ino); -+ goto out_delete; -+ } -+ J_ASSERT(new_inode != old_inode); -+ -+ J_ASSERT(!list_empty(&oei->i_orphan)); -+ -+ nei = EXT3_I(new_inode); -+ /* Ugh. We need to insert new_inode into the same spot on the list -+ * as old_inode was, to ensure the in-memory orphan list is still -+ * in the same order as the on-disk orphan list (badness otherwise). -+ */ -+ nei->i_orphan = oei->i_orphan; -+ nei->i_orphan.next->prev = &nei->i_orphan; -+ nei->i_orphan.prev->next = &nei->i_orphan; -+ nei->i_state |= EXT3_STATE_DELETE; -+ up(&sbi->s_orphan_lock); -+ -+ clear_inode(old_inode); -+ -+ spin_lock(&sbi->s_delete_lock); -+ J_ASSERT(list_empty(&new_inode->i_dentry)); -+ list_add_tail(&new_inode->i_dentry, &sbi->s_delete_list); -+ sbi->s_delete_blocks += blocks; -+ sbi->s_delete_inodes++; -+ spin_unlock(&sbi->s_delete_lock); -+ -+ ext3_debug("delete inode %lu (%lu blocks) by thread\n", -+ new_inode->i_ino, blocks); -+ -+ wake_up(&sbi->s_delete_thread_queue); -+ return; -+ -+out_delete: -+ ext3_delete_inode(old_inode); -+} -+#else -+#define ext3_start_delete_thread(sbi) do {} while(0) -+#define ext3_stop_delete_thread(sbi) do {} while(0) -+#endif /* EXT3_DELETE_THREAD */ -+ - void ext3_put_super (struct super_block * sb) - { - struct ext3_sb_info *sbi = EXT3_SB(sb); -@@ -407,6 +622,7 @@ - kdev_t j_dev = sbi->s_journal->j_dev; - int i; - -+ J_ASSERT(sbi->s_delete_inodes == 0); - ext3_xattr_put_super(sb); - journal_destroy(sbi->s_journal); - if (!(sb->s_flags & MS_RDONLY)) { -@@ -455,7 +671,11 @@ - write_inode: ext3_write_inode, /* BKL not held. Don't need */ - dirty_inode: ext3_dirty_inode, /* BKL not held. We take it */ - put_inode: ext3_put_inode, /* BKL not held. Don't need */ -+#ifdef EXT3_DELETE_THREAD -+ delete_inode: ext3_delete_inode_thread,/* BKL not held. We take it */ -+#else - delete_inode: ext3_delete_inode, /* BKL not held. We take it */ -+#endif - put_super: ext3_put_super, /* BKL held */ - write_super: ext3_write_super, /* BKL held */ - sync_fs: ext3_sync_fs, -@@ -524,6 +744,13 @@ - clear_opt (*mount_options, XATTR_USER); - else - #endif -+#ifdef EXT3_DELETE_THREAD -+ if (!strcmp(this_char, "asyncdel")) -+ set_opt(*mount_options, ASYNCDEL); -+ else if (!strcmp(this_char, "noasyncdel")) -+ clear_opt(*mount_options, ASYNCDEL); -+ else -+#endif - if (!strcmp (this_char, "bsddf")) - clear_opt (*mount_options, MINIX_DF); - else if (!strcmp (this_char, "nouid32")) { -@@ -1223,6 +1450,7 @@ - } - - ext3_setup_super (sb, es, sb->s_flags & MS_RDONLY); -+ ext3_start_delete_thread(sb); - /* - * akpm: core read_super() calls in here with the superblock locked. - * That deadlocks, because orphan cleanup needs to lock the superblock -@@ -1614,7 +1842,12 @@ - static int ext3_sync_fs(struct super_block *sb) - { - tid_t target; -- -+ -+ if (atomic_read(&sb->s_active) == 0) { -+ /* fs is being umounted: time to stop delete thread */ -+ ext3_stop_delete_thread(EXT3_SB(sb)); -+ } -+ - sb->s_dirt = 0; - target = log_start_commit(EXT3_SB(sb)->s_journal, NULL); - log_wait_commit(EXT3_SB(sb)->s_journal, target); -@@ -1678,6 +1911,9 @@ - if (!parse_options(data, &tmp, sbi, &tmp, 1)) - return -EINVAL; - -+ if (!test_opt(sb, ASYNCDEL) || (*flags & MS_RDONLY)) -+ ext3_stop_delete_thread(sbi); -+ - if (sbi->s_mount_opt & EXT3_MOUNT_ABORT) - ext3_abort(sb, __FUNCTION__, "Abort forced by user"); - -Index: linux-2.4.21-suse/fs/ext3/inode.c -=================================================================== ---- linux-2.4.21-suse.orig/fs/ext3/inode.c 2004-01-13 17:38:09.000000000 +0300 -+++ linux-2.4.21-suse/fs/ext3/inode.c 2004-01-13 17:38:10.000000000 +0300 -@@ -2552,6 +2552,118 @@ - return err; - } - -+#ifdef EXT3_DELETE_THREAD -+/* Move blocks from to-be-truncated inode over to a new inode, and delete -+ * that one from the delete thread instead. This avoids a lot of latency -+ * when truncating large files. -+ * -+ * If we have any problem deferring the truncate, just truncate it right away. -+ * If we defer it, we also mark how many blocks it would free, so that we -+ * can keep the statfs data correct, and we know if we should sleep on the -+ * delete thread when we run out of space. -+ */ -+void ext3_truncate_thread(struct inode *old_inode) -+{ -+ struct ext3_sb_info *sbi = EXT3_SB(old_inode->i_sb); -+ struct ext3_inode_info *nei, *oei = EXT3_I(old_inode); -+ struct inode *new_inode; -+ handle_t *handle; -+ unsigned long blocks = old_inode->i_blocks >> (old_inode->i_blkbits-9); -+ -+ if (!test_opt(old_inode->i_sb, ASYNCDEL) || !sbi->s_delete_list.next) -+ goto out_truncate; -+ -+ /* XXX This is a temporary limitation for code simplicity. -+ * We could truncate to arbitrary sizes at some later time. -+ */ -+ if (old_inode->i_size != 0) -+ goto out_truncate; -+ -+ /* We may want to truncate the inode immediately and not defer it */ -+ if (IS_SYNC(old_inode) || blocks <= EXT3_NDIR_BLOCKS || -+ old_inode->i_size > oei->i_disksize) -+ goto out_truncate; -+ -+ /* We can't use the delete thread as-is during real orphan recovery, -+ * as we add to the orphan list here, causing ext3_orphan_cleanup() -+ * to loop endlessly. It would be nice to do so, but needs work. -+ */ -+ if (oei->i_state & EXT3_STATE_DELETE || -+ sbi->s_mount_state & EXT3_ORPHAN_FS) { -+ ext3_debug("doing deferred inode %lu delete (%lu blocks)\n", -+ old_inode->i_ino, blocks); -+ goto out_truncate; -+ } -+ -+ ext3_discard_prealloc(old_inode); -+ -+ /* old_inode = 1 -+ * new_inode = sb + GDT + ibitmap -+ * orphan list = 1 inode/superblock for add, 2 inodes for del -+ * quota files = 2 * EXT3_SINGLEDATA_TRANS_BLOCKS -+ */ -+ handle = ext3_journal_start(old_inode, 7); -+ if (IS_ERR(handle)) -+ goto out_truncate; -+ -+ new_inode = ext3_new_inode(handle, old_inode, old_inode->i_mode); -+ if (IS_ERR(new_inode)) { -+ ext3_debug("truncate inode %lu directly (no new inodes)\n", -+ old_inode->i_ino); -+ goto out_journal; -+ } -+ -+ nei = EXT3_I(new_inode); -+ -+ down_write(&oei->truncate_sem); -+ new_inode->i_size = old_inode->i_size; -+ new_inode->i_blocks = old_inode->i_blocks; -+ new_inode->i_uid = old_inode->i_uid; -+ new_inode->i_gid = old_inode->i_gid; -+ new_inode->i_nlink = 0; -+ -+ /* FIXME when we do arbitrary truncates */ -+ old_inode->i_blocks = oei->i_file_acl ? old_inode->i_blksize / 512 : 0; -+ old_inode->i_mtime = old_inode->i_ctime = CURRENT_TIME; -+ -+ memcpy(nei->i_data, oei->i_data, sizeof(nei->i_data)); -+ memset(oei->i_data, 0, sizeof(oei->i_data)); -+ -+ nei->i_disksize = oei->i_disksize; -+ nei->i_state |= EXT3_STATE_DELETE; -+ up_write(&oei->truncate_sem); -+ -+ if (ext3_orphan_add(handle, new_inode) < 0) -+ goto out_journal; -+ -+ if (ext3_orphan_del(handle, old_inode) < 0) { -+ ext3_orphan_del(handle, new_inode); -+ iput(new_inode); -+ goto out_journal; -+ } -+ -+ ext3_journal_stop(handle, old_inode); -+ -+ spin_lock(&sbi->s_delete_lock); -+ J_ASSERT(list_empty(&new_inode->i_dentry)); -+ list_add_tail(&new_inode->i_dentry, &sbi->s_delete_list); -+ sbi->s_delete_blocks += blocks; -+ sbi->s_delete_inodes++; -+ spin_unlock(&sbi->s_delete_lock); -+ -+ ext3_debug("delete inode %lu (%lu blocks) by thread\n", -+ new_inode->i_ino, blocks); -+ -+ wake_up(&sbi->s_delete_thread_queue); -+ return; -+ -+out_journal: -+ ext3_journal_stop(handle, old_inode); -+out_truncate: -+ ext3_truncate(old_inode); -+} -+#endif /* EXT3_DELETE_THREAD */ -+ - /* - * On success, We end up with an outstanding reference count against - * iloc->bh. This _must_ be cleaned up later. -Index: linux-2.4.21-suse/fs/ext3/file.c -=================================================================== ---- linux-2.4.21-suse.orig/fs/ext3/file.c 2004-01-12 19:49:25.000000000 +0300 -+++ linux-2.4.21-suse/fs/ext3/file.c 2004-01-13 17:38:10.000000000 +0300 -@@ -125,7 +125,11 @@ - }; - - struct inode_operations ext3_file_inode_operations = { -+#ifdef EXT3_DELETE_THREAD -+ truncate: ext3_truncate_thread, /* BKL held */ -+#else - truncate: ext3_truncate, /* BKL held */ -+#endif - setattr: ext3_setattr, /* BKL held */ - setxattr: ext3_setxattr, /* BKL held */ - getxattr: ext3_getxattr, /* BKL held */ -Index: linux-2.4.21-suse/include/linux/ext3_fs.h -=================================================================== ---- linux-2.4.21-suse.orig/include/linux/ext3_fs.h 2004-01-13 17:38:09.000000000 +0300 -+++ linux-2.4.21-suse/include/linux/ext3_fs.h 2004-01-13 17:38:10.000000000 +0300 -@@ -193,6 +193,7 @@ - */ - #define EXT3_STATE_JDATA 0x00000001 /* journaled data exists */ - #define EXT3_STATE_NEW 0x00000002 /* inode is newly created */ -+#define EXT3_STATE_DELETE 0x00000010 /* deferred delete inode */ - - /* - * ioctl commands -@@ -320,6 +321,7 @@ - #define EXT3_MOUNT_UPDATE_JOURNAL 0x1000 /* Update the journal format */ - #define EXT3_MOUNT_NO_UID32 0x2000 /* Disable 32-bit UIDs */ - #define EXT3_MOUNT_XATTR_USER 0x4000 /* Extended user attributes */ -+#define EXT3_MOUNT_ASYNCDEL 0x20000 /* Delayed deletion */ - - /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ - #ifndef _LINUX_EXT2_FS_H -@@ -697,6 +699,9 @@ - extern void ext3_dirty_inode(struct inode *); - extern int ext3_change_inode_journal_flag(struct inode *, int); - extern void ext3_truncate (struct inode *); -+#ifdef EXT3_DELETE_THREAD -+extern void ext3_truncate_thread(struct inode *inode); -+#endif - extern void ext3_set_inode_flags(struct inode *); - - /* ioctl.c */ -Index: linux-2.4.21-suse/include/linux/ext3_fs_sb.h -=================================================================== ---- linux-2.4.21-suse.orig/include/linux/ext3_fs_sb.h 2004-01-12 19:49:25.000000000 +0300 -+++ linux-2.4.21-suse/include/linux/ext3_fs_sb.h 2004-01-13 17:38:10.000000000 +0300 -@@ -29,6 +29,8 @@ - - #define EXT3_MAX_GROUP_LOADED 8 - -+#define EXT3_DELETE_THREAD -+ - /* - * third extended-fs super-block data in memory - */ -@@ -76,6 +78,14 @@ - struct timer_list turn_ro_timer; /* For turning read-only (crash simulation) */ - wait_queue_head_t ro_wait_queue; /* For people waiting for the fs to go read-only */ - #endif -+#ifdef EXT3_DELETE_THREAD -+ spinlock_t s_delete_lock; -+ struct list_head s_delete_list; -+ unsigned long s_delete_blocks; -+ unsigned long s_delete_inodes; -+ wait_queue_head_t s_delete_thread_queue; -+ wait_queue_head_t s_delete_waiter_queue; -+#endif - }; - - #endif /* _LINUX_EXT3_FS_SB */ diff --git a/lustre/kernel_patches/patches/ext3-dentry-fid-2.4.24.patch b/lustre/kernel_patches/patches/ext3-dentry-fid-2.4.24.patch deleted file mode 100644 index 0aa7916..0000000 --- a/lustre/kernel_patches/patches/ext3-dentry-fid-2.4.24.patch +++ /dev/null @@ -1,52 +0,0 @@ -diff -rupN linux-2.4.24.orig/fs/ext3/namei.c linux-2.4.24/fs/ext3/namei.c ---- linux-2.4.24.orig/fs/ext3/namei.c Tue Oct 5 10:34:28 2004 -+++ linux-2.4.24/fs/ext3/namei.c Tue Oct 5 10:43:12 2004 -@@ -1112,6 +1112,7 @@ static struct dentry *ext3_lookup(struct - dentry->d_flags |= DCACHE_CROSS_REF; - dentry->d_generation = mds[1]; - dentry->d_mdsnum = mds[0]; -+ dentry->d_fid = mds[2]; - dentry->d_inum = ino; - d_add(dentry, NULL); - return NULL; -@@ -1334,7 +1335,8 @@ static int add_dirent_to_buf(handle_t *h - if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_MDSNUM) - && (dentry->d_flags & DCACHE_CROSS_REF) - && (dentry->d_mdsnum != EXT3_SB(sb)->s_mdsnum)) -- reclen += 8; /* we need space to store mds num */ -+ reclen += 12; /* we need space to store mds num, -+ * inode num and fid num. */ - if (!de) { - de = (struct ext3_dir_entry_2 *)bh->b_data; - top = bh->b_data + dir->i_sb->s_blocksize - reclen; -@@ -1387,6 +1389,7 @@ static int add_dirent_to_buf(handle_t *h - mds = (__u32 *)((char *)de + EXT3_DIR_REC_LEN(namelen)); - mds[0] = cpu_to_le32(dentry->d_mdsnum); - mds[1] = cpu_to_le32(dentry->d_generation); -+ mds[2] = cpu_to_le32(dentry->d_fid); - de->inode = cpu_to_le32(dentry->d_inum); - de->file_type = 128; - } else { -diff -rupN linux-2.4.24.orig/include/linux/dcache.h linux-2.4.24/include/linux/dcache.h ---- linux-2.4.24.orig/include/linux/dcache.h Tue Oct 5 10:34:28 2004 -+++ linux-2.4.24/include/linux/dcache.h Tue Oct 5 10:43:45 2004 -@@ -123,6 +123,7 @@ struct dentry { - unsigned d_inum; /* for cross-fs references (Lustre) */ - unsigned d_mdsnum; /* for cross-fs references (Lustre) */ - unsigned d_generation; /* for cross-fs references (Lustre) */ -+ unsigned d_fid; /* for cross-fs references (Lustre) */ - struct dentry * d_parent; /* parent directory */ - struct list_head d_hash; /* lookup hash list */ - struct list_head d_lru; /* d_count = 0 LRU list */ -diff -rupN linux-2.4.24.orig/include/linux/ext3_fs.h linux-2.4.24/include/linux/ext3_fs.h ---- linux-2.4.24.orig/include/linux/ext3_fs.h Tue Oct 5 10:34:28 2004 -+++ linux-2.4.24/include/linux/ext3_fs.h Tue Oct 5 10:44:29 2004 -@@ -589,7 +589,7 @@ struct ext3_dir_entry_2 { - #define EXT3_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT3_DIR_ROUND) & \ - ~EXT3_DIR_ROUND) - #define EXT3_DIR_REC_LEN_DE(de) (EXT3_DIR_REC_LEN((de)->name_len) + \ -- (((de)->file_type & 128) ? 8 : 0)) -+ (((de)->file_type & 128) ? 12 : 0)) - - /* - * Hash Tree Directory indexing diff --git a/lustre/kernel_patches/patches/ext3-ea-in-inode-2.4.24.patch b/lustre/kernel_patches/patches/ext3-ea-in-inode-2.4.24.patch deleted file mode 100644 index e6eaaf8..0000000 --- a/lustre/kernel_patches/patches/ext3-ea-in-inode-2.4.24.patch +++ /dev/null @@ -1,757 +0,0 @@ - fs/ext3/ialloc.c | 6 - fs/ext3/inode.c | 12 - fs/ext3/super.c | 6 - fs/ext3/xattr.c | 597 +++++++++++++++++++++++++++++++++++++++++++++- - include/linux/ext3_fs.h | 2 - include/linux/ext3_fs_i.h | 3 - 6 files changed, 615 insertions(+), 11 deletions(-) - ---- linux-2.4.22-ac1/fs/ext3/ialloc.c~ext3-ea-in-inode-2.4.22-rh 2003-10-08 13:57:56.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/ext3/ialloc.c 2003-10-08 15:13:31.000000000 +0400 -@@ -715,6 +715,12 @@ have_bit_and_group: - insert_inode_hash(inode); - inode->i_generation = sb->u.ext3_sb.s_next_generation++; - -+ if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) { -+ inode->u.ext3_i.i_extra_isize = sizeof(__u16) /* i_extra_isize */ -+ + sizeof(__u16); /* i_pad1 */ -+ } else -+ inode->u.ext3_i.i_extra_isize = 0; -+ - inode->u.ext3_i.i_state = EXT3_STATE_NEW; - err = ext3_get_inode_loc_new(inode, &iloc, 1); - if (err) goto fail; ---- linux-2.4.22-ac1/fs/ext3/inode.c~ext3-ea-in-inode-2.4.22-rh 2003-10-08 13:57:57.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/ext3/inode.c 2003-10-08 15:14:57.000000000 +0400 -@@ -2229,6 +2229,12 @@ void ext3_read_inode(struct inode * inod - inode->u.ext3_i.i_data[block] = iloc.raw_inode->i_block[block]; - INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan); - -+ if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) -+ inode->u.ext3_i.i_extra_isize = -+ le16_to_cpu(raw_inode->i_extra_isize); -+ else -+ inode->u.ext3_i.i_extra_isize = 0; -+ - if (S_ISREG(inode->i_mode)) { - inode->i_op = &ext3_file_inode_operations; - inode->i_fop = &ext3_file_operations; -@@ -2277,6 +2283,8 @@ static int ext3_do_update_inode(handle_t - if (err) - goto out_brelse; - } -+ if (EXT3_I(inode)->i_state & EXT3_STATE_NEW) -+ memset(raw_inode, 0, EXT3_INODE_SIZE(inode->i_sb)); - raw_inode->i_mode = cpu_to_le16(inode->i_mode); - if(!(test_opt(inode->i_sb, NO_UID32))) { - raw_inode->i_uid_low = cpu_to_le16(low_16_bits(inode->i_uid)); -@@ -2360,6 +2368,10 @@ static int ext3_do_update_inode(handle_t - else for (block = 0; block < EXT3_N_BLOCKS; block++) - raw_inode->i_block[block] = inode->u.ext3_i.i_data[block]; - -+ if (EXT3_INODE_SIZE(inode->i_sb) > EXT3_GOOD_OLD_INODE_SIZE) -+ raw_inode->i_extra_isize = -+ cpu_to_le16(EXT3_I(inode)->i_extra_isize); -+ - BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); - rc = ext3_journal_dirty_metadata(handle, bh); - if (!err) ---- linux-2.4.22-ac1/fs/ext3/super.c~ext3-ea-in-inode-2.4.22-rh 2003-10-08 13:57:57.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/ext3/super.c 2003-10-08 15:13:31.000000000 +0400 -@@ -1299,8 +1299,10 @@ struct super_block * ext3_read_super (st - } else { - sbi->s_inode_size = le16_to_cpu(es->s_inode_size); - sbi->s_first_ino = le32_to_cpu(es->s_first_ino); -- if (sbi->s_inode_size != EXT3_GOOD_OLD_INODE_SIZE) { -- printk (KERN_ERR -+ if ((sbi->s_inode_size < EXT3_GOOD_OLD_INODE_SIZE) || -+ (sbi->s_inode_size & (sbi->s_inode_size - 1)) || -+ (sbi->s_inode_size > blocksize)) { -+ printk (KERN_ERR - "EXT3-fs: unsupported inode size: %d\n", - sbi->s_inode_size); - goto failed_mount; ---- linux-2.4.22-ac1/fs/ext3/xattr.c~ext3-ea-in-inode-2.4.22-rh 2003-10-08 13:57:56.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/ext3/xattr.c 2003-10-12 16:36:07.000000000 +0400 -@@ -100,6 +100,9 @@ - static int ext3_xattr_set2(handle_t *, struct inode *, struct buffer_head *, - struct ext3_xattr_header *); - -+int ext3_xattr_block_set(handle_t *, struct inode *, int, const char *, -+ const void *, size_t, int); -+ - #ifdef CONFIG_EXT3_FS_XATTR_SHARING - - static int ext3_xattr_cache_insert(struct buffer_head *); -@@ -348,17 +351,12 @@ ext3_removexattr(struct dentry *dentry, - } - - /* -- * ext3_xattr_get() -- * -- * Copy an extended attribute into the buffer -- * provided, or compute the buffer size required. -- * Buffer is NULL to compute the size of the buffer required. -+ * ext3_xattr_block_get() - * -- * Returns a negative error number on failure, or the number of bytes -- * used / required on success. -+ * routine looks for attribute in EA block and returns it's value and size - */ - int --ext3_xattr_get(struct inode *inode, int name_index, const char *name, -+ext3_xattr_block_get(struct inode *inode, int name_index, const char *name, - void *buffer, size_t buffer_size) - { - struct buffer_head *bh = NULL; -@@ -447,6 +445,94 @@ cleanup: - } - - /* -+ * ext3_xattr_ibode_get() -+ * -+ * routine looks for attribute in inode body and returns it's value and size -+ */ -+int -+ext3_xattr_ibody_get(struct inode *inode, int name_index, const char *name, -+ void *buffer, size_t buffer_size) -+{ -+ int size, name_len = strlen(name), storage_size; -+ struct ext3_xattr_entry *last; -+ struct ext3_inode *raw_inode; -+ struct ext3_iloc iloc; -+ char *start, *end; -+ int ret = -ENOENT; -+ -+ if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE) -+ return -ENOENT; -+ -+ ret = ext3_get_inode_loc(inode, &iloc); -+ if (ret) -+ return ret; -+ raw_inode = iloc.raw_inode; -+ -+ storage_size = EXT3_SB(inode->i_sb)->s_inode_size - -+ EXT3_GOOD_OLD_INODE_SIZE - -+ EXT3_I(inode)->i_extra_isize - -+ sizeof(__u32); -+ start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE + -+ EXT3_I(inode)->i_extra_isize; -+ if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC) { -+ brelse(iloc.bh); -+ return -ENOENT; -+ } -+ start += sizeof(__u32); -+ end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size; -+ -+ last = (struct ext3_xattr_entry *) start; -+ while (!IS_LAST_ENTRY(last)) { -+ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last); -+ if (le32_to_cpu(last->e_value_size) > storage_size || -+ (char *) next >= end) { -+ ext3_error(inode->i_sb, "ext3_xattr_ibody_get", -+ "inode %ld", inode->i_ino); -+ brelse(iloc.bh); -+ return -EIO; -+ } -+ if (name_index == last->e_name_index && -+ name_len == last->e_name_len && -+ !memcmp(name, last->e_name, name_len)) -+ goto found; -+ last = next; -+ } -+ -+ /* can't find EA */ -+ brelse(iloc.bh); -+ return -ENOENT; -+ -+found: -+ size = le32_to_cpu(last->e_value_size); -+ if (buffer) { -+ ret = -ERANGE; -+ if (buffer_size >= size) { -+ memcpy(buffer, start + le16_to_cpu(last->e_value_offs), -+ size); -+ ret = size; -+ } -+ } else -+ ret = size; -+ brelse(iloc.bh); -+ return ret; -+} -+ -+int ext3_xattr_get(struct inode *inode, int name_index, const char *name, -+ void *buffer, size_t buffer_size) -+{ -+ int err; -+ -+ /* try to find attribute in inode body */ -+ err = ext3_xattr_ibody_get(inode, name_index, name, -+ buffer, buffer_size); -+ if (err < 0) -+ /* search was unsuccessful, try to find EA in dedicated block */ -+ err = ext3_xattr_block_get(inode, name_index, name, -+ buffer, buffer_size); -+ return err; -+} -+ -+/* - * ext3_xattr_list() - * - * Copy a list of attribute names into the buffer -@@ -457,7 +543,7 @@ cleanup: - * used / required on success. - */ - int --ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size) -+ext3_xattr_block_list(struct inode *inode, char *buffer, size_t buffer_size) - { - struct buffer_head *bh = NULL; - struct ext3_xattr_entry *entry; -@@ -530,6 +616,131 @@ cleanup: - return error; - } - -+/* ext3_xattr_ibody_list() -+ * -+ * generate list of attributes stored in inode body -+ */ -+int -+ext3_xattr_ibody_list(struct inode *inode, char *buffer, size_t buffer_size) -+{ -+ struct ext3_xattr_entry *last; -+ struct ext3_inode *raw_inode; -+ char *start, *end, *buf; -+ struct ext3_iloc iloc; -+ int storage_size; -+ int ret; -+ int size = 0; -+ -+ if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE) -+ return 0; -+ -+ ret = ext3_get_inode_loc(inode, &iloc); -+ if (ret) -+ return ret; -+ raw_inode = iloc.raw_inode; -+ -+ storage_size = EXT3_SB(inode->i_sb)->s_inode_size - -+ EXT3_GOOD_OLD_INODE_SIZE - -+ EXT3_I(inode)->i_extra_isize - -+ sizeof(__u32); -+ start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE + -+ EXT3_I(inode)->i_extra_isize; -+ if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC) { -+ brelse(iloc.bh); -+ return 0; -+ } -+ start += sizeof(__u32); -+ end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size; -+ -+ last = (struct ext3_xattr_entry *) start; -+ while (!IS_LAST_ENTRY(last)) { -+ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last); -+ struct ext3_xattr_handler *handler; -+ if (le32_to_cpu(last->e_value_size) > storage_size || -+ (char *) next >= end) { -+ ext3_error(inode->i_sb, "ext3_xattr_ibody_list", -+ "inode %ld", inode->i_ino); -+ brelse(iloc.bh); -+ return -EIO; -+ } -+ handler = ext3_xattr_handler(last->e_name_index); -+ if (handler) -+ size += handler->list(NULL, inode, last->e_name, -+ last->e_name_len); -+ last = next; -+ } -+ -+ if (!buffer) { -+ ret = size; -+ goto cleanup; -+ } else { -+ ret = -ERANGE; -+ if (size > buffer_size) -+ goto cleanup; -+ } -+ -+ last = (struct ext3_xattr_entry *) start; -+ buf = buffer; -+ while (!IS_LAST_ENTRY(last)) { -+ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last); -+ struct ext3_xattr_handler *handler; -+ handler = ext3_xattr_handler(last->e_name_index); -+ if (handler) -+ buf += handler->list(buf, inode, last->e_name, -+ last->e_name_len); -+ last = next; -+ } -+ ret = size; -+cleanup: -+ brelse(iloc.bh); -+ return ret; -+} -+ -+/* -+ * ext3_xattr_list() -+ * -+ * Copy a list of attribute names into the buffer -+ * provided, or compute the buffer size required. -+ * Buffer is NULL to compute the size of the buffer required. -+ * -+ * Returns a negative error number on failure, or the number of bytes -+ * used / required on success. -+ */ -+int -+ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size) -+{ -+ int error; -+ int size = buffer_size; -+ -+ /* get list of attributes stored in inode body */ -+ error = ext3_xattr_ibody_list(inode, buffer, buffer_size); -+ if (error < 0) { -+ /* some error occured while collecting -+ * attributes in inode body */ -+ size = 0; -+ goto cleanup; -+ } -+ size = error; -+ -+ /* get list of attributes stored in dedicated block */ -+ if (buffer) { -+ buffer_size -= error; -+ if (buffer_size <= 0) { -+ buffer = NULL; -+ buffer_size = 0; -+ } else -+ buffer += error; -+ } -+ -+ error = ext3_xattr_block_list(inode, buffer, buffer_size); -+ if (error < 0) -+ /* listing was successful, so we return len */ -+ size = 0; -+ -+cleanup: -+ return error + size; -+} -+ - /* - * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is - * not set, set it. -@@ -553,6 +764,279 @@ static void ext3_xattr_update_super_bloc - } - - /* -+ * ext3_xattr_ibody_find() -+ * -+ * search attribute and calculate free space in inode body -+ * NOTE: free space includes space our attribute hold -+ */ -+int -+ext3_xattr_ibody_find(struct inode *inode, int name_index, -+ const char *name, struct ext3_xattr_entry *rentry, int *free) -+{ -+ struct ext3_xattr_entry *last; -+ struct ext3_inode *raw_inode; -+ int name_len = strlen(name); -+ int err, storage_size; -+ struct ext3_iloc iloc; -+ char *start, *end; -+ int ret = -ENOENT; -+ -+ if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE) -+ return ret; -+ -+ err = ext3_get_inode_loc(inode, &iloc); -+ if (err) -+ return -EIO; -+ raw_inode = iloc.raw_inode; -+ -+ storage_size = EXT3_SB(inode->i_sb)->s_inode_size - -+ EXT3_GOOD_OLD_INODE_SIZE - -+ EXT3_I(inode)->i_extra_isize - -+ sizeof(__u32); -+ *free = storage_size - sizeof(__u32); -+ start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE + -+ EXT3_I(inode)->i_extra_isize; -+ if (le32_to_cpu((*(__u32*) start)) != EXT3_XATTR_MAGIC) { -+ brelse(iloc.bh); -+ return -ENOENT; -+ } -+ start += sizeof(__u32); -+ end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size; -+ -+ last = (struct ext3_xattr_entry *) start; -+ while (!IS_LAST_ENTRY(last)) { -+ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last); -+ if (le32_to_cpu(last->e_value_size) > storage_size || -+ (char *) next >= end) { -+ ext3_error(inode->i_sb, "ext3_xattr_ibody_find", -+ "inode %ld", inode->i_ino); -+ brelse(iloc.bh); -+ return -EIO; -+ } -+ -+ if (name_index == last->e_name_index && -+ name_len == last->e_name_len && -+ !memcmp(name, last->e_name, name_len)) { -+ memcpy(rentry, last, sizeof(struct ext3_xattr_entry)); -+ ret = 0; -+ } else { -+ *free -= EXT3_XATTR_LEN(last->e_name_len); -+ *free -= le32_to_cpu(last->e_value_size); -+ } -+ last = next; -+ } -+ -+ brelse(iloc.bh); -+ return ret; -+} -+ -+/* -+ * ext3_xattr_block_find() -+ * -+ * search attribute and calculate free space in EA block (if it allocated) -+ * NOTE: free space includes space our attribute hold -+ */ -+int -+ext3_xattr_block_find(struct inode *inode, int name_index, const char *name, -+ struct ext3_xattr_entry *rentry, int *free) -+{ -+ struct buffer_head *bh = NULL; -+ struct ext3_xattr_entry *entry; -+ char *end; -+ int name_len, error = -ENOENT; -+ -+ if (!EXT3_I(inode)->i_file_acl) { -+ *free = inode->i_sb->s_blocksize - -+ sizeof(struct ext3_xattr_header) - -+ sizeof(__u32); -+ return -ENOENT; -+ } -+ ea_idebug(inode, "reading block %d", EXT3_I(inode)->i_file_acl); -+ bh = sb_bread(inode->i_sb, EXT3_I(inode)->i_file_acl); -+ if (!bh) -+ return -EIO; -+ ea_bdebug(bh, "b_count=%d, refcount=%d", -+ atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount)); -+ end = bh->b_data + bh->b_size; -+ if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || -+ HDR(bh)->h_blocks != cpu_to_le32(1)) { -+bad_block: ext3_error(inode->i_sb, "ext3_xattr_get", -+ "inode %ld: bad block %d", inode->i_ino, -+ EXT3_I(inode)->i_file_acl); -+ brelse(bh); -+ return -EIO; -+ } -+ /* find named attribute */ -+ name_len = strlen(name); -+ *free = bh->b_size - sizeof(__u32); -+ -+ entry = FIRST_ENTRY(bh); -+ while (!IS_LAST_ENTRY(entry)) { -+ struct ext3_xattr_entry *next = -+ EXT3_XATTR_NEXT(entry); -+ if ((char *)next >= end) -+ goto bad_block; -+ if (name_index == entry->e_name_index && -+ name_len == entry->e_name_len && -+ memcmp(name, entry->e_name, name_len) == 0) { -+ memcpy(rentry, entry, sizeof(struct ext3_xattr_entry)); -+ error = 0; -+ } else { -+ *free -= EXT3_XATTR_LEN(entry->e_name_len); -+ *free -= le32_to_cpu(entry->e_value_size); -+ } -+ entry = next; -+ } -+ brelse(bh); -+ -+ return error; -+} -+ -+/* -+ * ext3_xattr_inode_set() -+ * -+ * this routine add/remove/replace attribute in inode body -+ */ -+int -+ext3_xattr_ibody_set(handle_t *handle, struct inode *inode, int name_index, -+ const char *name, const void *value, size_t value_len, -+ int flags) -+{ -+ struct ext3_xattr_entry *last, *next, *here = NULL; -+ struct ext3_inode *raw_inode; -+ int name_len = strlen(name); -+ int esize = EXT3_XATTR_LEN(name_len); -+ struct buffer_head *bh; -+ int err, storage_size; -+ struct ext3_iloc iloc; -+ int free, min_offs; -+ char *start, *end; -+ -+ if (EXT3_SB(inode->i_sb)->s_inode_size <= EXT3_GOOD_OLD_INODE_SIZE) -+ return -ENOSPC; -+ -+ err = ext3_get_inode_loc(inode, &iloc); -+ if (err) -+ return err; -+ raw_inode = iloc.raw_inode; -+ bh = iloc.bh; -+ -+ storage_size = EXT3_SB(inode->i_sb)->s_inode_size - -+ EXT3_GOOD_OLD_INODE_SIZE - -+ EXT3_I(inode)->i_extra_isize - -+ sizeof(__u32); -+ start = (char *) raw_inode + EXT3_GOOD_OLD_INODE_SIZE + -+ EXT3_I(inode)->i_extra_isize; -+ if ((*(__u32*) start) != EXT3_XATTR_MAGIC) { -+ /* inode had no attributes before */ -+ *((__u32*) start) = cpu_to_le32(EXT3_XATTR_MAGIC); -+ } -+ start += sizeof(__u32); -+ end = (char *) raw_inode + EXT3_SB(inode->i_sb)->s_inode_size; -+ min_offs = storage_size; -+ free = storage_size - sizeof(__u32); -+ -+ last = (struct ext3_xattr_entry *) start; -+ while (!IS_LAST_ENTRY(last)) { -+ next = EXT3_XATTR_NEXT(last); -+ if (le32_to_cpu(last->e_value_size) > storage_size || -+ (char *) next >= end) { -+ ext3_error(inode->i_sb, "ext3_xattr_ibody_set", -+ "inode %ld", inode->i_ino); -+ brelse(bh); -+ return -EIO; -+ } -+ -+ if (last->e_value_size) { -+ int offs = le16_to_cpu(last->e_value_offs); -+ if (offs < min_offs) -+ min_offs = offs; -+ } -+ if (name_index == last->e_name_index && -+ name_len == last->e_name_len && -+ !memcmp(name, last->e_name, name_len)) -+ here = last; -+ else { -+ /* we calculate all but our attribute -+ * because it will be removed before changing */ -+ free -= EXT3_XATTR_LEN(last->e_name_len); -+ free -= le32_to_cpu(last->e_value_size); -+ } -+ last = next; -+ } -+ -+ if (value && (esize + value_len > free)) { -+ brelse(bh); -+ return -ENOSPC; -+ } -+ -+ err = ext3_reserve_inode_write(handle, inode, &iloc); -+ if (err) { -+ brelse(bh); -+ return err; -+ } -+ -+ if (here) { -+ /* time to remove old value */ -+ struct ext3_xattr_entry *e; -+ int size = le32_to_cpu(here->e_value_size); -+ int border = le16_to_cpu(here->e_value_offs); -+ char *src; -+ -+ /* move tail */ -+ memmove(start + min_offs + size, start + min_offs, -+ border - min_offs); -+ -+ /* recalculate offsets */ -+ e = (struct ext3_xattr_entry *) start; -+ while (!IS_LAST_ENTRY(e)) { -+ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(e); -+ int offs = le16_to_cpu(e->e_value_offs); -+ if (offs < border) -+ e->e_value_offs = -+ cpu_to_le16(offs + size); -+ e = next; -+ } -+ min_offs += size; -+ -+ /* remove entry */ -+ border = EXT3_XATTR_LEN(here->e_name_len); -+ src = (char *) here + EXT3_XATTR_LEN(here->e_name_len); -+ size = (char *) last - src; -+ if ((char *) here + size > end) -+ printk("ALERT at %s:%d: 0x%p + %d > 0x%p\n", -+ __FILE__, __LINE__, here, size, end); -+ memmove(here, src, size); -+ last = (struct ext3_xattr_entry *) ((char *) last - border); -+ *((__u32 *) last) = 0; -+ } -+ -+ if (value) { -+ int offs = min_offs - value_len; -+ /* use last to create new entry */ -+ last->e_name_len = strlen(name); -+ last->e_name_index = name_index; -+ last->e_value_offs = cpu_to_le16(offs); -+ last->e_value_size = cpu_to_le32(value_len); -+ last->e_hash = last->e_value_block = 0; -+ memset(last->e_name, 0, esize); -+ memcpy(last->e_name, name, last->e_name_len); -+ if (start + offs + value_len > end) -+ printk("ALERT at %s:%d: 0x%p + %d + %d > 0x%p\n", -+ __FILE__, __LINE__, start, offs, -+ value_len, end); -+ memcpy(start + offs, value, value_len); -+ last = EXT3_XATTR_NEXT(last); -+ *((__u32 *) last) = 0; -+ } -+ -+ ext3_mark_iloc_dirty(handle, inode, &iloc); -+ brelse(bh); -+ -+ return 0; -+} -+ -+/* - * ext3_xattr_set() - * - * Create, replace or remove an extended attribute for this inode. Buffer -@@ -566,6 +1050,101 @@ static void ext3_xattr_update_super_bloc - */ - int - ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index, -+ const char *name, const void *value, size_t value_len, int flags) -+{ -+ struct ext3_xattr_entry entry; -+ int err, where = 0, found = 0, total; -+ int free1 = -1, free2 = -1; -+ int name_len; -+ -+ ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld", -+ name_index, name, value, (long)value_len); -+ -+ if (IS_RDONLY(inode)) -+ return -EROFS; -+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) -+ return -EPERM; -+ if (value == NULL) -+ value_len = 0; -+ if (name == NULL) -+ return -EINVAL; -+ name_len = strlen(name); -+ if (name_len > 255 || value_len > inode->i_sb->s_blocksize) -+ return -ERANGE; -+ -+ /* try to find attribute in inode body */ -+ err = ext3_xattr_ibody_find(inode, name_index, name, &entry, &free1); -+ if (err == 0) { -+ /* found EA in inode */ -+ found = 1; -+ where = 0; -+ } else if (err == -ENOENT) { -+ /* there is no such attribute in inode body */ -+ /* try to find attribute in dedicated block */ -+ err = ext3_xattr_block_find(inode, name_index, name, -+ &entry, &free2); -+ if (err != 0 && err != -ENOENT) { -+ /* not found EA in block */ -+ goto finish; -+ } else if (err == 0) { -+ /* found EA in block */ -+ where = 1; -+ found = 1; -+ } -+ } else -+ goto finish; -+ -+ /* check flags: may replace? may create ? */ -+ if (found && (flags & XATTR_CREATE)) { -+ err = -EEXIST; -+ goto finish; -+ } else if (!found && (flags & XATTR_REPLACE)) { -+ err = -ENODATA; -+ goto finish; -+ } -+ -+ /* check if we have enough space to store attribute */ -+ total = EXT3_XATTR_LEN(strlen(name)) + value_len; -+ if (free1 >= 0 && total > free1 && free2 >= 0 && total > free2) { -+ /* have no enough space */ -+ err = -ENOSPC; -+ goto finish; -+ } -+ -+ /* time to remove attribute */ -+ if (found) { -+ if (where == 0) { -+ /* EA is stored in inode body */ -+ ext3_xattr_ibody_set(handle, inode, name_index, name, -+ NULL, 0, flags); -+ } else { -+ /* EA is stored in separated block */ -+ ext3_xattr_block_set(handle, inode, name_index, name, -+ NULL, 0, flags); -+ } -+ } -+ -+ /* try to store EA in inode body */ -+ err = ext3_xattr_ibody_set(handle, inode, name_index, name, -+ value, value_len, flags); -+ if (err) { -+ /* can't store EA in inode body */ -+ /* try to store in block */ -+ err = ext3_xattr_block_set(handle, inode, name_index, -+ name, value, value_len, flags); -+ } -+ -+finish: -+ return err; -+} -+ -+/* -+ * ext3_xattr_block_set() -+ * -+ * this routine add/remove/replace attribute in EA block -+ */ -+int -+ext3_xattr_block_set(handle_t *handle, struct inode *inode, int name_index, - const char *name, const void *value, size_t value_len, int flags) - { - struct super_block *sb = inode->i_sb; -@@ -603,6 +1181,7 @@ ext3_xattr_set(handle_t *handle, struct - name_len = strlen(name); - if (name_len > 255 || value_len > sb->s_blocksize) - return -ERANGE; -+ - down(&ext3_xattr_sem); - - if (block) { ---- linux-2.4.22-ac1/include/linux/ext3_fs.h~ext3-ea-in-inode-2.4.22-rh 2003-10-08 13:57:57.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/include/linux/ext3_fs.h 2003-10-08 15:13:31.000000000 +0400 -@@ -265,6 +265,8 @@ struct ext3_inode { - __u32 m_i_reserved2[2]; - } masix2; - } osd2; /* OS dependent 2 */ -+ __u16 i_extra_isize; -+ __u16 i_pad1; - }; - - #define i_size_high i_dir_acl ---- linux-2.4.22-ac1/include/linux/ext3_fs_i.h~ext3-ea-in-inode-2.4.22-rh 2003-09-26 00:54:44.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/include/linux/ext3_fs_i.h 2003-10-08 15:13:31.000000000 +0400 -@@ -62,6 +62,9 @@ struct ext3_inode_info { - */ - loff_t i_disksize; - -+ /* on-disk additional length */ -+ __u16 i_extra_isize; -+ - /* - * truncate_sem is for serialising ext3_truncate() against - * ext3_getblock(). In the 2.4 ext2 design, great chunks of inode's - -_ diff --git a/lustre/kernel_patches/patches/ext3-error-export-2.4.24.patch b/lustre/kernel_patches/patches/ext3-error-export-2.4.24.patch deleted file mode 100644 index c52fc18..0000000 --- a/lustre/kernel_patches/patches/ext3-error-export-2.4.24.patch +++ /dev/null @@ -1,16 +0,0 @@ - fs/ext3/ext3-exports.c | 5 +++++ - 1 files changed, 5 insertions(+) - ---- linux/fs/ext3/ext3-exports.c~ext3-error-export Mon Jul 14 19:30:50 2003 -+++ linux-mmonroe/fs/ext3/ext3-exports.c Mon Jul 14 19:32:37 2003 -@@ -21,3 +21,8 @@ EXPORT_SYMBOL(ext3_xattr_list); - EXPORT_SYMBOL(ext3_xattr_set); - EXPORT_SYMBOL(ext3_prep_san_write); - EXPORT_SYMBOL(ext3_map_inode_page); -+ -+EXPORT_SYMBOL(ext3_abort); -+EXPORT_SYMBOL(ext3_decode_error); -+EXPORT_SYMBOL(__ext3_std_error); -+ - -_ diff --git a/lustre/kernel_patches/patches/ext3-extents-2.4.24.patch b/lustre/kernel_patches/patches/ext3-extents-2.4.24.patch deleted file mode 100644 index ec75945..0000000 --- a/lustre/kernel_patches/patches/ext3-extents-2.4.24.patch +++ /dev/null @@ -1,2765 +0,0 @@ -Index: linux-2.4.24-b1_4/fs/ext3/extents.c -=================================================================== ---- linux-2.4.24-b1_4.orig/fs/ext3/extents.c 2003-01-30 18:24:37.000000000 +0800 -+++ linux-2.4.24-b1_4/fs/ext3/extents.c 2004-09-30 14:04:33.000000000 +0800 -@@ -0,0 +1,2262 @@ -+/* -+ * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com -+ * Written by Alex Tomas -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public Licens -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111- -+ */ -+ -+/* -+ * Extents support for EXT3 -+ * -+ * TODO: -+ * - ext3_ext_walk_space() sould not use ext3_ext_find_extent() -+ * - ext3_ext_calc_credits() could take 'mergable' into account -+ * - ext3*_error() should be used in some situations -+ * - find_goal() [to be tested and improved] -+ * - smart tree reduction -+ * - arch-independence -+ * common on-disk format for big/little-endian arch -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static handle_t *ext3_ext_journal_restart(handle_t *handle, int needed) -+{ -+ int err; -+ -+ if (handle->h_buffer_credits > needed) -+ return handle; -+ if (!ext3_journal_extend(handle, needed)) -+ return handle; -+ err = ext3_journal_restart(handle, needed); -+ -+ return handle; -+} -+ -+static int inline -+ext3_ext_get_access_for_root(handle_t *h, struct ext3_extents_tree *tree) -+{ -+ if (tree->ops->get_write_access) -+ return tree->ops->get_write_access(h,tree->buffer); -+ else -+ return 0; -+} -+ -+static int inline -+ext3_ext_mark_root_dirty(handle_t *h, struct ext3_extents_tree *tree) -+{ -+ if (tree->ops->mark_buffer_dirty) -+ return tree->ops->mark_buffer_dirty(h,tree->buffer); -+ else -+ return 0; -+} -+ -+/* -+ * could return: -+ * - EROFS -+ * - ENOMEM -+ */ -+static int ext3_ext_get_access(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) -+{ -+ int err; -+ -+ if (path->p_bh) { -+ /* path points to block */ -+ err = ext3_journal_get_write_access(handle, path->p_bh); -+ } else { -+ /* path points to leaf/index in inode body */ -+ err = ext3_ext_get_access_for_root(handle, tree); -+ } -+ return err; -+} -+ -+/* -+ * could return: -+ * - EROFS -+ * - ENOMEM -+ * - EIO -+ */ -+static int ext3_ext_dirty(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) -+{ -+ int err; -+ if (path->p_bh) { -+ /* path points to block */ -+ err =ext3_journal_dirty_metadata(handle, path->p_bh); -+ } else { -+ /* path points to leaf/index in inode body */ -+ err = ext3_ext_mark_root_dirty(handle, tree); -+ } -+ return err; -+} -+ -+static int inline -+ext3_ext_new_block(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, struct ext3_extent *ex, -+ int *err) -+{ -+ int goal, depth, newblock; -+ struct inode *inode; -+ -+ EXT_ASSERT(tree); -+ if (tree->ops->new_block) -+ return tree->ops->new_block(handle, tree, path, ex, err); -+ -+ inode = tree->inode; -+ depth = EXT_DEPTH(tree); -+ if (path && depth > 0) { -+ goal = path[depth-1].p_block; -+ } else { -+ struct ext3_inode_info *ei = EXT3_I(inode); -+ unsigned long bg_start; -+ unsigned long colour; -+ -+ bg_start = (ei->i_block_group * -+ EXT3_BLOCKS_PER_GROUP(inode->i_sb)) + -+ le32_to_cpu(EXT3_SB(inode->i_sb)->s_es->s_first_data_block); -+ colour = (current->pid % 16) * -+ (EXT3_BLOCKS_PER_GROUP(inode->i_sb) / 16); -+ goal = bg_start + colour; -+ } -+ -+ newblock = ext3_new_block(handle, inode, goal, 0, 0, err); -+ return newblock; -+} -+ -+static inline void ext3_ext_tree_changed(struct ext3_extents_tree *tree) -+{ -+ struct ext3_extent_header *neh; -+ neh = EXT_ROOT_HDR(tree); -+ neh->eh_generation++; -+} -+ -+static inline int ext3_ext_space_block(struct ext3_extents_tree *tree) -+{ -+ int size; -+ -+ size = (tree->inode->i_sb->s_blocksize - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent); -+#ifdef AGRESSIVE_TEST -+ size = 6; -+#endif -+ return size; -+} -+ -+static inline int ext3_ext_space_block_idx(struct ext3_extents_tree *tree) -+{ -+ int size; -+ -+ size = (tree->inode->i_sb->s_blocksize - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent_idx); -+#ifdef AGRESSIVE_TEST -+ size = 5; -+#endif -+ return size; -+} -+ -+static inline int ext3_ext_space_root(struct ext3_extents_tree *tree) -+{ -+ int size; -+ -+ size = (tree->buffer_len - sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent); -+#ifdef AGRESSIVE_TEST -+ size = 3; -+#endif -+ return size; -+} -+ -+static inline int ext3_ext_space_root_idx(struct ext3_extents_tree *tree) -+{ -+ int size; -+ -+ size = (tree->buffer_len - -+ sizeof(struct ext3_extent_header)) -+ / sizeof(struct ext3_extent_idx); -+#ifdef AGRESSIVE_TEST -+ size = 4; -+#endif -+ return size; -+} -+ -+static void ext3_ext_show_path(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) -+{ -+#ifdef EXT_DEBUG -+ int k, l = path->p_depth; -+ -+ ext_debug(tree, "path:"); -+ for (k = 0; k <= l; k++, path++) { -+ if (path->p_idx) { -+ ext_debug(tree, " %d->%d", path->p_idx->ei_block, -+ path->p_idx->ei_leaf); -+ } else if (path->p_ext) { -+ ext_debug(tree, " %d:%d:%d", -+ path->p_ext->ee_block, -+ path->p_ext->ee_len, -+ path->p_ext->ee_start); -+ } else -+ ext_debug(tree, " []"); -+ } -+ ext_debug(tree, "\n"); -+#endif -+} -+ -+static void ext3_ext_show_leaf(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) -+{ -+#ifdef EXT_DEBUG -+ int depth = EXT_DEPTH(tree); -+ struct ext3_extent_header *eh; -+ struct ext3_extent *ex; -+ int i; -+ -+ if (!path) -+ return; -+ -+ eh = path[depth].p_hdr; -+ ex = EXT_FIRST_EXTENT(eh); -+ -+ for (i = 0; i < eh->eh_entries; i++, ex++) { -+ ext_debug(tree, "%d:%d:%d ", -+ ex->ee_block, ex->ee_len, ex->ee_start); -+ } -+ ext_debug(tree, "\n"); -+#endif -+} -+ -+static void ext3_ext_drop_refs(struct ext3_ext_path *path) -+{ -+ int depth = path->p_depth; -+ int i; -+ -+ for (i = 0; i <= depth; i++, path++) -+ if (path->p_bh) { -+ brelse(path->p_bh); -+ path->p_bh = NULL; -+ } -+} -+ -+/* -+ * binary search for closest index by given block -+ */ -+static inline void -+ext3_ext_binsearch_idx(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, int block) -+{ -+ struct ext3_extent_header *eh = path->p_hdr; -+ struct ext3_extent_idx *ix; -+ int l = 0, k, r; -+ -+ EXT_ASSERT(eh->eh_magic == EXT3_EXT_MAGIC); -+ EXT_ASSERT(eh->eh_entries <= eh->eh_max); -+ EXT_ASSERT(eh->eh_entries > 0); -+ -+ ext_debug(tree, "binsearch for %d(idx): ", block); -+ -+ path->p_idx = ix = EXT_FIRST_INDEX(eh); -+ -+ r = k = eh->eh_entries; -+ while (k > 1) { -+ k = (r - l) / 2; -+ if (block < ix[l + k].ei_block) -+ r -= k; -+ else -+ l += k; -+ ext_debug(tree, "%d:%d:%d ", k, l, r); -+ } -+ -+ ix += l; -+ path->p_idx = ix; -+ ext_debug(tree, " -> %d->%d ", path->p_idx->ei_block, path->p_idx->ei_leaf); -+ -+ while (l++ < r) { -+ if (block < ix->ei_block) -+ break; -+ path->p_idx = ix++; -+ } -+ ext_debug(tree, " -> %d->%d\n", path->p_idx->ei_block, -+ path->p_idx->ei_leaf); -+ -+#ifdef CHECK_BINSEARCH -+ { -+ struct ext3_extent_idx *chix; -+ -+ chix = ix = EXT_FIRST_INDEX(eh); -+ for (k = 0; k < eh->eh_entries; k++, ix++) { -+ if (k != 0 && ix->ei_block <= ix[-1].ei_block) { -+ printk("k=%d, ix=0x%p, first=0x%p\n", k, -+ ix, EXT_FIRST_INDEX(eh)); -+ printk("%u <= %u\n", -+ ix->ei_block,ix[-1].ei_block); -+ } -+ EXT_ASSERT(k == 0 || ix->ei_block > ix[-1].ei_block); -+ if (block < ix->ei_block) -+ break; -+ chix = ix; -+ } -+ EXT_ASSERT(chix == path->p_idx); -+ } -+#endif -+ -+} -+ -+/* -+ * binary search for closest extent by given block -+ */ -+static inline void -+ext3_ext_binsearch(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, int block) -+{ -+ struct ext3_extent_header *eh = path->p_hdr; -+ struct ext3_extent *ex; -+ int l = 0, k, r; -+ -+ EXT_ASSERT(eh->eh_magic == EXT3_EXT_MAGIC); -+ EXT_ASSERT(eh->eh_entries <= eh->eh_max); -+ -+ if (eh->eh_entries == 0) { -+ /* -+ * this leaf is empty yet: -+ * we get such a leaf in split/add case -+ */ -+ return; -+ } -+ -+ ext_debug(tree, "binsearch for %d: ", block); -+ -+ path->p_ext = ex = EXT_FIRST_EXTENT(eh); -+ -+ r = k = eh->eh_entries; -+ while (k > 1) { -+ k = (r - l) / 2; -+ if (block < ex[l + k].ee_block) -+ r -= k; -+ else -+ l += k; -+ ext_debug(tree, "%d:%d:%d ", k, l, r); -+ } -+ -+ ex += l; -+ path->p_ext = ex; -+ ext_debug(tree, " -> %d:%d:%d ", path->p_ext->ee_block, -+ path->p_ext->ee_start, path->p_ext->ee_len); -+ -+ while (l++ < r) { -+ if (block < ex->ee_block) -+ break; -+ path->p_ext = ex++; -+ } -+ ext_debug(tree, " -> %d:%d:%d\n", path->p_ext->ee_block, -+ path->p_ext->ee_start, path->p_ext->ee_len); -+ -+#ifdef CHECK_BINSEARCH -+ { -+ struct ext3_extent *chex; -+ -+ chex = ex = EXT_FIRST_EXTENT(eh); -+ for (k = 0; k < eh->eh_entries; k++, ex++) { -+ EXT_ASSERT(k == 0 || ex->ee_block > ex[-1].ee_block); -+ if (block < ex->ee_block) -+ break; -+ chex = ex; -+ } -+ EXT_ASSERT(chex == path->p_ext); -+ } -+#endif -+ -+} -+ -+int ext3_extent_tree_init(handle_t *handle, struct ext3_extents_tree *tree) -+{ -+ struct ext3_extent_header *eh; -+ -+ BUG_ON(tree->buffer_len == 0); -+ ext3_ext_get_access_for_root(handle, tree); -+ eh = EXT_ROOT_HDR(tree); -+ eh->eh_depth = 0; -+ eh->eh_entries = 0; -+ eh->eh_magic = EXT3_EXT_MAGIC; -+ eh->eh_max = ext3_ext_space_root(tree); -+ ext3_ext_mark_root_dirty(handle, tree); -+ ext3_ext_invalidate_cache(tree); -+ return 0; -+} -+ -+struct ext3_ext_path * -+ext3_ext_find_extent(struct ext3_extents_tree *tree, int block, -+ struct ext3_ext_path *path) -+{ -+ struct ext3_extent_header *eh; -+ struct buffer_head *bh; -+ int depth, i, ppos = 0; -+ -+ EXT_ASSERT(tree); -+ EXT_ASSERT(tree->inode); -+ EXT_ASSERT(tree->root); -+ -+ eh = EXT_ROOT_HDR(tree); -+ EXT_ASSERT(eh); -+ i = depth = EXT_DEPTH(tree); -+ EXT_ASSERT(eh->eh_max); -+ EXT_ASSERT(eh->eh_magic == EXT3_EXT_MAGIC); -+ EXT_ASSERT(i == 0 || eh->eh_entries > 0); -+ -+ /* account possible depth increase */ -+ if (!path) { -+ path = kmalloc(sizeof(struct ext3_ext_path) * (depth + 2), -+ GFP_NOFS); -+ if (!path) -+ return ERR_PTR(-ENOMEM); -+ } -+ memset(path, 0, sizeof(struct ext3_ext_path) * (depth + 1)); -+ path[0].p_hdr = eh; -+ -+ /* walk through the tree */ -+ while (i) { -+ ext_debug(tree, "depth %d: num %d, max %d\n", -+ ppos, eh->eh_entries, eh->eh_max); -+ ext3_ext_binsearch_idx(tree, path + ppos, block); -+ path[ppos].p_block = path[ppos].p_idx->ei_leaf; -+ path[ppos].p_depth = i; -+ path[ppos].p_ext = NULL; -+ -+ bh = sb_bread(tree->inode->i_sb, path[ppos].p_block); -+ if (!bh) { -+ ext3_ext_drop_refs(path); -+ kfree(path); -+ return ERR_PTR(-EIO); -+ } -+ eh = EXT_BLOCK_HDR(bh); -+ ppos++; -+ EXT_ASSERT(ppos <= depth); -+ path[ppos].p_bh = bh; -+ path[ppos].p_hdr = eh; -+ i--; -+ } -+ -+ path[ppos].p_depth = i; -+ path[ppos].p_hdr = eh; -+ path[ppos].p_ext = NULL; -+ -+ /* find extent */ -+ ext3_ext_binsearch(tree, path + ppos, block); -+ -+ ext3_ext_show_path(tree, path); -+ -+ return path; -+} -+ -+/* -+ * insert new index [logical;ptr] into the block at cupr -+ * it check where to insert: before curp or after curp -+ */ -+static int ext3_ext_insert_index(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *curp, -+ int logical, int ptr) -+{ -+ struct ext3_extent_idx *ix; -+ int len, err; -+ -+ if ((err = ext3_ext_get_access(handle, tree, curp))) -+ return err; -+ -+ EXT_ASSERT(logical != curp->p_idx->ei_block); -+ len = EXT_MAX_INDEX(curp->p_hdr) - curp->p_idx; -+ if (logical > curp->p_idx->ei_block) { -+ /* insert after */ -+ if (curp->p_idx != EXT_LAST_INDEX(curp->p_hdr)) { -+ len = (len - 1) * sizeof(struct ext3_extent_idx); -+ len = len < 0 ? 0 : len; -+ ext_debug(tree, "insert new index %d after: %d. " -+ "move %d from 0x%p to 0x%p\n", -+ logical, ptr, len, -+ (curp->p_idx + 1), (curp->p_idx + 2)); -+ memmove(curp->p_idx + 2, curp->p_idx + 1, len); -+ } -+ ix = curp->p_idx + 1; -+ } else { -+ /* insert before */ -+ len = len * sizeof(struct ext3_extent_idx); -+ len = len < 0 ? 0 : len; -+ ext_debug(tree, "insert new index %d before: %d. " -+ "move %d from 0x%p to 0x%p\n", -+ logical, ptr, len, -+ curp->p_idx, (curp->p_idx + 1)); -+ memmove(curp->p_idx + 1, curp->p_idx, len); -+ ix = curp->p_idx; -+ } -+ -+ ix->ei_block = logical; -+ ix->ei_leaf = ptr; -+ curp->p_hdr->eh_entries++; -+ -+ EXT_ASSERT(curp->p_hdr->eh_entries <= curp->p_hdr->eh_max); -+ EXT_ASSERT(ix <= EXT_LAST_INDEX(curp->p_hdr)); -+ -+ err = ext3_ext_dirty(handle, tree, curp); -+ ext3_std_error(tree->inode->i_sb, err); -+ -+ return err; -+} -+ -+/* -+ * routine inserts new subtree into the path, using free index entry -+ * at depth 'at: -+ * - allocates all needed blocks (new leaf and all intermediate index blocks) -+ * - makes decision where to split -+ * - moves remaining extens and index entries (right to the split point) -+ * into the newly allocated blocks -+ * - initialize subtree -+ */ -+static int ext3_ext_split(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext, int at) -+{ -+ struct buffer_head *bh = NULL; -+ int depth = EXT_DEPTH(tree); -+ struct ext3_extent_header *neh; -+ struct ext3_extent_idx *fidx; -+ struct ext3_extent *ex; -+ int i = at, k, m, a; -+ unsigned long newblock, oldblock, border; -+ int *ablocks = NULL; /* array of allocated blocks */ -+ int err = 0; -+ -+ /* make decision: where to split? */ -+ /* FIXME: now desicion is simplest: at current extent */ -+ -+ /* if current leaf will be splitted, then we should use -+ * border from split point */ -+ EXT_ASSERT(path[depth].p_ext <= EXT_MAX_EXTENT(path[depth].p_hdr)); -+ if (path[depth].p_ext != EXT_MAX_EXTENT(path[depth].p_hdr)) { -+ border = path[depth].p_ext[1].ee_block; -+ ext_debug(tree, "leaf will be splitted." -+ " next leaf starts at %d\n", -+ (int)border); -+ } else { -+ border = newext->ee_block; -+ ext_debug(tree, "leaf will be added." -+ " next leaf starts at %d\n", -+ (int)border); -+ } -+ -+ /* -+ * if error occurs, then we break processing -+ * and turn filesystem read-only. so, index won't -+ * be inserted and tree will be in consistent -+ * state. next mount will repair buffers too -+ */ -+ -+ /* -+ * get array to track all allocated blocks -+ * we need this to handle errors and free blocks -+ * upon them -+ */ -+ ablocks = kmalloc(sizeof(unsigned long) * depth, GFP_NOFS); -+ if (!ablocks) -+ return -ENOMEM; -+ memset(ablocks, 0, sizeof(unsigned long) * depth); -+ -+ /* allocate all needed blocks */ -+ ext_debug(tree, "allocate %d blocks for indexes/leaf\n", depth - at); -+ for (a = 0; a < depth - at; a++) { -+ newblock = ext3_ext_new_block(handle, tree, path, newext, &err); -+ if (newblock == 0) -+ goto cleanup; -+ ablocks[a] = newblock; -+ } -+ -+ /* initialize new leaf */ -+ newblock = ablocks[--a]; -+ EXT_ASSERT(newblock); -+ bh = sb_getblk(tree->inode->i_sb, newblock); -+ if (!bh) { -+ err = -EIO; -+ goto cleanup; -+ } -+ lock_buffer(bh); -+ -+ if ((err = ext3_journal_get_create_access(handle, bh))) -+ goto cleanup; -+ -+ neh = EXT_BLOCK_HDR(bh); -+ neh->eh_entries = 0; -+ neh->eh_max = ext3_ext_space_block(tree); -+ neh->eh_magic = EXT3_EXT_MAGIC; -+ neh->eh_depth = 0; -+ ex = EXT_FIRST_EXTENT(neh); -+ -+ /* move remain of path[depth] to the new leaf */ -+ EXT_ASSERT(path[depth].p_hdr->eh_entries == path[depth].p_hdr->eh_max); -+ /* start copy from next extent */ -+ /* TODO: we could do it by single memmove */ -+ m = 0; -+ path[depth].p_ext++; -+ while (path[depth].p_ext <= -+ EXT_MAX_EXTENT(path[depth].p_hdr)) { -+ ext_debug(tree, "move %d:%d:%d in new leaf %lu\n", -+ path[depth].p_ext->ee_block, -+ path[depth].p_ext->ee_start, -+ path[depth].p_ext->ee_len, -+ newblock); -+ memmove(ex++, path[depth].p_ext++, -+ sizeof(struct ext3_extent)); -+ neh->eh_entries++; -+ m++; -+ } -+ mark_buffer_uptodate(bh, 1); -+ unlock_buffer(bh); -+ -+ if ((err = ext3_journal_dirty_metadata(handle, bh))) -+ goto cleanup; -+ brelse(bh); -+ bh = NULL; -+ -+ /* correct old leaf */ -+ if (m) { -+ if ((err = ext3_ext_get_access(handle, tree, path + depth))) -+ goto cleanup; -+ path[depth].p_hdr->eh_entries -= m; -+ if ((err = ext3_ext_dirty(handle, tree, path + depth))) -+ goto cleanup; -+ -+ } -+ -+ /* create intermediate indexes */ -+ k = depth - at - 1; -+ EXT_ASSERT(k >= 0); -+ if (k) -+ ext_debug(tree, "create %d intermediate indices\n", k); -+ /* insert new index into current index block */ -+ /* current depth stored in i var */ -+ i = depth - 1; -+ while (k--) { -+ oldblock = newblock; -+ newblock = ablocks[--a]; -+ bh = sb_getblk(tree->inode->i_sb, newblock); -+ if (!bh) { -+ err = -EIO; -+ goto cleanup; -+ } -+ lock_buffer(bh); -+ -+ if ((err = ext3_journal_get_create_access(handle, bh))) -+ goto cleanup; -+ -+ neh = EXT_BLOCK_HDR(bh); -+ neh->eh_entries = 1; -+ neh->eh_magic = EXT3_EXT_MAGIC; -+ neh->eh_max = ext3_ext_space_block_idx(tree); -+ neh->eh_depth = depth - i; -+ fidx = EXT_FIRST_INDEX(neh); -+ fidx->ei_block = border; -+ fidx->ei_leaf = oldblock; -+ -+ ext_debug(tree, "int.index at %d (block %lu): %lu -> %lu\n", -+ i, newblock, border, oldblock); -+ /* copy indexes */ -+ m = 0; -+ path[i].p_idx++; -+ -+ ext_debug(tree, "cur 0x%p, last 0x%p\n", path[i].p_idx, -+ EXT_MAX_INDEX(path[i].p_hdr)); -+ EXT_ASSERT(EXT_MAX_INDEX(path[i].p_hdr) == -+ EXT_LAST_INDEX(path[i].p_hdr)); -+ while (path[i].p_idx <= EXT_MAX_INDEX(path[i].p_hdr)) { -+ ext_debug(tree, "%d: move %d:%d in new index %lu\n", -+ i, path[i].p_idx->ei_block, -+ path[i].p_idx->ei_leaf, newblock); -+ memmove(++fidx, path[i].p_idx++, -+ sizeof(struct ext3_extent_idx)); -+ neh->eh_entries++; -+ EXT_ASSERT(neh->eh_entries <= neh->eh_max); -+ m++; -+ } -+ mark_buffer_uptodate(bh, 1); -+ unlock_buffer(bh); -+ -+ if ((err = ext3_journal_dirty_metadata(handle, bh))) -+ goto cleanup; -+ brelse(bh); -+ bh = NULL; -+ -+ /* correct old index */ -+ if (m) { -+ err = ext3_ext_get_access(handle, tree, path + i); -+ if (err) -+ goto cleanup; -+ path[i].p_hdr->eh_entries -= m; -+ err = ext3_ext_dirty(handle, tree, path + i); -+ if (err) -+ goto cleanup; -+ } -+ -+ i--; -+ } -+ -+ /* insert new index */ -+ if (!err) -+ err = ext3_ext_insert_index(handle, tree, path + at, -+ border, newblock); -+ -+cleanup: -+ if (bh) { -+ if (buffer_locked(bh)) -+ unlock_buffer(bh); -+ brelse(bh); -+ } -+ -+ if (err) { -+ /* free all allocated blocks in error case */ -+ for (i = 0; i < depth; i++) { -+ if (!ablocks[i]) -+ continue; -+ ext3_free_blocks(handle, tree->inode, ablocks[i], 1); -+ } -+ } -+ kfree(ablocks); -+ -+ return err; -+} -+ -+/* -+ * routine implements tree growing procedure: -+ * - allocates new block -+ * - moves top-level data (index block or leaf) into the new block -+ * - initialize new top-level, creating index that points to the -+ * just created block -+ */ -+static int ext3_ext_grow_indepth(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) -+{ -+ struct ext3_ext_path *curp = path; -+ struct ext3_extent_header *neh; -+ struct ext3_extent_idx *fidx; -+ struct buffer_head *bh; -+ unsigned long newblock; -+ int err = 0; -+ -+ newblock = ext3_ext_new_block(handle, tree, path, newext, &err); -+ if (newblock == 0) -+ return err; -+ -+ bh = sb_getblk(tree->inode->i_sb, newblock); -+ if (!bh) { -+ err = -EIO; -+ ext3_std_error(tree->inode->i_sb, err); -+ return err; -+ } -+ lock_buffer(bh); -+ -+ if ((err = ext3_journal_get_create_access(handle, bh))) { -+ unlock_buffer(bh); -+ goto out; -+ } -+ -+ /* move top-level index/leaf into new block */ -+ memmove(bh->b_data, curp->p_hdr, tree->buffer_len); -+ -+ /* set size of new block */ -+ neh = EXT_BLOCK_HDR(bh); -+ /* old root could have indexes or leaves -+ * so calculate eh_max right way */ -+ if (EXT_DEPTH(tree)) -+ neh->eh_max = ext3_ext_space_block_idx(tree); -+ else -+ neh->eh_max = ext3_ext_space_block(tree); -+ neh->eh_magic = EXT3_EXT_MAGIC; -+ mark_buffer_uptodate(bh, 1); -+ unlock_buffer(bh); -+ -+ if ((err = ext3_journal_dirty_metadata(handle, bh))) -+ goto out; -+ -+ /* create index in new top-level index: num,max,pointer */ -+ if ((err = ext3_ext_get_access(handle, tree, curp))) -+ goto out; -+ -+ curp->p_hdr->eh_magic = EXT3_EXT_MAGIC; -+ curp->p_hdr->eh_max = ext3_ext_space_root_idx(tree); -+ curp->p_hdr->eh_entries = 1; -+ curp->p_idx = EXT_FIRST_INDEX(curp->p_hdr); -+ /* FIXME: it works, but actually path[0] can be index */ -+ curp->p_idx->ei_block = EXT_FIRST_EXTENT(path[0].p_hdr)->ee_block; -+ curp->p_idx->ei_leaf = newblock; -+ -+ neh = EXT_ROOT_HDR(tree); -+ fidx = EXT_FIRST_INDEX(neh); -+ ext_debug(tree, "new root: num %d(%d), lblock %d, ptr %d\n", -+ neh->eh_entries, neh->eh_max, fidx->ei_block, fidx->ei_leaf); -+ -+ neh->eh_depth = path->p_depth + 1; -+ err = ext3_ext_dirty(handle, tree, curp); -+out: -+ brelse(bh); -+ -+ return err; -+} -+ -+/* -+ * routine finds empty index and adds new leaf. if no free index found -+ * then it requests in-depth growing -+ */ -+static int ext3_ext_create_new_leaf(handle_t *handle, -+ struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) -+{ -+ struct ext3_ext_path *curp; -+ int depth, i, err = 0; -+ -+repeat: -+ i = depth = EXT_DEPTH(tree); -+ -+ /* walk up to the tree and look for free index entry */ -+ curp = path + depth; -+ while (i > 0 && !EXT_HAS_FREE_INDEX(curp)) { -+ i--; -+ curp--; -+ } -+ -+ /* we use already allocated block for index block -+ * so, subsequent data blocks should be contigoues */ -+ if (EXT_HAS_FREE_INDEX(curp)) { -+ /* if we found index with free entry, then use that -+ * entry: create all needed subtree and add new leaf */ -+ err = ext3_ext_split(handle, tree, path, newext, i); -+ -+ /* refill path */ -+ ext3_ext_drop_refs(path); -+ path = ext3_ext_find_extent(tree, newext->ee_block, path); -+ if (IS_ERR(path)) -+ err = PTR_ERR(path); -+ } else { -+ /* tree is full, time to grow in depth */ -+ err = ext3_ext_grow_indepth(handle, tree, path, newext); -+ -+ /* refill path */ -+ ext3_ext_drop_refs(path); -+ path = ext3_ext_find_extent(tree, newext->ee_block, path); -+ if (IS_ERR(path)) -+ err = PTR_ERR(path); -+ -+ /* -+ * only first (depth 0 -> 1) produces free space -+ * in all other cases we have to split growed tree -+ */ -+ depth = EXT_DEPTH(tree); -+ if (path[depth].p_hdr->eh_entries == path[depth].p_hdr->eh_max) { -+ /* now we need split */ -+ goto repeat; -+ } -+ } -+ -+ if (err) -+ return err; -+ -+ return 0; -+} -+ -+/* -+ * returns allocated block in subsequent extent or EXT_MAX_BLOCK -+ * NOTE: it consider block number from index entry as -+ * allocated block. thus, index entries have to be consistent -+ * with leafs -+ */ -+static unsigned long -+ext3_ext_next_allocated_block(struct ext3_ext_path *path) -+{ -+ int depth; -+ -+ EXT_ASSERT(path != NULL); -+ depth = path->p_depth; -+ -+ if (depth == 0 && path->p_ext == NULL) -+ return EXT_MAX_BLOCK; -+ -+ /* FIXME: what if index isn't full ?! */ -+ while (depth >= 0) { -+ if (depth == path->p_depth) { -+ /* leaf */ -+ if (path[depth].p_ext != -+ EXT_LAST_EXTENT(path[depth].p_hdr)) -+ return path[depth].p_ext[1].ee_block; -+ } else { -+ /* index */ -+ if (path[depth].p_idx != -+ EXT_LAST_INDEX(path[depth].p_hdr)) -+ return path[depth].p_idx[1].ei_block; -+ } -+ depth--; -+ } -+ -+ return EXT_MAX_BLOCK; -+} -+ -+/* -+ * returns first allocated block from next leaf or EXT_MAX_BLOCK -+ */ -+static unsigned ext3_ext_next_leaf_block(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) -+{ -+ int depth; -+ -+ EXT_ASSERT(path != NULL); -+ depth = path->p_depth; -+ -+ /* zero-tree has no leaf blocks at all */ -+ if (depth == 0) -+ return EXT_MAX_BLOCK; -+ -+ /* go to index block */ -+ depth--; -+ -+ while (depth >= 0) { -+ if (path[depth].p_idx != -+ EXT_LAST_INDEX(path[depth].p_hdr)) -+ return path[depth].p_idx[1].ei_block; -+ depth--; -+ } -+ -+ return EXT_MAX_BLOCK; -+} -+ -+/* -+ * if leaf gets modified and modified extent is first in the leaf -+ * then we have to correct all indexes above -+ * TODO: do we need to correct tree in all cases? -+ */ -+int ext3_ext_correct_indexes(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) -+{ -+ struct ext3_extent_header *eh; -+ int depth = EXT_DEPTH(tree); -+ struct ext3_extent *ex; -+ unsigned long border; -+ int k, err = 0; -+ -+ eh = path[depth].p_hdr; -+ ex = path[depth].p_ext; -+ EXT_ASSERT(ex); -+ EXT_ASSERT(eh); -+ -+ if (depth == 0) { -+ /* there is no tree at all */ -+ return 0; -+ } -+ -+ if (ex != EXT_FIRST_EXTENT(eh)) { -+ /* we correct tree if first leaf got modified only */ -+ return 0; -+ } -+ -+ /* -+ * TODO: we need correction if border is smaller then current one -+ */ -+ k = depth - 1; -+ border = path[depth].p_ext->ee_block; -+ if ((err = ext3_ext_get_access(handle, tree, path + k))) -+ return err; -+ path[k].p_idx->ei_block = border; -+ if ((err = ext3_ext_dirty(handle, tree, path + k))) -+ return err; -+ -+ while (k--) { -+ /* change all left-side indexes */ -+ if (path[k+1].p_idx != EXT_FIRST_INDEX(path[k+1].p_hdr)) -+ break; -+ if ((err = ext3_ext_get_access(handle, tree, path + k))) -+ break; -+ path[k].p_idx->ei_block = border; -+ if ((err = ext3_ext_dirty(handle, tree, path + k))) -+ break; -+ } -+ -+ return err; -+} -+ -+static int inline -+ext3_can_extents_be_merged(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex1, -+ struct ext3_extent *ex2) -+{ -+ if (ex1->ee_block + ex1->ee_len != ex2->ee_block) -+ return 0; -+ -+#ifdef AGRESSIVE_TEST -+ if (ex1->ee_len >= 4) -+ return 0; -+#endif -+ -+ if (!tree->ops->mergable) -+ return 1; -+ -+ return tree->ops->mergable(ex1, ex2); -+} -+ -+/* -+ * this routine tries to merge requsted extent into the existing -+ * extent or inserts requested extent as new one into the tree, -+ * creating new leaf in no-space case -+ */ -+int ext3_ext_insert_extent(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newext) -+{ -+ struct ext3_extent_header * eh; -+ struct ext3_extent *ex, *fex; -+ struct ext3_extent *nearex; /* nearest extent */ -+ struct ext3_ext_path *npath = NULL; -+ int depth, len, err, next; -+ -+ EXT_ASSERT(newext->ee_len > 0); -+ EXT_ASSERT(newext->ee_len < EXT_CACHE_MARK); -+ depth = EXT_DEPTH(tree); -+ ex = path[depth].p_ext; -+ EXT_ASSERT(path[depth].p_hdr); -+ -+ /* try to insert block into found extent and return */ -+ if (ex && ext3_can_extents_be_merged(tree, ex, newext)) { -+ ext_debug(tree, "append %d block to %d:%d (from %d)\n", -+ newext->ee_len, ex->ee_block, ex->ee_len, -+ ex->ee_start); -+ if ((err = ext3_ext_get_access(handle, tree, path + depth))) -+ return err; -+ ex->ee_len += newext->ee_len; -+ eh = path[depth].p_hdr; -+ nearex = ex; -+ goto merge; -+ } -+ -+repeat: -+ depth = EXT_DEPTH(tree); -+ eh = path[depth].p_hdr; -+ if (eh->eh_entries < eh->eh_max) -+ goto has_space; -+ -+ /* probably next leaf has space for us? */ -+ fex = EXT_LAST_EXTENT(eh); -+ next = ext3_ext_next_leaf_block(tree, path); -+ if (newext->ee_block > fex->ee_block && next != EXT_MAX_BLOCK) { -+ ext_debug(tree, "next leaf block - %d\n", next); -+ EXT_ASSERT(!npath); -+ npath = ext3_ext_find_extent(tree, next, NULL); -+ if (IS_ERR(npath)) -+ return PTR_ERR(npath); -+ EXT_ASSERT(npath->p_depth == path->p_depth); -+ eh = npath[depth].p_hdr; -+ if (eh->eh_entries < eh->eh_max) { -+ ext_debug(tree, "next leaf isnt full(%d)\n", -+ eh->eh_entries); -+ path = npath; -+ goto repeat; -+ } -+ ext_debug(tree, "next leaf hasno free space(%d,%d)\n", -+ eh->eh_entries, eh->eh_max); -+ } -+ -+ /* -+ * there is no free space in found leaf -+ * we're gonna add new leaf in the tree -+ */ -+ err = ext3_ext_create_new_leaf(handle, tree, path, newext); -+ if (err) -+ goto cleanup; -+ depth = EXT_DEPTH(tree); -+ eh = path[depth].p_hdr; -+ -+has_space: -+ nearex = path[depth].p_ext; -+ -+ if ((err = ext3_ext_get_access(handle, tree, path + depth))) -+ goto cleanup; -+ -+ if (!nearex) { -+ /* there is no extent in this leaf, create first one */ -+ ext_debug(tree, "first extent in the leaf: %d:%d:%d\n", -+ newext->ee_block, newext->ee_start, -+ newext->ee_len); -+ path[depth].p_ext = EXT_FIRST_EXTENT(eh); -+ } else if (newext->ee_block > nearex->ee_block) { -+ EXT_ASSERT(newext->ee_block != nearex->ee_block); -+ if (nearex != EXT_LAST_EXTENT(eh)) { -+ len = EXT_MAX_EXTENT(eh) - nearex; -+ len = (len - 1) * sizeof(struct ext3_extent); -+ len = len < 0 ? 0 : len; -+ ext_debug(tree, "insert %d:%d:%d after: nearest 0x%p, " -+ "move %d from 0x%p to 0x%p\n", -+ newext->ee_block, newext->ee_start, -+ newext->ee_len, -+ nearex, len, nearex + 1, nearex + 2); -+ memmove(nearex + 2, nearex + 1, len); -+ } -+ path[depth].p_ext = nearex + 1; -+ } else { -+ EXT_ASSERT(newext->ee_block != nearex->ee_block); -+ len = (EXT_MAX_EXTENT(eh) - nearex) * sizeof(struct ext3_extent); -+ len = len < 0 ? 0 : len; -+ ext_debug(tree, "insert %d:%d:%d before: nearest 0x%p, " -+ "move %d from 0x%p to 0x%p\n", -+ newext->ee_block, newext->ee_start, newext->ee_len, -+ nearex, len, nearex + 1, nearex + 2); -+ memmove(nearex + 1, nearex, len); -+ path[depth].p_ext = nearex; -+ } -+ -+ eh->eh_entries++; -+ nearex = path[depth].p_ext; -+ nearex->ee_block = newext->ee_block; -+ nearex->ee_start = newext->ee_start; -+ nearex->ee_len = newext->ee_len; -+ /* FIXME: support for large fs */ -+ nearex->ee_start_hi = 0; -+ -+merge: -+ /* try to merge extents to the right */ -+ while (nearex < EXT_LAST_EXTENT(eh)) { -+ if (!ext3_can_extents_be_merged(tree, nearex, nearex + 1)) -+ break; -+ /* merge with next extent! */ -+ nearex->ee_len += nearex[1].ee_len; -+ if (nearex + 1 < EXT_LAST_EXTENT(eh)) { -+ len = (EXT_LAST_EXTENT(eh) - nearex - 1) -+ * sizeof(struct ext3_extent); -+ memmove(nearex + 1, nearex + 2, len); -+ } -+ eh->eh_entries--; -+ EXT_ASSERT(eh->eh_entries > 0); -+ } -+ -+ /* try to merge extents to the left */ -+ -+ /* time to correct all indexes above */ -+ err = ext3_ext_correct_indexes(handle, tree, path); -+ if (err) -+ goto cleanup; -+ -+ err = ext3_ext_dirty(handle, tree, path + depth); -+ -+cleanup: -+ if (npath) { -+ ext3_ext_drop_refs(npath); -+ kfree(npath); -+ } -+ ext3_ext_tree_changed(tree); -+ ext3_ext_invalidate_cache(tree); -+ return err; -+} -+ -+int ext3_ext_walk_space(struct ext3_extents_tree *tree, unsigned long block, -+ unsigned long num, ext_prepare_callback func) -+{ -+ struct ext3_ext_path *path = NULL; -+ struct ext3_extent *ex, cbex; -+ unsigned long next, start = 0, end = 0; -+ unsigned long last = block + num; -+ int depth, exists, err = 0; -+ -+ EXT_ASSERT(tree); -+ EXT_ASSERT(func); -+ EXT_ASSERT(tree->inode); -+ EXT_ASSERT(tree->root); -+ -+ while (block < last && block != EXT_MAX_BLOCK) { -+ num = last - block; -+ /* find extent for this block */ -+ path = ext3_ext_find_extent(tree, block, path); -+ if (IS_ERR(path)) { -+ err = PTR_ERR(path); -+ path = NULL; -+ break; -+ } -+ -+ depth = EXT_DEPTH(tree); -+ EXT_ASSERT(path[depth].p_hdr); -+ ex = path[depth].p_ext; -+ next = ext3_ext_next_allocated_block(path); -+ -+ exists = 0; -+ if (!ex) { -+ /* there is no extent yet, so try to allocate -+ * all requested space */ -+ start = block; -+ end = block + num; -+ } else if (ex->ee_block > block) { -+ /* need to allocate space before found extent */ -+ start = block; -+ end = ex->ee_block; -+ if (block + num < end) -+ end = block + num; -+ } else if (block >= ex->ee_block + ex->ee_len) { -+ /* need to allocate space after found extent */ -+ start = block; -+ end = block + num; -+ if (end >= next) -+ end = next; -+ } else if (block >= ex->ee_block) { -+ /* -+ * some part of requested space is covered -+ * by found extent -+ */ -+ start = block; -+ end = ex->ee_block + ex->ee_len; -+ if (block + num < end) -+ end = block + num; -+ exists = 1; -+ } else { -+ BUG(); -+ } -+ EXT_ASSERT(end > start); -+ -+ if (!exists) { -+ cbex.ee_block = start; -+ cbex.ee_len = end - start; -+ cbex.ee_start = 0; -+ } else -+ cbex = *ex; -+ -+ EXT_ASSERT(path[depth].p_hdr); -+ err = func(tree, path, &cbex, exists); -+ ext3_ext_drop_refs(path); -+ -+ if (err < 0) -+ break; -+ if (err == EXT_REPEAT) -+ continue; -+ else if (err == EXT_BREAK) { -+ err = 0; -+ break; -+ } -+ -+ if (EXT_DEPTH(tree) != depth) { -+ /* depth was changed. we have to realloc path */ -+ kfree(path); -+ path = NULL; -+ } -+ -+ block = cbex.ee_block + cbex.ee_len; -+ } -+ -+ if (path) { -+ ext3_ext_drop_refs(path); -+ kfree(path); -+ } -+ -+ return err; -+} -+ -+static inline void -+ext3_ext_put_in_cache(struct ext3_extents_tree *tree, struct ext3_extent *ex) -+{ -+ if (tree->cex) { -+ EXT_ASSERT(ex); -+ EXT_ASSERT(ex->ee_len); -+ tree->cex->ee_block = ex->ee_block; -+ tree->cex->ee_start = ex->ee_start; -+ tree->cex->ee_len = ex->ee_len; -+ } -+} -+ -+/* -+ * this routine calculate boundaries of the gap requested block fits into -+ * and cache this gap -+ */ -+static inline void -+ext3_ext_put_gap_in_cache(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ unsigned long block) -+{ -+ int depth = EXT_DEPTH(tree); -+ struct ext3_extent *ex, gex; -+ -+ if (!tree->cex) -+ return; -+ -+ ex = path[depth].p_ext; -+ if (ex == NULL) { -+ /* there is no extent yet, so gap is [0;-] */ -+ gex.ee_block = 0; -+ gex.ee_len = EXT_CACHE_MARK; -+ ext_debug(tree, "cache gap(whole file):"); -+ } else if (block < ex->ee_block) { -+ gex.ee_block = block; -+ gex.ee_len = ex->ee_block - block; -+ ext_debug(tree, "cache gap(before): %lu [%lu:%lu]", -+ (unsigned long) block, -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len); -+ } else if (block >= ex->ee_block + ex->ee_len) { -+ gex.ee_block = ex->ee_block + ex->ee_len; -+ gex.ee_len = ext3_ext_next_allocated_block(path); -+ ext_debug(tree, "cache gap(after): [%lu:%lu] %lu", -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len, -+ (unsigned long) block); -+ EXT_ASSERT(gex.ee_len > gex.ee_block); -+ gex.ee_len = gex.ee_len - gex.ee_block; -+ } else { -+ BUG(); -+ } -+ -+ ext_debug(tree, " -> %lu:%lu\n", (unsigned long) gex.ee_block, -+ (unsigned long) gex.ee_len); -+ gex.ee_start = EXT_CACHE_MARK; -+ ext3_ext_put_in_cache(tree, &gex); -+} -+ -+static inline int -+ext3_ext_in_cache(struct ext3_extents_tree *tree, unsigned long block, -+ struct ext3_extent *ex) -+{ -+ struct ext3_extent *cex = tree->cex; -+ -+ /* is there cache storage at all? */ -+ if (!cex) -+ return 0; -+ -+ /* has cache valid data? */ -+ if (cex->ee_len == 0) -+ return 0; -+ -+ if (block >= cex->ee_block && block < cex->ee_block + cex->ee_len) { -+ ex->ee_block = cex->ee_block; -+ ex->ee_start = cex->ee_start; -+ ex->ee_len = cex->ee_len; -+ ext_debug(tree, "%lu cached by %lu:%lu:%lu\n", -+ (unsigned long) block, -+ (unsigned long) ex->ee_block, -+ (unsigned long) ex->ee_len, -+ (unsigned long) ex->ee_start); -+ return 1; -+ } -+ -+ /* not in cache */ -+ return 0; -+} -+ -+/* -+ * routine removes index from the index block -+ * it's used in truncate case only. thus all requests are for -+ * last index in the block only -+ */ -+int ext3_ext_rm_idx(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) -+{ -+ struct buffer_head *bh; -+ int err; -+ -+ /* free index block */ -+ path--; -+ EXT_ASSERT(path->p_hdr->eh_entries); -+ if ((err = ext3_ext_get_access(handle, tree, path))) -+ return err; -+ path->p_hdr->eh_entries--; -+ if ((err = ext3_ext_dirty(handle, tree, path))) -+ return err; -+ ext_debug(tree, "index is empty, remove it, free block %d\n", -+ path->p_idx->ei_leaf); -+ bh = sb_get_hash_table(tree->inode->i_sb, path->p_idx->ei_leaf); -+ ext3_forget(handle, 1, tree->inode, bh, path->p_idx->ei_leaf); -+ ext3_free_blocks(handle, tree->inode, path->p_idx->ei_leaf, 1); -+ return err; -+} -+ -+int ext3_ext_calc_credits_for_insert(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path) -+{ -+ int depth = EXT_DEPTH(tree); -+ int needed; -+ -+ if (path) { -+ /* probably there is space in leaf? */ -+ if (path[depth].p_hdr->eh_entries < path[depth].p_hdr->eh_max) -+ return 1; -+ } -+ -+ /* -+ * the worste case we're expecting is creation of the -+ * new root (growing in depth) with index splitting -+ * for splitting we have to consider depth + 1 because -+ * previous growing could increase it -+ */ -+ depth = depth + 1; -+ -+ /* -+ * growing in depth: -+ * block allocation + new root + old root -+ */ -+ needed = EXT3_ALLOC_NEEDED + 2; -+ -+ /* index split. we may need: -+ * allocate intermediate indexes and new leaf -+ * change two blocks at each level, but root -+ * modify root block (inode) -+ */ -+ needed += (depth * EXT3_ALLOC_NEEDED) + (2 * depth) + 1; -+ -+ return needed; -+} -+ -+static int -+ext3_ext_split_for_rm(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, unsigned long start, -+ unsigned long end) -+{ -+ struct ext3_extent *ex, tex; -+ struct ext3_ext_path *npath; -+ int depth, creds, err; -+ -+ depth = EXT_DEPTH(tree); -+ ex = path[depth].p_ext; -+ EXT_ASSERT(ex); -+ EXT_ASSERT(end < ex->ee_block + ex->ee_len - 1); -+ EXT_ASSERT(ex->ee_block < start); -+ -+ /* calculate tail extent */ -+ tex.ee_block = end + 1; -+ EXT_ASSERT(tex.ee_block < ex->ee_block + ex->ee_len); -+ tex.ee_len = ex->ee_block + ex->ee_len - tex.ee_block; -+ -+ creds = ext3_ext_calc_credits_for_insert(tree, path); -+ handle = ext3_ext_journal_restart(handle, creds); -+ if (IS_ERR(handle)) -+ return PTR_ERR(handle); -+ -+ /* calculate head extent. use primary extent */ -+ err = ext3_ext_get_access(handle, tree, path + depth); -+ if (err) -+ return err; -+ ex->ee_len = start - ex->ee_block; -+ err = ext3_ext_dirty(handle, tree, path + depth); -+ if (err) -+ return err; -+ -+ /* FIXME: some callback to free underlying resource -+ * and correct ee_start? */ -+ ext_debug(tree, "split extent: head %u:%u, tail %u:%u\n", -+ ex->ee_block, ex->ee_len, tex.ee_block, tex.ee_len); -+ -+ npath = ext3_ext_find_extent(tree, ex->ee_block, NULL); -+ if (IS_ERR(npath)) -+ return PTR_ERR(npath); -+ depth = EXT_DEPTH(tree); -+ EXT_ASSERT(npath[depth].p_ext->ee_block == ex->ee_block); -+ EXT_ASSERT(npath[depth].p_ext->ee_len == ex->ee_len); -+ -+ err = ext3_ext_insert_extent(handle, tree, npath, &tex); -+ ext3_ext_drop_refs(npath); -+ kfree(npath); -+ -+ return err; -+ -+} -+ -+static int -+ext3_ext_rm_leaf(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, unsigned long start, -+ unsigned long end) -+{ -+ struct ext3_extent *ex, *fu = NULL, *lu, *le; -+ int err = 0, correct_index = 0; -+ int depth = EXT_DEPTH(tree), credits; -+ struct ext3_extent_header *eh; -+ unsigned a, b, block, num; -+ -+ ext_debug(tree, "remove [%lu:%lu] in leaf\n", start, end); -+ if (!path[depth].p_hdr) -+ path[depth].p_hdr = EXT_BLOCK_HDR(path[depth].p_bh); -+ eh = path[depth].p_hdr; -+ EXT_ASSERT(eh); -+ EXT_ASSERT(eh->eh_entries <= eh->eh_max); -+ EXT_ASSERT(eh->eh_magic == EXT3_EXT_MAGIC); -+ -+ /* find where to start removing */ -+ le = ex = EXT_LAST_EXTENT(eh); -+ while (ex != EXT_FIRST_EXTENT(eh)) { -+ if (ex->ee_block <= end) -+ break; -+ ex--; -+ } -+ -+ if (start > ex->ee_block && end < ex->ee_block + ex->ee_len - 1) { -+ /* removal of internal part of the extent requested -+ * tail and head must be placed in different extent -+ * so, we have to insert one more extent */ -+ path[depth].p_ext = ex; -+ return ext3_ext_split_for_rm(handle, tree, path, start, end); -+ } -+ -+ lu = ex; -+ while (ex >= EXT_FIRST_EXTENT(eh) && -+ ex->ee_block + ex->ee_len > start) { -+ ext_debug(tree, "remove ext %u:%u\n", ex->ee_block, ex->ee_len); -+ path[depth].p_ext = ex; -+ -+ a = ex->ee_block > start ? ex->ee_block : start; -+ b = ex->ee_block + ex->ee_len - 1 < end ? -+ ex->ee_block + ex->ee_len - 1 : end; -+ -+ ext_debug(tree, " border %u:%u\n", a, b); -+ -+ if (a != ex->ee_block && b != ex->ee_block + ex->ee_len - 1) { -+ block = 0; -+ num = 0; -+ BUG(); -+ } else if (a != ex->ee_block) { -+ /* remove tail of the extent */ -+ block = ex->ee_block; -+ num = a - block; -+ } else if (b != ex->ee_block + ex->ee_len - 1) { -+ /* remove head of the extent */ -+ block = a; -+ num = b - a; -+ } else { -+ /* remove whole extent: excelent! */ -+ block = ex->ee_block; -+ num = 0; -+ EXT_ASSERT(a == ex->ee_block && -+ b == ex->ee_block + ex->ee_len - 1); -+ } -+ -+ if (ex == EXT_FIRST_EXTENT(eh)) -+ correct_index = 1; -+ -+ credits = 1; -+ if (correct_index) -+ credits += (EXT_DEPTH(tree) * EXT3_ALLOC_NEEDED) + 1; -+ if (tree->ops->remove_extent_credits) -+ credits+=tree->ops->remove_extent_credits(tree,ex,a,b); -+ -+ handle = ext3_ext_journal_restart(handle, credits); -+ if (IS_ERR(handle)) { -+ err = PTR_ERR(handle); -+ goto out; -+ } -+ -+ err = ext3_ext_get_access(handle, tree, path + depth); -+ if (err) -+ goto out; -+ -+ if (tree->ops->remove_extent) -+ err = tree->ops->remove_extent(tree, ex, a, b); -+ if (err) -+ goto out; -+ -+ if (num == 0) { -+ /* this extent is removed entirely mark slot unused */ -+ ex->ee_start = 0; -+ eh->eh_entries--; -+ fu = ex; -+ } -+ -+ ex->ee_block = block; -+ ex->ee_len = num; -+ -+ err = ext3_ext_dirty(handle, tree, path + depth); -+ if (err) -+ goto out; -+ -+ ext_debug(tree, "new extent: %u:%u:%u\n", -+ ex->ee_block, ex->ee_len, ex->ee_start); -+ ex--; -+ } -+ -+ if (fu) { -+ /* reuse unused slots */ -+ while (lu < le) { -+ if (lu->ee_start) { -+ *fu = *lu; -+ lu->ee_start = 0; -+ fu++; -+ } -+ lu++; -+ } -+ } -+ -+ if (correct_index && eh->eh_entries) -+ err = ext3_ext_correct_indexes(handle, tree, path); -+ -+ /* if this leaf is free, then we should -+ * remove it from index block above */ -+ if (err == 0 && eh->eh_entries == 0 && path[depth].p_bh != NULL) -+ err = ext3_ext_rm_idx(handle, tree, path + depth); -+ -+out: -+ return err; -+} -+ -+ -+static struct ext3_extent_idx * -+ext3_ext_last_covered(struct ext3_extent_header *hdr, unsigned long block) -+{ -+ struct ext3_extent_idx *ix; -+ -+ ix = EXT_LAST_INDEX(hdr); -+ while (ix != EXT_FIRST_INDEX(hdr)) { -+ if (ix->ei_block <= block) -+ break; -+ ix--; -+ } -+ return ix; -+} -+ -+/* -+ * returns 1 if current index have to be freed (even partial) -+ */ -+static int inline -+ext3_ext_more_to_rm(struct ext3_ext_path *path) -+{ -+ EXT_ASSERT(path->p_idx); -+ -+ if (path->p_idx < EXT_FIRST_INDEX(path->p_hdr)) -+ return 0; -+ -+ /* -+ * if truncate on deeper level happened it it wasn't partial -+ * so we have to consider current index for truncation -+ */ -+ if (path->p_hdr->eh_entries == path->p_block) -+ return 0; -+ return 1; -+} -+ -+int ext3_ext_remove_space(struct ext3_extents_tree *tree, -+ unsigned long start, unsigned long end) -+{ -+ struct inode *inode = tree->inode; -+ struct super_block *sb = inode->i_sb; -+ int depth = EXT_DEPTH(tree); -+ struct ext3_ext_path *path; -+ handle_t *handle; -+ int i = 0, err = 0; -+ -+ ext_debug(tree, "space to be removed: %lu:%lu\n", start, end); -+ -+ /* probably first extent we're gonna free will be last in block */ -+ handle = ext3_journal_start(inode, depth + 1); -+ if (IS_ERR(handle)) -+ return PTR_ERR(handle); -+ -+ ext3_ext_invalidate_cache(tree); -+ -+ /* -+ * we start scanning from right side freeing all the blocks -+ * after i_size and walking into the deep -+ */ -+ path = kmalloc(sizeof(struct ext3_ext_path) * (depth + 1), GFP_KERNEL); -+ if (IS_ERR(path)) { -+ ext3_error(sb, "ext3_ext_remove_space", -+ "Can't allocate path array"); -+ ext3_journal_stop(handle, inode); -+ return -ENOMEM; -+ } -+ memset(path, 0, sizeof(struct ext3_ext_path) * (depth + 1)); -+ path[i].p_hdr = EXT_ROOT_HDR(tree); -+ -+ while (i >= 0 && err == 0) { -+ if (i == depth) { -+ /* this is leaf block */ -+ err = ext3_ext_rm_leaf(handle, tree, path, start, end); -+ /* root level have p_bh == NULL, brelse() eats this */ -+ brelse(path[i].p_bh); -+ i--; -+ continue; -+ } -+ -+ /* this is index block */ -+ if (!path[i].p_hdr) { -+ ext_debug(tree, "initialize header\n"); -+ path[i].p_hdr = EXT_BLOCK_HDR(path[i].p_bh); -+ } -+ -+ EXT_ASSERT(path[i].p_hdr->eh_entries <= path[i].p_hdr->eh_max); -+ EXT_ASSERT(path[i].p_hdr->eh_magic == EXT3_EXT_MAGIC); -+ -+ if (!path[i].p_idx) { -+ /* this level hasn't touched yet */ -+ path[i].p_idx = -+ ext3_ext_last_covered(path[i].p_hdr, end); -+ path[i].p_block = path[i].p_hdr->eh_entries + 1; -+ ext_debug(tree, "init index ptr: hdr 0x%p, num %d\n", -+ path[i].p_hdr, path[i].p_hdr->eh_entries); -+ } else { -+ /* we've already was here, see at next index */ -+ path[i].p_idx--; -+ } -+ -+ ext_debug(tree, "level %d - index, first 0x%p, cur 0x%p\n", -+ i, EXT_FIRST_INDEX(path[i].p_hdr), -+ path[i].p_idx); -+ if (ext3_ext_more_to_rm(path + i)) { -+ /* go to the next level */ -+ ext_debug(tree, "move to level %d (block %d)\n", -+ i + 1, path[i].p_idx->ei_leaf); -+ memset(path + i + 1, 0, sizeof(*path)); -+ path[i+1].p_bh = sb_bread(sb, path[i].p_idx->ei_leaf); -+ if (!path[i+1].p_bh) { -+ /* should we reset i_size? */ -+ err = -EIO; -+ break; -+ } -+ /* put actual number of indexes to know is this -+ * number got changed at the next iteration */ -+ path[i].p_block = path[i].p_hdr->eh_entries; -+ i++; -+ } else { -+ /* we finish processing this index, go up */ -+ if (path[i].p_hdr->eh_entries == 0 && i > 0) { -+ /* index is empty, remove it -+ * handle must be already prepared by the -+ * truncatei_leaf() */ -+ err = ext3_ext_rm_idx(handle, tree, path + i); -+ } -+ /* root level have p_bh == NULL, brelse() eats this */ -+ brelse(path[i].p_bh); -+ i--; -+ ext_debug(tree, "return to level %d\n", i); -+ } -+ } -+ -+ /* TODO: flexible tree reduction should be here */ -+ if (path->p_hdr->eh_entries == 0) { -+ /* -+ * truncate to zero freed all the tree -+ * so, we need to correct eh_depth -+ */ -+ err = ext3_ext_get_access(handle, tree, path); -+ if (err == 0) { -+ EXT_ROOT_HDR(tree)->eh_depth = 0; -+ EXT_ROOT_HDR(tree)->eh_max = ext3_ext_space_root(tree); -+ err = ext3_ext_dirty(handle, tree, path); -+ } -+ } -+ ext3_ext_tree_changed(tree); -+ -+ kfree(path); -+ ext3_journal_stop(handle, inode); -+ -+ return err; -+} -+ -+/* -+ * called at mount time -+ */ -+void ext3_ext_init(struct super_block *sb) -+{ -+ /* -+ * possible initialization would be here -+ */ -+ -+ if (test_opt(sb, EXTENTS)) { -+ printk("EXT3-fs: file extents enabled"); -+#ifdef AGRESSIVE_TEST -+ printk(", agressive tests"); -+#endif -+#ifdef CHECK_BINSEARCH -+ printk(", check binsearch"); -+#endif -+ printk("\n"); -+ } -+} -+ -+/* -+ * called at umount time -+ */ -+void ext3_ext_release(struct super_block *sb) -+{ -+} -+ -+/************************************************************************ -+ * VFS related routines -+ ************************************************************************/ -+ -+static int ext3_get_inode_write_access(handle_t *handle, void *buffer) -+{ -+ /* we use in-core data, not bh */ -+ return 0; -+} -+ -+static int ext3_mark_buffer_dirty(handle_t *handle, void *buffer) -+{ -+ struct inode *inode = buffer; -+ return ext3_mark_inode_dirty(handle, inode); -+} -+ -+static int ext3_ext_mergable(struct ext3_extent *ex1, -+ struct ext3_extent *ex2) -+{ -+ /* FIXME: support for large fs */ -+ if (ex1->ee_start + ex1->ee_len == ex2->ee_start) -+ return 1; -+ return 0; -+} -+ -+static int -+ext3_remove_blocks_credits(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex, -+ unsigned long from, unsigned long to) -+{ -+ int needed; -+ -+ /* at present, extent can't cross block group */; -+ needed = 4; /* bitmap + group desc + sb + inode */ -+ -+#ifdef CONFIG_QUOTA -+ needed += 2 * EXT3_SINGLEDATA_TRANS_BLOCKS; -+#endif -+ return needed; -+} -+ -+static int -+ext3_remove_blocks(struct ext3_extents_tree *tree, -+ struct ext3_extent *ex, -+ unsigned long from, unsigned long to) -+{ -+ int needed = ext3_remove_blocks_credits(tree, ex, from, to); -+ handle_t *handle = ext3_journal_start(tree->inode, needed); -+ struct buffer_head *bh; -+ int i; -+ -+ if (IS_ERR(handle)) -+ return PTR_ERR(handle); -+ if (from >= ex->ee_block && to == ex->ee_block + ex->ee_len - 1) { -+ /* tail removal */ -+ unsigned long num, start; -+ num = ex->ee_block + ex->ee_len - from; -+ start = ex->ee_start + ex->ee_len - num; -+ ext_debug(tree, "free last %lu blocks starting %lu\n", -+ num, start); -+ for (i = 0; i < num; i++) { -+ bh = sb_get_hash_table(tree->inode->i_sb, start + i); -+ ext3_forget(handle, 0, tree->inode, bh, start + i); -+ } -+ ext3_free_blocks(handle, tree->inode, start, num); -+ } else if (from == ex->ee_block && to <= ex->ee_block + ex->ee_len - 1) { -+ printk("strange request: removal %lu-%lu from %u:%u\n", -+ from, to, ex->ee_block, ex->ee_len); -+ } else { -+ printk("strange request: removal(2) %lu-%lu from %u:%u\n", -+ from, to, ex->ee_block, ex->ee_len); -+ } -+ ext3_journal_stop(handle, tree->inode); -+ return 0; -+} -+ -+int ext3_ext_find_goal(struct inode *inode, struct ext3_ext_path *path, -+ unsigned long block) -+{ -+ struct ext3_inode_info *ei = EXT3_I(inode); -+ unsigned long bg_start; -+ unsigned long colour; -+ int depth; -+ -+ if (path) { -+ struct ext3_extent *ex; -+ depth = path->p_depth; -+ -+ /* try to predict block placement */ -+ if ((ex = path[depth].p_ext)) -+ return ex->ee_start + (block - ex->ee_block); -+ -+ /* it looks index is empty -+ * try to find starting from index itself */ -+ if (path[depth].p_bh) -+ return path[depth].p_bh->b_blocknr; -+ } -+ -+ /* OK. use inode's group */ -+ bg_start = (ei->i_block_group * EXT3_BLOCKS_PER_GROUP(inode->i_sb)) + -+ le32_to_cpu(EXT3_SB(inode->i_sb)->s_es->s_first_data_block); -+ colour = (current->pid % 16) * -+ (EXT3_BLOCKS_PER_GROUP(inode->i_sb) / 16); -+ return bg_start + colour + block; -+} -+ -+static int ext3_new_block_cb(handle_t *handle, struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *ex, int *err) -+{ -+ struct inode *inode = tree->inode; -+ int newblock, goal; -+ -+ EXT_ASSERT(path); -+ EXT_ASSERT(ex); -+ EXT_ASSERT(ex->ee_start); -+ EXT_ASSERT(ex->ee_len); -+ -+ /* reuse block from the extent to order data/metadata */ -+ newblock = ex->ee_start++; -+ ex->ee_len--; -+ if (ex->ee_len == 0) { -+ ex->ee_len = 1; -+ /* allocate new block for the extent */ -+ goal = ext3_ext_find_goal(inode, path, ex->ee_block); -+ ex->ee_start = ext3_new_block(handle, inode, goal, 0, 0, err); -+ if (ex->ee_start == 0) { -+ /* error occured: restore old extent */ -+ ex->ee_start = newblock; -+ return 0; -+ } -+ } -+ return newblock; -+} -+ -+static struct ext3_extents_helpers ext3_blockmap_helpers = { -+ .get_write_access = ext3_get_inode_write_access, -+ .mark_buffer_dirty = ext3_mark_buffer_dirty, -+ .mergable = ext3_ext_mergable, -+ .new_block = ext3_new_block_cb, -+ .remove_extent = ext3_remove_blocks, -+ .remove_extent_credits = ext3_remove_blocks_credits, -+}; -+ -+void ext3_init_tree_desc(struct ext3_extents_tree *tree, -+ struct inode *inode) -+{ -+ tree->inode = inode; -+ tree->root = (void *) EXT3_I(inode)->i_data; -+ tree->buffer = (void *) inode; -+ tree->buffer_len = sizeof(EXT3_I(inode)->i_data); -+ tree->cex = (struct ext3_extent *) &EXT3_I(inode)->i_cached_extent; -+ tree->ops = &ext3_blockmap_helpers; -+} -+ -+int ext3_ext_get_block(handle_t *handle, struct inode *inode, -+ long iblock, struct buffer_head *bh_result, int create) -+{ -+ struct ext3_ext_path *path = NULL; -+ struct ext3_extent newex; -+ struct ext3_extent *ex; -+ int goal, newblock, err = 0, depth; -+ struct ext3_extents_tree tree; -+ -+ clear_bit(BH_New, &bh_result->b_state); -+ ext3_init_tree_desc(&tree, inode); -+ ext_debug(&tree, "block %d requested for inode %u\n", -+ (int) iblock, (unsigned) inode->i_ino); -+ down_write(&EXT3_I(inode)->truncate_sem); -+ -+ /* check in cache */ -+ if (ext3_ext_in_cache(&tree, iblock, &newex)) { -+ if (newex.ee_start == EXT_CACHE_MARK) { -+ /* this is cached gap */ -+ if (!create) { -+ /* block isn't allocated yet and -+ * user don't want to allocate it */ -+ goto out2; -+ } -+ /* we should allocate requested block */ -+ } else if (newex.ee_start) { -+ /* block is already allocated */ -+ newblock = iblock - newex.ee_block + newex.ee_start; -+ goto out; -+ } -+ } -+ -+ /* find extent for this block */ -+ path = ext3_ext_find_extent(&tree, iblock, NULL); -+ if (IS_ERR(path)) { -+ err = PTR_ERR(path); -+ path = NULL; -+ goto out2; -+ } -+ -+ depth = EXT_DEPTH(&tree); -+ -+ /* -+ * consistent leaf must not be empty -+ * this situations is possible, though, _during_ tree modification -+ * this is why assert can't be put in ext3_ext_find_extent() -+ */ -+ EXT_ASSERT(path[depth].p_ext != NULL || depth == 0); -+ -+ if ((ex = path[depth].p_ext)) { -+ /* if found exent covers block, simple return it */ -+ if (iblock >= ex->ee_block && iblock < ex->ee_block + ex->ee_len) { -+ newblock = iblock - ex->ee_block + ex->ee_start; -+ ext_debug(&tree, "%d fit into %d:%d -> %d\n", -+ (int) iblock, ex->ee_block, ex->ee_len, -+ newblock); -+ ext3_ext_put_in_cache(&tree, ex); -+ goto out; -+ } -+ } -+ -+ /* -+ * requested block isn't allocated yet -+ * we couldn't try to create block if create flag is zero -+ */ -+ if (!create) { -+ /* put just found gap into cache to speedup subsequest reqs */ -+ ext3_ext_put_gap_in_cache(&tree, path, iblock); -+ goto out2; -+ } -+ -+ /* allocate new block */ -+ goal = ext3_ext_find_goal(inode, path, iblock); -+ newblock = ext3_new_block(handle, inode, goal, 0, 0, &err); -+ if (!newblock) -+ goto out2; -+ ext_debug(&tree, "allocate new block: goal %d, found %d\n", -+ goal, newblock); -+ -+ /* try to insert new extent into found leaf and return */ -+ newex.ee_block = iblock; -+ newex.ee_start = newblock; -+ newex.ee_len = 1; -+ err = ext3_ext_insert_extent(handle, &tree, path, &newex); -+ if (err) -+ goto out2; -+ -+ if (inode->i_size > EXT3_I(inode)->i_disksize) -+ EXT3_I(inode)->i_disksize = inode->i_size; -+ -+ /* previous routine could use block we allocated */ -+ newblock = newex.ee_start; -+ set_bit(BH_New, &bh_result->b_state); -+ -+ ext3_ext_put_in_cache(&tree, &newex); -+out: -+ ext3_ext_show_leaf(&tree, path); -+ set_bit(BH_Mapped, &bh_result->b_state); -+ bh_result->b_dev = inode->i_sb->s_dev; -+ bh_result->b_blocknr = newblock; -+out2: -+ if (path) { -+ ext3_ext_drop_refs(path); -+ kfree(path); -+ } -+ up_write(&EXT3_I(inode)->truncate_sem); -+ -+ return err; -+} -+ -+void ext3_ext_truncate(struct inode * inode) -+{ -+ struct address_space *mapping = inode->i_mapping; -+ struct super_block *sb = inode->i_sb; -+ struct ext3_extents_tree tree; -+ unsigned long last_block; -+ handle_t *handle; -+ int err = 0; -+ -+ ext3_init_tree_desc(&tree, inode); -+ -+ /* -+ * probably first extent we're gonna free will be last in block -+ */ -+ err = ext3_writepage_trans_blocks(inode) + 3; -+ handle = ext3_journal_start(inode, err); -+ if (IS_ERR(handle)) -+ return; -+ -+ ext3_block_truncate_page(handle, mapping, inode->i_size); -+ -+ down_write(&EXT3_I(inode)->truncate_sem); -+ ext3_ext_invalidate_cache(&tree); -+ -+ /* -+ * TODO: optimization is possible here -+ * probably we need not scaning at all, -+ * because page truncation is enough -+ */ -+ if (ext3_orphan_add(handle, inode)) -+ goto out_stop; -+ -+ /* we have to know where to truncate from in crash case */ -+ EXT3_I(inode)->i_disksize = inode->i_size; -+ ext3_mark_inode_dirty(handle, inode); -+ -+ last_block = (inode->i_size + sb->s_blocksize - 1) -+ >> EXT3_BLOCK_SIZE_BITS(sb); -+ err = ext3_ext_remove_space(&tree, last_block, EXT_MAX_BLOCK); -+ -+ /* In a multi-transaction truncate, we only make the final -+ * transaction synchronous */ -+ if (IS_SYNC(inode)) -+ handle->h_sync = 1; -+ -+out_stop: -+ /* -+ * If this was a simple ftruncate(), and the file will remain alive -+ * then we need to clear up the orphan record which we created above. -+ * However, if this was a real unlink then we were called by -+ * ext3_delete_inode(), and we allow that function to clean up the -+ * orphan info for us. -+ */ -+ if (inode->i_nlink) -+ ext3_orphan_del(handle, inode); -+ -+ up_write(&EXT3_I(inode)->truncate_sem); -+ ext3_journal_stop(handle, inode); -+} -+ -+/* -+ * this routine calculate max number of blocks we could modify -+ * in order to allocate new block for an inode -+ */ -+int ext3_ext_writepage_trans_blocks(struct inode *inode, int num) -+{ -+ struct ext3_extents_tree tree; -+ int needed; -+ -+ ext3_init_tree_desc(&tree, inode); -+ -+ needed = ext3_ext_calc_credits_for_insert(&tree, NULL); -+ -+ /* caller want to allocate num blocks */ -+ needed *= num; -+ -+#ifdef CONFIG_QUOTA -+ /* -+ * FIXME: real calculation should be here -+ * it depends on blockmap format of qouta file -+ */ -+ needed += 2 * EXT3_SINGLEDATA_TRANS_BLOCKS; -+#endif -+ -+ return needed; -+} -+ -+void ext3_extents_initialize_blockmap(handle_t *handle, struct inode *inode) -+{ -+ struct ext3_extents_tree tree; -+ -+ ext3_init_tree_desc(&tree, inode); -+ ext3_extent_tree_init(handle, &tree); -+} -+ -+static int -+ext3_ext_store_extent_cb(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newex, int exist) -+{ -+ struct ext3_extent_buf *buf = (struct ext3_extent_buf *) tree->private; -+ -+ if (!exist) -+ return EXT_CONTINUE; -+ if (buf->err < 0) -+ return EXT_BREAK; -+ if (buf->cur - buf->buffer + sizeof(*newex) > buf->buflen) -+ return EXT_BREAK; -+ -+ if (!copy_to_user(buf->cur, newex, sizeof(*newex))) { -+ buf->err++; -+ buf->cur += sizeof(*newex); -+ } else { -+ buf->err = -EFAULT; -+ return EXT_BREAK; -+ } -+ return EXT_CONTINUE; -+} -+ -+static int -+ext3_ext_collect_stats_cb(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *ex, int exist) -+{ -+ struct ext3_extent_tree_stats *buf = -+ (struct ext3_extent_tree_stats *) tree->private; -+ int depth; -+ -+ if (!exist) -+ return EXT_CONTINUE; -+ -+ depth = EXT_DEPTH(tree); -+ buf->extents_num++; -+ if (path[depth].p_ext == EXT_FIRST_EXTENT(path[depth].p_hdr)) -+ buf->leaf_num++; -+ return EXT_CONTINUE; -+} -+ -+int ext3_ext_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, -+ unsigned long arg) -+{ -+ int err = 0; -+ -+ if (!(EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL)) -+ return -EINVAL; -+ -+ if (cmd == EXT3_IOC_GET_EXTENTS) { -+ struct ext3_extent_buf buf; -+ struct ext3_extents_tree tree; -+ -+ if (copy_from_user(&buf, (void *) arg, sizeof(buf))) -+ return -EFAULT; -+ -+ ext3_init_tree_desc(&tree, inode); -+ buf.cur = buf.buffer; -+ buf.err = 0; -+ tree.private = &buf; -+ down_write(&EXT3_I(inode)->truncate_sem); -+ err = ext3_ext_walk_space(&tree, buf.start, EXT_MAX_BLOCK, -+ ext3_ext_store_extent_cb); -+ up_write(&EXT3_I(inode)->truncate_sem); -+ if (err == 0) -+ err = buf.err; -+ } else if (cmd == EXT3_IOC_GET_TREE_STATS) { -+ struct ext3_extent_tree_stats buf; -+ struct ext3_extents_tree tree; -+ -+ ext3_init_tree_desc(&tree, inode); -+ down_write(&EXT3_I(inode)->truncate_sem); -+ buf.depth = EXT_DEPTH(&tree); -+ buf.extents_num = 0; -+ buf.leaf_num = 0; -+ tree.private = &buf; -+ err = ext3_ext_walk_space(&tree, 0, EXT_MAX_BLOCK, -+ ext3_ext_collect_stats_cb); -+ up_write(&EXT3_I(inode)->truncate_sem); -+ if (!err) -+ err = copy_to_user((void *) arg, &buf, sizeof(buf)); -+ } else if (cmd == EXT3_IOC_GET_TREE_DEPTH) { -+ struct ext3_extents_tree tree; -+ ext3_init_tree_desc(&tree, inode); -+ down_write(&EXT3_I(inode)->truncate_sem); -+ err = EXT_DEPTH(&tree); -+ up_write(&EXT3_I(inode)->truncate_sem); -+ } -+ -+ return err; -+} -+ -+EXPORT_SYMBOL(ext3_init_tree_desc); -+EXPORT_SYMBOL(ext3_mark_inode_dirty); -+EXPORT_SYMBOL(ext3_ext_invalidate_cache); -+EXPORT_SYMBOL(ext3_ext_insert_extent); -+EXPORT_SYMBOL(ext3_ext_walk_space); -+EXPORT_SYMBOL(ext3_ext_find_goal); -+EXPORT_SYMBOL(ext3_ext_calc_credits_for_insert); -+ -Index: linux-2.4.24-b1_4/fs/ext3/ialloc.c -=================================================================== ---- linux-2.4.24-b1_4.orig/fs/ext3/ialloc.c 2004-09-30 14:04:27.000000000 +0800 -+++ linux-2.4.24-b1_4/fs/ext3/ialloc.c 2004-09-30 14:04:33.000000000 +0800 -@@ -592,10 +592,21 @@ - iloc.bh = NULL; - goto fail; - } -- err = ext3_mark_iloc_dirty(handle, inode, &iloc); -- if (err) goto fail; - -+ if (test_opt(sb, EXTENTS)) { -+ EXT3_I(inode)->i_flags |= EXT3_EXTENTS_FL; -+ ext3_extents_initialize_blockmap(handle, inode); -+ if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_EXTENTS)) { -+ err = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh); -+ if (err) goto fail; -+ EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_EXTENTS); -+ BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "call ext3_journal_dirty_metadata"); -+ err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); -+ } -+ } - -+ err = ext3_mark_iloc_dirty(handle, inode, &iloc); -+ if (err) goto fail; - - unlock_super (sb); - if(DQUOT_ALLOC_INODE(inode)) { -Index: linux-2.4.24-b1_4/fs/ext3/inode.c -=================================================================== ---- linux-2.4.24-b1_4.orig/fs/ext3/inode.c 2004-09-30 14:04:27.000000000 +0800 -+++ linux-2.4.24-b1_4/fs/ext3/inode.c 2004-09-30 14:04:33.000000000 +0800 -@@ -848,6 +848,15 @@ - goto reread; - } - -+static inline int -+ext3_get_block_wrap(handle_t *handle, struct inode *inode, long block, -+ struct buffer_head *bh, int create) -+{ -+ if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) -+ return ext3_ext_get_block(handle, inode, block, bh, create); -+ return ext3_get_block_handle(handle, inode, block, bh, create); -+} -+ - /* - * The BKL is not held on entry here. - */ -@@ -861,7 +870,7 @@ - handle = ext3_journal_current_handle(); - J_ASSERT(handle != 0); - } -- ret = ext3_get_block_handle(handle, inode, iblock, bh_result, create); -+ ret = ext3_get_block_wrap(handle, inode, iblock, bh_result, create); - return ret; - } - -@@ -879,7 +888,7 @@ - dummy.b_state = 0; - dummy.b_blocknr = -1000; - buffer_trace_init(&dummy.b_history); -- *errp = ext3_get_block_handle(handle, inode, block, &dummy, create); -+ *errp = ext3_get_block_wrap(handle, inode, block, &dummy, create); - if (!*errp && buffer_mapped(&dummy)) { - struct buffer_head *bh; - bh = sb_getblk(inode->i_sb, dummy.b_blocknr); -@@ -1403,7 +1412,7 @@ - * This required during truncate. We need to physically zero the tail end - * of that block so it doesn't yield old data if the file is later grown. - */ --static int ext3_block_truncate_page(handle_t *handle, -+int ext3_block_truncate_page(handle_t *handle, - struct address_space *mapping, loff_t from) - { - unsigned long index = from >> PAGE_CACHE_SHIFT; -@@ -1888,6 +1897,9 @@ - - ext3_discard_prealloc(inode); - -+ if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) -+ return ext3_ext_truncate(inode); -+ - handle = start_transaction(inode); - if (IS_ERR(handle)) - return; /* AKPM: return what? */ -@@ -2536,6 +2548,9 @@ - int indirects = (EXT3_NDIR_BLOCKS % bpp) ? 5 : 3; - int ret; - -+ if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) -+ return ext3_ext_writepage_trans_blocks(inode, bpp); -+ - if (ext3_should_journal_data(inode)) - ret = 3 * (bpp + indirects) + 2; - else -@@ -2972,7 +2987,7 @@ - - /* alloc blocks one by one */ - for (i = 0; i < nblocks; i++) { -- ret = ext3_get_block_handle(handle, inode, blocks[i], -+ ret = ext3_get_block_wrap(handle, inode, blocks[i], - &bh_tmp, 1); - if (ret) - break; -@@ -3048,7 +3063,7 @@ - if (blocks[i] != 0) - continue; - -- rc = ext3_get_block_handle(handle, inode, iblock, &bh, 1); -+ rc = ext3_get_block_wrap(handle, inode, iblock, &bh, 1); - if (rc) { - printk(KERN_INFO "ext3_map_inode_page: error %d " - "allocating block %ld\n", rc, iblock); -Index: linux-2.4.24-b1_4/fs/ext3/Makefile -=================================================================== ---- linux-2.4.24-b1_4.orig/fs/ext3/Makefile 2004-09-30 14:04:27.000000000 +0800 -+++ linux-2.4.24-b1_4/fs/ext3/Makefile 2004-09-30 14:04:33.000000000 +0800 -@@ -13,7 +13,9 @@ - - obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \ - ioctl.o namei.o super.o symlink.o hash.o ext3-exports.o \ -- xattr_trusted.o -+ xattr_trusted.o extents.o -+export-objs += extents.o -+ - obj-m := $(O_TARGET) - - export-objs += xattr.o -Index: linux-2.4.24-b1_4/fs/ext3/super.c -=================================================================== ---- linux-2.4.24-b1_4.orig/fs/ext3/super.c 2004-09-30 14:04:27.000000000 +0800 -+++ linux-2.4.24-b1_4/fs/ext3/super.c 2004-09-30 14:04:33.000000000 +0800 -@@ -530,6 +530,7 @@ - int i; - - J_ASSERT(sbi->s_delete_inodes == 0); -+ ext3_ext_release(sb); - ext3_xattr_put_super(sb); - journal_destroy(sbi->s_journal); - if (!(sb->s_flags & MS_RDONLY)) { -@@ -702,6 +703,10 @@ - return 0; - } - } -+ else if (!strcmp (this_char, "extents")) -+ set_opt (*mount_options, EXTENTS); -+ else if (!strcmp (this_char, "extdebug")) -+ set_opt (*mount_options, EXTDEBUG); - else if (!strcmp (this_char, "grpid") || - !strcmp (this_char, "bsdgroups")) - set_opt (*mount_options, GRPID); -@@ -1393,6 +1398,8 @@ - test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered": - "writeback"); - -+ ext3_ext_init(sb); -+ - return sb; - - failed_mount3: -Index: linux-2.4.24-b1_4/fs/ext3/ioctl.c -=================================================================== ---- linux-2.4.24-b1_4.orig/fs/ext3/ioctl.c 2004-09-30 14:04:22.000000000 +0800 -+++ linux-2.4.24-b1_4/fs/ext3/ioctl.c 2004-09-30 14:04:33.000000000 +0800 -@@ -174,6 +174,10 @@ - return ret; - } - #endif -+ case EXT3_IOC_GET_EXTENTS: -+ case EXT3_IOC_GET_TREE_STATS: -+ case EXT3_IOC_GET_TREE_DEPTH: -+ return ext3_ext_ioctl(inode, filp, cmd, arg); - default: - return -ENOTTY; - } -Index: linux-2.4.24-b1_4/include/linux/ext3_fs.h -=================================================================== ---- linux-2.4.24-b1_4.orig/include/linux/ext3_fs.h 2004-09-30 14:04:27.000000000 +0800 -+++ linux-2.4.24-b1_4/include/linux/ext3_fs.h 2004-09-30 14:07:09.000000000 +0800 -@@ -184,6 +184,7 @@ - #define EXT3_IMAGIC_FL 0x00002000 /* AFS directory */ - #define EXT3_JOURNAL_DATA_FL 0x00004000 /* file data should be journaled */ - #define EXT3_RESERVED_FL 0x80000000 /* reserved for ext3 lib */ -+#define EXT3_EXTENTS_FL 0x00080000 /* Inode uses extents */ - - #define EXT3_FL_USER_VISIBLE 0x00005FFF /* User visible flags */ - #define EXT3_FL_USER_MODIFIABLE 0x000000FF /* User modifiable flags */ -@@ -208,6 +209,9 @@ - #ifdef CONFIG_JBD_DEBUG - #define EXT3_IOC_WAIT_FOR_READONLY _IOR('f', 99, long) - #endif -+#define EXT3_IOC_GET_EXTENTS _IOR('f', 5, long) -+#define EXT3_IOC_GET_TREE_DEPTH _IOR('f', 6, long) -+#define EXT3_IOC_GET_TREE_STATS _IOR('f', 7, long) - - /* - * Structure of an inode on the disk -@@ -327,6 +331,8 @@ - #define EXT3_MOUNT_ASYNCDEL 0x20000 /* Delayed deletion */ - #define EXT3_MOUNT_IOPEN 0x40000 /* Allow access via iopen */ - #define EXT3_MOUNT_IOPEN_NOPRIV 0x80000 /* Make iopen world-readable */ -+#define EXT3_MOUNT_EXTENTS 0x100000 /* Extents support */ -+#define EXT3_MOUNT_EXTDEBUG 0x200000 /* Extents debug */ - - /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ - #ifndef _LINUX_EXT2_FS_H -@@ -503,10 +509,12 @@ - #define EXT3_FEATURE_INCOMPAT_FILETYPE 0x0002 - #define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ - #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */ -+#define EXT3_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */ - - #define EXT3_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR - #define EXT3_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_FILETYPE| \ -- EXT3_FEATURE_INCOMPAT_RECOVER) -+ EXT3_FEATURE_INCOMPAT_RECOVER| \ -+ EXT3_FEATURE_INCOMPAT_EXTENTS) - #define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \ - EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \ - EXT3_FEATURE_RO_COMPAT_BTREE_DIR) -@@ -688,6 +696,7 @@ - extern unsigned long ext3_count_free (struct buffer_head *, unsigned); - - /* inode.c */ -+extern int ext3_block_truncate_page(handle_t *, struct address_space *, loff_t); - extern int ext3_forget(handle_t *, int, struct inode *, struct buffer_head *, int); - extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *); - extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *); -@@ -769,6 +778,14 @@ - extern struct inode_operations ext3_symlink_inode_operations; - extern struct inode_operations ext3_fast_symlink_inode_operations; - -+/* extents.c */ -+extern int ext3_ext_writepage_trans_blocks(struct inode *, int); -+extern int ext3_ext_get_block(handle_t *, struct inode *, long, -+ struct buffer_head *, int); -+extern void ext3_ext_truncate(struct inode *); -+extern void ext3_ext_init(struct super_block *); -+extern void ext3_ext_release(struct super_block *); -+extern void ext3_extents_initialize_blockmap(handle_t *, struct inode *); - - #endif /* __KERNEL__ */ - -Index: linux-2.4.24-b1_4/include/linux/ext3_extents.h -=================================================================== ---- linux-2.4.24-b1_4.orig/include/linux/ext3_extents.h 2003-01-30 18:24:37.000000000 +0800 -+++ linux-2.4.24-b1_4/include/linux/ext3_extents.h 2004-09-30 14:04:33.000000000 +0800 -@@ -0,0 +1,237 @@ -+/* -+ * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com -+ * Written by Alex Tomas -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public Licens -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111- -+ */ -+ -+#ifndef _LINUX_EXT3_EXTENTS -+#define _LINUX_EXT3_EXTENTS -+ -+/* -+ * with AGRESSIVE_TEST defined capacity of index/leaf blocks -+ * become very little, so index split, in-depth growing and -+ * other hard changes happens much more often -+ * this is for debug purposes only -+ */ -+#define AGRESSIVE_TEST_ -+ -+/* -+ * if CHECK_BINSEARCH defined, then results of binary search -+ * will be checked by linear search -+ */ -+#define CHECK_BINSEARCH_ -+ -+/* -+ * if EXT_DEBUG is defined you can use 'extdebug' mount option -+ * to get lots of info what's going on -+ */ -+#define EXT_DEBUG -+#ifdef EXT_DEBUG -+#define ext_debug(tree,fmt,a...) \ -+do { \ -+ if (test_opt((tree)->inode->i_sb, EXTDEBUG)) \ -+ printk(fmt, ##a); \ -+} while (0); -+#else -+#define ext_debug(tree,fmt,a...) -+#endif -+ -+/* -+ * if EXT_STATS is defined then stats numbers are collected -+ * these number will be displayed at umount time -+ */ -+#define EXT_STATS_ -+ -+ -+#define EXT3_ALLOC_NEEDED 3 /* block bitmap + group desc. + sb */ -+ -+/* -+ * ext3_inode has i_block array (total 60 bytes) -+ * first 4 bytes are used to store: -+ * - tree depth (0 mean there is no tree yet. all extents in the inode) -+ * - number of alive extents in the inode -+ */ -+ -+/* -+ * this is extent on-disk structure -+ * it's used at the bottom of the tree -+ */ -+struct ext3_extent { -+ __u32 ee_block; /* first logical block extent covers */ -+ __u16 ee_len; /* number of blocks covered by extent */ -+ __u16 ee_start_hi; /* high 16 bits of physical block */ -+ __u32 ee_start; /* low 32 bigs of physical block */ -+}; -+ -+/* -+ * this is index on-disk structure -+ * it's used at all the levels, but the bottom -+ */ -+struct ext3_extent_idx { -+ __u32 ei_block; /* index covers logical blocks from 'block' */ -+ __u32 ei_leaf; /* pointer to the physical block of the next * -+ * level. leaf or next index could bet here */ -+ __u16 ei_leaf_hi; /* high 16 bits of physical block */ -+ __u16 ei_unused; -+}; -+ -+/* -+ * each block (leaves and indexes), even inode-stored has header -+ */ -+struct ext3_extent_header { -+ __u16 eh_magic; /* probably will support different formats */ -+ __u16 eh_entries; /* number of valid entries */ -+ __u16 eh_max; /* capacity of store in entries */ -+ __u16 eh_depth; /* has tree real underlaying blocks? */ -+ __u32 eh_generation; /* generation of the tree */ -+}; -+ -+#define EXT3_EXT_MAGIC 0xf30a -+ -+/* -+ * array of ext3_ext_path contains path to some extent -+ * creation/lookup routines use it for traversal/splitting/etc -+ * truncate uses it to simulate recursive walking -+ */ -+struct ext3_ext_path { -+ __u32 p_block; -+ __u16 p_depth; -+ struct ext3_extent *p_ext; -+ struct ext3_extent_idx *p_idx; -+ struct ext3_extent_header *p_hdr; -+ struct buffer_head *p_bh; -+}; -+ -+/* -+ * structure for external API -+ */ -+ -+/* -+ * ext3_extents_tree is used to pass initial information -+ * to top-level extents API -+ */ -+struct ext3_extents_helpers; -+struct ext3_extents_tree { -+ struct inode *inode; /* inode which tree belongs to */ -+ void *root; /* ptr to data top of tree resides at */ -+ void *buffer; /* will be passed as arg to ^^ routines */ -+ int buffer_len; -+ void *private; -+ struct ext3_extent *cex;/* last found extent */ -+ struct ext3_extents_helpers *ops; -+}; -+ -+struct ext3_extents_helpers { -+ int (*get_write_access)(handle_t *h, void *buffer); -+ int (*mark_buffer_dirty)(handle_t *h, void *buffer); -+ int (*mergable)(struct ext3_extent *ex1, struct ext3_extent *ex2); -+ int (*remove_extent_credits)(struct ext3_extents_tree *, -+ struct ext3_extent *, unsigned long, -+ unsigned long); -+ int (*remove_extent)(struct ext3_extents_tree *, -+ struct ext3_extent *, unsigned long, -+ unsigned long); -+ int (*new_block)(handle_t *, struct ext3_extents_tree *, -+ struct ext3_ext_path *, struct ext3_extent *, -+ int *); -+}; -+ -+/* -+ * to be called by ext3_ext_walk_space() -+ * negative retcode - error -+ * positive retcode - signal for ext3_ext_walk_space(), see below -+ * callback must return valid extent (passed or newly created) -+ */ -+typedef int (*ext_prepare_callback)(struct ext3_extents_tree *, -+ struct ext3_ext_path *, -+ struct ext3_extent *, int); -+ -+#define EXT_CONTINUE 0 -+#define EXT_BREAK 1 -+#define EXT_REPEAT 2 -+ -+ -+#define EXT_MAX_BLOCK 0xffffffff -+#define EXT_CACHE_MARK 0xffff -+ -+ -+#define EXT_FIRST_EXTENT(__hdr__) \ -+ ((struct ext3_extent *) (((char *) (__hdr__)) + \ -+ sizeof(struct ext3_extent_header))) -+#define EXT_FIRST_INDEX(__hdr__) \ -+ ((struct ext3_extent_idx *) (((char *) (__hdr__)) + \ -+ sizeof(struct ext3_extent_header))) -+#define EXT_HAS_FREE_INDEX(__path__) \ -+ ((__path__)->p_hdr->eh_entries < (__path__)->p_hdr->eh_max) -+#define EXT_LAST_EXTENT(__hdr__) \ -+ (EXT_FIRST_EXTENT((__hdr__)) + (__hdr__)->eh_entries - 1) -+#define EXT_LAST_INDEX(__hdr__) \ -+ (EXT_FIRST_INDEX((__hdr__)) + (__hdr__)->eh_entries - 1) -+#define EXT_MAX_EXTENT(__hdr__) \ -+ (EXT_FIRST_EXTENT((__hdr__)) + (__hdr__)->eh_max - 1) -+#define EXT_MAX_INDEX(__hdr__) \ -+ (EXT_FIRST_INDEX((__hdr__)) + (__hdr__)->eh_max - 1) -+ -+#define EXT_ROOT_HDR(tree) \ -+ ((struct ext3_extent_header *) (tree)->root) -+#define EXT_BLOCK_HDR(bh) \ -+ ((struct ext3_extent_header *) (bh)->b_data) -+#define EXT_DEPTH(_t_) \ -+ (((struct ext3_extent_header *)((_t_)->root))->eh_depth) -+#define EXT_GENERATION(_t_) \ -+ (((struct ext3_extent_header *)((_t_)->root))->eh_generation) -+ -+ -+#define EXT_ASSERT(__x__) if (!(__x__)) BUG(); -+ -+ -+/* -+ * this structure is used to gather extents from the tree via ioctl -+ */ -+struct ext3_extent_buf { -+ unsigned long start; -+ int buflen; -+ void *buffer; -+ void *cur; -+ int err; -+}; -+ -+/* -+ * this structure is used to collect stats info about the tree -+ */ -+struct ext3_extent_tree_stats { -+ int depth; -+ int extents_num; -+ int leaf_num; -+}; -+ -+void ext3_init_tree_desc(struct ext3_extents_tree *, struct inode *); -+extern int ext3_extent_tree_init(handle_t *, struct ext3_extents_tree *); -+extern int ext3_ext_calc_credits_for_insert(struct ext3_extents_tree *, struct ext3_ext_path *); -+extern int ext3_ext_insert_extent(handle_t *, struct ext3_extents_tree *, struct ext3_ext_path *, struct ext3_extent *); -+extern int ext3_ext_walk_space(struct ext3_extents_tree *, unsigned long, unsigned long, ext_prepare_callback); -+extern int ext3_ext_remove_space(struct ext3_extents_tree *, unsigned long, unsigned long); -+extern struct ext3_ext_path * ext3_ext_find_extent(struct ext3_extents_tree *, int, struct ext3_ext_path *); -+ -+static inline void -+ext3_ext_invalidate_cache(struct ext3_extents_tree *tree) -+{ -+ if (tree->cex) -+ tree->cex->ee_len = 0; -+} -+ -+ -+#endif /* _LINUX_EXT3_EXTENTS */ -+ -Index: linux-2.4.24-b1_4/include/linux/ext3_fs_i.h -=================================================================== ---- linux-2.4.24-b1_4.orig/include/linux/ext3_fs_i.h 2004-09-30 14:04:27.000000000 +0800 -+++ linux-2.4.24-b1_4/include/linux/ext3_fs_i.h 2004-09-30 14:04:33.000000000 +0800 -@@ -76,6 +76,8 @@ - * by other means, so we have truncate_sem. - */ - struct rw_semaphore truncate_sem; -+ -+ __u32 i_cached_extent[3]; - }; - - #endif /* _LINUX_EXT3_FS_I */ diff --git a/lustre/kernel_patches/patches/ext3-extents-asyncdel-2.4.24.patch b/lustre/kernel_patches/patches/ext3-extents-asyncdel-2.4.24.patch deleted file mode 100644 index 04d418f..0000000 --- a/lustre/kernel_patches/patches/ext3-extents-asyncdel-2.4.24.patch +++ /dev/null @@ -1,28 +0,0 @@ -Index: linux-2.4.24/fs/ext3/inode.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/inode.c 2004-05-18 12:34:48.000000000 -0700 -+++ linux-2.4.24/fs/ext3/inode.c 2004-05-18 12:47:50.000000000 -0700 -@@ -2244,6 +2244,12 @@ - else - inode->u.ext3_i.i_extra_isize = 0; - -+ if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) { -+ inode->u.ext3_i.i_cached_extent[0] = 0; -+ inode->u.ext3_i.i_cached_extent[1] = 0; -+ inode->u.ext3_i.i_cached_extent[2] = 0; -+ } -+ - if (S_ISREG(inode->i_mode)) { - inode->i_op = &ext3_file_inode_operations; - inode->i_fop = &ext3_file_operations; -@@ -2659,6 +2665,10 @@ - - memcpy(nei->i_data, oei->i_data, sizeof(nei->i_data)); - memset(oei->i_data, 0, sizeof(oei->i_data)); -+ if (EXT3_I(old_inode)->i_flags & EXT3_EXTENTS_FL) { -+ EXT3_I(new_inode)->i_flags |= EXT3_EXTENTS_FL; -+ ext3_extents_initialize_blockmap(handle, old_inode); -+ } - - nei->i_disksize = oei->i_disksize; - nei->i_state |= EXT3_STATE_DELETE; diff --git a/lustre/kernel_patches/patches/ext3-extents-in-ea-2.4.24.patch b/lustre/kernel_patches/patches/ext3-extents-in-ea-2.4.24.patch deleted file mode 100644 index e6df7db..0000000 --- a/lustre/kernel_patches/patches/ext3-extents-in-ea-2.4.24.patch +++ /dev/null @@ -1,365 +0,0 @@ -Index: linux-2.4.24/fs/ext3/extents-in-ea.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/extents-in-ea.c 2003-01-30 13:24:37.000000000 +0300 -+++ linux-2.4.24/fs/ext3/extents-in-ea.c 2004-08-10 16:13:06.000000000 +0400 -@@ -0,0 +1,224 @@ -+/* -+ * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com -+ * Written by Alex Tomas -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public Licens -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111- -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+static int ext3_get_ea_write_access(handle_t *handle, void *buffer) -+{ -+ struct buffer_head *bh = (struct buffer_head *) buffer; -+ return ext3_journal_get_write_access(handle, bh); -+} -+ -+static int ext3_mark_ea_buffer_dirty(handle_t *handle, void *buffer) -+{ -+ struct buffer_head *bh = (struct buffer_head *) buffer; -+ ext3_journal_dirty_metadata(handle, bh); -+ return 0; -+} -+ -+static struct ext3_extents_helpers ext3_ea_helpers = { -+ .get_write_access = ext3_get_ea_write_access, -+ .mark_buffer_dirty = ext3_mark_ea_buffer_dirty, -+ .mergable = NULL, -+ .new_block = NULL, -+ .remove_extent = NULL, -+ .remove_extent_credits = NULL, -+}; -+ -+int ext3_init_tree_in_ea_desc(struct ext3_extents_tree *tree, -+ struct inode *inode, int name_index, -+ const char *eaname) -+{ -+ struct buffer_head *bh; -+ int offset, err, size; -+ -+ err = ext3_xattr_get_ea_loc(inode, name_index, eaname, -+ &bh, &offset, &size); -+ if (err) -+ return err; -+ -+ EXT_ASSERT(bh); -+ EXT_ASSERT(size >= sizeof(struct ext3_extent_header) -+ + sizeof(struct ext3_extent)); -+ tree->inode = inode; -+ tree->root = (void *) bh->b_data + offset; -+ tree->buffer_len = size; -+ tree->buffer = (void *) bh; -+ tree->ops = &ext3_ea_helpers; -+ tree->cex = NULL; /* FIXME: add cache store later */ -+ return 0; -+} -+ -+void ext3_release_tree_in_ea_desc(struct ext3_extents_tree *tree) -+{ -+ struct buffer_head *bh; -+ -+ bh = (struct buffer_head *) tree->buffer; -+ EXT_ASSERT(bh); -+ brelse(bh); -+} -+ -+int ext3_init_tree_in_ea(struct inode *inode, int name_index, -+ const char *eaname, int size) -+{ -+ struct ext3_extents_tree tree; -+ handle_t *handle; -+ char *root; -+ int err; -+ -+ root = kmalloc(size, GFP_USER); -+ if (!root) -+ return -ENOMEM; -+ memset(root, 0, size); -+ -+ /* first, create ea to store root of the tree */ -+ handle = ext3_journal_start(inode, EXT3_ALLOC_NEEDED + 3); -+ if (IS_ERR(handle)) -+ return PTR_ERR(handle); -+ if ((err = ext3_xattr_set(handle, inode, name_index, -+ eaname, root, size, 0))) -+ goto out; -+ if ((err = ext3_init_tree_in_ea_desc(&tree, inode, name_index, eaname))) -+ goto out; -+ err = ext3_extent_tree_init(handle, &tree); -+ ext3_release_tree_in_ea_desc(&tree); -+out: -+ ext3_journal_stop(handle, inode); -+ kfree(root); -+ return err; -+} -+ -+static int -+ext3_ext_in_ea_new_extent(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newex, int exist) -+{ -+ struct inode *inode = tree->inode; -+ handle_t *handle; -+ int needed, err; -+ unsigned long tgen; -+ -+ if (exist) -+ return EXT_CONTINUE; -+ -+ tgen = EXT_GENERATION(tree); -+ needed = ext3_ext_calc_credits_for_insert(tree, path); -+ up_write(&EXT3_I(inode)->truncate_sem); -+ handle = ext3_journal_start(tree->inode, needed + 10); -+ if (IS_ERR(handle)) { -+ down_write(&EXT3_I(inode)->truncate_sem); -+ return PTR_ERR(handle); -+ } -+ -+ if (tgen != EXT_GENERATION(tree)) { -+ /* the tree has changed. so path can be invalid at moment */ -+ ext3_journal_stop(handle, inode); -+ down_write(&EXT3_I(inode)->truncate_sem); -+ return EXT_REPEAT; -+ } -+ -+ down_write(&EXT3_I(inode)->truncate_sem); -+ -+ /* insert new extent */ -+ newex->ee_start = 0; -+ err = ext3_ext_insert_extent(handle, tree, path, newex); -+ if (!err) -+ ext3_journal_stop(handle, tree->inode); -+ -+ return err; -+} -+ -+int ext3_ext_in_ea_alloc_space(struct inode *inode, int name_index, -+ const char *eaname, unsigned long from, -+ unsigned long num) -+{ -+ struct ext3_extents_tree tree; -+ int err; -+ -+ err = ext3_init_tree_in_ea_desc(&tree, inode, name_index, eaname); -+ if (err == 0) { -+ down_write(&EXT3_I(inode)->truncate_sem); -+ err = ext3_ext_walk_space(&tree, from, num, -+ ext3_ext_in_ea_new_extent); -+ ext3_release_tree_in_ea_desc(&tree); -+ up_write(&EXT3_I(inode)->truncate_sem); -+ } -+ return err; -+} -+ -+int ext3_ext_in_ea_remove_space(struct inode *inode, int name_index, -+ const char *eaname, unsigned long from, -+ unsigned long num) -+{ -+ struct ext3_extents_tree tree; -+ int err; -+ -+ err = ext3_init_tree_in_ea_desc(&tree, inode, name_index, eaname); -+ if (err == 0) { -+ err = ext3_ext_remove_space(&tree, from, num); -+ ext3_release_tree_in_ea_desc(&tree); -+ } -+ return err; -+} -+ -+int ext3_ext_in_ea_presence(struct inode *inode, int name_index, -+ const char *eaname, unsigned long block) -+{ -+ struct ext3_extents_tree tree; -+ struct ext3_ext_path *path; -+ struct ext3_extent *ex; -+ int err, depth; -+ -+ err = ext3_init_tree_in_ea_desc(&tree, inode, name_index, eaname); -+ if (err) -+ return err; -+ -+ /* find extent for this block */ -+ path = ext3_ext_find_extent(&tree, block, NULL); -+ if (IS_ERR(path)) { -+ err = PTR_ERR(path); -+ goto out; -+ } -+ -+ depth = EXT_DEPTH(&tree); -+ ex = path[depth].p_ext; -+ if (!ex) { -+ /* there is no extent yet */ -+ goto out; -+ } -+ -+ if (block >= ex->ee_block && block < ex->ee_block + ex->ee_len) -+ err = 1; -+out: -+ ext3_release_tree_in_ea_desc(&tree); -+ return err; -+} -+ -Index: linux-2.4.24/fs/ext3/Makefile -=================================================================== ---- linux-2.4.24.orig/fs/ext3/Makefile 2004-08-10 16:09:22.000000000 +0400 -+++ linux-2.4.24/fs/ext3/Makefile 2004-08-10 16:10:10.000000000 +0400 -@@ -19,7 +19,7 @@ - obj-m := $(O_TARGET) - - export-objs += xattr.o --obj-$(CONFIG_EXT3_FS_XATTR) += xattr.o -+obj-$(CONFIG_EXT3_FS_XATTR) += xattr.o extents-in-ea.o - obj-$(CONFIG_EXT3_FS_XATTR_USER) += xattr_user.o - - include $(TOPDIR)/Rules.make -Index: linux-2.4.24/fs/ext3/xattr.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/xattr.c 2004-08-07 16:35:25.000000000 +0400 -+++ linux-2.4.24/fs/ext3/xattr.c 2004-08-10 16:10:10.000000000 +0400 -@@ -771,7 +771,8 @@ - */ - int - ext3_xattr_ibody_find(struct inode *inode, int name_index, -- const char *name, struct ext3_xattr_entry *rentry, int *free) -+ const char *name, struct ext3_xattr_entry *rentry, int *free, -+ struct buffer_head **bh, int *offset) - { - struct ext3_xattr_entry *last; - struct ext3_inode *raw_inode; -@@ -818,6 +819,15 @@ - name_len == last->e_name_len && - !memcmp(name, last->e_name, name_len)) { - memcpy(rentry, last, sizeof(struct ext3_xattr_entry)); -+ if (offset) { -+ void *voff; -+ voff = start + le16_to_cpu(last->e_value_offs); -+ *offset = voff - (void *) iloc.bh->b_data; -+ } -+ if (bh) { -+ get_bh(iloc.bh); -+ *bh = iloc.bh; -+ } - ret = 0; - } else { - *free -= EXT3_XATTR_LEN(last->e_name_len); -@@ -838,7 +848,8 @@ - */ - int - ext3_xattr_block_find(struct inode *inode, int name_index, const char *name, -- struct ext3_xattr_entry *rentry, int *free) -+ struct ext3_xattr_entry *rentry, int *free, -+ struct buffer_head **tbh, int *offset) - { - struct buffer_head *bh = NULL; - struct ext3_xattr_entry *entry; -@@ -881,6 +892,12 @@ - memcmp(name, entry->e_name, name_len) == 0) { - memcpy(rentry, entry, sizeof(struct ext3_xattr_entry)); - error = 0; -+ if (offset) -+ *offset = le16_to_cpu(entry->e_value_offs); -+ if (tbh) { -+ get_bh(bh); -+ *tbh = bh; -+ } - } else { - *free -= EXT3_XATTR_LEN(entry->e_name_len); - *free -= le32_to_cpu(entry->e_value_size); -@@ -1073,7 +1090,8 @@ - return -ERANGE; - - /* try to find attribute in inode body */ -- err = ext3_xattr_ibody_find(inode, name_index, name, &entry, &free1); -+ err = ext3_xattr_ibody_find(inode, name_index, name, -+ &entry, &free1, NULL, NULL); - if (err == 0) { - /* found EA in inode */ - found = 1; -@@ -1082,7 +1100,7 @@ - /* there is no such attribute in inode body */ - /* try to find attribute in dedicated block */ - err = ext3_xattr_block_find(inode, name_index, name, -- &entry, &free2); -+ &entry, &free2, NULL, NULL); - if (err != 0 && err != -ENOENT) { - /* not found EA in block */ - goto finish; -@@ -1138,6 +1156,38 @@ - return err; - } - -+int ext3_xattr_get_ea_loc(struct inode *inode, int name_index, -+ const char *name, struct buffer_head **bh, -+ int *offset, int *size) -+{ -+ int free1 = -1, free2 = -1, err, name_len; -+ struct ext3_xattr_entry entry; -+ -+ ea_idebug(inode, "name=%d.%s", name_index, name); -+ -+ if (name == NULL) -+ return -EINVAL; -+ name_len = strlen(name); -+ if (name_len > 255) -+ return -ERANGE; -+ -+ down(&ext3_xattr_sem); -+ -+ /* try to find attribute in inode body */ -+ err = ext3_xattr_ibody_find(inode, name_index, name, -+ &entry, &free1, bh, offset); -+ if (err == -ENOENT) { -+ /* there is no such attribute in inode body */ -+ /* try to find attribute in dedicated block */ -+ err = ext3_xattr_block_find(inode, name_index, name, -+ &entry, &free2, bh, offset); -+ } -+ if (err == 0 && size) -+ *size = le32_to_cpu(entry.e_value_size); -+ up(&ext3_xattr_sem); -+ return err; -+} -+ - /* - * ext3_xattr_block_set() - * -Index: linux-2.4.24/include/linux/ext3_xattr.h -=================================================================== ---- linux-2.4.24.orig/include/linux/ext3_xattr.h 2004-08-07 16:35:25.000000000 +0400 -+++ linux-2.4.24/include/linux/ext3_xattr.h 2004-08-10 16:10:10.000000000 +0400 -@@ -80,6 +80,7 @@ - extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t); - extern int ext3_xattr_list(struct inode *, char *, size_t); - extern int ext3_xattr_set(handle_t *handle, struct inode *, int, const char *, const void *, size_t, int); -+extern int ext3_xattr_get_ea_loc(struct inode *, int, const char *, struct buffer_head **, int *, int *); - - extern void ext3_xattr_delete_inode(handle_t *, struct inode *); - extern void ext3_xattr_put_super(struct super_block *); diff --git a/lustre/kernel_patches/patches/ext3-extents-in-ea-exports-symbol-2.4.24.patch b/lustre/kernel_patches/patches/ext3-extents-in-ea-exports-symbol-2.4.24.patch deleted file mode 100644 index cb8eaf3..0000000 --- a/lustre/kernel_patches/patches/ext3-extents-in-ea-exports-symbol-2.4.24.patch +++ /dev/null @@ -1,116 +0,0 @@ -Index: linux-2.4.24/fs/ext3/extents-in-ea.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/extents-in-ea.c 2004-08-10 16:18:18.000000000 +0400 -+++ linux-2.4.24/fs/ext3/extents-in-ea.c 2004-08-10 16:19:13.000000000 +0400 -@@ -115,7 +115,7 @@ - kfree(root); - return err; - } -- -+EXPORT_SYMBOL(ext3_init_tree_in_ea); - static int - ext3_ext_in_ea_new_extent(struct ext3_extents_tree *tree, - struct ext3_ext_path *path, -@@ -173,7 +173,7 @@ - } - return err; - } -- -+EXPORT_SYMBOL(ext3_ext_in_ea_alloc_space); - int ext3_ext_in_ea_remove_space(struct inode *inode, int name_index, - const char *eaname, unsigned long from, - unsigned long num) -@@ -188,7 +188,7 @@ - } - return err; - } -- -+EXPORT_SYMBOL(ext3_ext_in_ea_remove_space); - int ext3_ext_in_ea_presence(struct inode *inode, int name_index, - const char *eaname, unsigned long block) - { -@@ -331,3 +331,49 @@ - return err; - } - -+EXPORT_SYMBOL(ext3_ext_in_ea_ioctl); -+int ext3_ext_in_ea_get_extents(struct inode *inode, int name_index, -+ const char *eaname, char **buf, int *size) -+{ -+ /*allocate the buffer and put the extents there*/ -+ struct ext3_extents_tree tree; -+ struct ext3_extent_buf ex_buf; -+ int err; -+ err = ext3_init_tree_in_ea_desc(&tree, inode, name_index, eaname); -+ if (err) -+ goto out; -+ ex_buf.cur = *buf; -+ ex_buf.err = 0; -+ tree.private = &ex_buf; -+ ex_buf.start = 0; -+ -+ err = ext3_ext_walk_space(&tree, ex_buf.start, EXT_MAX_BLOCK, -+ ext3_ext_store_extent_cb); -+ if (err == 0) -+ err = ex_buf.err; -+ ext3_release_tree_in_ea_desc(&tree); -+out: -+ return err; -+} -+EXPORT_SYMBOL(ext3_ext_in_ea_get_extents); -+int ext3_ext_in_ea_get_extents_num(struct inode *inode, int name_index, -+ const char *eaname, int *size) -+{ -+ struct ext3_extents_tree tree; -+ struct ext3_extent_tree_stats stats_buf; -+ int err = 0, ext_num; -+ /*get extents number*/ -+ err = ext3_init_tree_in_ea_desc(&tree, inode, name_index, eaname); -+ if (err) -+ return err; -+ tree.private = &stats_buf; -+ err = ext3_ext_walk_space(&tree, 0, EXT_MAX_BLOCK, -+ ext3_ext_collect_stats_cb); -+ ext_num = stats_buf.extents_num; -+ ext3_release_tree_in_ea_desc(&tree); -+ -+ *size = ext_num * sizeof(struct ext3_extent); -+ -+ return err; -+} -+EXPORT_SYMBOL(ext3_ext_in_ea_get_extents_num); -Index: linux-2.4.24/fs/ext3/Makefile -=================================================================== ---- linux-2.4.24.orig/fs/ext3/Makefile 2004-08-10 16:10:10.000000000 +0400 -+++ linux-2.4.24/fs/ext3/Makefile 2004-08-10 16:18:47.000000000 +0400 -@@ -13,13 +13,16 @@ - - obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \ - ioctl.o namei.o super.o symlink.o hash.o ext3-exports.o \ -- xattr_trusted.o extents.o -+ xattr_trusted.o extents.o extents-in-ea.o - export-objs += extents.o - - obj-m := $(O_TARGET) - - export-objs += xattr.o --obj-$(CONFIG_EXT3_FS_XATTR) += xattr.o extents-in-ea.o -+ifeq ($(CONFIG_EXT3_FS_XATTR),y) -+export-objs += extents-in-ea.o -+endif -+obj-$(CONFIG_EXT3_FS_XATTR) += xattr.o - obj-$(CONFIG_EXT3_FS_XATTR_USER) += xattr_user.o - - include $(TOPDIR)/Rules.make -Index: linux-2.4.24/fs/ext3/ioctl.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/ioctl.c 2004-08-10 16:14:40.000000000 +0400 -+++ linux-2.4.24/fs/ext3/ioctl.c 2004-08-10 16:18:47.000000000 +0400 -@@ -11,6 +11,7 @@ - #include - #include - #include -+#include - #include - #include - diff --git a/lustre/kernel_patches/patches/ext3-extents-in-ea-ioctl-2.4.24.patch b/lustre/kernel_patches/patches/ext3-extents-in-ea-ioctl-2.4.24.patch deleted file mode 100644 index ee526c7..0000000 --- a/lustre/kernel_patches/patches/ext3-extents-in-ea-ioctl-2.4.24.patch +++ /dev/null @@ -1,154 +0,0 @@ -Index: linux-2.4.24/fs/ext3/extents-in-ea.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/extents-in-ea.c 2004-08-10 16:13:06.000000000 +0400 -+++ linux-2.4.24/fs/ext3/extents-in-ea.c 2004-08-10 16:18:18.000000000 +0400 -@@ -222,3 +222,112 @@ - return err; - } - -+static int -+ext3_ext_store_extent_cb(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *newex, int exist) -+{ -+ struct ext3_extent_buf *buf = (struct ext3_extent_buf *) tree->private; -+ -+ if (!exist) -+ return EXT_CONTINUE; -+ if (buf->err < 0) -+ return EXT_BREAK; -+ if (buf->cur - buf->buffer + sizeof(*newex) > buf->buflen) -+ return EXT_BREAK; -+ -+ if (!copy_to_user(buf->cur, newex, sizeof(*newex))) { -+ buf->err++; -+ buf->cur += sizeof(*newex); -+ } else { -+ buf->err = -EFAULT; -+ return EXT_BREAK; -+ } -+ return EXT_CONTINUE; -+} -+ -+static int -+ext3_ext_collect_stats_cb(struct ext3_extents_tree *tree, -+ struct ext3_ext_path *path, -+ struct ext3_extent *ex, int exist) -+{ -+ struct ext3_extent_tree_stats *buf = -+ (struct ext3_extent_tree_stats *) tree->private; -+ int depth; -+ -+ if (!exist) -+ return EXT_CONTINUE; -+ -+ depth = EXT_DEPTH(tree); -+ buf->extents_num++; -+ if (path[depth].p_ext == EXT_FIRST_EXTENT(path[depth].p_hdr)) -+ buf->leaf_num++; -+ return EXT_CONTINUE; -+} -+ -+struct ea_tree_desc { -+ int name_index; -+ char eaname[256]; -+}; -+ -+int ext3_ext_in_ea_ioctl(struct inode *inode, struct file *filp, -+ unsigned int cmd, unsigned long arg) -+{ -+ int err = 0; -+ -+ if (cmd == EXT3_IOC_EA_TREE_INIT) { -+ struct ea_tree_desc desc; -+ -+ if (copy_from_user(&desc, (void *) arg, sizeof(desc))) -+ return -EFAULT; -+ err = ext3_init_tree_in_ea(inode, desc.name_index, -+ desc.eaname, 64); -+ } else if (cmd == EXT3_IOC_GET_EA_EXTENTS) { -+ struct ext3_extents_tree tree; -+ struct ext3_extent_buf buf; -+ struct ea_tree_desc desc; -+ -+ if (copy_from_user(&buf, (void *) arg, sizeof(buf))) -+ return -EFAULT; -+ if (copy_from_user(&desc, buf.cur, sizeof(desc))) -+ return -EFAULT; -+ err = ext3_init_tree_in_ea_desc(&tree, inode, -+ desc.name_index, desc.eaname); -+ if (err) -+ goto out; -+ buf.cur = buf.buffer; -+ buf.err = 0; -+ tree.private = &buf; -+ err = ext3_ext_walk_space(&tree, buf.start, EXT_MAX_BLOCK, -+ ext3_ext_store_extent_cb); -+ if (err == 0) -+ err = buf.err; -+ ext3_release_tree_in_ea_desc(&tree); -+ } else if (cmd == EXT3_IOC_EA_TREE_ALLOCATE) { -+ struct ext3_extent_buf buf; -+ struct ea_tree_desc desc; -+ -+ if (copy_from_user(&buf, (void *) arg, sizeof(buf))) -+ return -EFAULT; -+ if (copy_from_user(&desc, buf.cur, sizeof(desc))) -+ return -EFAULT; -+ err = ext3_ext_in_ea_alloc_space(inode, desc.name_index, -+ desc.eaname, buf.start, -+ buf.err); -+ } else if (cmd == EXT3_IOC_EA_TREE_REMOVE) { -+ struct ext3_extent_buf buf; -+ struct ea_tree_desc desc; -+ -+ if (copy_from_user(&buf, (void *) arg, sizeof(buf))) -+ return -EFAULT; -+ if (copy_from_user(&desc, buf.cur, sizeof(desc))) -+ return -EFAULT; -+ err = ext3_ext_in_ea_remove_space(inode, desc.name_index, -+ desc.eaname, buf.start, -+ buf.err); -+ } -+ -+out: -+ return err; -+} -+ -Index: linux-2.4.24/fs/ext3/ioctl.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/ioctl.c 2004-08-10 16:09:22.000000000 +0400 -+++ linux-2.4.24/fs/ext3/ioctl.c 2004-08-10 16:14:40.000000000 +0400 -@@ -178,6 +178,13 @@ - case EXT3_IOC_GET_TREE_STATS: - case EXT3_IOC_GET_TREE_DEPTH: - return ext3_ext_ioctl(inode, filp, cmd, arg); -+ case EXT3_IOC_GET_EA_EXTENTS: -+ case EXT3_IOC_GET_EA_TREE_DEPTH: -+ case EXT3_IOC_GET_EA_TREE_STATS: -+ case EXT3_IOC_EA_TREE_INIT: -+ case EXT3_IOC_EA_TREE_ALLOCATE: -+ case EXT3_IOC_EA_TREE_REMOVE: -+ return ext3_ext_in_ea_ioctl(inode, filp, cmd, arg); - default: - return -ENOTTY; - } -Index: linux-2.4.24/include/linux/ext3_fs.h -=================================================================== ---- linux-2.4.24.orig/include/linux/ext3_fs.h 2004-08-10 16:09:22.000000000 +0400 -+++ linux-2.4.24/include/linux/ext3_fs.h 2004-08-10 16:14:40.000000000 +0400 -@@ -214,6 +214,14 @@ - #define EXT3_IOC_GET_TREE_DEPTH _IOR('f', 6, long) - #define EXT3_IOC_GET_TREE_STATS _IOR('f', 7, long) - -+#define EXT3_IOC_GET_EA_EXTENTS _IOR('f', 10, long) -+#define EXT3_IOC_GET_EA_TREE_DEPTH _IOR('f', 11, long) -+#define EXT3_IOC_GET_EA_TREE_STATS _IOR('f', 12, long) -+#define EXT3_IOC_EA_TREE_INIT _IOW('f', 13, long) -+#define EXT3_IOC_EA_TREE_ALLOCATE _IOW('f', 14, long) -+#define EXT3_IOC_EA_TREE_REMOVE _IOW('f', 15, long) -+ -+ - /* - * Structure of an inode on the disk - */ diff --git a/lustre/kernel_patches/patches/ext3-htree-2.4.24.patch b/lustre/kernel_patches/patches/ext3-htree-2.4.24.patch deleted file mode 100644 index ca2cacf..0000000 --- a/lustre/kernel_patches/patches/ext3-htree-2.4.24.patch +++ /dev/null @@ -1,2573 +0,0 @@ - fs/ext3/Makefile | 2 - fs/ext3/dir.c | 302 +++++++++ - fs/ext3/file.c | 3 - fs/ext3/hash.c | 215 ++++++ - fs/ext3/namei.c | 1421 ++++++++++++++++++++++++++++++++++++++++----- - fs/ext3/super.c | 7 - include/linux/ext3_fs.h | 85 ++ - include/linux/ext3_fs_sb.h | 2 - include/linux/ext3_jbd.h | 2 - include/linux/rbtree.h | 2 - lib/rbtree.c | 42 + - 11 files changed, 1922 insertions(+), 161 deletions(-) - ---- linux-2.4.22-ac1/fs/ext3/dir.c~ext3-htree-2.4.22-rh 2001-11-10 01:25:04.000000000 +0300 -+++ linux-2.4.22-ac1-alexey/fs/ext3/dir.c 2003-09-25 14:58:30.000000000 +0400 -@@ -21,12 +21,16 @@ - #include - #include - #include -+#include -+#include - - static unsigned char ext3_filetype_table[] = { - DT_UNKNOWN, DT_REG, DT_DIR, DT_CHR, DT_BLK, DT_FIFO, DT_SOCK, DT_LNK - }; - - static int ext3_readdir(struct file *, void *, filldir_t); -+static int ext3_dx_readdir(struct file * filp, -+ void * dirent, filldir_t filldir); - - struct file_operations ext3_dir_operations = { - read: generic_read_dir, -@@ -35,6 +39,17 @@ struct file_operations ext3_dir_operatio - fsync: ext3_sync_file, /* BKL held */ - }; - -+ -+static unsigned char get_dtype(struct super_block *sb, int filetype) -+{ -+ if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_FILETYPE) || -+ (filetype >= EXT3_FT_MAX)) -+ return DT_UNKNOWN; -+ -+ return (ext3_filetype_table[filetype]); -+} -+ -+ - int ext3_check_dir_entry (const char * function, struct inode * dir, - struct ext3_dir_entry_2 * de, - struct buffer_head * bh, -@@ -79,6 +94,16 @@ static int ext3_readdir(struct file * fi - - sb = inode->i_sb; - -+ if (is_dx(inode)) { -+ err = ext3_dx_readdir(filp, dirent, filldir); -+ if (err != ERR_BAD_DX_DIR) -+ return err; -+ /* -+ * We don't set the inode dirty flag since it's not -+ * critical that it get flushed back to the disk. -+ */ -+ EXT3_I(filp->f_dentry->d_inode)->i_flags &= ~EXT3_INDEX_FL; -+ } - stored = 0; - bh = NULL; - offset = filp->f_pos & (sb->s_blocksize - 1); -@@ -162,18 +187,12 @@ revalidate: - * during the copy operation. - */ - unsigned long version = filp->f_version; -- unsigned char d_type = DT_UNKNOWN; - -- if (EXT3_HAS_INCOMPAT_FEATURE(sb, -- EXT3_FEATURE_INCOMPAT_FILETYPE) -- && de->file_type < EXT3_FT_MAX) -- d_type = -- ext3_filetype_table[de->file_type]; - error = filldir(dirent, de->name, - de->name_len, - filp->f_pos, - le32_to_cpu(de->inode), -- d_type); -+ get_dtype(sb, de->file_type)); - if (error) - break; - if (version != filp->f_version) -@@ -188,3 +207,272 @@ revalidate: - UPDATE_ATIME(inode); - return 0; - } -+ -+#ifdef CONFIG_EXT3_INDEX -+/* -+ * These functions convert from the major/minor hash to an f_pos -+ * value. -+ * -+ * Currently we only use major hash numer. This is unfortunate, but -+ * on 32-bit machines, the same VFS interface is used for lseek and -+ * llseek, so if we use the 64 bit offset, then the 32-bit versions of -+ * lseek/telldir/seekdir will blow out spectacularly, and from within -+ * the ext2 low-level routine, we don't know if we're being called by -+ * a 64-bit version of the system call or the 32-bit version of the -+ * system call. Worse yet, NFSv2 only allows for a 32-bit readdir -+ * cookie. Sigh. -+ */ -+#define hash2pos(major, minor) (major >> 1) -+#define pos2maj_hash(pos) ((pos << 1) & 0xffffffff) -+#define pos2min_hash(pos) (0) -+ -+/* -+ * This structure holds the nodes of the red-black tree used to store -+ * the directory entry in hash order. -+ */ -+struct fname { -+ __u32 hash; -+ __u32 minor_hash; -+ rb_node_t rb_hash; -+ struct fname *next; -+ __u32 inode; -+ __u8 name_len; -+ __u8 file_type; -+ char name[0]; -+}; -+ -+/* -+ * This functoin implements a non-recursive way of freeing all of the -+ * nodes in the red-black tree. -+ */ -+static void free_rb_tree_fname(rb_root_t *root) -+{ -+ rb_node_t *n = root->rb_node; -+ rb_node_t *parent; -+ struct fname *fname; -+ -+ while (n) { -+ /* Do the node's children first */ -+ if ((n)->rb_left) { -+ n = n->rb_left; -+ continue; -+ } -+ if (n->rb_right) { -+ n = n->rb_right; -+ continue; -+ } -+ /* -+ * The node has no children; free it, and then zero -+ * out parent's link to it. Finally go to the -+ * beginning of the loop and try to free the parent -+ * node. -+ */ -+ parent = n->rb_parent; -+ fname = rb_entry(n, struct fname, rb_hash); -+ kfree(fname); -+ if (!parent) -+ root->rb_node = 0; -+ else if (parent->rb_left == n) -+ parent->rb_left = 0; -+ else if (parent->rb_right == n) -+ parent->rb_right = 0; -+ n = parent; -+ } -+ root->rb_node = 0; -+} -+ -+ -+struct dir_private_info *create_dir_info(loff_t pos) -+{ -+ struct dir_private_info *p; -+ -+ p = kmalloc(sizeof(struct dir_private_info), GFP_KERNEL); -+ if (!p) -+ return NULL; -+ p->root.rb_node = 0; -+ p->curr_node = 0; -+ p->extra_fname = 0; -+ p->last_pos = 0; -+ p->curr_hash = pos2maj_hash(pos); -+ p->curr_minor_hash = pos2min_hash(pos); -+ p->next_hash = 0; -+ return p; -+} -+ -+void ext3_htree_free_dir_info(struct dir_private_info *p) -+{ -+ free_rb_tree_fname(&p->root); -+ kfree(p); -+} -+ -+/* -+ * Given a directory entry, enter it into the fname rb tree. -+ */ -+int ext3_htree_store_dirent(struct file *dir_file, __u32 hash, -+ __u32 minor_hash, -+ struct ext3_dir_entry_2 *dirent) -+{ -+ rb_node_t **p, *parent = NULL; -+ struct fname * fname, *new_fn; -+ struct dir_private_info *info; -+ int len; -+ -+ info = (struct dir_private_info *) dir_file->private_data; -+ p = &info->root.rb_node; -+ -+ /* Create and allocate the fname structure */ -+ len = sizeof(struct fname) + dirent->name_len + 1; -+ new_fn = kmalloc(len, GFP_KERNEL); -+ if (!new_fn) -+ return -ENOMEM; -+ memset(new_fn, 0, len); -+ new_fn->hash = hash; -+ new_fn->minor_hash = minor_hash; -+ new_fn->inode = le32_to_cpu(dirent->inode); -+ new_fn->name_len = dirent->name_len; -+ new_fn->file_type = dirent->file_type; -+ memcpy(new_fn->name, dirent->name, dirent->name_len); -+ new_fn->name[dirent->name_len] = 0; -+ -+ while (*p) { -+ parent = *p; -+ fname = rb_entry(parent, struct fname, rb_hash); -+ -+ /* -+ * If the hash and minor hash match up, then we put -+ * them on a linked list. This rarely happens... -+ */ -+ if ((new_fn->hash == fname->hash) && -+ (new_fn->minor_hash == fname->minor_hash)) { -+ new_fn->next = fname->next; -+ fname->next = new_fn; -+ return 0; -+ } -+ -+ if (new_fn->hash < fname->hash) -+ p = &(*p)->rb_left; -+ else if (new_fn->hash > fname->hash) -+ p = &(*p)->rb_right; -+ else if (new_fn->minor_hash < fname->minor_hash) -+ p = &(*p)->rb_left; -+ else /* if (new_fn->minor_hash > fname->minor_hash) */ -+ p = &(*p)->rb_right; -+ } -+ -+ rb_link_node(&new_fn->rb_hash, parent, p); -+ rb_insert_color(&new_fn->rb_hash, &info->root); -+ return 0; -+} -+ -+ -+ -+/* -+ * This is a helper function for ext3_dx_readdir. It calls filldir -+ * for all entres on the fname linked list. (Normally there is only -+ * one entry on the linked list, unless there are 62 bit hash collisions.) -+ */ -+static int call_filldir(struct file * filp, void * dirent, -+ filldir_t filldir, struct fname *fname) -+{ -+ struct dir_private_info *info = filp->private_data; -+ loff_t curr_pos; -+ struct inode *inode = filp->f_dentry->d_inode; -+ struct super_block * sb; -+ int error; -+ -+ sb = inode->i_sb; -+ -+ if (!fname) { -+ printk("call_filldir: called with null fname?!?\n"); -+ return 0; -+ } -+ curr_pos = hash2pos(fname->hash, fname->minor_hash); -+ while (fname) { -+ error = filldir(dirent, fname->name, -+ fname->name_len, curr_pos, -+ fname->inode, -+ get_dtype(sb, fname->file_type)); -+ if (error) { -+ filp->f_pos = curr_pos; -+ info->extra_fname = fname->next; -+ return error; -+ } -+ fname = fname->next; -+ } -+ return 0; -+} -+ -+static int ext3_dx_readdir(struct file * filp, -+ void * dirent, filldir_t filldir) -+{ -+ struct dir_private_info *info = filp->private_data; -+ struct inode *inode = filp->f_dentry->d_inode; -+ struct fname *fname; -+ int ret; -+ -+ if (!info) { -+ info = create_dir_info(filp->f_pos); -+ if (!info) -+ return -ENOMEM; -+ filp->private_data = info; -+ } -+ -+ /* Some one has messed with f_pos; reset the world */ -+ if (info->last_pos != filp->f_pos) { -+ free_rb_tree_fname(&info->root); -+ info->curr_node = 0; -+ info->extra_fname = 0; -+ info->curr_hash = pos2maj_hash(filp->f_pos); -+ info->curr_minor_hash = pos2min_hash(filp->f_pos); -+ } -+ -+ /* -+ * If there are any leftover names on the hash collision -+ * chain, return them first. -+ */ -+ if (info->extra_fname && -+ call_filldir(filp, dirent, filldir, info->extra_fname)) -+ goto finished; -+ -+ if (!info->curr_node) -+ info->curr_node = rb_get_first(&info->root); -+ -+ while (1) { -+ /* -+ * Fill the rbtree if we have no more entries, -+ * or the inode has changed since we last read in the -+ * cached entries. -+ */ -+ if ((!info->curr_node) || -+ (filp->f_version != inode->i_version)) { -+ info->curr_node = 0; -+ free_rb_tree_fname(&info->root); -+ filp->f_version = inode->i_version; -+ ret = ext3_htree_fill_tree(filp, info->curr_hash, -+ info->curr_minor_hash, -+ &info->next_hash); -+ if (ret < 0) -+ return ret; -+ if (ret == 0) -+ break; -+ info->curr_node = rb_get_first(&info->root); -+ } -+ -+ fname = rb_entry(info->curr_node, struct fname, rb_hash); -+ info->curr_hash = fname->hash; -+ info->curr_minor_hash = fname->minor_hash; -+ if (call_filldir(filp, dirent, filldir, fname)) -+ break; -+ -+ info->curr_node = rb_get_next(info->curr_node); -+ if (!info->curr_node) { -+ info->curr_hash = info->next_hash; -+ info->curr_minor_hash = 0; -+ } -+ } -+finished: -+ info->last_pos = filp->f_pos; -+ UPDATE_ATIME(inode); -+ return 0; -+} -+#endif ---- linux-2.4.22-ac1/fs/ext3/file.c~ext3-htree-2.4.22-rh 2003-08-25 15:44:43.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/ext3/file.c 2003-09-25 14:55:12.000000000 +0400 -@@ -35,6 +35,9 @@ static int ext3_release_file (struct ino - { - if (filp->f_mode & FMODE_WRITE) - ext3_discard_prealloc (inode); -+ if (is_dx(inode) && filp->private_data) -+ ext3_htree_free_dir_info(filp->private_data); -+ - return 0; - } - ---- /dev/null 2003-01-30 13:24:37.000000000 +0300 -+++ linux-2.4.22-ac1-alexey/fs/ext3/hash.c 2003-09-25 14:55:12.000000000 +0400 -@@ -0,0 +1,215 @@ -+/* -+ * linux/fs/ext3/hash.c -+ * -+ * Copyright (C) 2002 by Theodore Ts'o -+ * -+ * This file is released under the GPL v2. -+ * -+ * This file may be redistributed under the terms of the GNU Public -+ * License. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#define DELTA 0x9E3779B9 -+ -+static void TEA_transform(__u32 buf[4], __u32 const in[]) -+{ -+ __u32 sum = 0; -+ __u32 b0 = buf[0], b1 = buf[1]; -+ __u32 a = in[0], b = in[1], c = in[2], d = in[3]; -+ int n = 16; -+ -+ do { -+ sum += DELTA; -+ b0 += ((b1 << 4)+a) ^ (b1+sum) ^ ((b1 >> 5)+b); -+ b1 += ((b0 << 4)+c) ^ (b0+sum) ^ ((b0 >> 5)+d); -+ } while(--n); -+ -+ buf[0] += b0; -+ buf[1] += b1; -+} -+ -+/* F, G and H are basic MD4 functions: selection, majority, parity */ -+#define F(x, y, z) ((z) ^ ((x) & ((y) ^ (z)))) -+#define G(x, y, z) (((x) & (y)) + (((x) ^ (y)) & (z))) -+#define H(x, y, z) ((x) ^ (y) ^ (z)) -+ -+/* -+ * The generic round function. The application is so specific that -+ * we don't bother protecting all the arguments with parens, as is generally -+ * good macro practice, in favor of extra legibility. -+ * Rotation is separate from addition to prevent recomputation -+ */ -+#define ROUND(f, a, b, c, d, x, s) \ -+ (a += f(b, c, d) + x, a = (a << s) | (a >> (32-s))) -+#define K1 0 -+#define K2 013240474631UL -+#define K3 015666365641UL -+ -+/* -+ * Basic cut-down MD4 transform. Returns only 32 bits of result. -+ */ -+static void halfMD4Transform (__u32 buf[4], __u32 const in[]) -+{ -+ __u32 a = buf[0], b = buf[1], c = buf[2], d = buf[3]; -+ -+ /* Round 1 */ -+ ROUND(F, a, b, c, d, in[0] + K1, 3); -+ ROUND(F, d, a, b, c, in[1] + K1, 7); -+ ROUND(F, c, d, a, b, in[2] + K1, 11); -+ ROUND(F, b, c, d, a, in[3] + K1, 19); -+ ROUND(F, a, b, c, d, in[4] + K1, 3); -+ ROUND(F, d, a, b, c, in[5] + K1, 7); -+ ROUND(F, c, d, a, b, in[6] + K1, 11); -+ ROUND(F, b, c, d, a, in[7] + K1, 19); -+ -+ /* Round 2 */ -+ ROUND(G, a, b, c, d, in[1] + K2, 3); -+ ROUND(G, d, a, b, c, in[3] + K2, 5); -+ ROUND(G, c, d, a, b, in[5] + K2, 9); -+ ROUND(G, b, c, d, a, in[7] + K2, 13); -+ ROUND(G, a, b, c, d, in[0] + K2, 3); -+ ROUND(G, d, a, b, c, in[2] + K2, 5); -+ ROUND(G, c, d, a, b, in[4] + K2, 9); -+ ROUND(G, b, c, d, a, in[6] + K2, 13); -+ -+ /* Round 3 */ -+ ROUND(H, a, b, c, d, in[3] + K3, 3); -+ ROUND(H, d, a, b, c, in[7] + K3, 9); -+ ROUND(H, c, d, a, b, in[2] + K3, 11); -+ ROUND(H, b, c, d, a, in[6] + K3, 15); -+ ROUND(H, a, b, c, d, in[1] + K3, 3); -+ ROUND(H, d, a, b, c, in[5] + K3, 9); -+ ROUND(H, c, d, a, b, in[0] + K3, 11); -+ ROUND(H, b, c, d, a, in[4] + K3, 15); -+ -+ buf[0] += a; -+ buf[1] += b; -+ buf[2] += c; -+ buf[3] += d; -+} -+ -+#undef ROUND -+#undef F -+#undef G -+#undef H -+#undef K1 -+#undef K2 -+#undef K3 -+ -+/* The old legacy hash */ -+static __u32 dx_hack_hash (const char *name, int len) -+{ -+ __u32 hash0 = 0x12a3fe2d, hash1 = 0x37abe8f9; -+ while (len--) { -+ __u32 hash = hash1 + (hash0 ^ (*name++ * 7152373)); -+ -+ if (hash & 0x80000000) hash -= 0x7fffffff; -+ hash1 = hash0; -+ hash0 = hash; -+ } -+ return (hash0 << 1); -+} -+ -+static void str2hashbuf(const char *msg, int len, __u32 *buf, int num) -+{ -+ __u32 pad, val; -+ int i; -+ -+ pad = (__u32)len | ((__u32)len << 8); -+ pad |= pad << 16; -+ -+ val = pad; -+ if (len > num*4) -+ len = num * 4; -+ for (i=0; i < len; i++) { -+ if ((i % 4) == 0) -+ val = pad; -+ val = msg[i] + (val << 8); -+ if ((i % 4) == 3) { -+ *buf++ = val; -+ val = pad; -+ num--; -+ } -+ } -+ if (--num >= 0) -+ *buf++ = val; -+ while (--num >= 0) -+ *buf++ = pad; -+} -+ -+/* -+ * Returns the hash of a filename. If len is 0 and name is NULL, then -+ * this function can be used to test whether or not a hash version is -+ * supported. -+ * -+ * The seed is an 4 longword (32 bits) "secret" which can be used to -+ * uniquify a hash. If the seed is all zero's, then some default seed -+ * may be used. -+ * -+ * A particular hash version specifies whether or not the seed is -+ * represented, and whether or not the returned hash is 32 bits or 64 -+ * bits. 32 bit hashes will return 0 for the minor hash. -+ */ -+int ext3fs_dirhash(const char *name, int len, struct dx_hash_info *hinfo) -+{ -+ __u32 hash; -+ __u32 minor_hash = 0; -+ const char *p; -+ int i; -+ __u32 in[8], buf[4]; -+ -+ /* Initialize the default seed for the hash checksum functions */ -+ buf[0] = 0x67452301; -+ buf[1] = 0xefcdab89; -+ buf[2] = 0x98badcfe; -+ buf[3] = 0x10325476; -+ -+ /* Check to see if the seed is all zero's */ -+ if (hinfo->seed) { -+ for (i=0; i < 4; i++) { -+ if (hinfo->seed[i]) -+ break; -+ } -+ if (i < 4) -+ memcpy(buf, hinfo->seed, sizeof(buf)); -+ } -+ -+ switch (hinfo->hash_version) { -+ case DX_HASH_LEGACY: -+ hash = dx_hack_hash(name, len); -+ break; -+ case DX_HASH_HALF_MD4: -+ p = name; -+ while (len > 0) { -+ str2hashbuf(p, len, in, 8); -+ halfMD4Transform(buf, in); -+ len -= 32; -+ p += 32; -+ } -+ minor_hash = buf[2]; -+ hash = buf[1]; -+ break; -+ case DX_HASH_TEA: -+ p = name; -+ while (len > 0) { -+ str2hashbuf(p, len, in, 4); -+ TEA_transform(buf, in); -+ len -= 16; -+ p += 16; -+ } -+ hash = buf[0]; -+ minor_hash = buf[1]; -+ break; -+ default: -+ hinfo->hash = 0; -+ return -1; -+ } -+ hinfo->hash = hash & ~1; -+ hinfo->minor_hash = minor_hash; -+ return 0; -+} ---- linux-2.4.22-ac1/fs/ext3/Makefile~ext3-htree-2.4.22-rh 2003-09-25 14:39:01.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/ext3/Makefile 2003-09-25 14:55:12.000000000 +0400 -@@ -12,7 +12,7 @@ O_TARGET := ext3.o - export-objs := super.o inode.o - - obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ -- ioctl.o namei.o super.o symlink.o -+ ioctl.o namei.o super.o symlink.o hash.o - obj-m := $(O_TARGET) - - include $(TOPDIR)/Rules.make ---- linux-2.4.22-ac1/fs/ext3/namei.c~ext3-htree-2.4.22-rh 2003-09-25 14:16:29.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/ext3/namei.c 2003-09-25 14:58:37.000000000 +0400 -@@ -16,6 +16,12 @@ - * David S. Miller (davem@caip.rutgers.edu), 1995 - * Directory entry file type support and forward compatibility hooks - * for B-tree directories by Theodore Ts'o (tytso@mit.edu), 1998 -+ * Hash Tree Directory indexing (c) -+ * Daniel Phillips, 2001 -+ * Hash Tree Directory indexing porting -+ * Christopher Li, 2002 -+ * Hash Tree Directory indexing cleanup -+ * Theodore Ts'o, 2002 - */ - - #include -@@ -38,6 +44,642 @@ - #define NAMEI_RA_SIZE (NAMEI_RA_CHUNKS * NAMEI_RA_BLOCKS) - #define NAMEI_RA_INDEX(c,b) (((c) * NAMEI_RA_BLOCKS) + (b)) - -+static struct buffer_head *ext3_append(handle_t *handle, -+ struct inode *inode, -+ u32 *block, int *err) -+{ -+ struct buffer_head *bh; -+ -+ *block = inode->i_size >> inode->i_sb->s_blocksize_bits; -+ -+ if ((bh = ext3_bread(handle, inode, *block, 1, err))) { -+ inode->i_size += inode->i_sb->s_blocksize; -+ EXT3_I(inode)->i_disksize = inode->i_size; -+ ext3_journal_get_write_access(handle,bh); -+ } -+ return bh; -+} -+ -+#ifndef assert -+#define assert(test) J_ASSERT(test) -+#endif -+ -+#ifndef swap -+#define swap(x, y) do { typeof(x) z = x; x = y; y = z; } while (0) -+#endif -+ -+typedef struct { u32 v; } le_u32; -+typedef struct { u16 v; } le_u16; -+ -+#ifdef DX_DEBUG -+#define dxtrace(command) command -+#else -+#define dxtrace(command) -+#endif -+ -+struct fake_dirent -+{ -+ /*le*/u32 inode; -+ /*le*/u16 rec_len; -+ u8 name_len; -+ u8 file_type; -+}; -+ -+struct dx_countlimit -+{ -+ le_u16 limit; -+ le_u16 count; -+}; -+ -+struct dx_entry -+{ -+ le_u32 hash; -+ le_u32 block; -+}; -+ -+/* -+ * dx_root_info is laid out so that if it should somehow get overlaid by a -+ * dirent the two low bits of the hash version will be zero. Therefore, the -+ * hash version mod 4 should never be 0. Sincerely, the paranoia department. -+ */ -+ -+struct dx_root -+{ -+ struct fake_dirent dot; -+ char dot_name[4]; -+ struct fake_dirent dotdot; -+ char dotdot_name[4]; -+ struct dx_root_info -+ { -+ le_u32 reserved_zero; -+ u8 hash_version; -+ u8 info_length; /* 8 */ -+ u8 indirect_levels; -+ u8 unused_flags; -+ } -+ info; -+ struct dx_entry entries[0]; -+}; -+ -+struct dx_node -+{ -+ struct fake_dirent fake; -+ struct dx_entry entries[0]; -+}; -+ -+ -+struct dx_frame -+{ -+ struct buffer_head *bh; -+ struct dx_entry *entries; -+ struct dx_entry *at; -+}; -+ -+struct dx_map_entry -+{ -+ u32 hash; -+ u32 offs; -+}; -+ -+#ifdef CONFIG_EXT3_INDEX -+static inline unsigned dx_get_block (struct dx_entry *entry); -+static void dx_set_block (struct dx_entry *entry, unsigned value); -+static inline unsigned dx_get_hash (struct dx_entry *entry); -+static void dx_set_hash (struct dx_entry *entry, unsigned value); -+static unsigned dx_get_count (struct dx_entry *entries); -+static unsigned dx_get_limit (struct dx_entry *entries); -+static void dx_set_count (struct dx_entry *entries, unsigned value); -+static void dx_set_limit (struct dx_entry *entries, unsigned value); -+static unsigned dx_root_limit (struct inode *dir, unsigned infosize); -+static unsigned dx_node_limit (struct inode *dir); -+static struct dx_frame *dx_probe(struct dentry *dentry, -+ struct inode *dir, -+ struct dx_hash_info *hinfo, -+ struct dx_frame *frame, -+ int *err); -+static void dx_release (struct dx_frame *frames); -+static int dx_make_map (struct ext3_dir_entry_2 *de, int size, -+ struct dx_hash_info *hinfo, struct dx_map_entry map[]); -+static void dx_sort_map(struct dx_map_entry *map, unsigned count); -+static struct ext3_dir_entry_2 *dx_move_dirents (char *from, char *to, -+ struct dx_map_entry *offsets, int count); -+static struct ext3_dir_entry_2* dx_pack_dirents (char *base, int size); -+static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block); -+static int ext3_htree_next_block(struct inode *dir, __u32 hash, -+ struct dx_frame *frame, -+ struct dx_frame *frames, int *err, -+ __u32 *start_hash); -+static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry, -+ struct ext3_dir_entry_2 **res_dir, int *err); -+static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry, -+ struct inode *inode); -+ -+/* -+ * Future: use high four bits of block for coalesce-on-delete flags -+ * Mask them off for now. -+ */ -+ -+static inline unsigned dx_get_block (struct dx_entry *entry) -+{ -+ return le32_to_cpu(entry->block.v) & 0x00ffffff; -+} -+ -+static inline void dx_set_block (struct dx_entry *entry, unsigned value) -+{ -+ entry->block.v = cpu_to_le32(value); -+} -+ -+static inline unsigned dx_get_hash (struct dx_entry *entry) -+{ -+ return le32_to_cpu(entry->hash.v); -+} -+ -+static inline void dx_set_hash (struct dx_entry *entry, unsigned value) -+{ -+ entry->hash.v = cpu_to_le32(value); -+} -+ -+static inline unsigned dx_get_count (struct dx_entry *entries) -+{ -+ return le16_to_cpu(((struct dx_countlimit *) entries)->count.v); -+} -+ -+static inline unsigned dx_get_limit (struct dx_entry *entries) -+{ -+ return le16_to_cpu(((struct dx_countlimit *) entries)->limit.v); -+} -+ -+static inline void dx_set_count (struct dx_entry *entries, unsigned value) -+{ -+ ((struct dx_countlimit *) entries)->count.v = cpu_to_le16(value); -+} -+ -+static inline void dx_set_limit (struct dx_entry *entries, unsigned value) -+{ -+ ((struct dx_countlimit *) entries)->limit.v = cpu_to_le16(value); -+} -+ -+static inline unsigned dx_root_limit (struct inode *dir, unsigned infosize) -+{ -+ unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(1) - -+ EXT3_DIR_REC_LEN(2) - infosize; -+ return 0? 20: entry_space / sizeof(struct dx_entry); -+} -+ -+static inline unsigned dx_node_limit (struct inode *dir) -+{ -+ unsigned entry_space = dir->i_sb->s_blocksize - EXT3_DIR_REC_LEN(0); -+ return 0? 22: entry_space / sizeof(struct dx_entry); -+} -+ -+/* -+ * Debug -+ */ -+#ifdef DX_DEBUG -+struct stats -+{ -+ unsigned names; -+ unsigned space; -+ unsigned bcount; -+}; -+ -+static struct stats dx_show_leaf(struct dx_hash_info *hinfo, struct ext3_dir_entry_2 *de, -+ int size, int show_names) -+{ -+ unsigned names = 0, space = 0; -+ char *base = (char *) de; -+ struct dx_hash_info h = *hinfo; -+ -+ printk("names: "); -+ while ((char *) de < base + size) -+ { -+ if (de->inode) -+ { -+ if (show_names) -+ { -+ int len = de->name_len; -+ char *name = de->name; -+ while (len--) printk("%c", *name++); -+ ext3fs_dirhash(de->name, de->name_len, &h); -+ printk(":%x.%u ", h.hash, -+ ((char *) de - base)); -+ } -+ space += EXT3_DIR_REC_LEN(de->name_len); -+ names++; -+ } -+ de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len)); -+ } -+ printk("(%i)\n", names); -+ return (struct stats) { names, space, 1 }; -+} -+ -+struct stats dx_show_entries(struct dx_hash_info *hinfo, struct inode *dir, -+ struct dx_entry *entries, int levels) -+{ -+ unsigned blocksize = dir->i_sb->s_blocksize; -+ unsigned count = dx_get_count (entries), names = 0, space = 0, i; -+ unsigned bcount = 0; -+ struct buffer_head *bh; -+ int err; -+ printk("%i indexed blocks...\n", count); -+ for (i = 0; i < count; i++, entries++) -+ { -+ u32 block = dx_get_block(entries), hash = i? dx_get_hash(entries): 0; -+ u32 range = i < count - 1? (dx_get_hash(entries + 1) - hash): ~hash; -+ struct stats stats; -+ printk("%s%3u:%03u hash %8x/%8x ",levels?"":" ", i, block, hash, range); -+ if (!(bh = ext3_bread (NULL,dir, block, 0,&err))) continue; -+ stats = levels? -+ dx_show_entries(hinfo, dir, ((struct dx_node *) bh->b_data)->entries, levels - 1): -+ dx_show_leaf(hinfo, (struct ext3_dir_entry_2 *) bh->b_data, blocksize, 0); -+ names += stats.names; -+ space += stats.space; -+ bcount += stats.bcount; -+ brelse (bh); -+ } -+ if (bcount) -+ printk("%snames %u, fullness %u (%u%%)\n", levels?"":" ", -+ names, space/bcount,(space/bcount)*100/blocksize); -+ return (struct stats) { names, space, bcount}; -+} -+#endif /* DX_DEBUG */ -+ -+/* -+ * Probe for a directory leaf block to search. -+ * -+ * dx_probe can return ERR_BAD_DX_DIR, which means there was a format -+ * error in the directory index, and the caller should fall back to -+ * searching the directory normally. The callers of dx_probe **MUST** -+ * check for this error code, and make sure it never gets reflected -+ * back to userspace. -+ */ -+static struct dx_frame * -+dx_probe(struct dentry *dentry, struct inode *dir, -+ struct dx_hash_info *hinfo, struct dx_frame *frame_in, int *err) -+{ -+ unsigned count, indirect; -+ struct dx_entry *at, *entries, *p, *q, *m; -+ struct dx_root *root; -+ struct buffer_head *bh; -+ struct dx_frame *frame = frame_in; -+ u32 hash; -+ -+ frame->bh = NULL; -+ if (dentry) -+ dir = dentry->d_parent->d_inode; -+ if (!(bh = ext3_bread (NULL,dir, 0, 0, err))) -+ goto fail; -+ root = (struct dx_root *) bh->b_data; -+ if (root->info.hash_version != DX_HASH_TEA && -+ root->info.hash_version != DX_HASH_HALF_MD4 && -+ root->info.hash_version != DX_HASH_LEGACY) { -+ ext3_warning(dir->i_sb, __FUNCTION__, -+ "Unrecognised inode hash code %d", -+ root->info.hash_version); -+ brelse(bh); -+ *err = ERR_BAD_DX_DIR; -+ goto fail; -+ } -+ hinfo->hash_version = root->info.hash_version; -+ hinfo->seed = dir->i_sb->u.ext3_sb.s_hash_seed; -+ if (dentry) -+ ext3fs_dirhash(dentry->d_name.name, dentry->d_name.len, hinfo); -+ hash = hinfo->hash; -+ -+ if (root->info.unused_flags & 1) { -+ ext3_warning(dir->i_sb, __FUNCTION__, -+ "Unimplemented inode hash flags: %#06x", -+ root->info.unused_flags); -+ brelse(bh); -+ *err = ERR_BAD_DX_DIR; -+ goto fail; -+ } -+ -+ if ((indirect = root->info.indirect_levels) > 1) { -+ ext3_warning(dir->i_sb, __FUNCTION__, -+ "Unimplemented inode hash depth: %#06x", -+ root->info.indirect_levels); -+ brelse(bh); -+ *err = ERR_BAD_DX_DIR; -+ goto fail; -+ } -+ -+ entries = (struct dx_entry *) (((char *)&root->info) + -+ root->info.info_length); -+ assert(dx_get_limit(entries) == dx_root_limit(dir, -+ root->info.info_length)); -+ dxtrace (printk("Look up %x", hash)); -+ while (1) -+ { -+ count = dx_get_count(entries); -+ assert (count && count <= dx_get_limit(entries)); -+ p = entries + 1; -+ q = entries + count - 1; -+ while (p <= q) -+ { -+ m = p + (q - p)/2; -+ dxtrace(printk(".")); -+ if (dx_get_hash(m) > hash) -+ q = m - 1; -+ else -+ p = m + 1; -+ } -+ -+ if (0) // linear search cross check -+ { -+ unsigned n = count - 1; -+ at = entries; -+ while (n--) -+ { -+ dxtrace(printk(",")); -+ if (dx_get_hash(++at) > hash) -+ { -+ at--; -+ break; -+ } -+ } -+ assert (at == p - 1); -+ } -+ -+ at = p - 1; -+ dxtrace(printk(" %x->%u\n", at == entries? 0: dx_get_hash(at), dx_get_block(at))); -+ frame->bh = bh; -+ frame->entries = entries; -+ frame->at = at; -+ if (!indirect--) return frame; -+ if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0, err))) -+ goto fail2; -+ at = entries = ((struct dx_node *) bh->b_data)->entries; -+ assert (dx_get_limit(entries) == dx_node_limit (dir)); -+ frame++; -+ } -+fail2: -+ while (frame >= frame_in) { -+ brelse(frame->bh); -+ frame--; -+ } -+fail: -+ return NULL; -+} -+ -+static void dx_release (struct dx_frame *frames) -+{ -+ if (frames[0].bh == NULL) -+ return; -+ -+ if (((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels) -+ brelse(frames[1].bh); -+ brelse(frames[0].bh); -+} -+ -+/* -+ * This function increments the frame pointer to search the next leaf -+ * block, and reads in the necessary intervening nodes if the search -+ * should be necessary. Whether or not the search is necessary is -+ * controlled by the hash parameter. If the hash value is even, then -+ * the search is only continued if the next block starts with that -+ * hash value. This is used if we are searching for a specific file. -+ * -+ * If the hash value is HASH_NB_ALWAYS, then always go to the next block. -+ * -+ * This function returns 1 if the caller should continue to search, -+ * or 0 if it should not. If there is an error reading one of the -+ * index blocks, it will return -1. -+ * -+ * If start_hash is non-null, it will be filled in with the starting -+ * hash of the next page. -+ */ -+static int ext3_htree_next_block(struct inode *dir, __u32 hash, -+ struct dx_frame *frame, -+ struct dx_frame *frames, int *err, -+ __u32 *start_hash) -+{ -+ struct dx_frame *p; -+ struct buffer_head *bh; -+ int num_frames = 0; -+ __u32 bhash; -+ -+ *err = ENOENT; -+ p = frame; -+ /* -+ * Find the next leaf page by incrementing the frame pointer. -+ * If we run out of entries in the interior node, loop around and -+ * increment pointer in the parent node. When we break out of -+ * this loop, num_frames indicates the number of interior -+ * nodes need to be read. -+ */ -+ while (1) { -+ if (++(p->at) < p->entries + dx_get_count(p->entries)) -+ break; -+ if (p == frames) -+ return 0; -+ num_frames++; -+ p--; -+ } -+ -+ /* -+ * If the hash is 1, then continue only if the next page has a -+ * continuation hash of any value. This is used for readdir -+ * handling. Otherwise, check to see if the hash matches the -+ * desired contiuation hash. If it doesn't, return since -+ * there's no point to read in the successive index pages. -+ */ -+ bhash = dx_get_hash(p->at); -+ if (start_hash) -+ *start_hash = bhash; -+ if ((hash & 1) == 0) { -+ if ((bhash & ~1) != hash) -+ return 0; -+ } -+ /* -+ * If the hash is HASH_NB_ALWAYS, we always go to the next -+ * block so no check is necessary -+ */ -+ while (num_frames--) { -+ if (!(bh = ext3_bread(NULL, dir, dx_get_block(p->at), -+ 0, err))) -+ return -1; /* Failure */ -+ p++; -+ brelse (p->bh); -+ p->bh = bh; -+ p->at = p->entries = ((struct dx_node *) bh->b_data)->entries; -+ } -+ return 1; -+} -+ -+ -+/* -+ * p is at least 6 bytes before the end of page -+ */ -+static inline struct ext3_dir_entry_2 *ext3_next_entry(struct ext3_dir_entry_2 *p) -+{ -+ return (struct ext3_dir_entry_2 *)((char*)p + le16_to_cpu(p->rec_len)); -+} -+ -+/* -+ * This function fills a red-black tree with information from a -+ * directory. We start scanning the directory in hash order, starting -+ * at start_hash and start_minor_hash. -+ * -+ * This function returns the number of entries inserted into the tree, -+ * or a negative error code. -+ */ -+int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash, -+ __u32 start_minor_hash, __u32 *next_hash) -+{ -+ struct dx_hash_info hinfo; -+ struct buffer_head *bh; -+ struct ext3_dir_entry_2 *de, *top; -+ static struct dx_frame frames[2], *frame; -+ struct inode *dir; -+ int block, err; -+ int count = 0; -+ int ret; -+ __u32 hashval; -+ -+ dxtrace(printk("In htree_fill_tree, start hash: %x:%x\n", start_hash, -+ start_minor_hash)); -+ dir = dir_file->f_dentry->d_inode; -+ hinfo.hash = start_hash; -+ hinfo.minor_hash = 0; -+ frame = dx_probe(0, dir_file->f_dentry->d_inode, &hinfo, frames, &err); -+ if (!frame) -+ return err; -+ -+ /* Add '.' and '..' from the htree header */ -+ if (!start_hash && !start_minor_hash) { -+ de = (struct ext3_dir_entry_2 *) frames[0].bh->b_data; -+ if ((err = ext3_htree_store_dirent(dir_file, 0, 0, de)) != 0) -+ goto errout; -+ de = ext3_next_entry(de); -+ if ((err = ext3_htree_store_dirent(dir_file, 0, 0, de)) != 0) -+ goto errout; -+ count += 2; -+ } -+ -+ while (1) { -+ block = dx_get_block(frame->at); -+ dxtrace(printk("Reading block %d\n", block)); -+ if (!(bh = ext3_bread (NULL, dir, block, 0, &err))) -+ goto errout; -+ -+ de = (struct ext3_dir_entry_2 *) bh->b_data; -+ top = (struct ext3_dir_entry_2 *) ((char *) de + dir->i_sb->s_blocksize - -+ EXT3_DIR_REC_LEN(0)); -+ for (; de < top; de = ext3_next_entry(de)) { -+ ext3fs_dirhash(de->name, de->name_len, &hinfo); -+ if ((hinfo.hash < start_hash) || -+ ((hinfo.hash == start_hash) && -+ (hinfo.minor_hash < start_minor_hash))) -+ continue; -+ if ((err = ext3_htree_store_dirent(dir_file, -+ hinfo.hash, hinfo.minor_hash, de)) != 0) -+ goto errout; -+ count++; -+ } -+ brelse (bh); -+ hashval = ~1; -+ ret = ext3_htree_next_block(dir, HASH_NB_ALWAYS, -+ frame, frames, &err, &hashval); -+ if (next_hash) -+ *next_hash = hashval; -+ if (ret == -1) -+ goto errout; -+ /* -+ * Stop if: (a) there are no more entries, or -+ * (b) we have inserted at least one entry and the -+ * next hash value is not a continuation -+ */ -+ if ((ret == 0) || -+ (count && ((hashval & 1) == 0))) -+ break; -+ } -+ dx_release(frames); -+ dxtrace(printk("Fill tree: returned %d entries\n", count)); -+ return count; -+errout: -+ dx_release(frames); -+ return (err); -+} -+ -+ -+/* -+ * Directory block splitting, compacting -+ */ -+ -+static int dx_make_map (struct ext3_dir_entry_2 *de, int size, -+ struct dx_hash_info *hinfo, struct dx_map_entry *map_tail) -+{ -+ int count = 0; -+ char *base = (char *) de; -+ struct dx_hash_info h = *hinfo; -+ -+ while ((char *) de < base + size) -+ { -+ if (de->name_len && de->inode) { -+ ext3fs_dirhash(de->name, de->name_len, &h); -+ map_tail--; -+ map_tail->hash = h.hash; -+ map_tail->offs = (u32) ((char *) de - base); -+ count++; -+ } -+ /* XXX: do we need to check rec_len == 0 case? -Chris */ -+ de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len)); -+ } -+ return count; -+} -+ -+static void dx_sort_map (struct dx_map_entry *map, unsigned count) -+{ -+ struct dx_map_entry *p, *q, *top = map + count - 1; -+ int more; -+ /* Combsort until bubble sort doesn't suck */ -+ while (count > 2) -+ { -+ count = count*10/13; -+ if (count - 9 < 2) /* 9, 10 -> 11 */ -+ count = 11; -+ for (p = top, q = p - count; q >= map; p--, q--) -+ if (p->hash < q->hash) -+ swap(*p, *q); -+ } -+ /* Garden variety bubble sort */ -+ do { -+ more = 0; -+ q = top; -+ while (q-- > map) -+ { -+ if (q[1].hash >= q[0].hash) -+ continue; -+ swap(*(q+1), *q); -+ more = 1; -+ } -+ } while(more); -+} -+ -+static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block) -+{ -+ struct dx_entry *entries = frame->entries; -+ struct dx_entry *old = frame->at, *new = old + 1; -+ int count = dx_get_count(entries); -+ -+ assert(count < dx_get_limit(entries)); -+ assert(old < entries + count); -+ memmove(new + 1, new, (char *)(entries + count) - (char *)(new)); -+ dx_set_hash(new, hash); -+ dx_set_block(new, block); -+ dx_set_count(entries, count + 1); -+} -+#endif -+ -+ -+static void ext3_update_dx_flag(struct inode *inode) -+{ -+ if (!EXT3_HAS_COMPAT_FEATURE(inode->i_sb, -+ EXT3_FEATURE_COMPAT_DIR_INDEX)) -+ EXT3_I(inode)->i_flags &= ~EXT3_INDEX_FL; -+} -+ - /* - * NOTE! unlike strncmp, ext3_match returns 1 for success, 0 for failure. - * -@@ -94,6 +736,7 @@ static int inline search_dirblock(struct - return 0; - } - -+ - /* - * ext3_find_entry() - * -@@ -105,6 +748,8 @@ static int inline search_dirblock(struct - * The returned buffer_head has ->b_count elevated. The caller is expected - * to brelse() it when appropriate. - */ -+ -+ - static struct buffer_head * ext3_find_entry (struct dentry *dentry, - struct ext3_dir_entry_2 ** res_dir) - { -@@ -119,12 +764,32 @@ static struct buffer_head * ext3_find_en - int num = 0; - int nblocks, i, err; - struct inode *dir = dentry->d_parent->d_inode; -+ int namelen; -+ const u8 *name; -+ unsigned blocksize; - - *res_dir = NULL; - sb = dir->i_sb; -- -+ blocksize = sb->s_blocksize; -+ namelen = dentry->d_name.len; -+ name = dentry->d_name.name; -+ if (namelen > EXT3_NAME_LEN) -+ return NULL; -+#ifdef CONFIG_EXT3_INDEX -+ if (is_dx(dir)) { -+ bh = ext3_dx_find_entry(dentry, res_dir, &err); -+ /* -+ * On success, or if the error was file not found, -+ * return. Otherwise, fall back to doing a search the -+ * old fashioned way. -+ */ -+ if (bh || (err != ERR_BAD_DX_DIR)) -+ return bh; -+ dxtrace(printk("ext3_find_entry: dx failed, falling back\n")); -+ } -+#endif - nblocks = dir->i_size >> EXT3_BLOCK_SIZE_BITS(sb); -- start = dir->u.ext3_i.i_dir_start_lookup; -+ start = EXT3_I(dir)->i_dir_start_lookup; - if (start >= nblocks) - start = 0; - block = start; -@@ -166,7 +831,7 @@ restart: - i = search_dirblock(bh, dir, dentry, - block << EXT3_BLOCK_SIZE_BITS(sb), res_dir); - if (i == 1) { -- dir->u.ext3_i.i_dir_start_lookup = block; -+ EXT3_I(dir)->i_dir_start_lookup = block; - ret = bh; - goto cleanup_and_exit; - } else { -@@ -197,6 +862,66 @@ cleanup_and_exit: - return ret; - } - -+#ifdef CONFIG_EXT3_INDEX -+static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry, -+ struct ext3_dir_entry_2 **res_dir, int *err) -+{ -+ struct super_block * sb; -+ struct dx_hash_info hinfo; -+ u32 hash; -+ struct dx_frame frames[2], *frame; -+ struct ext3_dir_entry_2 *de, *top; -+ struct buffer_head *bh; -+ unsigned long block; -+ int retval; -+ int namelen = dentry->d_name.len; -+ const u8 *name = dentry->d_name.name; -+ struct inode *dir = dentry->d_parent->d_inode; -+ -+ sb = dir->i_sb; -+ if (!(frame = dx_probe (dentry, 0, &hinfo, frames, err))) -+ return NULL; -+ hash = hinfo.hash; -+ do { -+ block = dx_get_block(frame->at); -+ if (!(bh = ext3_bread (NULL,dir, block, 0, err))) -+ goto errout; -+ de = (struct ext3_dir_entry_2 *) bh->b_data; -+ top = (struct ext3_dir_entry_2 *) ((char *) de + sb->s_blocksize - -+ EXT3_DIR_REC_LEN(0)); -+ for (; de < top; de = ext3_next_entry(de)) -+ if (ext3_match (namelen, name, de)) { -+ if (!ext3_check_dir_entry("ext3_find_entry", -+ dir, de, bh, -+ (block<b_data))) { -+ brelse (bh); -+ goto errout; -+ } -+ *res_dir = de; -+ dx_release (frames); -+ return bh; -+ } -+ brelse (bh); -+ /* Check to see if we should continue to search */ -+ retval = ext3_htree_next_block(dir, hash, frame, -+ frames, err, 0); -+ if (retval == -1) { -+ ext3_warning(sb, __FUNCTION__, -+ "error reading index page in directory #%lu", -+ dir->i_ino); -+ goto errout; -+ } -+ } while (retval == 1); -+ -+ *err = -ENOENT; -+errout: -+ dxtrace(printk("%s not found\n", name)); -+ dx_release (frames); -+ return NULL; -+} -+#endif -+ - static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry) - { - struct inode * inode; -@@ -213,8 +938,9 @@ static struct dentry *ext3_lookup(struct - brelse (bh); - inode = iget(dir->i_sb, ino); - -- if (!inode) -+ if (!inode) { - return ERR_PTR(-EACCES); -+ } - } - d_add(dentry, inode); - return NULL; -@@ -238,6 +964,301 @@ static inline void ext3_set_de_type(stru - de->file_type = ext3_type_by_mode[(mode & S_IFMT)>>S_SHIFT]; - } - -+#ifdef CONFIG_EXT3_INDEX -+static struct ext3_dir_entry_2 * -+dx_move_dirents(char *from, char *to, struct dx_map_entry *map, int count) -+{ -+ unsigned rec_len = 0; -+ -+ while (count--) { -+ struct ext3_dir_entry_2 *de = (struct ext3_dir_entry_2 *) (from + map->offs); -+ rec_len = EXT3_DIR_REC_LEN(de->name_len); -+ memcpy (to, de, rec_len); -+ ((struct ext3_dir_entry_2 *)to)->rec_len = cpu_to_le16(rec_len); -+ de->inode = 0; -+ map++; -+ to += rec_len; -+ } -+ return (struct ext3_dir_entry_2 *) (to - rec_len); -+} -+ -+static struct ext3_dir_entry_2* dx_pack_dirents(char *base, int size) -+{ -+ struct ext3_dir_entry_2 *next, *to, *prev, *de = (struct ext3_dir_entry_2 *) base; -+ unsigned rec_len = 0; -+ -+ prev = to = de; -+ while ((char*)de < base + size) { -+ next = (struct ext3_dir_entry_2 *) ((char *) de + -+ le16_to_cpu(de->rec_len)); -+ if (de->inode && de->name_len) { -+ rec_len = EXT3_DIR_REC_LEN(de->name_len); -+ if (de > to) -+ memmove(to, de, rec_len); -+ to->rec_len = cpu_to_le16(rec_len); -+ prev = to; -+ to = (struct ext3_dir_entry_2 *)((char *)to + rec_len); -+ } -+ de = next; -+ } -+ return prev; -+} -+ -+static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir, -+ struct buffer_head **bh,struct dx_frame *frame, -+ struct dx_hash_info *hinfo, int *error) -+{ -+ unsigned blocksize = dir->i_sb->s_blocksize; -+ unsigned count, continued; -+ struct buffer_head *bh2; -+ u32 newblock; -+ u32 hash2; -+ struct dx_map_entry *map; -+ char *data1 = (*bh)->b_data, *data2; -+ unsigned split; -+ struct ext3_dir_entry_2 *de = NULL, *de2; -+ int err; -+ -+ bh2 = ext3_append (handle, dir, &newblock, error); -+ if (!(bh2)) { -+ brelse(*bh); -+ *bh = NULL; -+ goto errout; -+ } -+ -+ BUFFER_TRACE(*bh, "get_write_access"); -+ err = ext3_journal_get_write_access(handle, *bh); -+ if (err) { -+ journal_error: -+ brelse(*bh); -+ brelse(bh2); -+ *bh = NULL; -+ ext3_std_error(dir->i_sb, err); -+ goto errout; -+ } -+ BUFFER_TRACE(frame->bh, "get_write_access"); -+ err = ext3_journal_get_write_access(handle, frame->bh); -+ if (err) -+ goto journal_error; -+ -+ data2 = bh2->b_data; -+ -+ /* create map in the end of data2 block */ -+ map = (struct dx_map_entry *) (data2 + blocksize); -+ count = dx_make_map ((struct ext3_dir_entry_2 *) data1, -+ blocksize, hinfo, map); -+ map -= count; -+ split = count/2; // need to adjust to actual middle -+ dx_sort_map (map, count); -+ hash2 = map[split].hash; -+ continued = hash2 == map[split - 1].hash; -+ dxtrace(printk("Split block %i at %x, %i/%i\n", -+ dx_get_block(frame->at), hash2, split, count-split)); -+ -+ /* Fancy dance to stay within two buffers */ -+ de2 = dx_move_dirents(data1, data2, map + split, count - split); -+ de = dx_pack_dirents(data1,blocksize); -+ de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de); -+ de2->rec_len = cpu_to_le16(data2 + blocksize - (char *) de2); -+ dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data1, blocksize, 1)); -+ dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data2, blocksize, 1)); -+ -+ /* Which block gets the new entry? */ -+ if (hinfo->hash >= hash2) -+ { -+ swap(*bh, bh2); -+ de = de2; -+ } -+ dx_insert_block (frame, hash2 + continued, newblock); -+ err = ext3_journal_dirty_metadata (handle, bh2); -+ if (err) -+ goto journal_error; -+ err = ext3_journal_dirty_metadata (handle, frame->bh); -+ if (err) -+ goto journal_error; -+ brelse (bh2); -+ dxtrace(dx_show_index ("frame", frame->entries)); -+errout: -+ return de; -+} -+#endif -+ -+ -+/* -+ * Add a new entry into a directory (leaf) block. If de is non-NULL, -+ * it points to a directory entry which is guaranteed to be large -+ * enough for new directory entry. If de is NULL, then -+ * add_dirent_to_buf will attempt search the directory block for -+ * space. It will return -ENOSPC if no space is available, and -EIO -+ * and -EEXIST if directory entry already exists. -+ * -+ * NOTE! bh is NOT released in the case where ENOSPC is returned. In -+ * all other cases bh is released. -+ */ -+static int add_dirent_to_buf(handle_t *handle, struct dentry *dentry, -+ struct inode *inode, struct ext3_dir_entry_2 *de, -+ struct buffer_head * bh) -+{ -+ struct inode *dir = dentry->d_parent->d_inode; -+ const char *name = dentry->d_name.name; -+ int namelen = dentry->d_name.len; -+ unsigned long offset = 0; -+ unsigned short reclen; -+ int nlen, rlen, err; -+ char *top; -+ -+ reclen = EXT3_DIR_REC_LEN(namelen); -+ if (!de) { -+ de = (struct ext3_dir_entry_2 *)bh->b_data; -+ top = bh->b_data + dir->i_sb->s_blocksize - reclen; -+ while ((char *) de <= top) { -+ if (!ext3_check_dir_entry("ext3_add_entry", dir, de, -+ bh, offset)) { -+ brelse (bh); -+ return -EIO; -+ } -+ if (ext3_match (namelen, name, de)) { -+ brelse (bh); -+ return -EEXIST; -+ } -+ nlen = EXT3_DIR_REC_LEN(de->name_len); -+ rlen = le16_to_cpu(de->rec_len); -+ if ((de->inode? rlen - nlen: rlen) >= reclen) -+ break; -+ de = (struct ext3_dir_entry_2 *)((char *)de + rlen); -+ offset += rlen; -+ } -+ if ((char *) de > top) -+ return -ENOSPC; -+ } -+ BUFFER_TRACE(bh, "get_write_access"); -+ err = ext3_journal_get_write_access(handle, bh); -+ if (err) { -+ ext3_std_error(dir->i_sb, err); -+ brelse(bh); -+ return err; -+ } -+ -+ /* By now the buffer is marked for journaling */ -+ nlen = EXT3_DIR_REC_LEN(de->name_len); -+ rlen = le16_to_cpu(de->rec_len); -+ if (de->inode) { -+ struct ext3_dir_entry_2 *de1 = (struct ext3_dir_entry_2 *)((char *)de + nlen); -+ de1->rec_len = cpu_to_le16(rlen - nlen); -+ de->rec_len = cpu_to_le16(nlen); -+ de = de1; -+ } -+ de->file_type = EXT3_FT_UNKNOWN; -+ if (inode) { -+ de->inode = cpu_to_le32(inode->i_ino); -+ ext3_set_de_type(dir->i_sb, de, inode->i_mode); -+ } else -+ de->inode = 0; -+ de->name_len = namelen; -+ memcpy (de->name, name, namelen); -+ /* -+ * XXX shouldn't update any times until successful -+ * completion of syscall, but too many callers depend -+ * on this. -+ * -+ * XXX similarly, too many callers depend on -+ * ext3_new_inode() setting the times, but error -+ * recovery deletes the inode, so the worst that can -+ * happen is that the times are slightly out of date -+ * and/or different from the directory change time. -+ */ -+ dir->i_mtime = dir->i_ctime = CURRENT_TIME; -+ ext3_update_dx_flag(dir); -+ dir->i_version = ++event; -+ ext3_mark_inode_dirty(handle, dir); -+ BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); -+ err = ext3_journal_dirty_metadata(handle, bh); -+ if (err) -+ ext3_std_error(dir->i_sb, err); -+ brelse(bh); -+ return 0; -+} -+ -+#ifdef CONFIG_EXT3_INDEX -+/* -+ * This converts a one block unindexed directory to a 3 block indexed -+ * directory, and adds the dentry to the indexed directory. -+ */ -+static int make_indexed_dir(handle_t *handle, struct dentry *dentry, -+ struct inode *inode, struct buffer_head *bh) -+{ -+ struct inode *dir = dentry->d_parent->d_inode; -+ const char *name = dentry->d_name.name; -+ int namelen = dentry->d_name.len; -+ struct buffer_head *bh2; -+ struct dx_root *root; -+ struct dx_frame frames[2], *frame; -+ struct dx_entry *entries; -+ struct ext3_dir_entry_2 *de, *de2; -+ char *data1, *top; -+ unsigned len; -+ int retval; -+ unsigned blocksize; -+ struct dx_hash_info hinfo; -+ u32 block; -+ -+ blocksize = dir->i_sb->s_blocksize; -+ dxtrace(printk("Creating index\n")); -+ retval = ext3_journal_get_write_access(handle, bh); -+ if (retval) { -+ ext3_std_error(dir->i_sb, retval); -+ brelse(bh); -+ return retval; -+ } -+ root = (struct dx_root *) bh->b_data; -+ -+ EXT3_I(dir)->i_flags |= EXT3_INDEX_FL; -+ bh2 = ext3_append (handle, dir, &block, &retval); -+ if (!(bh2)) { -+ brelse(bh); -+ return retval; -+ } -+ data1 = bh2->b_data; -+ -+ /* The 0th block becomes the root, move the dirents out */ -+ de = (struct ext3_dir_entry_2 *)&root->dotdot; -+ de = (struct ext3_dir_entry_2 *)((char *)de + le16_to_cpu(de->rec_len)); -+ len = ((char *) root) + blocksize - (char *) de; -+ memcpy (data1, de, len); -+ de = (struct ext3_dir_entry_2 *) data1; -+ top = data1 + len; -+ while (((char *) de2=(char*)de+le16_to_cpu(de->rec_len)) < top) -+ de = de2; -+ de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de); -+ /* Initialize the root; the dot dirents already exist */ -+ de = (struct ext3_dir_entry_2 *) (&root->dotdot); -+ de->rec_len = cpu_to_le16(blocksize - EXT3_DIR_REC_LEN(2)); -+ memset (&root->info, 0, sizeof(root->info)); -+ root->info.info_length = sizeof(root->info); -+ root->info.hash_version = dir->i_sb->u.ext3_sb.s_def_hash_version; -+ entries = root->entries; -+ dx_set_block (entries, 1); -+ dx_set_count (entries, 1); -+ dx_set_limit (entries, dx_root_limit(dir, sizeof(root->info))); -+ -+ /* Initialize as for dx_probe */ -+ hinfo.hash_version = root->info.hash_version; -+ hinfo.seed = dir->i_sb->u.ext3_sb.s_hash_seed; -+ ext3fs_dirhash(name, namelen, &hinfo); -+ frame = frames; -+ frame->entries = entries; -+ frame->at = entries; -+ frame->bh = bh; -+ bh = bh2; -+ de = do_split(handle,dir, &bh, frame, &hinfo, &retval); -+ dx_release (frames); -+ if (!(de)) -+ return retval; -+ -+ return add_dirent_to_buf(handle, dentry, inode, de, bh); -+} -+#endif -+ - /* - * ext3_add_entry() - * -@@ -248,127 +1269,198 @@ static inline void ext3_set_de_type(stru - * may not sleep between calling this and putting something into - * the entry, as someone else might have used it while you slept. - */ -- --/* -- * AKPM: the journalling code here looks wrong on the error paths -- */ - static int ext3_add_entry (handle_t *handle, struct dentry *dentry, - struct inode *inode) - { - struct inode *dir = dentry->d_parent->d_inode; -- const char *name = dentry->d_name.name; -- int namelen = dentry->d_name.len; - unsigned long offset; -- unsigned short rec_len; - struct buffer_head * bh; -- struct ext3_dir_entry_2 * de, * de1; -+ struct ext3_dir_entry_2 *de; - struct super_block * sb; - int retval; -+#ifdef CONFIG_EXT3_INDEX -+ int dx_fallback=0; -+#endif -+ unsigned blocksize; -+ unsigned nlen, rlen; -+ u32 block, blocks; - - sb = dir->i_sb; -- -- if (!namelen) -+ blocksize = sb->s_blocksize; -+ if (!dentry->d_name.len) - return -EINVAL; -- bh = ext3_bread (handle, dir, 0, 0, &retval); -+#ifdef CONFIG_EXT3_INDEX -+ if (is_dx(dir)) { -+ retval = ext3_dx_add_entry(handle, dentry, inode); -+ if (!retval || (retval != ERR_BAD_DX_DIR)) -+ return retval; -+ EXT3_I(dir)->i_flags &= ~EXT3_INDEX_FL; -+ dx_fallback++; -+ ext3_mark_inode_dirty(handle, dir); -+ } -+#endif -+ blocks = dir->i_size >> sb->s_blocksize_bits; -+ for (block = 0, offset = 0; block < blocks; block++) { -+ bh = ext3_bread(handle, dir, block, 0, &retval); -+ if(!bh) -+ return retval; -+ retval = add_dirent_to_buf(handle, dentry, inode, 0, bh); -+ if (retval != -ENOSPC) -+ return retval; -+ -+#ifdef CONFIG_EXT3_INDEX -+ if (blocks == 1 && !dx_fallback && -+ EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX)) -+ return make_indexed_dir(handle, dentry, inode, bh); -+#endif -+ brelse(bh); -+ } -+ bh = ext3_append(handle, dir, &block, &retval); - if (!bh) - return retval; -- rec_len = EXT3_DIR_REC_LEN(namelen); -- offset = 0; - de = (struct ext3_dir_entry_2 *) bh->b_data; -- while (1) { -- if ((char *)de >= sb->s_blocksize + bh->b_data) { -- brelse (bh); -- bh = NULL; -- bh = ext3_bread (handle, dir, -- offset >> EXT3_BLOCK_SIZE_BITS(sb), 1, &retval); -- if (!bh) -- return retval; -- if (dir->i_size <= offset) { -- if (dir->i_size == 0) { -- brelse(bh); -- return -ENOENT; -- } -+ de->inode = 0; -+ de->rec_len = cpu_to_le16(rlen = blocksize); -+ nlen = 0; -+ return add_dirent_to_buf(handle, dentry, inode, de, bh); -+} - -- ext3_debug ("creating next block\n"); -+#ifdef CONFIG_EXT3_INDEX -+/* -+ * Returns 0 for success, or a negative error value -+ */ -+static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry, -+ struct inode *inode) -+{ -+ struct dx_frame frames[2], *frame; -+ struct dx_entry *entries, *at; -+ struct dx_hash_info hinfo; -+ struct buffer_head * bh; -+ struct inode *dir = dentry->d_parent->d_inode; -+ struct super_block * sb = dir->i_sb; -+ struct ext3_dir_entry_2 *de; -+ int err; - -- BUFFER_TRACE(bh, "get_write_access"); -- ext3_journal_get_write_access(handle, bh); -- de = (struct ext3_dir_entry_2 *) bh->b_data; -- de->inode = 0; -- de->rec_len = le16_to_cpu(sb->s_blocksize); -- dir->u.ext3_i.i_disksize = -- dir->i_size = offset + sb->s_blocksize; -- dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -- ext3_mark_inode_dirty(handle, dir); -- } else { -+ frame = dx_probe(dentry, 0, &hinfo, frames, &err); -+ if (!frame) -+ return err; -+ entries = frame->entries; -+ at = frame->at; - -- ext3_debug ("skipping to next block\n"); -+ if (!(bh = ext3_bread(handle,dir, dx_get_block(frame->at), 0, &err))) -+ goto cleanup; - -- de = (struct ext3_dir_entry_2 *) bh->b_data; -- } -- } -- if (!ext3_check_dir_entry ("ext3_add_entry", dir, de, bh, -- offset)) { -- brelse (bh); -- return -ENOENT; -- } -- if (ext3_match (namelen, name, de)) { -- brelse (bh); -- return -EEXIST; -+ BUFFER_TRACE(bh, "get_write_access"); -+ err = ext3_journal_get_write_access(handle, bh); -+ if (err) -+ goto journal_error; -+ -+ err = add_dirent_to_buf(handle, dentry, inode, 0, bh); -+ if (err != -ENOSPC) { -+ bh = 0; -+ goto cleanup; -+ } -+ -+ /* Block full, should compress but for now just split */ -+ dxtrace(printk("using %u of %u node entries\n", -+ dx_get_count(entries), dx_get_limit(entries))); -+ /* Need to split index? */ -+ if (dx_get_count(entries) == dx_get_limit(entries)) { -+ u32 newblock; -+ unsigned icount = dx_get_count(entries); -+ int levels = frame - frames; -+ struct dx_entry *entries2; -+ struct dx_node *node2; -+ struct buffer_head *bh2; -+ -+ if (levels && (dx_get_count(frames->entries) == -+ dx_get_limit(frames->entries))) { -+ ext3_warning(sb, __FUNCTION__, -+ "Directory index full!\n"); -+ err = -ENOSPC; -+ goto cleanup; - } -- if ((le32_to_cpu(de->inode) == 0 && -- le16_to_cpu(de->rec_len) >= rec_len) || -- (le16_to_cpu(de->rec_len) >= -- EXT3_DIR_REC_LEN(de->name_len) + rec_len)) { -- BUFFER_TRACE(bh, "get_write_access"); -- ext3_journal_get_write_access(handle, bh); -- /* By now the buffer is marked for journaling */ -- offset += le16_to_cpu(de->rec_len); -- if (le32_to_cpu(de->inode)) { -- de1 = (struct ext3_dir_entry_2 *) ((char *) de + -- EXT3_DIR_REC_LEN(de->name_len)); -- de1->rec_len = -- cpu_to_le16(le16_to_cpu(de->rec_len) - -- EXT3_DIR_REC_LEN(de->name_len)); -- de->rec_len = cpu_to_le16( -- EXT3_DIR_REC_LEN(de->name_len)); -- de = de1; -+ bh2 = ext3_append (handle, dir, &newblock, &err); -+ if (!(bh2)) -+ goto cleanup; -+ node2 = (struct dx_node *)(bh2->b_data); -+ entries2 = node2->entries; -+ node2->fake.rec_len = cpu_to_le16(sb->s_blocksize); -+ node2->fake.inode = 0; -+ BUFFER_TRACE(frame->bh, "get_write_access"); -+ err = ext3_journal_get_write_access(handle, frame->bh); -+ if (err) -+ goto journal_error; -+ if (levels) { -+ unsigned icount1 = icount/2, icount2 = icount - icount1; -+ unsigned hash2 = dx_get_hash(entries + icount1); -+ dxtrace(printk("Split index %i/%i\n", icount1, icount2)); -+ -+ BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */ -+ err = ext3_journal_get_write_access(handle, -+ frames[0].bh); -+ if (err) -+ goto journal_error; -+ -+ memcpy ((char *) entries2, (char *) (entries + icount1), -+ icount2 * sizeof(struct dx_entry)); -+ dx_set_count (entries, icount1); -+ dx_set_count (entries2, icount2); -+ dx_set_limit (entries2, dx_node_limit(dir)); -+ -+ /* Which index block gets the new entry? */ -+ if (at - entries >= icount1) { -+ frame->at = at = at - entries - icount1 + entries2; -+ frame->entries = entries = entries2; -+ swap(frame->bh, bh2); - } -- de->file_type = EXT3_FT_UNKNOWN; -- if (inode) { -- de->inode = cpu_to_le32(inode->i_ino); -- ext3_set_de_type(dir->i_sb, de, inode->i_mode); -- } else -- de->inode = 0; -- de->name_len = namelen; -- memcpy (de->name, name, namelen); -- /* -- * XXX shouldn't update any times until successful -- * completion of syscall, but too many callers depend -- * on this. -- * -- * XXX similarly, too many callers depend on -- * ext3_new_inode() setting the times, but error -- * recovery deletes the inode, so the worst that can -- * happen is that the times are slightly out of date -- * and/or different from the directory change time. -- */ -- dir->i_mtime = dir->i_ctime = CURRENT_TIME; -- dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -- dir->i_version = ++event; -- ext3_mark_inode_dirty(handle, dir); -- BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); -- ext3_journal_dirty_metadata(handle, bh); -- brelse(bh); -- return 0; -+ dx_insert_block (frames + 0, hash2, newblock); -+ dxtrace(dx_show_index ("node", frames[1].entries)); -+ dxtrace(dx_show_index ("node", -+ ((struct dx_node *) bh2->b_data)->entries)); -+ err = ext3_journal_dirty_metadata(handle, bh2); -+ if (err) -+ goto journal_error; -+ brelse (bh2); -+ } else { -+ dxtrace(printk("Creating second level index...\n")); -+ memcpy((char *) entries2, (char *) entries, -+ icount * sizeof(struct dx_entry)); -+ dx_set_limit(entries2, dx_node_limit(dir)); -+ -+ /* Set up root */ -+ dx_set_count(entries, 1); -+ dx_set_block(entries + 0, newblock); -+ ((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels = 1; -+ -+ /* Add new access path frame */ -+ frame = frames + 1; -+ frame->at = at = at - entries + entries2; -+ frame->entries = entries = entries2; -+ frame->bh = bh2; -+ err = ext3_journal_get_write_access(handle, -+ frame->bh); -+ if (err) -+ goto journal_error; - } -- offset += le16_to_cpu(de->rec_len); -- de = (struct ext3_dir_entry_2 *) -- ((char *) de + le16_to_cpu(de->rec_len)); -+ ext3_journal_dirty_metadata(handle, frames[0].bh); - } -- brelse (bh); -- return -ENOSPC; -+ de = do_split(handle, dir, &bh, frame, &hinfo, &err); -+ if (!de) -+ goto cleanup; -+ err = add_dirent_to_buf(handle, dentry, inode, de, bh); -+ bh = 0; -+ goto cleanup; -+ -+journal_error: -+ ext3_std_error(dir->i_sb, err); -+cleanup: -+ if (bh) -+ brelse(bh); -+ dx_release(frames); -+ return err; - } -+#endif - - /* - * ext3_delete_entry deletes a directory entry by merging it with the -@@ -455,9 +1547,11 @@ static int ext3_create (struct inode * d - struct inode * inode; - int err; - -- handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3); -- if (IS_ERR(handle)) -+ handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + -+ EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3); -+ if (IS_ERR(handle)) { - return PTR_ERR(handle); -+ } - - if (IS_SYNC(dir)) - handle->h_sync = 1; -@@ -481,9 +1575,11 @@ static int ext3_mknod (struct inode * di - struct inode *inode; - int err; - -- handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3); -- if (IS_ERR(handle)) -+ handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + -+ EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3); -+ if (IS_ERR(handle)) { - return PTR_ERR(handle); -+ } - - if (IS_SYNC(dir)) - handle->h_sync = 1; -@@ -509,9 +1605,11 @@ static int ext3_mkdir(struct inode * dir - if (dir->i_nlink >= EXT3_LINK_MAX) - return -EMLINK; - -- handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 3); -- if (IS_ERR(handle)) -+ handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + -+ EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3); -+ if (IS_ERR(handle)) { - return PTR_ERR(handle); -+ } - - if (IS_SYNC(dir)) - handle->h_sync = 1; -@@ -523,7 +1621,7 @@ static int ext3_mkdir(struct inode * dir - - inode->i_op = &ext3_dir_inode_operations; - inode->i_fop = &ext3_dir_operations; -- inode->i_size = inode->u.ext3_i.i_disksize = inode->i_sb->s_blocksize; -+ inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize; - inode->i_blocks = 0; - dir_block = ext3_bread (handle, inode, 0, 1, &err); - if (!dir_block) { -@@ -556,21 +1654,19 @@ static int ext3_mkdir(struct inode * dir - inode->i_mode |= S_ISGID; - ext3_mark_inode_dirty(handle, inode); - err = ext3_add_entry (handle, dentry, inode); -- if (err) -- goto out_no_entry; -+ if (err) { -+ inode->i_nlink = 0; -+ ext3_mark_inode_dirty(handle, inode); -+ iput (inode); -+ goto out_stop; -+ } - dir->i_nlink++; -- dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -+ ext3_update_dx_flag(dir); - ext3_mark_inode_dirty(handle, dir); - d_instantiate(dentry, inode); - out_stop: - ext3_journal_stop(handle, dir); - return err; -- --out_no_entry: -- inode->i_nlink = 0; -- ext3_mark_inode_dirty(handle, inode); -- iput (inode); -- goto out_stop; - } - - /* -@@ -657,7 +1753,7 @@ int ext3_orphan_add(handle_t *handle, st - int err = 0, rc; - - lock_super(sb); -- if (!list_empty(&inode->u.ext3_i.i_orphan)) -+ if (!list_empty(&EXT3_I(inode)->i_orphan)) - goto out_unlock; - - /* Orphan handling is only valid for files with data blocks -@@ -698,7 +1794,7 @@ int ext3_orphan_add(handle_t *handle, st - * This is safe: on error we're going to ignore the orphan list - * anyway on the next recovery. */ - if (!err) -- list_add(&inode->u.ext3_i.i_orphan, &EXT3_SB(sb)->s_orphan); -+ list_add(&EXT3_I(inode)->i_orphan, &EXT3_SB(sb)->s_orphan); - - jbd_debug(4, "superblock will point to %ld\n", inode->i_ino); - jbd_debug(4, "orphan inode %ld will point to %d\n", -@@ -716,25 +1812,26 @@ out_unlock: - int ext3_orphan_del(handle_t *handle, struct inode *inode) - { - struct list_head *prev; -+ struct ext3_inode_info *ei = EXT3_I(inode); - struct ext3_sb_info *sbi; - unsigned long ino_next; - struct ext3_iloc iloc; - int err = 0; - - lock_super(inode->i_sb); -- if (list_empty(&inode->u.ext3_i.i_orphan)) { -+ if (list_empty(&ei->i_orphan)) { - unlock_super(inode->i_sb); - return 0; - } - - ino_next = NEXT_ORPHAN(inode); -- prev = inode->u.ext3_i.i_orphan.prev; -+ prev = ei->i_orphan.prev; - sbi = EXT3_SB(inode->i_sb); - - jbd_debug(4, "remove inode %lu from orphan list\n", inode->i_ino); - -- list_del(&inode->u.ext3_i.i_orphan); -- INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan); -+ list_del(&ei->i_orphan); -+ INIT_LIST_HEAD(&ei->i_orphan); - - /* If we're on an error path, we may not have a valid - * transaction handle with which to update the orphan list on -@@ -795,8 +1892,9 @@ static int ext3_rmdir (struct inode * di - handle_t *handle; - - handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS); -- if (IS_ERR(handle)) -+ if (IS_ERR(handle)) { - return PTR_ERR(handle); -+ } - - retval = -ENOENT; - bh = ext3_find_entry (dentry, &de); -@@ -834,7 +1932,7 @@ static int ext3_rmdir (struct inode * di - dir->i_nlink--; - inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; - ext3_mark_inode_dirty(handle, inode); -- dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -+ ext3_update_dx_flag(dir); - ext3_mark_inode_dirty(handle, dir); - - end_rmdir: -@@ -852,8 +1950,9 @@ static int ext3_unlink(struct inode * di - handle_t *handle; - - handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS); -- if (IS_ERR(handle)) -+ if (IS_ERR(handle)) { - return PTR_ERR(handle); -+ } - - if (IS_SYNC(dir)) - handle->h_sync = 1; -@@ -880,7 +1979,7 @@ static int ext3_unlink(struct inode * di - if (retval) - goto end_unlink; - dir->i_ctime = dir->i_mtime = CURRENT_TIME; -- dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -+ ext3_update_dx_flag(dir); - ext3_mark_inode_dirty(handle, dir); - inode->i_nlink--; - if (!inode->i_nlink) -@@ -906,9 +2005,11 @@ static int ext3_symlink (struct inode * - if (l > dir->i_sb->s_blocksize) - return -ENAMETOOLONG; - -- handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + 5); -- if (IS_ERR(handle)) -+ handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + -+ EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5); -+ if (IS_ERR(handle)) { - return PTR_ERR(handle); -+ } - - if (IS_SYNC(dir)) - handle->h_sync = 1; -@@ -918,7 +2019,7 @@ static int ext3_symlink (struct inode * - if (IS_ERR(inode)) - goto out_stop; - -- if (l > sizeof (inode->u.ext3_i.i_data)) { -+ if (l > sizeof (EXT3_I(inode)->i_data)) { - inode->i_op = &page_symlink_inode_operations; - inode->i_mapping->a_ops = &ext3_aops; - /* -@@ -927,24 +2028,22 @@ static int ext3_symlink (struct inode * - * i_size in generic_commit_write(). - */ - err = block_symlink(inode, symname, l); -- if (err) -- goto out_no_entry; -+ if (err) { -+ ext3_dec_count(handle, inode); -+ ext3_mark_inode_dirty(handle, inode); -+ iput (inode); -+ goto out_stop; -+ } - } else { - inode->i_op = &ext3_fast_symlink_inode_operations; -- memcpy((char*)&inode->u.ext3_i.i_data,symname,l); -+ memcpy((char*)&EXT3_I(inode)->i_data,symname,l); - inode->i_size = l-1; - } -- inode->u.ext3_i.i_disksize = inode->i_size; -+ EXT3_I(inode)->i_disksize = inode->i_size; - err = ext3_add_nondir(handle, dentry, inode); - out_stop: - ext3_journal_stop(handle, dir); - return err; -- --out_no_entry: -- ext3_dec_count(handle, inode); -- ext3_mark_inode_dirty(handle, inode); -- iput (inode); -- goto out_stop; - } - - static int ext3_link (struct dentry * old_dentry, -@@ -957,12 +2056,15 @@ static int ext3_link (struct dentry * ol - if (S_ISDIR(inode->i_mode)) - return -EPERM; - -- if (inode->i_nlink >= EXT3_LINK_MAX) -+ if (inode->i_nlink >= EXT3_LINK_MAX) { - return -EMLINK; -+ } - -- handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS); -- if (IS_ERR(handle)) -+ handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + -+ EXT3_INDEX_EXTRA_TRANS_BLOCKS); -+ if (IS_ERR(handle)) { - return PTR_ERR(handle); -+ } - - if (IS_SYNC(dir)) - handle->h_sync = 1; -@@ -995,9 +2097,11 @@ static int ext3_rename (struct inode * o - - old_bh = new_bh = dir_bh = NULL; - -- handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS + 2); -- if (IS_ERR(handle)) -+ handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS + -+ EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2); -+ if (IS_ERR(handle)) { - return PTR_ERR(handle); -+ } - - if (IS_SYNC(old_dir) || IS_SYNC(new_dir)) - handle->h_sync = 1; -@@ -1070,14 +2174,37 @@ static int ext3_rename (struct inode * o - /* - * ok, that's it - */ -- ext3_delete_entry(handle, old_dir, old_de, old_bh); -+ if (le32_to_cpu(old_de->inode) != old_inode->i_ino || -+ old_de->name_len != old_dentry->d_name.len || -+ strncmp(old_de->name, old_dentry->d_name.name, old_de->name_len) || -+ (retval = ext3_delete_entry(handle, old_dir, -+ old_de, old_bh)) == -ENOENT) { -+ /* old_de could have moved from under us during htree split, so -+ * make sure that we are deleting the right entry. We might -+ * also be pointing to a stale entry in the unused part of -+ * old_bh so just checking inum and the name isn't enough. */ -+ struct buffer_head *old_bh2; -+ struct ext3_dir_entry_2 *old_de2; -+ -+ old_bh2 = ext3_find_entry(old_dentry, &old_de2); -+ if (old_bh2) { -+ retval = ext3_delete_entry(handle, old_dir, -+ old_de2, old_bh2); -+ brelse(old_bh2); -+ } -+ } -+ if (retval) { -+ ext3_warning(old_dir->i_sb, "ext3_rename", -+ "Deleting old file (%lu), %d, error=%d", -+ old_dir->i_ino, old_dir->i_nlink, retval); -+ } - - if (new_inode) { - new_inode->i_nlink--; - new_inode->i_ctime = CURRENT_TIME; - } - old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME; -- old_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -+ ext3_update_dx_flag(old_dir); - if (dir_bh) { - BUFFER_TRACE(dir_bh, "get_write_access"); - ext3_journal_get_write_access(handle, dir_bh); -@@ -1089,7 +2212,7 @@ static int ext3_rename (struct inode * o - new_inode->i_nlink--; - } else { - new_dir->i_nlink++; -- new_dir->u.ext3_i.i_flags &= ~EXT3_INDEX_FL; -+ ext3_update_dx_flag(new_dir); - ext3_mark_inode_dirty(handle, new_dir); - } - } ---- linux-2.4.22-ac1/fs/ext3/super.c~ext3-htree-2.4.22-rh 2003-09-25 14:39:01.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/ext3/super.c 2003-09-25 14:55:12.000000000 +0400 -@@ -714,6 +714,7 @@ static int ext3_setup_super(struct super - es->s_mtime = cpu_to_le32(CURRENT_TIME); - ext3_update_dynamic_rev(sb); - EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER); -+ - ext3_commit_super (sb, es, 1); - if (test_opt (sb, DEBUG)) - printk (KERN_INFO -@@ -724,6 +725,7 @@ static int ext3_setup_super(struct super - EXT3_BLOCKS_PER_GROUP(sb), - EXT3_INODES_PER_GROUP(sb), - sbi->s_mount_opt); -+ - printk(KERN_INFO "EXT3 FS " EXT3FS_VERSION ", " EXT3FS_DATE " on %s, ", - bdevname(sb->s_dev)); - if (EXT3_SB(sb)->s_journal->j_inode == NULL) { -@@ -897,6 +899,7 @@ static loff_t ext3_max_size(int bits) - return res; - } - -+ - struct super_block * ext3_read_super (struct super_block * sb, void * data, - int silent) - { -@@ -1073,6 +1076,9 @@ struct super_block * ext3_read_super (st - sbi->s_mount_state = le16_to_cpu(es->s_state); - sbi->s_addr_per_block_bits = log2(EXT3_ADDR_PER_BLOCK(sb)); - sbi->s_desc_per_block_bits = log2(EXT3_DESC_PER_BLOCK(sb)); -+ for (i=0; i < 4; i++) -+ sbi->s_hash_seed[i] = le32_to_cpu(es->s_hash_seed[i]); -+ sbi->s_def_hash_version = es->s_def_hash_version; - - if (sbi->s_blocks_per_group > blocksize * 8) { - printk (KERN_ERR -@@ -1846,6 +1852,7 @@ static void __exit exit_ext3_fs(void) - unregister_filesystem(&ext3_fs_type); - } - -+EXPORT_SYMBOL(ext3_force_commit); - EXPORT_SYMBOL(ext3_bread); - - MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); ---- linux-2.4.22-ac1/include/linux/ext3_fs.h~ext3-htree-2.4.22-rh 2003-09-25 14:16:29.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/include/linux/ext3_fs.h 2003-09-25 14:58:30.000000000 +0400 -@@ -40,6 +40,11 @@ - #define EXT3FS_VERSION "2.4-0.9.19" - - /* -+ * Always enable hashed directories -+ */ -+#define CONFIG_EXT3_INDEX -+ -+/* - * Debug code - */ - #ifdef EXT3FS_DEBUG -@@ -440,8 +445,11 @@ struct ext3_super_block { - /*E0*/ __u32 s_journal_inum; /* inode number of journal file */ - __u32 s_journal_dev; /* device number of journal file */ - __u32 s_last_orphan; /* start of list of inodes to delete */ -- --/*EC*/ __u32 s_reserved[197]; /* Padding to the end of the block */ -+ __u32 s_hash_seed[4]; /* HTREE hash seed */ -+ __u8 s_def_hash_version; /* Default hash version to use */ -+ __u8 s_reserved_char_pad; -+ __u16 s_reserved_word_pad; -+ __u32 s_reserved[192]; /* Padding to the end of the block */ - }; - - #ifdef __KERNEL__ -@@ -578,9 +586,46 @@ struct ext3_dir_entry_2 { - #define EXT3_DIR_ROUND (EXT3_DIR_PAD - 1) - #define EXT3_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT3_DIR_ROUND) & \ - ~EXT3_DIR_ROUND) -+/* -+ * Hash Tree Directory indexing -+ * (c) Daniel Phillips, 2001 -+ */ -+ -+#ifdef CONFIG_EXT3_INDEX -+ #define is_dx(dir) (EXT3_HAS_COMPAT_FEATURE(dir->i_sb, \ -+ EXT3_FEATURE_COMPAT_DIR_INDEX) && \ -+ (EXT3_I(dir)->i_flags & EXT3_INDEX_FL)) -+#define EXT3_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT3_LINK_MAX) -+#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1) -+#else -+ #define is_dx(dir) 0 -+#define EXT3_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT3_LINK_MAX) -+#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2) -+#endif -+ -+/* Legal values for the dx_root hash_version field: */ -+ -+#define DX_HASH_LEGACY 0 -+#define DX_HASH_HALF_MD4 1 -+#define DX_HASH_TEA 2 -+ -+/* hash info structure used by the directory hash */ -+struct dx_hash_info -+{ -+ u32 hash; -+ u32 minor_hash; -+ int hash_version; -+ u32 *seed; -+}; - - #ifdef __KERNEL__ - /* -+ * Control parameters used by ext3_htree_next_block -+ */ -+#define HASH_NB_ALWAYS 1 -+ -+ -+/* - * Describe an inode's exact location on disk and in memory - */ - struct ext3_iloc -@@ -590,6 +635,27 @@ struct ext3_iloc - unsigned long block_group; - }; - -+ -+/* -+ * This structure is stuffed into the struct file's private_data field -+ * for directories. It is where we put information so that we can do -+ * readdir operations in hash tree order. -+ */ -+struct dir_private_info { -+ rb_root_t root; -+ rb_node_t *curr_node; -+ struct fname *extra_fname; -+ loff_t last_pos; -+ __u32 curr_hash; -+ __u32 curr_minor_hash; -+ __u32 next_hash; -+}; -+ -+/* -+ * Special error return code only used by dx_probe() and its callers. -+ */ -+#define ERR_BAD_DX_DIR -75000 -+ - /* - * Function prototypes - */ -@@ -617,11 +683,20 @@ extern struct ext3_group_desc * ext3_get - - /* dir.c */ - extern int ext3_check_dir_entry(const char *, struct inode *, -- struct ext3_dir_entry_2 *, struct buffer_head *, -- unsigned long); -+ struct ext3_dir_entry_2 *, -+ struct buffer_head *, unsigned long); -+extern int ext3_htree_store_dirent(struct file *dir_file, __u32 hash, -+ __u32 minor_hash, -+ struct ext3_dir_entry_2 *dirent); -+extern void ext3_htree_free_dir_info(struct dir_private_info *p); -+ - /* fsync.c */ - extern int ext3_sync_file (struct file *, struct dentry *, int); - -+/* hash.c */ -+extern int ext3fs_dirhash(const char *name, int len, struct -+ dx_hash_info *hinfo); -+ - /* ialloc.c */ - extern struct inode * ext3_new_inode (handle_t *, const struct inode *, int); - extern void ext3_free_inode (handle_t *, struct inode *); -@@ -655,6 +730,8 @@ extern int ext3_ioctl (struct inode *, s - /* namei.c */ - extern int ext3_orphan_add(handle_t *, struct inode *); - extern int ext3_orphan_del(handle_t *, struct inode *); -+extern int ext3_htree_fill_tree(struct file *dir_file, __u32 start_hash, -+ __u32 start_minor_hash, __u32 *next_hash); - - /* super.c */ - extern void ext3_error (struct super_block *, const char *, const char *, ...) ---- linux-2.4.22-ac1/include/linux/ext3_fs_sb.h~ext3-htree-2.4.22-rh 2003-09-25 14:16:34.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/include/linux/ext3_fs_sb.h 2003-09-25 14:55:12.000000000 +0400 -@@ -62,6 +62,8 @@ struct ext3_sb_info { - int s_inode_size; - int s_first_ino; - u32 s_next_generation; -+ u32 s_hash_seed[4]; -+ int s_def_hash_version; - - unsigned long s_dir_count; - u8 *s_debts; ---- linux-2.4.22-ac1/include/linux/ext3_jbd.h~ext3-htree-2.4.22-rh 2003-06-13 18:51:38.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/include/linux/ext3_jbd.h 2003-09-25 14:55:12.000000000 +0400 -@@ -63,6 +63,8 @@ extern int ext3_writepage_trans_blocks(s - - #define EXT3_RESERVE_TRANS_BLOCKS 12U - -+#define EXT3_INDEX_EXTRA_TRANS_BLOCKS 8 -+ - int - ext3_mark_iloc_dirty(handle_t *handle, - struct inode *inode, ---- linux-2.4.22-ac1/include/linux/rbtree.h~ext3-htree-2.4.22-rh 2001-11-22 22:46:18.000000000 +0300 -+++ linux-2.4.22-ac1-alexey/include/linux/rbtree.h 2003-09-25 14:55:12.000000000 +0400 -@@ -120,6 +120,8 @@ rb_root_t; - - extern void rb_insert_color(rb_node_t *, rb_root_t *); - extern void rb_erase(rb_node_t *, rb_root_t *); -+extern rb_node_t *rb_get_first(rb_root_t *root); -+extern rb_node_t *rb_get_next(rb_node_t *n); - - static inline void rb_link_node(rb_node_t * node, rb_node_t * parent, rb_node_t ** rb_link) - { ---- linux-2.4.22-ac1/lib/rbtree.c~ext3-htree-2.4.22-rh 2002-08-03 04:39:46.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/lib/rbtree.c 2003-09-25 14:55:12.000000000 +0400 -@@ -17,6 +17,8 @@ - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - linux/lib/rbtree.c -+ -+ rb_get_first and rb_get_next written by Theodore Ts'o, 9/8/2002 - */ - - #include -@@ -294,3 +296,43 @@ void rb_erase(rb_node_t * node, rb_root_ - __rb_erase_color(child, parent, root); - } - EXPORT_SYMBOL(rb_erase); -+ -+/* -+ * This function returns the first node (in sort order) of the tree. -+ */ -+rb_node_t *rb_get_first(rb_root_t *root) -+{ -+ rb_node_t *n; -+ -+ n = root->rb_node; -+ if (!n) -+ return 0; -+ while (n->rb_left) -+ n = n->rb_left; -+ return n; -+} -+EXPORT_SYMBOL(rb_get_first); -+ -+/* -+ * Given a node, this function will return the next node in the tree. -+ */ -+rb_node_t *rb_get_next(rb_node_t *n) -+{ -+ rb_node_t *parent; -+ -+ if (n->rb_right) { -+ n = n->rb_right; -+ while (n->rb_left) -+ n = n->rb_left; -+ return n; -+ } else { -+ while ((parent = n->rb_parent)) { -+ if (n == parent->rb_left) -+ return parent; -+ n = parent; -+ } -+ return 0; -+ } -+} -+EXPORT_SYMBOL(rb_get_next); -+ - -_ diff --git a/lustre/kernel_patches/patches/ext3-inode-reuse-2.4.24.patch b/lustre/kernel_patches/patches/ext3-inode-reuse-2.4.24.patch deleted file mode 100644 index 18c69ff..0000000 --- a/lustre/kernel_patches/patches/ext3-inode-reuse-2.4.24.patch +++ /dev/null @@ -1,352 +0,0 @@ -Index: linux-2.4.20/fs/ext3/ialloc.c -=================================================================== ---- linux-2.4.20.orig/fs/ext3/ialloc.c 2003-10-25 00:37:13.000000000 +0400 -+++ linux-2.4.20/fs/ext3/ialloc.c 2003-10-29 20:33:33.000000000 +0300 -@@ -241,11 +241,16 @@ - - bh = sb->u.ext3_sb.s_inode_bitmap[bitmap_nr]; - -- BUFFER_TRACE(bh, "get_write_access"); -- fatal = ext3_journal_get_write_access(handle, bh); -+ BUFFER_TRACE(bh, "get_undo_access"); -+ fatal = ext3_journal_get_undo_access(handle, bh); - if (fatal) - goto error_return; - -+ /* to prevent inode reusing within single transaction -bzzz */ -+ BUFFER_TRACE(bh, "clear in b_committed_data"); -+ J_ASSERT_BH(bh, bh2jh(bh)->b_committed_data != NULL); -+ ext3_set_bit(bit, bh2jh(bh)->b_committed_data); -+ - /* Ok, now we can actually update the inode bitmaps.. */ - if (!ext3_clear_bit (bit, bh->b_data)) - ext3_error (sb, "ext3_free_inode", -@@ -319,6 +324,131 @@ - return 0; - } - -+static int ext3_test_allocatable(int nr, struct buffer_head *bh) -+{ -+ if (ext3_test_bit(nr, bh->b_data)) -+ return 0; -+ if (!buffer_jbd(bh) || !bh2jh(bh)->b_committed_data) -+ return 1; -+#if 0 -+ if (!ext3_test_bit(nr, bh2jh(bh)->b_committed_data)) -+ printk("EXT3-fs: inode %d was used\n", nr); -+#endif -+ return !ext3_test_bit(nr, bh2jh(bh)->b_committed_data); -+} -+ -+int ext3_find_group_dir(const struct inode *dir, -+ struct ext3_group_desc **gdp, -+ struct buffer_head **bh) -+{ -+ struct super_block *sb = dir->i_sb; -+ struct ext3_super_block *es; -+ struct ext3_group_desc *tmp; -+ int i = 0, j, avefreei; -+ -+ es = EXT3_SB(sb)->s_es; -+ avefreei = le32_to_cpu(es->s_free_inodes_count) / -+ sb->u.ext3_sb.s_groups_count; -+ for (j = 0; j < sb->u.ext3_sb.s_groups_count; j++) { -+ struct buffer_head *temp_buffer; -+ tmp = ext3_get_group_desc(sb, j, &temp_buffer); -+ if (tmp && le16_to_cpu(tmp->bg_free_inodes_count) && -+ le16_to_cpu(tmp->bg_free_inodes_count) >= avefreei) { -+ if (!*gdp || (le16_to_cpu(tmp->bg_free_blocks_count) > -+ le16_to_cpu((*gdp)->bg_free_blocks_count))) { -+ i = j; -+ *gdp = tmp; -+ *bh = temp_buffer; -+ } -+ } -+ } -+ -+ return i; -+} -+ -+int ext3_find_group_other(const struct inode *dir, -+ struct ext3_group_desc **gdp, -+ struct buffer_head **bh) -+{ -+ struct super_block *sb = dir->i_sb; -+ struct ext3_group_desc *tmp; -+ int i, j; -+ -+ /* -+ * Try to place the inode in its parent directory -+ */ -+ i = dir->u.ext3_i.i_block_group; -+ tmp = ext3_get_group_desc(sb, i, bh); -+ if (tmp && le16_to_cpu(tmp->bg_free_inodes_count)) -+ *gdp = tmp; -+ else { -+ /* -+ * Use a quadratic hash to find a group with a -+ * free inode -+ */ -+ for (j = 1; j < sb->u.ext3_sb.s_groups_count; j <<= 1) { -+ i += j; -+ if (i >= sb->u.ext3_sb.s_groups_count) -+ i -= sb->u.ext3_sb.s_groups_count; -+ tmp = ext3_get_group_desc (sb, i, bh); -+ if (tmp && le16_to_cpu(tmp->bg_free_inodes_count)) { -+ *gdp = tmp; -+ break; -+ } -+ } -+ } -+ if (!*gdp) { -+ /* -+ * That failed: try linear search for a free inode -+ */ -+ i = dir->u.ext3_i.i_block_group + 1; -+ for (j = 2; j < sb->u.ext3_sb.s_groups_count; j++) { -+ if (++i >= sb->u.ext3_sb.s_groups_count) -+ i = 0; -+ tmp = ext3_get_group_desc (sb, i, bh); -+ if (tmp && le16_to_cpu(tmp->bg_free_inodes_count)) { -+ *gdp = tmp; -+ break; -+ } -+ } -+ } -+ -+ return i; -+} -+ -+static int ext3_find_group(const struct inode *dir, int mode, -+ struct ext3_group_desc **gdp, -+ struct buffer_head **bh) -+{ -+ if (S_ISDIR(mode)) -+ return ext3_find_group_dir(dir, gdp, bh); -+ return ext3_find_group_other(dir, gdp, bh); -+} -+ -+static int ext3_find_usable_inode(struct super_block *sb, -+ struct buffer_head *bh) -+{ -+ int here, maxinodes, next; -+ -+ maxinodes = EXT3_INODES_PER_GROUP(sb); -+ here = 0; -+ -+ while (here < maxinodes) { -+ next = ext3_find_next_zero_bit((unsigned long *) bh->b_data, -+ maxinodes, here); -+ if (next >= maxinodes) -+ return -1; -+ if (ext3_test_allocatable(next, bh)) -+ return next; -+ -+ J_ASSERT_BH(bh, bh2jh(bh)->b_committed_data); -+ here = ext3_find_next_zero_bit -+ ((unsigned long *) bh2jh(bh)->b_committed_data, -+ maxinodes, next); -+ } -+ return -1; -+} -+ - /* - * There are two policies for allocating an inode. If the new inode is - * a directory, then a forward search is made for a block group with both -@@ -336,7 +466,7 @@ - struct super_block * sb; - struct buffer_head * bh; - struct buffer_head * bh2; -- int i, j, avefreei; -+ int i, j, k; - struct inode * inode; - int bitmap_nr; - struct ext3_group_desc * gdp; -@@ -371,11 +501,12 @@ - - bh = EXT3_SB(sb)->s_inode_bitmap[bitmap_nr]; - -- BUFFER_TRACE(bh, "get_write_access"); -- err = ext3_journal_get_write_access(handle, bh); -+ BUFFER_TRACE(bh, "get_undo_access"); -+ err = ext3_journal_get_undo_access(handle, bh); - if (err) goto fail; - -- if (ext3_set_bit(j, bh->b_data)) { -+ if (!ext3_test_allocatable(j, bh) || -+ ext3_set_bit(j, bh->b_data)) { - printk(KERN_ERR "goal inode %lu unavailable\n", goal); - /* Oh well, we tried. */ - goto repeat; -@@ -393,119 +524,70 @@ - - repeat: - gdp = NULL; -- i = 0; -- -- if (S_ISDIR(mode)) { -- avefreei = le32_to_cpu(es->s_free_inodes_count) / -- sb->u.ext3_sb.s_groups_count; -- if (!gdp) { -- for (j = 0; j < sb->u.ext3_sb.s_groups_count; j++) { -- struct buffer_head *temp_buffer; -- tmp = ext3_get_group_desc (sb, j, &temp_buffer); -- if (tmp && -- le16_to_cpu(tmp->bg_free_inodes_count) && -- le16_to_cpu(tmp->bg_free_inodes_count) >= -- avefreei) { -- if (!gdp || (le16_to_cpu(tmp->bg_free_blocks_count) > -- le16_to_cpu(gdp->bg_free_blocks_count))) { -- i = j; -- gdp = tmp; -- bh2 = temp_buffer; -- } -- } -- } -- } -- } else { -- /* -- * Try to place the inode in its parent directory -- */ -- i = dir->u.ext3_i.i_block_group; -- tmp = ext3_get_group_desc (sb, i, &bh2); -- if (tmp && le16_to_cpu(tmp->bg_free_inodes_count)) -- gdp = tmp; -- else -- { -- /* -- * Use a quadratic hash to find a group with a -- * free inode -- */ -- for (j = 1; j < sb->u.ext3_sb.s_groups_count; j <<= 1) { -- i += j; -- if (i >= sb->u.ext3_sb.s_groups_count) -- i -= sb->u.ext3_sb.s_groups_count; -- tmp = ext3_get_group_desc (sb, i, &bh2); -- if (tmp && -- le16_to_cpu(tmp->bg_free_inodes_count)) { -- gdp = tmp; -- break; -- } -- } -- } -- if (!gdp) { -- /* -- * That failed: try linear search for a free inode -- */ -- i = dir->u.ext3_i.i_block_group + 1; -- for (j = 2; j < sb->u.ext3_sb.s_groups_count; j++) { -- if (++i >= sb->u.ext3_sb.s_groups_count) -- i = 0; -- tmp = ext3_get_group_desc (sb, i, &bh2); -- if (tmp && -- le16_to_cpu(tmp->bg_free_inodes_count)) { -- gdp = tmp; -- break; -- } -- } -- } -- } - -+ /* choose group */ -+ i = ext3_find_group(dir, mode, &gdp, &bh2); - err = -ENOSPC; - if (!gdp) - goto out; -- -+ - err = -EIO; -- bitmap_nr = load_inode_bitmap (sb, i); -+ bitmap_nr = load_inode_bitmap(sb, i); - if (bitmap_nr < 0) - goto fail; -- - bh = sb->u.ext3_sb.s_inode_bitmap[bitmap_nr]; - -- if ((j = ext3_find_first_zero_bit ((unsigned long *) bh->b_data, -- EXT3_INODES_PER_GROUP(sb))) < -- EXT3_INODES_PER_GROUP(sb)) { -- BUFFER_TRACE(bh, "get_write_access"); -- err = ext3_journal_get_write_access(handle, bh); -- if (err) goto fail; -- -- if (ext3_set_bit (j, bh->b_data)) { -- ext3_error (sb, "ext3_new_inode", -- "bit already set for inode %d", j); -- goto repeat; -- } -- BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); -- err = ext3_journal_dirty_metadata(handle, bh); -- if (err) goto fail; -- } else { -- if (le16_to_cpu(gdp->bg_free_inodes_count) != 0) { -- ext3_error (sb, "ext3_new_inode", -- "Free inodes count corrupted in group %d", -- i); -- /* Is it really ENOSPC? */ -- err = -ENOSPC; -- if (sb->s_flags & MS_RDONLY) -- goto fail; -- -- BUFFER_TRACE(bh2, "get_write_access"); -- err = ext3_journal_get_write_access(handle, bh2); -- if (err) goto fail; -- gdp->bg_free_inodes_count = 0; -- BUFFER_TRACE(bh2, "call ext3_journal_dirty_metadata"); -- err = ext3_journal_dirty_metadata(handle, bh2); -- if (err) goto fail; -+ /* try to allocate in selected group */ -+ j = ext3_find_usable_inode(sb, bh); -+ err = -ENOSPC; -+ if (j >= 0) -+ goto found_free; -+ -+ /* can't allocate: try to allocate in ANY another groups */ -+ k = i; -+ err = -EIO; -+ for (i = i + 1; i != k; i++) { -+ if (i >= sb->u.ext3_sb.s_groups_count) -+ i = 0; -+ tmp = ext3_get_group_desc(sb, i, &bh2); -+ if (le16_to_cpu(tmp->bg_free_inodes_count) == 0) -+ continue; -+ -+ bitmap_nr = load_inode_bitmap(sb, i); -+ if (bitmap_nr < 0) -+ goto fail; -+ bh = sb->u.ext3_sb.s_inode_bitmap[bitmap_nr]; -+ -+ /* try to allocate in selected group */ -+ if ((j = ext3_find_usable_inode(sb, bh)) >= 0) { -+ gdp = tmp; -+ break; - } -- goto repeat; - } -+ err = -ENOSPC; -+ if (!gdp) -+ goto out; -+ -+ found_free: -+ BUFFER_TRACE(bh, "get_undo_access"); -+ err = ext3_journal_get_undo_access(handle, bh); -+ if (err) -+ goto fail; -+ -+ if (ext3_set_bit(j, bh->b_data)) { -+ ext3_error (sb, "ext3_new_inode", -+ "bit already set for inode %d", j); -+ goto fail; -+ } -+ BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); -+ err = ext3_journal_dirty_metadata(handle, bh); -+ if (err) -+ goto fail; -+ - have_bit_and_group: -+ if (buffer_jbd(bh) && bh2jh(bh)->b_committed_data) -+ J_ASSERT_BH(bh, !ext3_test_bit(j, bh2jh(bh)->b_committed_data)); -+ - j += i * EXT3_INODES_PER_GROUP(sb) + 1; - if (j < EXT3_FIRST_INO(sb) || j > le32_to_cpu(es->s_inodes_count)) { - ext3_error (sb, "ext3_new_inode", diff --git a/lustre/kernel_patches/patches/ext3-map_inode_page-2.4.24.patch b/lustre/kernel_patches/patches/ext3-map_inode_page-2.4.24.patch deleted file mode 100644 index 675dc95..0000000 --- a/lustre/kernel_patches/patches/ext3-map_inode_page-2.4.24.patch +++ /dev/null @@ -1,105 +0,0 @@ - - - - fs/ext3/ext3-exports.c | 3 ++ - fs/ext3/inode.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 58 insertions(+) - -Index: lum/fs/ext3/inode.c -=================================================================== ---- lum.orig/fs/ext3/inode.c Sat Nov 22 16:38:51 2003 -+++ lum/fs/ext3/inode.c Fri Nov 28 00:37:18 2003 -@@ -2979,3 +2979,75 @@ - ret = ret2; - return ret; - } -+ -+/* copied from fs/buffer.c */ -+static void unmap_underlying_metadata(struct buffer_head * bh) -+{ -+ struct buffer_head *old_bh; -+ -+ old_bh = get_hash_table(bh->b_dev, bh->b_blocknr, bh->b_size); -+ if (old_bh) { -+ mark_buffer_clean(old_bh); -+ wait_on_buffer(old_bh); -+ clear_bit(BH_Req, &old_bh->b_state); -+ __brelse(old_bh); -+ } -+} -+ -+int ext3_map_inode_page(struct inode *inode, struct page *page, -+ unsigned long *blocks, int *created, int create) -+{ -+ unsigned int blocksize, blocks_per_page; -+ unsigned long iblock; -+ void *handle; -+ int i, rc = 0, failed = 0, needed_blocks; -+ -+ blocksize = inode->i_sb->s_blocksize; -+ blocks_per_page = PAGE_SIZE >> inode->i_sb->s_blocksize_bits; -+ iblock = page->index * blocks_per_page; -+ -+ for (i = 0; i < blocks_per_page; i++, iblock++) { -+ blocks[i] = ext3_bmap(inode->i_mapping, iblock); -+ if (blocks[i] == 0) { -+ failed++; -+ created[i] = -1; -+ } else { -+ created[i] = 0; -+ } -+ } -+ -+ if (failed == 0 || create == 0) -+ return 0; -+ -+ needed_blocks = ext3_writepage_trans_blocks(inode); -+ lock_kernel(); -+ handle = ext3_journal_start(inode, needed_blocks); -+ unlock_kernel(); -+ if (IS_ERR(handle)) -+ return PTR_ERR(handle); -+ -+ iblock = page->index * blocks_per_page; -+ for (i = 0; i < blocks_per_page; i++, iblock++) { -+ struct buffer_head bh; -+ -+ if (blocks[i] != 0) -+ continue; -+ -+ rc = ext3_get_block_handle(handle, inode, iblock, &bh, 1); -+ if (rc) { -+ printk(KERN_INFO "ext3_map_inode_page: error %d " -+ "allocating block %ld\n", rc, iblock); -+ goto out; -+ } -+ if (buffer_new(&bh)) -+ unmap_underlying_metadata(&bh); -+ blocks[i] = bh.b_blocknr; -+ created[i] = 1; -+ } -+ -+ out: -+ lock_kernel(); -+ ext3_journal_stop(handle, inode); -+ unlock_kernel(); -+ return rc; -+} -Index: lum/fs/ext3/ext3-exports.c -=================================================================== ---- lum.orig/fs/ext3/ext3-exports.c Sat Nov 22 16:38:51 2003 -+++ lum/fs/ext3/ext3-exports.c Sat Nov 22 16:38:51 2003 -@@ -9,6 +9,8 @@ - - int ext3_prep_san_write(struct inode *inode, long *blocks, - int nblocks, loff_t newsize); -+int ext3_map_inode_page(struct inode *inode, struct page *page, -+ unsigned long *block, int *created, int create); - - EXPORT_SYMBOL(ext3_force_commit); - EXPORT_SYMBOL(ext3_bread); -@@ -18,3 +20,4 @@ - EXPORT_SYMBOL(ext3_xattr_list); - EXPORT_SYMBOL(ext3_xattr_set); - EXPORT_SYMBOL(ext3_prep_san_write); -+EXPORT_SYMBOL(ext3_map_inode_page); diff --git a/lustre/kernel_patches/patches/ext3-mballoc-2.4.24.patch b/lustre/kernel_patches/patches/ext3-mballoc-2.4.24.patch deleted file mode 100644 index 9aefd43..0000000 --- a/lustre/kernel_patches/patches/ext3-mballoc-2.4.24.patch +++ /dev/null @@ -1,373 +0,0 @@ -Index: linux-2.4.24/fs/ext3/balloc.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/balloc.c 2004-01-10 17:04:42.000000000 +0300 -+++ linux-2.4.24/fs/ext3/balloc.c 2004-02-06 11:05:42.000000000 +0300 -@@ -11,6 +11,7 @@ - * David S. Miller (davem@caip.rutgers.edu), 1995 - */ - -+#include - #include - #include - #include -@@ -1007,3 +1008,303 @@ - bitmap_count); - } - #endif -+ -+#define MBDEBUG_ -+#ifdef MBDEBUG -+#define mbdebug(fmt,a...) printk(fmt, ##a) -+#else -+#define mbdebug(fmt,a...) -+#endif -+ -+/* -+ * in alloc_status we track allocation: the best found extent, how many -+ * extents we've skipped, etc -+ */ -+struct alloc_status { -+ struct inode *inode; -+ struct super_block *sb; -+ int goal; /* goal for allocation */ -+ int target_len; /* goal for len */ -+ int start, len; /* the best found extent */ -+ int num; /* number of extent: to limit searching */ -+}; -+ -+/* -+ * ext3_test_extent() compares requested extent with existing in as. -+ * if requested extent is better than that, then replace old one. -+ * then it tries to understand is new extent suitable or not -+ * return 1 if caller can complete searching -+ */ -+inline int ext3_test_extent(struct alloc_status *as, int group, -+ int start, int len) -+{ -+ struct ext3_super_block * es = EXT3_SB(as->sb)->s_es; -+ unsigned long tmp; -+ -+ J_ASSERT(as->target_len >= len); -+ -+ mbdebug("found extent %d:%d\n", start, len); -+ tmp = start + group * EXT3_BLOCKS_PER_GROUP(as->sb) -+ + le32_to_cpu(es->s_first_data_block); -+ -+ /* account requests in order to limit searching */ -+ as->num++; -+ -+ if (as->num == 20) -+ return 1; -+ -+ /* if hit goal, then searching may complete right now */ -+ if (tmp == as->goal) { -+nice: -+ as->start = tmp; -+ as->len = len; -+ return 1; -+ } -+ -+ /* if found extent has length we need, return it right now */ -+ if (as->target_len == len) -+ goto nice; -+ -+ /* first, check is found extent better than we have in as */ -+ if (as->len > len) { -+better: -+ as->start = tmp; -+ as->len = len; -+ return 0; -+ } -+ -+ /* FIXME: more checks! */ -+ as->start = tmp; -+ as->len = len; -+ -+ /* 1) closeness to goal */ -+ -+ /* 2) extent length */ -+ /* 3) number of tested extent (we check all found extents) */ -+ /* */ -+ return 0; -+} -+ -+/* -+ * this routine tries to find upto *len free contig. blocks -+ * return number of found block (+ length of extent in *len) -+ * or -1 if no free blocks at all -+ */ -+int ext3_find_free_extent(struct buffer_head *bh, int goal, int *len, int max) -+{ -+ int i, l = 0; -+ -+repeat: -+ if (goal >= max) -+ return -1; -+ /* find first free block */ -+ i = ext3_find_next_zero_bit(bh->b_data, max, goal); -+ if (i >= max) { -+ /* no free block */ -+ return -1; -+ } -+ /* check upto len block for ability to be allocated */ -+ while (l < *len && i + l < max) { -+ if (!ext3_test_allocatable(i + l, bh)) -+ break; -+ l++; -+ } -+ if (l == 0) { -+ goal = i + 1; -+ goto repeat; -+ } -+ *len = l; -+ return i; -+} -+ -+/* -+ * this routine loops over group, finds free extents and tests them -+ * for some criterias -+ * it may return negative value if group can't be loaded, 0 - if -+ * no good extent can be found, 1 - if good extent found -+ */ -+int ext3_find_extent_in_group(struct alloc_status *as, int group, -+ unsigned long goal, int len) -+{ -+ int k, i, l, bitmap_nr, found = 0; -+ struct super_block *sb = as->sb; -+ int max = EXT3_BLOCKS_PER_GROUP(sb); -+ struct buffer_head *bh, *bmbh; -+ struct ext3_group_desc *gdp; -+ -+ mbdebug("look for %d blocks in group %d starting from %lu\n", -+ len, group, goal); -+ -+ gdp = ext3_get_group_desc(as->sb, group, &bh); -+ if (!gdp) -+ return -EIO; -+ -+ if (le16_to_cpu(gdp->bg_free_blocks_count) == 0) -+ return 0; -+ -+ bitmap_nr = load_block_bitmap(as->sb, group); -+ if (bitmap_nr < 0) -+ return -EIO; -+ -+ bmbh = EXT3_SB(sb)->s_block_bitmap[bitmap_nr]; -+ -+ i = goal; -+ /* scan from goal to the end */ -+repeat: -+ while (i < max) { -+ l = len; -+ k = ext3_find_free_extent(bmbh, i, &l, max); -+ i = k + l; -+ if (k < 0) -+ break; -+ if (ext3_test_extent(as, group, k, l)) { -+ found = 1; -+ goto out; -+ } -+ } -+ -+ if (goal) { -+ /* scan from 0 upto goal */ -+ mbdebug("repeat from %lu in %d\n", goal, group); -+ max = goal - 1; -+ goal = i = 0; -+ goto repeat; -+ } -+out: -+ return found; -+} -+ -+#define check_in_committed(bh,j) \ -+ J_ASSERT_BH((bh), !ext3_test_bit((j), bh2jh((bh))->b_committed_data)) -+ -+int ext3_new_blocks(handle_t *handle, struct inode *inode, int *num, -+ unsigned long goal, int *errp) -+{ -+ struct super_block *sb = inode->i_sb; -+ int first_group, group, bitmap_nr; -+ struct buffer_head *bh, *bmbh; -+ struct ext3_super_block *es; -+ struct ext3_group_desc *gdp; -+ struct alloc_status as; -+ int err, bit, i; -+ -+ J_ASSERT(num && *num > 0); -+ -+ if (DQUOT_ALLOC_BLOCK(inode, *num)) { -+ *errp = -EDQUOT; -+ return 0; -+ } -+ -+ es = EXT3_SB(inode->i_sb)->s_es; -+ -+ *errp = 0; -+ as.target_len = *num; -+ as.sb = sb; -+ as.inode = inode; -+ as.goal = goal; -+ as.start = -1; -+ as.len = 0; -+ as.num = 0; -+ -+ if (goal < le32_to_cpu(es->s_first_data_block) || -+ goal >= le32_to_cpu(es->s_blocks_count)) -+ goal = le32_to_cpu(es->s_first_data_block); -+ -+ lock_super(sb); -+ first_group = (goal - le32_to_cpu(es->s_first_data_block)) / -+ EXT3_BLOCKS_PER_GROUP(sb); -+ goal = (goal - le32_to_cpu(es->s_first_data_block)) % -+ EXT3_BLOCKS_PER_GROUP(sb); -+ group = first_group; -+ do { -+ err = ext3_find_extent_in_group(&as, group, goal, *num); -+ if (err < 0) -+ goto error_out; -+ else if (err) -+ break; -+ -+ /* reset goal for next groups */ -+ goal = 0; -+ -+ /* try next group */ -+ if (++group == EXT3_SB(sb)->s_groups_count) -+ group = 0; -+ } while (group != first_group); -+ -+ if (as.len == 0) { -+ err = -ENOSPC; -+ goto error_out; -+ } -+ -+ /* in the end we've found something, allocate it */ -+ mbdebug("best extent: %u:%u\n", as.start, as.len); -+ -+ group = (as.start - le32_to_cpu(es->s_first_data_block)) / -+ EXT3_BLOCKS_PER_GROUP(sb); -+ bit = (as.start - le32_to_cpu(es->s_first_data_block)) % -+ EXT3_BLOCKS_PER_GROUP(sb); -+ gdp = ext3_get_group_desc(sb, group, &bh); -+ if (!gdp) { -+ err = -EIO; -+ goto error_out; -+ } -+ -+ /* mark block(s) used in bitmap ... */ -+ bitmap_nr = load_block_bitmap(sb, group); -+ if (bitmap_nr < 0) { -+ err = -EIO; -+ goto error_out; -+ } -+ bmbh = EXT3_SB(sb)->s_block_bitmap[bitmap_nr]; -+ /* Make sure we use undo access for the bitmap, because it is -+ critical that we do the frozen_data COW on bitmap buffers in -+ all cases even if the buffer is in BJ_Forget state in the -+ committing transaction. */ -+ err = ext3_journal_get_undo_access(handle, bmbh); -+ if (err) -+ goto error_out; -+ err = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh); -+ if (err) -+ goto error_out; -+ err = ext3_journal_get_write_access(handle, bh); -+ if (err) -+ goto error_out; -+ for (i = 0; i < as.len; i++) { -+ J_ASSERT(!ext3_test_bit(bit + i, bmbh->b_data)); -+ if (buffer_jbd(bmbh) && bh2jh(bmbh)->b_committed_data) -+ check_in_committed(bmbh, bit + i); -+ set_bit(bit + i, bmbh->b_data); -+ } -+ err = ext3_journal_dirty_metadata(handle, bmbh); -+ if (err) -+ goto error_out; -+ -+ /* ... and correct group descriptor */ -+ gdp->bg_free_blocks_count = -+ cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) - as.len); -+ es->s_free_blocks_count = -+ cpu_to_le32(le32_to_cpu(es->s_free_blocks_count) - as.len); -+ err = ext3_journal_dirty_metadata(handle, bmbh); -+ if (err) -+ goto error_out; -+ err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); -+ if (err) -+ goto error_out; -+ sb->s_dirt = 1; -+ -+ if (*num != as.len) -+ DQUOT_FREE_BLOCK(inode, *num - as.len); -+ *num = as.len; -+ -+out: -+ unlock_super(sb); -+ return as.start; -+ -+error_out: -+ as.start = 0; -+ *errp = err; -+ goto out; -+} -+ -+EXPORT_SYMBOL(ext3_new_blocks); -+ -Index: linux-2.4.24/fs/ext3/file.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/file.c 2004-01-31 02:06:18.000000000 +0300 -+++ linux-2.4.24/fs/ext3/file.c 2004-02-06 10:20:46.000000000 +0300 -@@ -69,6 +69,18 @@ - int err; - struct inode *inode = file->f_dentry->d_inode; - -+#if 0 -+ /* allocate all the space to be written */ -+ if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) { -+ int blocksize = inode->i_sb->s_blocksize; -+ unsigned long start, end; -+ -+ start = (unsigned long) *ppos / blocksize; -+ end = ((unsigned long) *ppos + count + blocksize - 1) -+ / blocksize; -+ ext3_ext_allocate_nblocks(inode, start, end - start); -+ } -+#endif - ret = generic_file_write(file, buf, count, ppos); - - /* Skip file flushing code if there was an error, or if nothing -Index: linux-2.4.24/fs/ext3/Makefile -=================================================================== ---- linux-2.4.24.orig/fs/ext3/Makefile 2004-02-05 18:44:25.000000000 +0300 -+++ linux-2.4.24/fs/ext3/Makefile 2004-02-06 10:20:46.000000000 +0300 -@@ -14,7 +14,7 @@ - obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \ - ioctl.o namei.o super.o symlink.o hash.o ext3-exports.o \ - xattr_trusted.o extents.o --export-objs += extents.o -+export-objs += extents.o balloc.o - - obj-m := $(O_TARGET) - -Index: linux-2.4.24/include/linux/ext3_fs.h -=================================================================== ---- linux-2.4.24.orig/include/linux/ext3_fs.h 2004-01-30 00:09:37.000000000 +0300 -+++ linux-2.4.24/include/linux/ext3_fs.h 2004-02-06 10:20:46.000000000 +0300 -@@ -58,6 +58,8 @@ - #define ext3_debug(f, a...) do {} while (0) - #endif - -+#define EXT3_MULTIBLOCK_ALLOCATOR 1 -+ - /* - * Special inodes numbers - */ -@@ -667,6 +669,7 @@ - extern struct ext3_group_desc * ext3_get_group_desc(struct super_block * sb, - unsigned int block_group, - struct buffer_head ** bh); -+extern int ext3_new_blocks(handle_t*, struct inode*, int*, unsigned long, int*); - - /* dir.c */ - extern int ext3_check_dir_entry(const char *, struct inode *, diff --git a/lustre/kernel_patches/patches/ext3-mballoc2-2.4.24.patch b/lustre/kernel_patches/patches/ext3-mballoc2-2.4.24.patch deleted file mode 100644 index 4b6d0da..0000000 --- a/lustre/kernel_patches/patches/ext3-mballoc2-2.4.24.patch +++ /dev/null @@ -1,1762 +0,0 @@ -Index: linux-2.4.24/fs/ext3/mballoc.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/mballoc.c 2003-01-30 13:24:37.000000000 +0300 -+++ linux-2.4.24/fs/ext3/mballoc.c 2004-08-06 04:50:53.000000000 +0400 -@@ -0,0 +1,1399 @@ -+/* -+ * Copyright (c) 2004, Cluster File Systems, Inc, info@clusterfs.com -+ * Written by Alex Tomas -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public Licens -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111- -+ */ -+ -+ -+/* -+ * mballoc.c contains the multiblocks allocation routines -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* -+ * TODO: -+ * - do not scan from the beginning, try to remember first free block -+ * - mb_mark_used_* may allocate chunk right after splitting buddy -+ * - special flag to advice allocator to look for requested + N blocks -+ * this may improve interaction between extents and mballoc -+ */ -+ -+/* -+ * with AGRESSIVE_CHECK allocator runs consistency checks over -+ * structures. this checks slow things down a lot -+ */ -+#define AGGRESSIVE_CHECK__ -+ -+/* -+ */ -+#define MB_DEBUG__ -+#ifdef MB_DEBUG -+#define mb_debug(fmt,a...) printk(fmt, ##a) -+#else -+#define mb_debug(fmt,a...) -+#endif -+ -+/* -+ * where to save buddies structures beetween umount/mount (clean case only) -+ */ -+#define EXT3_BUDDY_FILE ".buddy" -+ -+/* -+ * max. number of chunks to be tracked in ext3_free_extent struct -+ */ -+#define MB_ARR_SIZE 32 -+ -+struct ext3_allocation_context { -+ struct super_block *ac_sb; -+ -+ /* search goals */ -+ int ac_g_group; -+ int ac_g_start; -+ int ac_g_len; -+ int ac_g_flags; -+ -+ /* the best found extent */ -+ int ac_b_group; -+ int ac_b_start; -+ int ac_b_len; -+ -+ /* number of iterations done. we have to track to limit searching */ -+ int ac_repeats; -+ int ac_groups_scanned; -+ int ac_status; -+}; -+ -+#define AC_STATUS_CONTINUE 1 -+#define AC_STATUS_FOUND 2 -+ -+ -+struct ext3_buddy { -+ void *bd_bitmap; -+ void *bd_buddy; -+ int bd_blkbits; -+ struct buffer_head *bd_bh; -+ struct buffer_head *bd_bh2; -+ struct ext3_buddy_group_blocks *bd_bd; -+ struct super_block *bd_sb; -+}; -+ -+struct ext3_free_extent { -+ int fe_start; -+ int fe_len; -+ unsigned char fe_orders[MB_ARR_SIZE]; -+ unsigned char fe_nums; -+ unsigned char fe_back; -+}; -+ -+#define in_range(b, first, len) ((b) >= (first) && (b) <= (first) + (len) - 1) -+ -+ -+int ext3_create (struct inode *, struct dentry *, int, struct nameidata *); -+void ext3_free_blocks_old(handle_t *, struct inode *, unsigned long, unsigned long); -+int ext3_new_block_old(handle_t *, struct inode *, unsigned long, u32 *, u32 *, int *); -+int ext3_mb_reserve_blocks(struct super_block *, int); -+void ext3_mb_release_blocks(struct super_block *, int); -+void ext3_mb_poll_new_transaction(struct super_block *, handle_t *); -+void ext3_mb_free_committed_blocks(struct super_block *); -+int load_block_bitmap (struct super_block *, unsigned int); -+ -+struct buffer_head * -+read_block_bitmap_bh(struct super_block *sb, unsigned int block_group) -+{ -+ struct buffer_head *bh; -+ int bitmap_nr; -+ -+ bitmap_nr = load_block_bitmap(sb, block_group); -+ if (bitmap_nr < 0) -+ return NULL; -+ -+ bh = EXT3_SB(sb)->s_block_bitmap[bitmap_nr]; -+ return bh; -+} -+ -+static inline void *mb_find_buddy(struct ext3_buddy *e3b, int order, int *max) -+{ -+ int i = 1; -+ void *bb; -+ -+ J_ASSERT(e3b->bd_bitmap != e3b->bd_buddy); -+ J_ASSERT(max != NULL); -+ -+ if (order > e3b->bd_blkbits + 1) -+ return NULL; -+ -+ /* at order 0 we see each particular block */ -+ *max = 1 << (e3b->bd_blkbits + 3); -+ if (order == 0) -+ return e3b->bd_bitmap; -+ -+ bb = e3b->bd_buddy; -+ *max = *max >> 1; -+ while (i < order) { -+ bb += 1 << (e3b->bd_blkbits - i); -+ i++; -+ *max = *max >> 1; -+ } -+ return bb; -+} -+ -+static int ext3_mb_load_desc(struct super_block *sb, int group, -+ struct ext3_buddy *e3b) -+{ -+ struct ext3_sb_info *sbi = EXT3_SB(sb); -+ -+ J_ASSERT(sbi->s_buddy_blocks[group].bb_bitmap); -+ J_ASSERT(sbi->s_buddy_blocks[group].bb_buddy); -+ -+ /* load bitmap */ -+ e3b->bd_bh = sb_getblk(sb, sbi->s_buddy_blocks[group].bb_bitmap); -+ if (e3b->bd_bh == NULL) { -+ ext3_error(sb, "ext3_mb_load_desc", -+ "can't get block for buddy bitmap\n"); -+ goto out; -+ } -+ if (!buffer_uptodate(e3b->bd_bh)) { -+ ll_rw_block(READ, 1, &e3b->bd_bh); -+ wait_on_buffer(e3b->bd_bh); -+ } -+ J_ASSERT(buffer_uptodate(e3b->bd_bh)); -+ -+ /* load buddy */ -+ e3b->bd_bh2 = sb_getblk(sb, sbi->s_buddy_blocks[group].bb_buddy); -+ if (e3b->bd_bh2 == NULL) { -+ ext3_error(sb, "ext3_mb_load_desc", -+ "can't get block for buddy bitmap\n"); -+ goto out; -+ } -+ if (!buffer_uptodate(e3b->bd_bh2)) { -+ ll_rw_block(READ, 1, &e3b->bd_bh2); -+ wait_on_buffer(e3b->bd_bh2); -+ } -+ J_ASSERT(buffer_uptodate(e3b->bd_bh2)); -+ -+ e3b->bd_bitmap = e3b->bd_bh->b_data; -+ e3b->bd_buddy = e3b->bd_bh2->b_data; -+ e3b->bd_blkbits = sb->s_blocksize_bits; -+ e3b->bd_bd = sbi->s_buddy_blocks + group; -+ e3b->bd_sb = sb; -+ -+ return 0; -+out: -+ brelse(e3b->bd_bh); -+ brelse(e3b->bd_bh2); -+ e3b->bd_bh = NULL; -+ e3b->bd_bh2 = NULL; -+ return -EIO; -+} -+ -+static void ext3_mb_dirty_buddy(struct ext3_buddy *e3b) -+{ -+ mark_buffer_dirty(e3b->bd_bh); -+ mark_buffer_dirty(e3b->bd_bh2); -+} -+ -+static void ext3_mb_release_desc(struct ext3_buddy *e3b) -+{ -+ brelse(e3b->bd_bh); -+ brelse(e3b->bd_bh2); -+} -+ -+#ifdef AGGRESSIVE_CHECK -+static void mb_check_buddy(struct ext3_buddy *e3b) -+{ -+ int order = e3b->bd_blkbits + 1; -+ int max, max2, i, j, k, count; -+ void *buddy, *buddy2; -+ -+ if (!test_opt(e3b->bd_sb, MBALLOC)) -+ return; -+ -+ while (order > 1) { -+ buddy = mb_find_buddy(e3b, order, &max); -+ J_ASSERT(buddy); -+ buddy2 = mb_find_buddy(e3b, order - 1, &max2); -+ J_ASSERT(buddy2); -+ J_ASSERT(buddy != buddy2); -+ J_ASSERT(max * 2 == max2); -+ -+ count = 0; -+ for (i = 0; i < max; i++) { -+ -+ if (!test_bit(i, buddy)) { -+ /* only single bit in buddy2 may be 1 */ -+ if (test_bit(i << 1, buddy2)) -+ J_ASSERT(!test_bit((i<<1)+1, buddy2)); -+ else if (test_bit((i << 1) + 1, buddy2)) -+ J_ASSERT(!test_bit(i << 1, buddy2)); -+ continue; -+ } -+ -+ /* both bits in buddy2 must be 0 */ -+ J_ASSERT(!test_bit(i << 1, buddy2)); -+ J_ASSERT(!test_bit((i << 1) + 1, buddy2)); -+ -+ for (j = 0; j < (1 << order); j++) { -+ k = (i * (1 << order)) + j; -+ J_ASSERT(test_bit(k, e3b->bd_bitmap)); -+ } -+ count++; -+ } -+ J_ASSERT(e3b->bd_bd->bb_counters[order] == count); -+ order--; -+ } -+ -+ buddy = mb_find_buddy(e3b, 0, &max); -+ for (i = 0; i < max; i++) { -+ if (test_bit(i, buddy)) -+ continue; -+ /* check used bits only */ -+ for (j = 0; j < e3b->bd_blkbits + 1; j++) { -+ buddy2 = mb_find_buddy(e3b, j, &max2); -+ k = i >> j; -+ J_ASSERT(k < max2); -+ J_ASSERT(!test_bit(k, buddy2)); -+ } -+ } -+} -+#else -+#define mb_check_buddy(e3b) -+#endif -+ -+static inline void -+ext3_lock_group(struct super_block *sb, int group) -+{ -+ spin_lock(&EXT3_SB(sb)->s_buddy_blocks[group].bb_lock); -+} -+ -+static inline void -+ext3_unlock_group(struct super_block *sb, int group) -+{ -+ spin_unlock(&EXT3_SB(sb)->s_buddy_blocks[group].bb_lock); -+} -+ -+static int mb_find_order_for_block(struct ext3_buddy *e3b, int block) -+{ -+ int order = 1; -+ void *bb; -+ -+ J_ASSERT(e3b->bd_bitmap != e3b->bd_buddy); -+ J_ASSERT(block < (1 << (e3b->bd_blkbits + 3))); -+ -+ bb = e3b->bd_buddy; -+ while (order <= e3b->bd_blkbits + 1) { -+ block = block >> 1; -+ if (test_bit(block, bb)) { -+ /* this block is part of buddy of order 'order' */ -+ return order; -+ } -+ bb += 1 << (e3b->bd_blkbits - order); -+ order++; -+ } -+ return 0; -+} -+ -+static inline void mb_clear_bits(void *bm, int cur, int len) -+{ -+ __u32 *addr; -+ -+ len = cur + len; -+ while (cur < len) { -+ if ((cur & 31) == 0 && (len - cur) >= 32) { -+ /* fast path: clear whole word at once */ -+ addr = bm + (cur >> 3); -+ *addr = 0; -+ cur += 32; -+ continue; -+ } -+ clear_bit(cur, bm); -+ cur++; -+ } -+} -+ -+static inline void mb_set_bits(void *bm, int cur, int len) -+{ -+ __u32 *addr; -+ -+ len = cur + len; -+ while (cur < len) { -+ if ((cur & 31) == 0 && (len - cur) >= 32) { -+ /* fast path: clear whole word at once */ -+ addr = bm + (cur >> 3); -+ *addr = 0xffffffff; -+ cur += 32; -+ continue; -+ } -+ set_bit(cur, bm); -+ cur++; -+ } -+} -+ -+static int mb_free_blocks(struct ext3_buddy *e3b, int first, int count) -+{ -+ int block, max, order; -+ void *buddy, *buddy2; -+ -+ mb_check_buddy(e3b); -+ while (count-- > 0) { -+ block = first++; -+ order = 0; -+ -+ J_ASSERT(!test_bit(block, e3b->bd_bitmap)); -+ set_bit(block, e3b->bd_bitmap); -+ e3b->bd_bd->bb_counters[order]++; -+ -+ /* start of the buddy */ -+ buddy = mb_find_buddy(e3b, order, &max); -+ -+ do { -+ block &= ~1UL; -+ if (!test_bit(block, buddy) || -+ !test_bit(block + 1, buddy)) -+ break; -+ -+ /* both the buddies are free, try to coalesce them */ -+ buddy2 = mb_find_buddy(e3b, order + 1, &max); -+ -+ if (!buddy2) -+ break; -+ -+ if (order > 0) { -+ /* for special purposes, we don't clear -+ * free bits in bitmap */ -+ clear_bit(block, buddy); -+ clear_bit(block + 1, buddy); -+ } -+ e3b->bd_bd->bb_counters[order]--; -+ e3b->bd_bd->bb_counters[order]--; -+ -+ block = block >> 1; -+ order++; -+ e3b->bd_bd->bb_counters[order]++; -+ -+ set_bit(block, buddy2); -+ buddy = buddy2; -+ } while (1); -+ } -+ mb_check_buddy(e3b); -+ -+ return 0; -+} -+ -+/* -+ * returns 1 if out extent is enough to fill needed space -+ */ -+int mb_make_backward_extent(struct ext3_free_extent *in, -+ struct ext3_free_extent *out, int needed) -+{ -+ int i; -+ -+ J_ASSERT(in); -+ J_ASSERT(out); -+ J_ASSERT(in->fe_nums < MB_ARR_SIZE); -+ -+ out->fe_len = 0; -+ out->fe_start = in->fe_start + in->fe_len; -+ out->fe_nums = 0; -+ -+ /* for single-chunk extent we need not back order -+ * also, if an extent doesn't fill needed space -+ * then it makes no sense to try back order becase -+ * if we select this extent then it'll be use as is */ -+ if (in->fe_nums < 2 || in->fe_len < needed) -+ return 0; -+ -+ i = in->fe_nums - 1; -+ while (i >= 0 && out->fe_len < needed) { -+ out->fe_len += (1 << in->fe_orders[i]); -+ out->fe_start -= (1 << in->fe_orders[i]); -+ i--; -+ } -+ /* FIXME: in some situation fe_orders may be too small to hold -+ * all the buddies */ -+ J_ASSERT(out->fe_len >= needed); -+ -+ for (i++; i < in->fe_nums; i++) -+ out->fe_orders[out->fe_nums++] = in->fe_orders[i]; -+ J_ASSERT(out->fe_nums < MB_ARR_SIZE); -+ out->fe_back = 1; -+ -+ return 1; -+} -+ -+int mb_find_extent(struct ext3_buddy *e3b, int order, int block, -+ int needed, struct ext3_free_extent *ex) -+{ -+ int space = needed; -+ int next, max, ord; -+ void *buddy; -+ -+ J_ASSERT(ex != NULL); -+ -+ ex->fe_nums = 0; -+ ex->fe_len = 0; -+ -+ buddy = mb_find_buddy(e3b, order, &max); -+ J_ASSERT(buddy); -+ J_ASSERT(block < max); -+ if (!test_bit(block, buddy)) -+ goto nofree; -+ -+ if (order == 0) { -+ /* find actual order */ -+ order = mb_find_order_for_block(e3b, block); -+ block = block >> order; -+ } -+ -+ ex->fe_orders[ex->fe_nums++] = order; -+ ex->fe_len = 1 << order; -+ ex->fe_start = block << order; -+ ex->fe_back = 0; -+ -+ while ((space = space - (1 << order)) > 0) { -+ -+ buddy = mb_find_buddy(e3b, order, &max); -+ J_ASSERT(buddy); -+ -+ if (block + 1 >= max) -+ break; -+ -+ next = (block + 1) * (1 << order); -+ if (!test_bit(next, e3b->bd_bitmap)) -+ break; -+ -+ ord = mb_find_order_for_block(e3b, next); -+ -+ if ((1 << ord) >= needed) { -+ /* we dont want to coalesce with self-enough buddies */ -+ break; -+ } -+ order = ord; -+ block = next >> order; -+ ex->fe_len += 1 << order; -+ -+ if (ex->fe_nums < MB_ARR_SIZE) -+ ex->fe_orders[ex->fe_nums++] = order; -+ } -+ -+nofree: -+ J_ASSERT(ex->fe_start + ex->fe_len <= (1 << (e3b->bd_blkbits + 3))); -+ return ex->fe_len; -+} -+ -+static int mb_mark_used_backward(struct ext3_buddy *e3b, -+ struct ext3_free_extent *ex, int len) -+{ -+ int start = ex->fe_start, len0 = len; -+ int ord, mlen, max, cur; -+ void *buddy; -+ -+ start = ex->fe_start + ex->fe_len - 1; -+ while (len) { -+ ord = mb_find_order_for_block(e3b, start); -+ if (((start >> ord) << ord) == (start - (1 << ord) + 1) && -+ len >= (1 << ord)) { -+ /* the whole chunk may be allocated at once! */ -+ mlen = 1 << ord; -+ buddy = mb_find_buddy(e3b, ord, &max); -+ J_ASSERT((start >> ord) < max); -+ clear_bit(start >> ord, buddy); -+ e3b->bd_bd->bb_counters[ord]--; -+ start -= mlen; -+ len -= mlen; -+ J_ASSERT(len >= 0); -+ J_ASSERT(start >= 0); -+ continue; -+ } -+ -+ /* we have to split large buddy */ -+ J_ASSERT(ord > 0); -+ buddy = mb_find_buddy(e3b, ord, &max); -+ clear_bit(start >> ord, buddy); -+ e3b->bd_bd->bb_counters[ord]--; -+ -+ ord--; -+ cur = (start >> ord) & ~1U; -+ buddy = mb_find_buddy(e3b, ord, &max); -+ set_bit(cur, buddy); -+ set_bit(cur + 1, buddy); -+ e3b->bd_bd->bb_counters[ord]++; -+ e3b->bd_bd->bb_counters[ord]++; -+ } -+ -+ /* now drop all the bits in bitmap */ -+ mb_clear_bits(e3b->bd_bitmap, ex->fe_start + ex->fe_len - len0, len0); -+ -+ mb_check_buddy(e3b); -+ -+ return 0; -+} -+ -+static int mb_mark_used_forward(struct ext3_buddy *e3b, -+ struct ext3_free_extent *ex, int len) -+{ -+ int start = ex->fe_start, len0 = len; -+ int ord, mlen, max, cur; -+ void *buddy; -+ -+ while (len) { -+ ord = mb_find_order_for_block(e3b, start); -+ -+ if (((start >> ord) << ord) == start && len >= (1 << ord)) { -+ /* the whole chunk may be allocated at once! */ -+ mlen = 1 << ord; -+ buddy = mb_find_buddy(e3b, ord, &max); -+ J_ASSERT((start >> ord) < max); -+ clear_bit(start >> ord, buddy); -+ e3b->bd_bd->bb_counters[ord]--; -+ start += mlen; -+ len -= mlen; -+ J_ASSERT(len >= 0); -+ continue; -+ } -+ -+ /* we have to split large buddy */ -+ J_ASSERT(ord > 0); -+ buddy = mb_find_buddy(e3b, ord, &max); -+ clear_bit(start >> ord, buddy); -+ e3b->bd_bd->bb_counters[ord]--; -+ -+ ord--; -+ cur = (start >> ord) & ~1U; -+ buddy = mb_find_buddy(e3b, ord, &max); -+ set_bit(cur, buddy); -+ set_bit(cur + 1, buddy); -+ e3b->bd_bd->bb_counters[ord]++; -+ e3b->bd_bd->bb_counters[ord]++; -+ } -+ -+ /* now drop all the bits in bitmap */ -+ mb_clear_bits(e3b->bd_bitmap, ex->fe_start, len0); -+ -+ mb_check_buddy(e3b); -+ -+ return 0; -+} -+ -+int inline mb_mark_used(struct ext3_buddy *e3b, -+ struct ext3_free_extent *ex, int len) -+{ -+ int err; -+ -+ J_ASSERT(ex); -+ if (ex->fe_back == 0) -+ err = mb_mark_used_forward(e3b, ex, len); -+ else -+ err = mb_mark_used_backward(e3b, ex, len); -+ return err; -+} -+ -+int ext3_mb_new_in_group(struct ext3_allocation_context *ac, -+ struct ext3_buddy *e3b, int group) -+{ -+ struct super_block *sb = ac->ac_sb; -+ int err, gorder, max, i; -+ struct ext3_free_extent curex; -+ -+ /* let's know order of allocation */ -+ gorder = 0; -+ while (ac->ac_g_len > (1 << gorder)) -+ gorder++; -+ -+ if ((ac->ac_g_flags & 1) && ac->ac_g_group == group) { -+ /* someone asks for space at this specified block -+ * probably he wants to merge it into existing extent */ -+ if (test_bit(ac->ac_g_start, e3b->bd_bitmap)) { -+ /* good. at least one block is free */ -+ max = mb_find_extent(e3b, 0, ac->ac_g_start, -+ ac->ac_g_len, &curex); -+ max = min(curex.fe_len, ac->ac_g_len); -+ mb_mark_used(e3b, &curex, max); -+ -+ ac->ac_b_group = group; -+ ac->ac_b_start = curex.fe_start; -+ ac->ac_b_len = max; -+ ac->ac_status = AC_STATUS_FOUND; -+ err = 0; -+ goto out; -+ } -+ /* don't try to find goal anymore */ -+ ac->ac_g_flags &= ~1; -+ } -+ -+ i = 0; -+ while (1) { -+ i = find_next_bit(e3b->bd_bitmap, sb->s_blocksize * 8, i); -+ if (i >= sb->s_blocksize * 8) -+ break; -+ -+ max = mb_find_extent(e3b, 0, i, ac->ac_g_len, &curex); -+ if (max >= ac->ac_g_len) { -+ max = min(curex.fe_len, ac->ac_g_len); -+ mb_mark_used(e3b, &curex, max); -+ -+ ac->ac_b_group = group; -+ ac->ac_b_start = curex.fe_start; -+ ac->ac_b_len = max; -+ ac->ac_status = AC_STATUS_FOUND; -+ break; -+ } -+ i += max; -+ } -+ -+ return 0; -+ -+out: -+ return err; -+} -+ -+int mb_good_group(struct ext3_allocation_context *ac, int group, int cr) -+{ -+ struct ext3_group_desc *gdp; -+ int free_blocks; -+ -+ gdp = ext3_get_group_desc(ac->ac_sb, group, NULL); -+ if (!gdp) -+ return 0; -+ free_blocks = le16_to_cpu(gdp->bg_free_blocks_count); -+ if (free_blocks == 0) -+ return 0; -+ -+ /* someone wants this block very much */ -+ if ((ac->ac_g_flags & 1) && ac->ac_g_group == group) -+ return 1; -+ -+ /* FIXME: I'd like to take fragmentation into account here */ -+ if (cr == 0) { -+ if (free_blocks >= ac->ac_g_len >> 1) -+ return 1; -+ } else if (cr == 1) { -+ if (free_blocks >= ac->ac_g_len >> 2) -+ return 1; -+ } else if (cr == 2) { -+ return 1; -+ } else { -+ BUG(); -+ } -+ return 0; -+} -+ -+int ext3_mb_new_blocks(handle_t *handle, struct inode *inode, -+ unsigned long goal, int *len, int flags, int *errp) -+{ -+ struct buffer_head *bitmap_bh = NULL; -+ struct ext3_allocation_context ac; -+ int i, group, block, cr, err = 0; -+ struct ext3_group_desc *gdp; -+ struct ext3_super_block *es; -+ struct buffer_head *gdp_bh; -+ struct ext3_sb_info *sbi; -+ struct super_block *sb; -+ struct ext3_buddy e3b; -+ -+ J_ASSERT(len != NULL); -+ J_ASSERT(*len > 0); -+ -+ sb = inode->i_sb; -+ if (!sb) { -+ printk("ext3_mb_new_nblocks: nonexistent device"); -+ return 0; -+ } -+ -+ ext3_mb_poll_new_transaction(sb, handle); -+ -+ sbi = EXT3_SB(sb); -+ es = EXT3_SB(sb)->s_es; -+ -+ if (!(flags & 2)) { -+ /* someone asks for non-reserved blocks */ -+ BUG_ON(*len > 1); -+ err = ext3_mb_reserve_blocks(sb, 1); -+ if (err) { -+ *errp = err; -+ return 0; -+ } -+ } -+ -+ /* -+ * Check quota for allocation of this blocks. -+ */ -+ while (*len && DQUOT_ALLOC_BLOCK(inode, *len)) -+ *len -= 1; -+ if (*len == 0) { -+ *errp = -EDQUOT; -+ block = 0; -+ goto out; -+ } -+ -+ /* start searching from the goal */ -+ if (goal < le32_to_cpu(es->s_first_data_block) || -+ goal >= le32_to_cpu(es->s_blocks_count)) -+ goal = le32_to_cpu(es->s_first_data_block); -+ group = (goal - le32_to_cpu(es->s_first_data_block)) / -+ EXT3_BLOCKS_PER_GROUP(sb); -+ block = ((goal - le32_to_cpu(es->s_first_data_block)) % -+ EXT3_BLOCKS_PER_GROUP(sb)); -+ -+ /* set up allocation goals */ -+ ac.ac_b_group = ac.ac_b_start = ac.ac_b_len = 0; -+ ac.ac_status = 0; -+ ac.ac_groups_scanned = 0; -+ ac.ac_sb = inode->i_sb; -+ ac.ac_g_group = group; -+ ac.ac_g_start = block; -+ ac.ac_g_len = *len; -+ ac.ac_g_flags = flags; -+ -+ /* loop over the groups */ -+ for (cr = 0; cr < 3 && ac.ac_status != AC_STATUS_FOUND; cr++) { -+ for (i = 0; i < EXT3_SB(sb)->s_groups_count; group++, i++) { -+ if (group == EXT3_SB(sb)->s_groups_count) -+ group = 0; -+ -+ /* check is group good for our criteries */ -+ if (!mb_good_group(&ac, group, cr)) -+ continue; -+ -+ err = ext3_mb_load_desc(ac.ac_sb, group, &e3b); -+ if (err) -+ goto out_err; -+ -+ ext3_lock_group(sb, group); -+ if (!mb_good_group(&ac, group, cr)) { -+ /* someone did allocation from this group */ -+ ext3_unlock_group(sb, group); -+ ext3_mb_release_desc(&e3b); -+ continue; -+ } -+ -+ err = ext3_mb_new_in_group(&ac, &e3b, group); -+ ext3_unlock_group(sb, group); -+ if (ac.ac_status == AC_STATUS_FOUND) -+ ext3_mb_dirty_buddy(&e3b); -+ ext3_mb_release_desc(&e3b); -+ if (err) -+ goto out_err; -+ if (ac.ac_status == AC_STATUS_FOUND) -+ break; -+ } -+ } -+ -+ if (ac.ac_status != AC_STATUS_FOUND) { -+ /* unfortunately, we can't satisfy this request */ -+ J_ASSERT(ac.ac_b_len == 0); -+ DQUOT_FREE_BLOCK(inode, *len); -+ *errp = -ENOSPC; -+ block = 0; -+ goto out; -+ } -+ -+ /* good news - free block(s) have been found. now it's time -+ * to mark block(s) in good old journaled bitmap */ -+ block = ac.ac_b_group * EXT3_BLOCKS_PER_GROUP(sb) -+ + ac.ac_b_start + le32_to_cpu(es->s_first_data_block); -+ -+ /* we made a desicion, now mark found blocks in good old -+ * bitmap to be journaled */ -+ -+ ext3_debug("using block group %d(%d)\n", -+ ac.ac_b_group.group, gdp->bg_free_blocks_count); -+ -+ bitmap_bh = read_block_bitmap_bh(sb, ac.ac_b_group); -+ if (!bitmap_bh) { -+ *errp = -EIO; -+ goto out_err; -+ } -+ -+ err = ext3_journal_get_write_access(handle, bitmap_bh); -+ if (err) { -+ *errp = err; -+ goto out_err; -+ } -+ -+ gdp = ext3_get_group_desc(sb, ac.ac_b_group, &gdp_bh); -+ if (!gdp) { -+ *errp = -EIO; -+ goto out_err; -+ } -+ -+ err = ext3_journal_get_write_access(handle, gdp_bh); -+ if (err) -+ goto out_err; -+ -+ block = ac.ac_b_start + ac.ac_b_group * EXT3_BLOCKS_PER_GROUP(sb) -+ + le32_to_cpu(es->s_first_data_block); -+ -+ if (block == le32_to_cpu(gdp->bg_block_bitmap) || -+ block == le32_to_cpu(gdp->bg_inode_bitmap) || -+ in_range(block, le32_to_cpu(gdp->bg_inode_table), -+ EXT3_SB(sb)->s_itb_per_group)) -+ ext3_error(sb, "ext3_new_block", -+ "Allocating block in system zone - " -+ "block = %u", block); -+#if 0 -+ for (i = 0; i < ac.ac_b_len; i++) -+ J_ASSERT(!test_bit(ac.ac_b_start + i, bitmap_bh->b_data)); -+#endif -+ mb_set_bits(bitmap_bh->b_data, ac.ac_b_start, ac.ac_b_len); -+ -+ ext3_lock_group(sb, ac.ac_b_group); -+ gdp->bg_free_blocks_count = -+ cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) - -+ ac.ac_b_len); -+ ext3_unlock_group(sb, ac.ac_b_group); -+ spin_lock(&sbi->s_md_lock); -+ es->s_free_blocks_count = -+ cpu_to_le32(le32_to_cpu(es->s_free_blocks_count) - ac.ac_b_len); -+ spin_unlock(&sbi->s_md_lock); -+ -+ err = ext3_journal_dirty_metadata(handle, bitmap_bh); -+ if (err) -+ goto out_err; -+ err = ext3_journal_dirty_metadata(handle, gdp_bh); -+ if (err) -+ goto out_err; -+ -+ sb->s_dirt = 1; -+ *errp = 0; -+ -+ /* drop non-allocated, but dquote'd blocks */ -+ J_ASSERT(*len >= ac.ac_b_len); -+ DQUOT_FREE_BLOCK(inode, *len - ac.ac_b_len); -+ -+ *len = ac.ac_b_len; -+ J_ASSERT(block != 0); -+ goto out; -+ -+out_err: -+ /* if we've already allocated something, roll it back */ -+ if (ac.ac_status == AC_STATUS_FOUND) { -+ /* FIXME: free blocks here */ -+ } -+ -+ DQUOT_FREE_BLOCK(inode, *len); -+ *errp = err; -+ block = 0; -+out: -+ if (!(flags & 2)) { -+ /* block wasn't reserved before and we reserved it -+ * at the beginning of allocation. it doesn't matter -+ * whether we allocated anything or we failed: time -+ * to release reservation. NOTE: because I expect -+ * any multiblock request from delayed allocation -+ * path only, here is single block always */ -+ ext3_mb_release_blocks(sb, 1); -+ } -+ return block; -+} -+ -+int ext3_mb_generate_buddy(struct super_block *sb, int group) -+{ -+ struct buffer_head *bh; -+ int i, err, count = 0; -+ struct ext3_buddy e3b; -+ -+ err = ext3_mb_load_desc(sb, group, &e3b); -+ if (err) -+ goto out; -+ memset(e3b.bd_bh->b_data, 0, sb->s_blocksize); -+ memset(e3b.bd_bh2->b_data, 0, sb->s_blocksize); -+ -+ bh = read_block_bitmap_bh(sb, group); -+ if (bh == NULL) { -+ err = -EIO; -+ goto out2; -+ } -+ -+ /* loop over the blocks, nad create buddies for free ones */ -+ for (i = 0; i < sb->s_blocksize * 8; i++) { -+ if (!test_bit(i, (void *) bh->b_data)) { -+ mb_free_blocks(&e3b, i, 1); -+ count++; -+ } -+ } -+ mb_check_buddy(&e3b); -+ ext3_mb_dirty_buddy(&e3b); -+ -+out2: -+ ext3_mb_release_desc(&e3b); -+out: -+ return err; -+} -+ -+#define MB_CREDITS \ -+ (EXT3_DATA_TRANS_BLOCKS + 3 + EXT3_INDEX_EXTRA_TRANS_BLOCKS) -+ -+int ext3_mb_init_backend(struct super_block *sb) -+{ -+ struct inode *root = sb->s_root->d_inode; -+ struct ext3_sb_info *sbi = EXT3_SB(sb); -+ struct dentry *db; -+ tid_t target; -+ int err, i; -+ -+ sbi->s_buddy_blocks = kmalloc(sizeof(struct ext3_buddy_group_blocks) * -+ sbi->s_groups_count, GFP_KERNEL); -+ if (sbi->s_buddy_blocks == NULL) { -+ printk("can't allocate mem for buddy maps\n"); -+ return -ENOMEM; -+ } -+ memset(sbi->s_buddy_blocks, 0, -+ sizeof(struct ext3_buddy_group_blocks) * sbi->s_groups_count); -+ sbi->s_buddy = NULL; -+ -+ down(&root->i_sem); -+ db = lookup_one_len(EXT3_BUDDY_FILE, sb->s_root, -+ strlen(EXT3_BUDDY_FILE)); -+ if (IS_ERR(db)) { -+ err = PTR_ERR(db); -+ printk("can't lookup buddy file: %d\n", err); -+ goto out; -+ } -+ -+ if (db->d_inode != NULL) { -+ sbi->s_buddy = igrab(db->d_inode); -+ goto map; -+ } -+ -+ err = ext3_create(root, db, S_IFREG, NULL); -+ if (err) { -+ printk("error while creation buddy file: %d\n", err); -+ } else { -+ sbi->s_buddy = igrab(db->d_inode); -+ } -+ -+map: -+ for (i = 0; i < sbi->s_groups_count; i++) { -+ struct buffer_head *bh = NULL; -+ handle_t *handle; -+ -+ handle = ext3_journal_start(sbi->s_buddy, MB_CREDITS); -+ if (IS_ERR(handle)) { -+ err = PTR_ERR(handle); -+ goto out2; -+ } -+ -+ /* allocate block for bitmap */ -+ bh = ext3_getblk(handle, sbi->s_buddy, i * 2, 1, &err); -+ if (bh == NULL) { -+ printk("can't get block for buddy bitmap: %d\n", err); -+ goto out2; -+ } -+ sbi->s_buddy_blocks[i].bb_bitmap = bh->b_blocknr; -+ brelse(bh); -+ -+ /* allocate block for buddy */ -+ bh = ext3_getblk(handle, sbi->s_buddy, i * 2 + 1, 1, &err); -+ if (bh == NULL) { -+ printk("can't get block for buddy: %d\n", err); -+ goto out2; -+ } -+ sbi->s_buddy_blocks[i].bb_buddy = bh->b_blocknr; -+ brelse(bh); -+ ext3_journal_stop(handle, sbi->s_buddy); -+ spin_lock_init(&sbi->s_buddy_blocks[i].bb_lock); -+ sbi->s_buddy_blocks[i].bb_md_cur = NULL; -+ sbi->s_buddy_blocks[i].bb_tid = 0; -+ } -+ -+ if ((target = log_start_commit(sbi->s_journal, NULL))) -+ log_wait_commit(sbi->s_journal, target); -+ -+out2: -+ dput(db); -+out: -+ up(&root->i_sem); -+ return err; -+} -+ -+int ext3_mb_release(struct super_block *sb) -+{ -+ struct ext3_sb_info *sbi = EXT3_SB(sb); -+ -+ if (!test_opt(sb, MBALLOC)) -+ return 0; -+ -+ /* release freed, non-committed blocks */ -+ spin_lock(&sbi->s_md_lock); -+ list_splice_init(&sbi->s_closed_transaction, -+ &sbi->s_committed_transaction); -+ list_splice_init(&sbi->s_active_transaction, -+ &sbi->s_committed_transaction); -+ spin_unlock(&sbi->s_md_lock); -+ ext3_mb_free_committed_blocks(sb); -+ -+ if (sbi->s_buddy_blocks) -+ kfree(sbi->s_buddy_blocks); -+ if (sbi->s_buddy) -+ iput(sbi->s_buddy); -+ if (sbi->s_blocks_reserved) -+ printk("ext3-fs: %ld blocks being reserved at umount!\n", -+ sbi->s_blocks_reserved); -+ return 0; -+} -+ -+int ext3_mb_init(struct super_block *sb) -+{ -+ struct ext3_super_block *es; -+ int i; -+ -+ if (!test_opt(sb, MBALLOC)) -+ return 0; -+ -+ /* init file for buddy data */ -+ clear_opt(EXT3_SB(sb)->s_mount_opt, MBALLOC); -+ ext3_mb_init_backend(sb); -+ -+ es = EXT3_SB(sb)->s_es; -+ for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) -+ ext3_mb_generate_buddy(sb, i); -+ spin_lock_init(&EXT3_SB(sb)->s_reserve_lock); -+ spin_lock_init(&EXT3_SB(sb)->s_md_lock); -+ INIT_LIST_HEAD(&EXT3_SB(sb)->s_active_transaction); -+ INIT_LIST_HEAD(&EXT3_SB(sb)->s_closed_transaction); -+ INIT_LIST_HEAD(&EXT3_SB(sb)->s_committed_transaction); -+ set_opt(EXT3_SB(sb)->s_mount_opt, MBALLOC); -+ printk("EXT3-fs: mballoc enabled\n"); -+ return 0; -+} -+ -+void ext3_mb_free_committed_blocks(struct super_block *sb) -+{ -+ struct ext3_sb_info *sbi = EXT3_SB(sb); -+ int err, i, count = 0, count2 = 0; -+ struct ext3_free_metadata *md; -+ struct ext3_buddy e3b; -+ -+ if (list_empty(&sbi->s_committed_transaction)) -+ return; -+ -+ /* there is committed blocks to be freed yet */ -+ do { -+ /* get next array of blocks */ -+ md = NULL; -+ spin_lock(&sbi->s_md_lock); -+ if (!list_empty(&sbi->s_committed_transaction)) { -+ md = list_entry(sbi->s_committed_transaction.next, -+ struct ext3_free_metadata, list); -+ list_del(&md->list); -+ } -+ spin_unlock(&sbi->s_md_lock); -+ -+ if (md == NULL) -+ break; -+ -+ mb_debug("gonna free %u blocks in group %u (0x%p):", -+ md->num, md->group, md); -+ -+ err = ext3_mb_load_desc(sb, md->group, &e3b); -+ BUG_ON(err != 0); -+ -+ /* there are blocks to put in buddy to make them really free */ -+ count += md->num; -+ count2++; -+ ext3_lock_group(sb, md->group); -+ for (i = 0; i < md->num; i++) { -+ mb_debug(" %u", md->blocks[i]); -+ mb_free_blocks(&e3b, md->blocks[i], 1); -+ } -+ mb_debug("\n"); -+ ext3_unlock_group(sb, md->group); -+ -+ kfree(md); -+ ext3_mb_dirty_buddy(&e3b); -+ ext3_mb_release_desc(&e3b); -+ -+ } while (md); -+ mb_debug("freed %u blocks in %u structures\n", count, count2); -+} -+ -+void ext3_mb_poll_new_transaction(struct super_block *sb, handle_t *handle) -+{ -+ struct ext3_sb_info *sbi = EXT3_SB(sb); -+ -+ if (sbi->s_last_transaction == handle->h_transaction->t_tid) -+ return; -+ -+ /* new transaction! time to close last one and free blocks for -+ * committed transaction. we know that only transaction can be -+ * active, so previos transaction can be being logged and we -+ * know that transaction before previous is known to be alreade -+ * logged. this means that now we may free blocks freed in all -+ * transactions before previous one. hope I'm clear enough ... */ -+ -+ spin_lock(&sbi->s_md_lock); -+ if (sbi->s_last_transaction != handle->h_transaction->t_tid) { -+ mb_debug("new transaction %lu, old %lu\n", -+ (unsigned long) handle->h_transaction->t_tid, -+ (unsigned long) sbi->s_last_transaction); -+ list_splice_init(&sbi->s_closed_transaction, -+ &sbi->s_committed_transaction); -+ list_splice_init(&sbi->s_active_transaction, -+ &sbi->s_closed_transaction); -+ sbi->s_last_transaction = handle->h_transaction->t_tid; -+ } -+ spin_unlock(&sbi->s_md_lock); -+ -+ ext3_mb_free_committed_blocks(sb); -+} -+ -+int ext3_mb_free_metadata(handle_t *handle, struct ext3_buddy *e3b, -+ int group, int block, int count) -+{ -+ struct ext3_buddy_group_blocks *db = e3b->bd_bd; -+ struct super_block *sb = e3b->bd_sb; -+ struct ext3_sb_info *sbi = EXT3_SB(sb); -+ struct ext3_free_metadata *md; -+ int i; -+ -+ ext3_lock_group(sb, group); -+ for (i = 0; i < count; i++) { -+ md = db->bb_md_cur; -+ if (md && db->bb_tid != handle->h_transaction->t_tid) { -+ db->bb_md_cur = NULL; -+ md = NULL; -+ } -+ -+ if (md == NULL) { -+ ext3_unlock_group(sb, group); -+ md = kmalloc(sizeof(*md), GFP_KERNEL); -+ if (md == NULL) -+ return -ENOMEM; -+ md->num = 0; -+ md->group = group; -+ -+ ext3_lock_group(sb, group); -+ if (db->bb_md_cur == NULL) { -+ spin_lock(&sbi->s_md_lock); -+ list_add(&md->list, &sbi->s_active_transaction); -+ spin_unlock(&sbi->s_md_lock); -+ db->bb_md_cur = md; -+ db->bb_tid = handle->h_transaction->t_tid; -+ mb_debug("new md 0x%p for group %u\n", -+ md, md->group); -+ } else { -+ kfree(md); -+ md = db->bb_md_cur; -+ } -+ } -+ -+ BUG_ON(md->num >= EXT3_BB_MAX_BLOCKS); -+ md->blocks[md->num] = block + i; -+ md->num++; -+ if (md->num == EXT3_BB_MAX_BLOCKS) { -+ /* no more space, put full container on a sb's list */ -+ db->bb_md_cur = NULL; -+ } -+ } -+ ext3_unlock_group(sb, group); -+ return 0; -+} -+ -+void ext3_mb_free_blocks(handle_t *handle, struct inode *inode, -+ unsigned long block, unsigned long count, int metadata) -+{ -+ struct buffer_head *bitmap_bh = NULL; -+ struct ext3_group_desc *gdp; -+ struct ext3_super_block *es; -+ unsigned long bit, overflow; -+ struct buffer_head *gd_bh; -+ unsigned long block_group; -+ struct ext3_sb_info *sbi; -+ struct super_block *sb; -+ struct ext3_buddy e3b; -+ int err = 0, ret; -+ -+ sb = inode->i_sb; -+ if (!sb) { -+ printk ("ext3_free_blocks: nonexistent device"); -+ return; -+ } -+ -+ ext3_mb_poll_new_transaction(sb, handle); -+ -+ sbi = EXT3_SB(sb); -+ es = EXT3_SB(sb)->s_es; -+ if (block < le32_to_cpu(es->s_first_data_block) || -+ block + count < block || -+ block + count > le32_to_cpu(es->s_blocks_count)) { -+ ext3_error (sb, "ext3_free_blocks", -+ "Freeing blocks not in datazone - " -+ "block = %lu, count = %lu", block, count); -+ goto error_return; -+ } -+ -+ ext3_debug("freeing block %lu\n", block); -+ -+do_more: -+ overflow = 0; -+ block_group = (block - le32_to_cpu(es->s_first_data_block)) / -+ EXT3_BLOCKS_PER_GROUP(sb); -+ bit = (block - le32_to_cpu(es->s_first_data_block)) % -+ EXT3_BLOCKS_PER_GROUP(sb); -+ /* -+ * Check to see if we are freeing blocks across a group -+ * boundary. -+ */ -+ if (bit + count > EXT3_BLOCKS_PER_GROUP(sb)) { -+ overflow = bit + count - EXT3_BLOCKS_PER_GROUP(sb); -+ count -= overflow; -+ } -+ bitmap_bh = read_block_bitmap_bh(sb, block_group); -+ if (!bitmap_bh) -+ goto error_return; -+ gdp = ext3_get_group_desc (sb, block_group, &gd_bh); -+ if (!gdp) -+ goto error_return; -+ -+ if (in_range (le32_to_cpu(gdp->bg_block_bitmap), block, count) || -+ in_range (le32_to_cpu(gdp->bg_inode_bitmap), block, count) || -+ in_range (block, le32_to_cpu(gdp->bg_inode_table), -+ EXT3_SB(sb)->s_itb_per_group) || -+ in_range (block + count - 1, le32_to_cpu(gdp->bg_inode_table), -+ EXT3_SB(sb)->s_itb_per_group)) -+ ext3_error (sb, "ext3_free_blocks", -+ "Freeing blocks in system zones - " -+ "Block = %lu, count = %lu", -+ block, count); -+ -+ BUFFER_TRACE(bitmap_bh, "getting write access"); -+ err = ext3_journal_get_write_access(handle, bitmap_bh); -+ if (err) -+ goto error_return; -+ -+ /* -+ * We are about to modify some metadata. Call the journal APIs -+ * to unshare ->b_data if a currently-committing transaction is -+ * using it -+ */ -+ BUFFER_TRACE(gd_bh, "get_write_access"); -+ err = ext3_journal_get_write_access(handle, gd_bh); -+ if (err) -+ goto error_return; -+ -+ err = ext3_mb_load_desc(sb, block_group, &e3b); -+ if (err) -+ goto error_return; -+ -+ if (metadata) { -+ /* blocks being freed are metadata. these blocks shouldn't -+ * be used until this transaction is committed */ -+ ext3_mb_free_metadata(handle, &e3b, block_group, bit, count); -+ } else { -+ ext3_lock_group(sb, block_group); -+ mb_free_blocks(&e3b, bit, count); -+ gdp->bg_free_blocks_count = -+ cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) + count); -+ ext3_unlock_group(sb, block_group); -+ spin_lock(&sbi->s_md_lock); -+ es->s_free_blocks_count = -+ cpu_to_le32(le32_to_cpu(es->s_free_blocks_count) + count); -+ spin_unlock(&sbi->s_md_lock); -+ } -+ -+ ext3_mb_dirty_buddy(&e3b); -+ ext3_mb_release_desc(&e3b); -+ -+ /* FIXME: undo logic will be implemented later and another way */ -+ mb_clear_bits(bitmap_bh->b_data, bit, count); -+ DQUOT_FREE_BLOCK(inode, count); -+ -+ /* We dirtied the bitmap block */ -+ BUFFER_TRACE(bitmap_bh, "dirtied bitmap block"); -+ err = ext3_journal_dirty_metadata(handle, bitmap_bh); -+ -+ /* And the group descriptor block */ -+ BUFFER_TRACE(gd_bh, "dirtied group descriptor block"); -+ ret = ext3_journal_dirty_metadata(handle, gd_bh); -+ if (!err) err = ret; -+ -+ if (overflow && !err) { -+ block += count; -+ count = overflow; -+ goto do_more; -+ } -+ sb->s_dirt = 1; -+error_return: -+ ext3_std_error(sb, err); -+ return; -+} -+ -+int ext3_mb_reserve_blocks(struct super_block *sb, int blocks) -+{ -+ struct ext3_sb_info *sbi = EXT3_SB(sb); -+ struct ext3_super_block *es; -+ int free, ret = -ENOSPC; -+ -+ BUG_ON(blocks < 0); -+ es = EXT3_SB(sb)->s_es; -+ spin_lock(&sbi->s_reserve_lock); -+ free = le32_to_cpu(es->s_free_blocks_count); -+ if (blocks <= free - sbi->s_blocks_reserved) { -+ sbi->s_blocks_reserved += blocks; -+ ret = 0; -+ } -+ spin_unlock(&sbi->s_reserve_lock); -+ return ret; -+} -+ -+void ext3_mb_release_blocks(struct super_block *sb, int blocks) -+{ -+ struct ext3_sb_info *sbi = EXT3_SB(sb); -+ -+ BUG_ON(blocks < 0); -+ spin_lock(&sbi->s_reserve_lock); -+ sbi->s_blocks_reserved -= blocks; -+ if (sbi->s_blocks_reserved < 0) -+ printk("EXT3-fs: reserve leak %ld\n", sbi->s_blocks_reserved); -+ if (sbi->s_blocks_reserved < 0) -+ sbi->s_blocks_reserved = 0; -+ spin_unlock(&sbi->s_reserve_lock); -+} -+ -+int ext3_new_block(handle_t *handle, struct inode *inode, -+ unsigned long goal, u32 *pc, u32 *pb, int *errp) -+{ -+ int ret, len; -+ -+ if (!test_opt(inode->i_sb, MBALLOC)) { -+ ret = ext3_new_block_old(handle, inode, goal, pc, pb, errp); -+ goto out; -+ } -+ len = 1; -+ ret = ext3_mb_new_blocks(handle, inode, goal, &len, 0, errp); -+out: -+ return ret; -+} -+ -+ -+void ext3_free_blocks(handle_t *handle, struct inode * inode, -+ unsigned long block, unsigned long count, int metadata) -+{ -+ if (!test_opt(inode->i_sb, MBALLOC)) -+ ext3_free_blocks_old(handle, inode, block, count); -+ else -+ ext3_mb_free_blocks(handle, inode, block, count, metadata); -+ return; -+} -+ -Index: linux-2.4.24/fs/ext3/super.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/super.c 2004-08-06 03:59:09.000000000 +0400 -+++ linux-2.4.24/fs/ext3/super.c 2004-08-06 03:59:09.000000000 +0400 -@@ -529,6 +529,7 @@ - kdev_t j_dev = sbi->s_journal->j_dev; - int i; - -+ ext3_mb_release(sb); - J_ASSERT(sbi->s_delete_inodes == 0); - ext3_ext_release(sb); - ext3_xattr_put_super(sb); -@@ -781,6 +782,8 @@ - else if (want_numeric(value, "journal", inum)) - return 0; - } -+ else if (!strcmp (this_char, "mballoc")) -+ set_opt (*mount_options, MBALLOC); - else if (!strcmp (this_char, "noload")) - set_opt (*mount_options, NOLOAD); - else if (!strcmp (this_char, "data")) { -@@ -1406,6 +1409,7 @@ - "writeback"); - - ext3_ext_init(sb); -+ ext3_mb_init(sb); - - if (test_opt(sb, PDIROPS)) { - printk (KERN_INFO "EXT3-fs: mounted filesystem with parallel dirops\n"); -Index: linux-2.4.24/fs/ext3/Makefile -=================================================================== ---- linux-2.4.24.orig/fs/ext3/Makefile 2004-08-06 03:59:07.000000000 +0400 -+++ linux-2.4.24/fs/ext3/Makefile 2004-08-06 03:59:09.000000000 +0400 -@@ -13,7 +13,7 @@ - - obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \ - ioctl.o namei.o super.o symlink.o hash.o ext3-exports.o \ -- xattr_trusted.o extents.o extents-in-ea.o -+ xattr_trusted.o extents.o extents-in-ea.o mballoc.o - export-objs += extents.o - - obj-m := $(O_TARGET) -Index: linux-2.4.24/fs/ext3/balloc.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/balloc.c 2004-08-06 00:42:23.000000000 +0400 -+++ linux-2.4.24/fs/ext3/balloc.c 2004-08-06 03:59:09.000000000 +0400 -@@ -203,8 +203,7 @@ - * differentiating between a group for which we have never performed a bitmap - * IO request, and a group for which the last bitmap read request failed. - */ --static inline int load_block_bitmap (struct super_block * sb, -- unsigned int block_group) -+int load_block_bitmap (struct super_block * sb, unsigned int block_group) - { - int slot; - -@@ -253,8 +252,8 @@ - } - - /* Free given blocks, update quota and i_blocks field */ --void ext3_free_blocks (handle_t *handle, struct inode * inode, -- unsigned long block, unsigned long count) -+void ext3_free_blocks_old (handle_t *handle, struct inode * inode, -+ unsigned long block, unsigned long count) - { - struct buffer_head *bitmap_bh; - struct buffer_head *gd_bh; -@@ -528,9 +527,9 @@ - * bitmap, and then for any free bit if that fails. - * This function also updates quota and i_blocks field. - */ --int ext3_new_block (handle_t *handle, struct inode * inode, -- unsigned long goal, u32 * prealloc_count, -- u32 * prealloc_block, int * errp) -+int ext3_new_block_old (handle_t *handle, struct inode * inode, -+ unsigned long goal, u32 * prealloc_count, -+ u32 * prealloc_block, int * errp) - { - struct buffer_head * bh, *bhtmp; - struct buffer_head * bh2; -Index: linux-2.4.24/fs/ext3/namei.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/namei.c 2004-08-06 03:59:09.000000000 +0400 -+++ linux-2.4.24/fs/ext3/namei.c 2004-08-06 03:59:09.000000000 +0400 -@@ -1944,7 +1944,7 @@ - * If the create succeeds, we fill in the inode information - * with d_instantiate(). - */ --static int ext3_create (struct inode * dir, struct dentry * dentry, int mode) -+int ext3_create (struct inode * dir, struct dentry * dentry, int mode) - { - handle_t *handle; - struct inode * inode; -Index: linux-2.4.24/fs/ext3/inode.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/inode.c 2004-08-06 03:59:09.000000000 +0400 -+++ linux-2.4.24/fs/ext3/inode.c 2004-08-06 03:59:09.000000000 +0400 -@@ -254,7 +254,7 @@ - inode->u.ext3_i.i_prealloc_count = 0; - inode->u.ext3_i.i_prealloc_block = 0; - /* Writer: end */ -- ext3_free_blocks (inode, block, total); -+ ext3_free_blocks (inode, block, total, 1); - } - unlock_kernel(); - #endif -@@ -618,7 +618,7 @@ - ext3_journal_forget(handle, branch[i].bh); - } - for (i = 0; i < keys; i++) -- ext3_free_blocks(handle, inode, le32_to_cpu(branch[i].key), 1); -+ ext3_free_blocks(handle, inode, le32_to_cpu(branch[i].key), 1, 1); - return err; - } - -@@ -722,7 +722,7 @@ - if (err == -EAGAIN) - for (i = 0; i < num; i++) - ext3_free_blocks(handle, inode, -- le32_to_cpu(where[i].key), 1); -+ le32_to_cpu(where[i].key), 1, 1); - return err; - } - -@@ -1650,7 +1650,7 @@ - } - } - -- ext3_free_blocks(handle, inode, block_to_free, count); -+ ext3_free_blocks(handle, inode, block_to_free, count, 1); - } - - /** -@@ -1821,7 +1821,7 @@ - ext3_journal_test_restart(handle, inode); - } - -- ext3_free_blocks(handle, inode, nr, 1); -+ ext3_free_blocks(handle, inode, nr, 1, 1); - - if (parent_bh) { - /* -Index: linux-2.4.24/fs/ext3/extents.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/extents.c 2004-08-06 03:59:01.000000000 +0400 -+++ linux-2.4.24/fs/ext3/extents.c 2004-08-06 03:59:09.000000000 +0400 -@@ -741,7 +741,7 @@ - for (i = 0; i < depth; i++) { - if (!ablocks[i]) - continue; -- ext3_free_blocks(handle, tree->inode, ablocks[i], 1); -+ ext3_free_blocks(handle, tree->inode, ablocks[i], 1, 1); - } - } - kfree(ablocks); -@@ -1385,7 +1385,7 @@ - path->p_idx->e_leaf); - bh = sb_get_hash_table(tree->inode->i_sb, path->p_idx->e_leaf); - ext3_forget(handle, 1, tree->inode, bh, path->p_idx->e_leaf); -- ext3_free_blocks(handle, tree->inode, path->p_idx->e_leaf, 1); -+ ext3_free_blocks(handle, tree->inode, path->p_idx->e_leaf, 1, 1); - return err; - } - -@@ -1842,10 +1842,12 @@ - int needed = ext3_remove_blocks_credits(tree, ex, from, to); - handle_t *handle = ext3_journal_start(tree->inode, needed); - struct buffer_head *bh; -- int i; -+ int i, metadata = 0; - - if (IS_ERR(handle)) - return PTR_ERR(handle); -+ if (S_ISDIR(tree->inode->i_mode)) -+ metadata = 1; - if (from >= ex->e_block && to == ex->e_block + ex->e_num - 1) { - /* tail removal */ - unsigned long num, start; -@@ -1857,7 +1859,7 @@ - bh = sb_get_hash_table(tree->inode->i_sb, start + i); - ext3_forget(handle, 0, tree->inode, bh, start + i); - } -- ext3_free_blocks(handle, tree->inode, start, num); -+ ext3_free_blocks(handle, tree->inode, start, num, metadata); - } else if (from == ex->e_block && to <= ex->e_block + ex->e_num - 1) { - printk("strange request: removal %lu-%lu from %u:%u\n", - from, to, ex->e_block, ex->e_num); -Index: linux-2.4.24/fs/ext3/xattr.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/xattr.c 2004-08-06 03:59:08.000000000 +0400 -+++ linux-2.4.24/fs/ext3/xattr.c 2004-08-06 03:59:09.000000000 +0400 -@@ -174,7 +174,7 @@ - ext3_xattr_free_block(handle_t *handle, struct inode * inode, - unsigned long block) - { -- ext3_free_blocks(handle, inode, block, 1); -+ ext3_free_blocks(handle, inode, block, 1, 1); - inode->i_blocks -= inode->i_sb->s_blocksize >> 9; - } - -@@ -182,7 +182,7 @@ - # define ext3_xattr_quota_free(inode) \ - DQUOT_FREE_BLOCK(inode, 1) - # define ext3_xattr_free_block(handle, inode, block) \ -- ext3_free_blocks(handle, inode, block, 1) -+ ext3_free_blocks(handle, inode, block, 1, 1) - #endif - - #if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) -Index: linux-2.4.24/include/linux/ext3_fs.h -=================================================================== ---- linux-2.4.24.orig/include/linux/ext3_fs.h 2004-08-06 03:59:09.000000000 +0400 -+++ linux-2.4.24/include/linux/ext3_fs.h 2004-08-06 03:59:09.000000000 +0400 -@@ -343,6 +343,7 @@ - #define EXT3_MOUNT_ASYNCDEL 0x20000 /* Delayed deletion */ - #define EXT3_MOUNT_EXTENTS 0x40000 /* Extents support */ - #define EXT3_MOUNT_EXTDEBUG 0x80000 /* Extents debug */ -+#define EXT3_MOUNT_MBALLOC 0x100000/* buddy allocation support */ - - /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ - #ifndef _LINUX_EXT2_FS_H -@@ -677,7 +678,7 @@ - extern int ext3_new_block (handle_t *, struct inode *, unsigned long, - __u32 *, __u32 *, int *); - extern void ext3_free_blocks (handle_t *, struct inode *, unsigned long, -- unsigned long); -+ unsigned long, int); - extern unsigned long ext3_count_free_blocks (struct super_block *); - extern void ext3_check_blocks_bitmap (struct super_block *); - extern struct ext3_group_desc * ext3_get_group_desc(struct super_block * sb, -Index: linux-2.4.24/include/linux/ext3_fs_sb.h -=================================================================== ---- linux-2.4.24.orig/include/linux/ext3_fs_sb.h 2004-08-06 03:59:09.000000000 +0400 -+++ linux-2.4.24/include/linux/ext3_fs_sb.h 2004-08-06 04:01:55.000000000 +0400 -@@ -19,6 +19,7 @@ - #ifdef __KERNEL__ - #include - #include -+#include - #endif - - /* -@@ -31,6 +32,25 @@ - - #define EXT3_DELETE_THREAD - -+#define EXT3_BB_MAX_BLOCKS 30 -+struct ext3_free_metadata { -+ unsigned short group; -+ unsigned short num; -+ unsigned short blocks[EXT3_BB_MAX_BLOCKS]; -+ struct list_head list; -+}; -+ -+#define EXT3_BB_MAX_ORDER 14 -+ -+struct ext3_buddy_group_blocks { -+ unsigned long bb_bitmap; -+ unsigned long bb_buddy; -+ spinlock_t bb_lock; -+ unsigned bb_counters[EXT3_BB_MAX_ORDER]; -+ struct ext3_free_metadata *bb_md_cur; -+ unsigned long bb_tid; -+}; -+ - /* - * third extended-fs super-block data in memory - */ -@@ -87,6 +107,17 @@ - wait_queue_head_t s_delete_waiter_queue; - #endif - u32 s_mdsnum; -+ -+ /* for buddy allocator */ -+ struct ext3_buddy_group_blocks *s_buddy_blocks; -+ struct inode *s_buddy; -+ long s_blocks_reserved; -+ spinlock_t s_reserve_lock; -+ struct list_head s_active_transaction; -+ struct list_head s_closed_transaction; -+ struct list_head s_committed_transaction; -+ spinlock_t s_md_lock; -+ unsigned int s_last_transaction; - }; - - #endif /* _LINUX_EXT3_FS_SB */ -Index: linux-2.4.24/include/asm-i386/bitops.h -=================================================================== ---- linux-2.4.24.orig/include/asm-i386/bitops.h 2004-08-06 01:43:20.000000000 +0400 -+++ linux-2.4.24/include/asm-i386/bitops.h 2004-08-06 03:59:09.000000000 +0400 -@@ -352,6 +352,67 @@ - } - - /** -+ * find_first_bit - find the first set bit in a memory region -+ * @addr: The address to start the search at -+ * @size: The maximum size to search -+ * -+ * Returns the bit-number of the first set bit, not the number of the byte -+ * containing a bit. -+ */ -+static __inline__ int find_first_bit(const unsigned long *addr, unsigned size) -+{ -+ int d0, d1; -+ int res; -+ -+ /* This looks at memory. Mark it volatile to tell gcc not to move it around */ -+ __asm__ __volatile__( -+ "xorl %%eax,%%eax\n\t" -+ "repe; scasl\n\t" -+ "jz 1f\n\t" -+ "leal -4(%%edi),%%edi\n\t" -+ "bsfl (%%edi),%%eax\n" -+ "1:\tsubl %%ebx,%%edi\n\t" -+ "shll $3,%%edi\n\t" -+ "addl %%edi,%%eax" -+ :"=a" (res), "=&c" (d0), "=&D" (d1) -+ :"1" ((size + 31) >> 5), "2" (addr), "b" (addr) : "memory"); -+ return res; -+} -+ -+/** -+ * find_next_bit - find the first set bit in a memory region -+ * @addr: The address to base the search on -+ * @offset: The bitnumber to start searching at -+ * @size: The maximum size to search -+ */ -+static __inline__ int find_next_bit(const unsigned long *addr, int size, int offset) -+{ -+ const unsigned long *p = addr + (offset >> 5); -+ int set = 0, bit = offset & 31, res; -+ -+ if (bit) { -+ /* -+ * Look for nonzero in the first 32 bits: -+ */ -+ __asm__("bsfl %1,%0\n\t" -+ "jne 1f\n\t" -+ "movl $32, %0\n" -+ "1:" -+ : "=r" (set) -+ : "r" (*p >> bit)); -+ if (set < (32 - bit)) -+ return set + offset; -+ set = 32 - bit; -+ p++; -+ } -+ /* -+ * No set bit yet, search remaining full words for a bit -+ */ -+ res = find_first_bit (p, size - 32 * (p - addr)); -+ return (offset + set + res); -+} -+ -+/** - * hweightN - returns the hamming weight of a N-bit word - * @x: the word to weigh - * diff --git a/lustre/kernel_patches/patches/ext3-mds-num-2.4.24.patch b/lustre/kernel_patches/patches/ext3-mds-num-2.4.24.patch deleted file mode 100644 index e0b1763..0000000 --- a/lustre/kernel_patches/patches/ext3-mds-num-2.4.24.patch +++ /dev/null @@ -1,300 +0,0 @@ -Index: linux-2.4.24/fs/ext3/namei.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/namei.c 2004-09-23 13:10:48.181661672 +0400 -+++ linux-2.4.24/fs/ext3/namei.c 2004-09-23 13:10:48.274647536 +0400 -@@ -1099,6 +1099,23 @@ - inode = NULL; - if (bh) { - unsigned long ino = le32_to_cpu(de->inode); -+ unsigned type = de->file_type; -+ __u32 *mds; -+ mds = (__u32 *)((char *) de + EXT3_DIR_REC_LEN(de->name_len)); -+ if ((type & 128) && EXT3_HAS_INCOMPAT_FEATURE(dir->i_sb, -+ EXT3_FEATURE_INCOMPAT_MDSNUM) && -+ mds[0] != EXT3_SB(dir->i_sb)->s_mdsnum) { -+ struct ext3_super_block *es; -+ es = EXT3_SB(dir->i_sb)->s_es; -+ ext3_unlock_htree(dir, lock); -+ brelse (bh); -+ dentry->d_flags |= DCACHE_CROSS_REF; -+ dentry->d_generation = mds[1]; -+ dentry->d_mdsnum = mds[0]; -+ dentry->d_inum = ino; -+ d_add(dentry, NULL); -+ return NULL; -+ } - ext3_unlock_htree(dir, lock); - brelse (bh); - inode = iget(dir->i_sb, ino); -@@ -1138,7 +1155,7 @@ - while (count--) { - struct ext3_dir_entry_2 *de = - (struct ext3_dir_entry_2 *) (from + map->offs); -- rec_len = EXT3_DIR_REC_LEN(de->name_len); -+ rec_len = EXT3_DIR_REC_LEN_DE(de); - memcpy (to, de, rec_len); - ((struct ext3_dir_entry_2 *)to)->rec_len = cpu_to_le16(rec_len); - de->inode = 0; -@@ -1159,7 +1176,7 @@ - next = (struct ext3_dir_entry_2 *) ((char *) de + - le16_to_cpu(de->rec_len)); - if (de->inode && de->name_len) { -- rec_len = EXT3_DIR_REC_LEN(de->name_len); -+ rec_len = EXT3_DIR_REC_LEN_DE(de); - if (de > to) - memmove(to, de, rec_len); - to->rec_len = cpu_to_le16(rec_len); -@@ -1275,6 +1292,7 @@ - struct buffer_head * bh) - { - struct inode *dir = dentry->d_parent->d_inode; -+ struct super_block *sb = dir->i_sb; - const char *name = dentry->d_name.name; - int namelen = dentry->d_name.len; - unsigned long offset = 0; -@@ -1283,6 +1301,10 @@ - char *top; - - reclen = EXT3_DIR_REC_LEN(namelen); -+ if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_MDSNUM) -+ && (dentry->d_flags & DCACHE_CROSS_REF) -+ && (dentry->d_mdsnum != EXT3_SB(sb)->s_mdsnum)) -+ reclen += 8; /* we need space to store mds num */ - if (!de) { - de = (struct ext3_dir_entry_2 *)bh->b_data; - top = bh->b_data + dir->i_sb->s_blocksize - reclen; -@@ -1296,7 +1318,7 @@ - brelse (bh); - return -EEXIST; - } -- nlen = EXT3_DIR_REC_LEN(de->name_len); -+ nlen = EXT3_DIR_REC_LEN_DE(de); - rlen = le16_to_cpu(de->rec_len); - if ((de->inode? rlen - nlen: rlen) >= reclen) - break; -@@ -1315,7 +1337,7 @@ - } - - /* By now the buffer is marked for journaling */ -- nlen = EXT3_DIR_REC_LEN(de->name_len); -+ nlen = EXT3_DIR_REC_LEN_DE(de); - rlen = le16_to_cpu(de->rec_len); - if (de->inode) { - struct ext3_dir_entry_2 *de1 = -@@ -1327,8 +1349,20 @@ - de->file_type = EXT3_FT_UNKNOWN; - if (inode) { - de->inode = cpu_to_le32(inode->i_ino); -- ext3_set_de_type(dir->i_sb, de, inode->i_mode); -- } else -+ ext3_set_de_type(sb, de, inode->i_mode); -+ } else if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_MDSNUM) -+ && (dentry->d_flags & DCACHE_CROSS_REF)) { -+ if (dentry->d_mdsnum != EXT3_SB(sb)->s_mdsnum) { -+ __u32 *mds; -+ mds = (__u32 *)((char *)de + EXT3_DIR_REC_LEN(namelen)); -+ mds[0] = cpu_to_le32(dentry->d_mdsnum); -+ mds[1] = cpu_to_le32(dentry->d_generation); -+ de->inode = cpu_to_le32(dentry->d_inum); -+ de->file_type = 128; -+ } else { -+ de->inode = cpu_to_le32(dentry->d_inum); -+ } -+ } else - de->inode = 0; - de->name_len = namelen; - memcpy (de->name, name, namelen); -@@ -2662,6 +2696,79 @@ - } - - /* -+ * caller has to make sure directory is protected -+ */ -+int ext3_add_dir_entry(struct dentry *dentry) -+{ -+ struct inode *dir = dentry->d_parent->d_inode; -+ handle_t *handle; -+ int err; -+ -+ handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + -+ EXT3_INDEX_EXTRA_TRANS_BLOCKS); -+ if (IS_ERR(handle)) { -+ return PTR_ERR(handle); -+ } -+ -+ if (IS_SYNC(dir)) -+ handle->h_sync = 1; -+ -+ err = ext3_add_entry(handle, dentry, NULL); -+ ext3_journal_stop(handle, dir); -+ return err; -+} -+ -+/* -+ * caller has to make sure directory is protected -+ */ -+int ext3_del_dir_entry(struct dentry *dentry) -+{ -+ struct inode * inode; -+ struct inode * dir = dentry->d_parent->d_inode; -+ struct buffer_head * bh; -+ struct ext3_dir_entry_2 * de; -+ handle_t *handle; -+ void *lock; -+ int retval; -+ -+ handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS); -+ if (IS_ERR(handle)) { -+ return PTR_ERR(handle); -+ } -+ -+ if (IS_SYNC(dir)) -+ handle->h_sync = 1; -+ -+ retval = -ENOENT; -+ bh = ext3_find_entry (dentry, &de, 1, &lock); -+ if (!bh) -+ goto end_unlink; -+ -+ inode = dentry->d_inode; -+ if (inode) -+ DQUOT_INIT(inode); -+ -+ retval = ext3_delete_entry(handle, dir, de, bh); -+ ext3_unlock_htree(dir, lock); -+ if (retval) -+ goto end_unlink; -+ dir->i_ctime = dir->i_mtime = CURRENT_TIME; -+ ext3_update_dx_flag(dir); -+ if (inode) { -+ inode->i_ctime = dir->i_ctime; -+ ext3_mark_inode_dirty(handle, inode); -+ if (S_ISDIR(inode->i_mode)) -+ dir->i_nlink--; -+ } -+ ext3_mark_inode_dirty(handle, dir); -+ retval = 0; -+ -+end_unlink: -+ ext3_journal_stop(handle, dir); -+ brelse (bh); -+ return retval; -+} -+/* - * directories can handle most operations... - */ - struct inode_operations ext3_dir_inode_operations = { -Index: linux-2.4.24/fs/ext3/dir.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/dir.c 2004-09-23 13:10:45.649046688 +0400 -+++ linux-2.4.24/fs/ext3/dir.c 2004-09-23 13:10:48.275647384 +0400 -@@ -42,6 +42,9 @@ - - static unsigned char get_dtype(struct super_block *sb, int filetype) - { -+ if (EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_MDSNUM)) -+ return DT_UNKNOWN; -+ - if (!EXT3_HAS_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_FILETYPE) || - (filetype >= EXT3_FT_MAX)) - return DT_UNKNOWN; -@@ -67,8 +70,10 @@ - else if (((char *) de - bh->b_data) + rlen > dir->i_sb->s_blocksize) - error_msg = "directory entry across blocks"; - else if (le32_to_cpu(de->inode) > -- le32_to_cpu(dir->i_sb->u.ext3_sb.s_es->s_inodes_count)) -- error_msg = "inode out of bounds"; -+ le32_to_cpu(dir->i_sb->u.ext3_sb.s_es->s_inodes_count)) { -+ if (de->file_type != 128) -+ error_msg = "inode out of bounds"; -+ } - - if (error_msg != NULL) - ext3_error (dir->i_sb, function, -Index: linux-2.4.24/fs/ext3/ext3-exports.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/ext3-exports.c 2004-09-23 13:10:46.365937704 +0400 -+++ linux-2.4.24/fs/ext3/ext3-exports.c 2004-09-23 13:10:48.275647384 +0400 -@@ -26,3 +26,10 @@ - EXPORT_SYMBOL(ext3_decode_error); - EXPORT_SYMBOL(__ext3_std_error); - -+int ext3_add_dir_entry (struct dentry *dentry); -+EXPORT_SYMBOL(ext3_add_dir_entry); -+int ext3_del_dir_entry(struct dentry *dentry); -+EXPORT_SYMBOL(ext3_del_dir_entry); -+ -+ -+ -Index: linux-2.4.24/include/linux/ext3_fs.h -=================================================================== ---- linux-2.4.24.orig/include/linux/ext3_fs.h 2004-09-23 13:10:48.188660608 +0400 -+++ linux-2.4.24/include/linux/ext3_fs.h 2004-09-23 13:17:40.703948752 +0400 -@@ -446,7 +446,8 @@ - __u8 s_def_hash_version; /* Default hash version to use */ - __u8 s_reserved_char_pad; - __u16 s_reserved_word_pad; -- __u32 s_reserved[192]; /* Padding to the end of the block */ -+ __u32 s_mdsnum; -+ __u32 s_reserved[191]; /* Padding to the end of the block */ - }; - - #ifdef __KERNEL__ -@@ -519,11 +520,13 @@ - #define EXT3_FEATURE_INCOMPAT_FILETYPE 0x0002 - #define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ - #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */ -+#define EXT3_FEATURE_INCOMPAT_MDSNUM 0x0020 /* direntry has mdsnum */ - #define EXT3_FEATURE_INCOMPAT_EXTENTS 0x0040 /* extents support */ - - #define EXT3_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR - #define EXT3_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_FILETYPE| \ - EXT3_FEATURE_INCOMPAT_RECOVER| \ -+ EXT3_FEATURE_INCOMPAT_MDSNUM| \ - EXT3_FEATURE_INCOMPAT_EXTENTS) - #define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \ - EXT3_FEATURE_RO_COMPAT_LARGE_FILE| \ -@@ -585,6 +588,9 @@ - #define EXT3_DIR_ROUND (EXT3_DIR_PAD - 1) - #define EXT3_DIR_REC_LEN(name_len) (((name_len) + 8 + EXT3_DIR_ROUND) & \ - ~EXT3_DIR_ROUND) -+#define EXT3_DIR_REC_LEN_DE(de) (EXT3_DIR_REC_LEN((de)->name_len) + \ -+ (((de)->file_type & 128) ? 8 : 0)) -+ - /* - * Hash Tree Directory indexing - * (c) Daniel Phillips, 2001 -Index: linux-2.4.24/include/linux/ext3_fs_sb.h -=================================================================== ---- linux-2.4.24.orig/include/linux/ext3_fs_sb.h 2004-09-23 13:10:46.069982696 +0400 -+++ linux-2.4.24/include/linux/ext3_fs_sb.h 2004-09-23 13:11:21.026668472 +0400 -@@ -86,6 +86,7 @@ - wait_queue_head_t s_delete_thread_queue; - wait_queue_head_t s_delete_waiter_queue; - #endif -+ u32 s_mdsnum; - }; - - #endif /* _LINUX_EXT3_FS_SB */ -Index: linux-2.4.24/include/linux/dcache.h -=================================================================== ---- linux-2.4.24.orig/include/linux/dcache.h 2004-09-23 13:10:46.153969928 +0400 -+++ linux-2.4.24/include/linux/dcache.h 2004-09-23 13:11:06.451884176 +0400 -@@ -120,6 +120,9 @@ - atomic_t d_count; - unsigned int d_flags; - struct inode * d_inode; /* Where the name belongs to - NULL is negative */ -+ unsigned d_inum; /* for cross-fs references (Lustre) */ -+ unsigned d_mdsnum; /* for cross-fs references (Lustre) */ -+ unsigned d_generation; /* for cross-fs references (Lustre) */ - struct dentry * d_parent; /* parent directory */ - struct list_head d_hash; /* lookup hash list */ - struct list_head d_lru; /* d_count = 0 LRU list */ -@@ -193,6 +196,7 @@ - */ - #define DCACHE_REFERENCED 0x0008 /* Recently used, don't discard. */ - #define DCACHE_LUSTRE_INVALID 0x0010 /* Lustre invalidated */ -+#define DCACHE_CROSS_REF 0x0020 /* entry points to inode on another MDS */ - - extern spinlock_t dcache_lock; - diff --git a/lustre/kernel_patches/patches/ext3-nlinks-2.4.24.patch b/lustre/kernel_patches/patches/ext3-nlinks-2.4.24.patch deleted file mode 100644 index f198362..0000000 --- a/lustre/kernel_patches/patches/ext3-nlinks-2.4.24.patch +++ /dev/null @@ -1,170 +0,0 @@ ---- ./fs/ext3/namei.c.orig 2004-08-19 12:53:21.000000000 +0800 -+++ ./fs/ext3/namei.c 2004-08-19 12:44:18.000000000 +0800 -@@ -1541,11 +1541,16 @@ - static inline void ext3_inc_count(handle_t *handle, struct inode *inode) - { - inode->i_nlink++; -+ if (is_dx(inode) && inode->i_nlink > 1) { -+ if (inode->i_nlink >= 65000) /* limit is 16-bit i_links_count */ -+ inode->i_nlink = 1; -+ } - } - - static inline void ext3_dec_count(handle_t *handle, struct inode *inode) - { -- inode->i_nlink--; -+ if (!S_ISDIR(inode->i_mode) || inode->i_nlink > 2) -+ inode->i_nlink--; - } - - static int ext3_add_nondir(handle_t *handle, -@@ -1646,7 +1651,7 @@ - struct ext3_dir_entry_2 * de; - int err; - -- if (dir->i_nlink >= EXT3_LINK_MAX) -+ if (EXT3_DIR_LINK_MAXED(dir)) - return -EMLINK; - - handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + -@@ -1668,7 +1673,7 @@ - inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize; - dir_block = ext3_bread (handle, inode, 0, 1, &err); - if (!dir_block) { -- inode->i_nlink--; /* is this nlink == 0? */ -+ ext3_dec_count(handle, inode); /* is this nlink == 0? */ - ext3_mark_inode_dirty(handle, inode); - iput (inode); - goto out_stop; -@@ -1700,7 +1705,7 @@ - iput (inode); - goto out_stop; - } -- dir->i_nlink++; -+ ext3_inc_count(handle, dir); - ext3_update_dx_flag(dir); - ext3_mark_inode_dirty(handle, dir); - d_instantiate(dentry, inode); -@@ -1761,10 +1766,11 @@ - } - de = (struct ext3_dir_entry_2 *) bh->b_data; - } -- if (!ext3_check_dir_entry ("empty_dir", inode, de, bh, -- offset)) { -- brelse (bh); -- return 1; -+ if (!ext3_check_dir_entry("empty_dir", inode, de, bh, offset)) { -+ /* On error skip the de and offset to the next block. */ -+ de = (void *)(bh->b_data + sb->s_blocksize); -+ offset = (offset | (sb->s_blocksize - 1)) + 1; -+ continue; - } - if (le32_to_cpu(de->inode)) { - brelse (bh); -@@ -1957,14 +1963,14 @@ - retval = ext3_delete_entry(handle, dir, de, bh); - if (retval) - goto end_rmdir; -- if (inode->i_nlink != 2) -- ext3_warning (inode->i_sb, "ext3_rmdir", -- "empty directory has nlink!=2 (%d)", -- inode->i_nlink); -+ if (!EXT3_DIR_LINK_EMPTY(inode)) -+ ext3_warning(inode->i_sb, __FUNCTION__, -+ "empty directory has too many links (%d)", -+ inode->i_nlink); - inode->i_version = ++event; - inode->i_nlink = 0; - ext3_orphan_add(handle, inode); -- dir->i_nlink--; -+ ext3_dec_count(handle, dir); - inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; - ext3_mark_inode_dirty(handle, inode); - ext3_update_dx_flag(dir); -@@ -2046,7 +2052,7 @@ - dir->i_ctime = dir->i_mtime = CURRENT_TIME; - ext3_update_dx_flag(dir); - ext3_mark_inode_dirty(handle, dir); -- inode->i_nlink--; -+ ext3_dec_count(handle, inode); - if (!inode->i_nlink) { - ext3_try_to_delay_deletion(inode); - ext3_orphan_add(handle, inode); -@@ -2140,9 +2146,8 @@ - if (S_ISDIR(inode->i_mode)) - return -EPERM; - -- if (inode->i_nlink >= EXT3_LINK_MAX) { -+ if (EXT3_DIR_LINK_MAXED(inode)) - return -EMLINK; -- } - - handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + - EXT3_INDEX_EXTRA_TRANS_BLOCKS); -@@ -2226,8 +2231,8 @@ - if (le32_to_cpu(PARENT_INO(dir_bh->b_data)) != old_dir->i_ino) - goto end_rename; - retval = -EMLINK; -- if (!new_inode && new_dir!=old_dir && -- new_dir->i_nlink >= EXT3_LINK_MAX) -+ if (!new_inode && new_dir != old_dir && -+ EXT3_DIR_LINK_MAXED(new_dir)) - goto end_rename; - } - if (!new_bh) { -@@ -2285,7 +2290,7 @@ - } - - if (new_inode) { -- new_inode->i_nlink--; -+ ext3_dec_count(handle, new_inode); - new_inode->i_ctime = CURRENT_TIME; - } - old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME; -@@ -2296,11 +2301,11 @@ - PARENT_INO(dir_bh->b_data) = le32_to_cpu(new_dir->i_ino); - BUFFER_TRACE(dir_bh, "call ext3_journal_dirty_metadata"); - ext3_journal_dirty_metadata(handle, dir_bh); -- old_dir->i_nlink--; -+ ext3_dec_count(handle, old_dir); - if (new_inode) { -- new_inode->i_nlink--; -+ ext3_dec_count(handle, new_inode); - } else { -- new_dir->i_nlink++; -+ ext3_inc_count(handle, new_dir); - ext3_update_dx_flag(new_dir); - ext3_mark_inode_dirty(handle, new_dir); - } ---- ./include/linux/ext3_fs.h.orig 2004-08-19 12:53:52.000000000 +0800 -+++ ./include/linux/ext3_fs.h 2004-08-19 11:06:33.000000000 +0800 -@@ -42,7 +42,7 @@ - /* - * Always enable hashed directories - */ --#define CONFIG_EXT3_INDEX -+#define CONFIG_EXT3_INDEX 1 - - /* - * Debug code -@@ -581,14 +581,15 @@ - */ - - #ifdef CONFIG_EXT3_INDEX -- #define is_dx(dir) (EXT3_HAS_COMPAT_FEATURE(dir->i_sb, \ -- EXT3_FEATURE_COMPAT_DIR_INDEX) && \ -+#define is_dx(dir) (EXT3_HAS_COMPAT_FEATURE(dir->i_sb, \ -+ EXT3_FEATURE_COMPAT_DIR_INDEX) && \ - (EXT3_I(dir)->i_flags & EXT3_INDEX_FL)) --#define EXT3_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT3_LINK_MAX) --#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1) -+#define EXT3_DIR_LINK_MAXED(dir) (!is_dx(dir) && (dir)->i_nlink >=EXT3_LINK_MAX) -+#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || \ -+ (is_dx(dir) && (dir)->i_nlink == 1)) - #else - #define is_dx(dir) 0 --#define EXT3_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT3_LINK_MAX) -+#define EXT3_DIR_LINK_MAXED(dir) ((dir)->i_nlink >= EXT3_LINK_MAX) - #define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2) - #endif - diff --git a/lustre/kernel_patches/patches/ext3-no-write-super-2.4.24.patch b/lustre/kernel_patches/patches/ext3-no-write-super-2.4.24.patch deleted file mode 100644 index 37a5d7a..0000000 --- a/lustre/kernel_patches/patches/ext3-no-write-super-2.4.24.patch +++ /dev/null @@ -1,15 +0,0 @@ - fs/ext3/super.c | 1 - - 1 files changed, 1 deletion(-) - ---- linux-2.4.18-chaos/fs/ext3/super.c~ext3-no-write-super-chaos 2003-08-24 21:34:53.000000000 +0400 -+++ linux-2.4.18-chaos-alexey/fs/ext3/super.c 2003-08-24 21:40:47.000000000 +0400 -@@ -1818,7 +1818,6 @@ void ext3_write_super (struct super_bloc - if (down_trylock(&sb->s_lock) == 0) - BUG(); - sb->s_dirt = 0; -- log_start_commit(EXT3_SB(sb)->s_journal, NULL); - } - - static int ext3_sync_fs(struct super_block *sb) - -_ diff --git a/lustre/kernel_patches/patches/ext3-noread-2.4.24.patch b/lustre/kernel_patches/patches/ext3-noread-2.4.24.patch deleted file mode 100644 index f8270b2..0000000 --- a/lustre/kernel_patches/patches/ext3-noread-2.4.24.patch +++ /dev/null @@ -1,218 +0,0 @@ - fs/ext3/ialloc.c | 47 ++++++++++++++++++++++- - fs/ext3/inode.c | 96 +++++++++++++++++++++++++++++++++++++----------- - include/linux/ext3_fs.h | 2 + - 3 files changed, 121 insertions(+), 24 deletions(-) - ---- linux-2.4.20/fs/ext3/ialloc.c~ext3-noread-2.4.20 2003-05-16 12:21:39.000000000 +0800 -+++ linux-2.4.20-root/fs/ext3/ialloc.c 2003-05-16 12:21:46.000000000 +0800 -@@ -289,6 +289,37 @@ error_return: - } - - /* -+ * @block_group: block group of inode -+ * @offset: relative offset of inode within @block_group -+ * -+ * Check whether any of the inodes in this disk block are in use. -+ * -+ * Caller must be holding superblock lock (group/bitmap read lock in future). -+ */ -+int ext3_itable_block_used(struct super_block *sb, unsigned int block_group, -+ int offset) -+{ -+ int bitmap_nr = load_inode_bitmap(sb, block_group); -+ int inodes_per_block; -+ unsigned long inum, iend; -+ struct buffer_head *ibitmap; -+ -+ if (bitmap_nr < 0) -+ return 1; -+ -+ inodes_per_block = sb->s_blocksize / EXT3_SB(sb)->s_inode_size; -+ inum = offset & ~(inodes_per_block - 1); -+ iend = inum + inodes_per_block; -+ ibitmap = EXT3_SB(sb)->s_inode_bitmap[bitmap_nr]; -+ for (; inum < iend; inum++) { -+ if (inum != offset && ext3_test_bit(inum, ibitmap->b_data)) -+ return 1; -+ } -+ -+ return 0; -+} -+ -+/* - * There are two policies for allocating an inode. If the new inode is - * a directory, then a forward search is made for a block group with both - * free space and a low directory-to-inode ratio; if that fails, then of -@@ -310,6 +341,7 @@ struct inode * ext3_new_inode (handle_t - struct ext3_group_desc * gdp; - struct ext3_group_desc * tmp; - struct ext3_super_block * es; -+ struct ext3_iloc iloc; - int err = 0; - - /* Cannot create files in a deleted directory */ -@@ -510,8 +542,19 @@ repeat: - inode->i_generation = sb->u.ext3_sb.s_next_generation++; - - inode->u.ext3_i.i_state = EXT3_STATE_NEW; -- err = ext3_mark_inode_dirty(handle, inode); -- if (err) goto fail; -+ err = ext3_get_inode_loc_new(inode, &iloc, 1); -+ if (err) goto fail; -+ BUFFER_TRACE(iloc->bh, "get_write_access"); -+ err = ext3_journal_get_write_access(handle, iloc.bh); -+ if (err) { -+ brelse(iloc.bh); -+ iloc.bh = NULL; -+ goto fail; -+ } -+ err = ext3_mark_iloc_dirty(handle, inode, &iloc); -+ if (err) goto fail; -+ -+ - - unlock_super (sb); - if(DQUOT_ALLOC_INODE(inode)) { ---- linux-2.4.20/fs/ext3/inode.c~ext3-noread-2.4.20 2003-05-16 12:21:41.000000000 +0800 -+++ linux-2.4.20-root/fs/ext3/inode.c 2003-05-16 12:22:15.000000000 +0800 -@@ -2013,14 +2013,19 @@ out_stop: - ext3_journal_stop(handle, inode); - } - --/* -- * ext3_get_inode_loc returns with an extra refcount against the -- * inode's underlying buffer_head on success. -- */ -- --int ext3_get_inode_loc (struct inode *inode, struct ext3_iloc *iloc) -+#define NUM_INODE_PREREAD 16 -+ -+/* -+ * ext3_get_inode_loc returns with an extra refcount against the inode's -+ * underlying buffer_head on success. If this is for a new inode allocation -+ * (new is non-zero) then we may be able to optimize away the read if there -+ * are no other in-use inodes in this inode table block. If we need to do -+ * a read, then read in a whole chunk of blocks to avoid blocking again soon -+ * if we are doing lots of creates/updates. -+ */ -+int ext3_get_inode_loc_new(struct inode *inode, struct ext3_iloc *iloc, int new) - { -- struct buffer_head *bh = 0; -+ struct buffer_head *bh[NUM_INODE_PREREAD]; - unsigned long block; - unsigned long block_group; - unsigned long group_desc; -@@ -2045,31 +2050,73 @@ int ext3_get_inode_loc (struct inode *in - } - group_desc = block_group >> EXT3_DESC_PER_BLOCK_BITS(inode->i_sb); - desc = block_group & (EXT3_DESC_PER_BLOCK(inode->i_sb) - 1); -- bh = inode->i_sb->u.ext3_sb.s_group_desc[group_desc]; -- if (!bh) { -+ if (!(inode->i_sb->u.ext3_sb.s_group_desc[group_desc])) { - ext3_error (inode->i_sb, "ext3_get_inode_loc", - "Descriptor not loaded"); - goto bad_inode; - } - -- gdp = (struct ext3_group_desc *) bh->b_data; -+ gdp = (struct ext3_group_desc *)(inode->i_sb->u.ext3_sb.s_group_desc[group_desc]->b_data); - /* - * Figure out the offset within the block group inode table - */ -- offset = ((inode->i_ino - 1) % EXT3_INODES_PER_GROUP(inode->i_sb)) * -- EXT3_INODE_SIZE(inode->i_sb); -+ offset = ((inode->i_ino - 1) % EXT3_INODES_PER_GROUP(inode->i_sb)); -+ - block = le32_to_cpu(gdp[desc].bg_inode_table) + -- (offset >> EXT3_BLOCK_SIZE_BITS(inode->i_sb)); -- if (!(bh = sb_bread(inode->i_sb, block))) { -- ext3_error (inode->i_sb, "ext3_get_inode_loc", -- "unable to read inode block - " -- "inode=%lu, block=%lu", inode->i_ino, block); -- goto bad_inode; -- } -- offset &= (EXT3_BLOCK_SIZE(inode->i_sb) - 1); -+ (offset * EXT3_INODE_SIZE(inode->i_sb) >> EXT3_BLOCK_SIZE_BITS(inode->i_sb)); - -- iloc->bh = bh; -- iloc->raw_inode = (struct ext3_inode *) (bh->b_data + offset); -+ bh[0] = sb_getblk(inode->i_sb, block); -+ if (buffer_uptodate(bh[0])) -+ goto done; -+ -+ /* If we don't really need to read this block, and it isn't already -+ * in memory, then we just zero it out. Otherwise, we keep the -+ * current block contents (deleted inode data) for posterity. -+ */ -+ if (new && !ext3_itable_block_used(inode->i_sb, block_group, offset)) { -+ lock_buffer(bh[0]); -+ memset(bh[0]->b_data, 0, bh[0]->b_size); -+ mark_buffer_uptodate(bh[0], 1); -+ unlock_buffer(bh[0]); -+ } else { -+ unsigned long block_end, itable_end; -+ int count = 1; -+ -+ itable_end = le32_to_cpu(gdp[desc].bg_inode_table) + -+ inode->i_sb->u.ext3_sb.s_itb_per_group; -+ block_end = block + NUM_INODE_PREREAD; -+ if (block_end > itable_end) -+ block_end = itable_end; -+ -+ for (++block; block < block_end; block++) { -+ bh[count] = sb_getblk(inode->i_sb, block); -+ if (count && (buffer_uptodate(bh[count]) || -+ buffer_locked(bh[count]))) { -+ __brelse(bh[count]); -+ } else -+ count++; -+ } -+ -+ ll_rw_block(READ, count, bh); -+ -+ /* Release all but the block we actually need (bh[0]) */ -+ while (--count > 0) -+ __brelse(bh[count]); -+ -+ wait_on_buffer(bh[0]); -+ if (!buffer_uptodate(bh[0])) { -+ ext3_error(inode->i_sb, __FUNCTION__, -+ "unable to read inode block - " -+ "inode=%lu, block=%lu", inode->i_ino, -+ bh[0]->b_blocknr); -+ goto bad_inode; -+ } -+ } -+done: -+ offset = (offset * EXT3_INODE_SIZE(inode->i_sb)) & (EXT3_BLOCK_SIZE(inode->i_sb) - 1); -+ -+ iloc->bh = bh[0]; -+ iloc->raw_inode = (struct ext3_inode *)(bh[0]->b_data + offset); - iloc->block_group = block_group; - - return 0; -@@ -2078,6 +2125,11 @@ int ext3_get_inode_loc (struct inode *in - return -EIO; - } - -+int ext3_get_inode_loc(struct inode *inode, struct ext3_iloc *iloc) -+{ -+ return ext3_get_inode_loc_new(inode, iloc, 0); -+} -+ - void ext3_read_inode(struct inode * inode) - { - struct ext3_iloc iloc; ---- linux-2.4.20/include/linux/ext3_fs.h~ext3-noread-2.4.20 2003-05-16 12:21:39.000000000 +0800 -+++ linux-2.4.20-root/include/linux/ext3_fs.h 2003-05-16 12:21:46.000000000 +0800 -@@ -683,6 +683,8 @@ extern int ext3_forget(handle_t *, int, - extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *); - extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *); - -+extern int ext3_itable_block_used(struct super_block *sb, unsigned int, int); -+extern int ext3_get_inode_loc_new(struct inode *, struct ext3_iloc *, int); - extern int ext3_get_inode_loc (struct inode *, struct ext3_iloc *); - extern void ext3_read_inode (struct inode *); - extern void ext3_write_inode (struct inode *, int); - -_ diff --git a/lustre/kernel_patches/patches/ext3-orphan_lock-2.4.24.patch b/lustre/kernel_patches/patches/ext3-orphan_lock-2.4.24.patch deleted file mode 100644 index f2d4889..0000000 --- a/lustre/kernel_patches/patches/ext3-orphan_lock-2.4.24.patch +++ /dev/null @@ -1,82 +0,0 @@ - fs/ext3/namei.c | 15 +++++++-------- - fs/ext3/namei.c.orig | 21 +++++++++++++++------ - fs/ext3/super.c | 1 + - include/linux/ext3_fs_sb.h | 1 + - include/linux/ext3_fs_sb.h.orig | 2 ++ - 5 files changed, 26 insertions(+), 14 deletions(-) - ---- linux-2.4.22-ac1/fs/ext3/namei.c~ext3-orphan_lock-2.4.22-rh 2003-09-26 00:24:09.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/ext3/namei.c 2003-09-26 00:26:36.000000000 +0400 -@@ -1748,8 +1748,8 @@ int ext3_orphan_add(handle_t *handle, st - struct super_block *sb = inode->i_sb; - struct ext3_iloc iloc; - int err = 0, rc; -- -- lock_super(sb); -+ -+ down(&EXT3_SB(sb)->s_orphan_lock); - if (!list_empty(&EXT3_I(inode)->i_orphan)) - goto out_unlock; - -@@ -1797,7 +1797,7 @@ int ext3_orphan_add(handle_t *handle, st - jbd_debug(4, "orphan inode %ld will point to %d\n", - inode->i_ino, NEXT_ORPHAN(inode)); - out_unlock: -- unlock_super(sb); -+ up(&EXT3_SB(sb)->s_orphan_lock); - ext3_std_error(inode->i_sb, err); - return err; - } -@@ -1810,20 +1810,19 @@ int ext3_orphan_del(handle_t *handle, st - { - struct list_head *prev; - struct ext3_inode_info *ei = EXT3_I(inode); -- struct ext3_sb_info *sbi; -+ struct ext3_sb_info *sbi = EXT3_SB(inode->i_sb); - unsigned long ino_next; - struct ext3_iloc iloc; - int err = 0; - -- lock_super(inode->i_sb); -+ down(&sbi->s_orphan_lock); - if (list_empty(&ei->i_orphan)) { -- unlock_super(inode->i_sb); -+ up(&sbi->s_orphan_lock); - return 0; - } - - ino_next = NEXT_ORPHAN(inode); - prev = ei->i_orphan.prev; -- sbi = EXT3_SB(inode->i_sb); - - jbd_debug(4, "remove inode %lu from orphan list\n", inode->i_ino); - -@@ -1872,7 +1871,7 @@ int ext3_orphan_del(handle_t *handle, st - out_err: - ext3_std_error(inode->i_sb, err); - out: -- unlock_super(inode->i_sb); -+ up(&sbi->s_orphan_lock); - return err; - - out_brelse: ---- linux-2.4.22-ac1/fs/ext3/super.c~ext3-orphan_lock-2.4.22-rh 2003-09-26 00:24:09.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/fs/ext3/super.c 2003-09-26 00:25:22.000000000 +0400 -@@ -1164,6 +1164,7 @@ struct super_block * ext3_read_super (st - sb->s_op = &ext3_sops; - sb->dq_op = &ext3_qops; - INIT_LIST_HEAD(&sbi->s_orphan); /* unlinked but open files */ -+ sema_init(&sbi->s_orphan_lock, 1); - - sb->s_root = 0; - ---- linux-2.4.22-ac1/include/linux/ext3_fs_sb.h~ext3-orphan_lock-2.4.22-rh 2003-09-26 00:24:08.000000000 +0400 -+++ linux-2.4.22-ac1-alexey/include/linux/ext3_fs_sb.h 2003-09-26 00:25:22.000000000 +0400 -@@ -72,6 +72,7 @@ struct ext3_sb_info { - struct inode * s_journal_inode; - struct journal_s * s_journal; - struct list_head s_orphan; -+ struct semaphore s_orphan_lock; - unsigned long s_commit_interval; - struct block_device *journal_bdev; - #ifdef CONFIG_JBD_DEBUG diff --git a/lustre/kernel_patches/patches/ext3-pdirops-2.4.24-chaos.patch b/lustre/kernel_patches/patches/ext3-pdirops-2.4.24-chaos.patch deleted file mode 100644 index c472368..0000000 --- a/lustre/kernel_patches/patches/ext3-pdirops-2.4.24-chaos.patch +++ /dev/null @@ -1,1239 +0,0 @@ - fs/ext3/ialloc.c | 3 - fs/ext3/inode.c | 3 - fs/ext3/namei.c | 582 +++++++++++++++++++++++++++++++++++++--------- - fs/ext3/super.c | 14 + - include/linux/ext3_fs.h | 1 - include/linux/ext3_fs_i.h | 6 - 6 files changed, 500 insertions(+), 109 deletions(-) - -Index: lum/fs/ext3/namei.c -=================================================================== ---- lum.orig/fs/ext3/namei.c 2004-06-03 16:32:28.000000000 -0400 -+++ lum/fs/ext3/namei.c 2004-06-03 16:45:45.000000000 -0400 -@@ -51,6 +51,9 @@ - { - struct buffer_head *bh; - -+ /* with parallel dir operations all appends -+ * have to be serialized -bzzz */ -+ down(&EXT3_I(inode)->i_append_sem); - *block = inode->i_size >> inode->i_sb->s_blocksize_bits; - - if ((bh = ext3_bread(handle, inode, *block, 1, err))) { -@@ -58,6 +61,8 @@ - EXT3_I(inode)->i_disksize = inode->i_size; - ext3_journal_get_write_access(handle,bh); - } -+ up(&EXT3_I(inode)->i_append_sem); -+ - return bh; - } - -@@ -134,6 +139,8 @@ - struct buffer_head *bh; - struct dx_entry *entries; - struct dx_entry *at; -+ unsigned long leaf; -+ unsigned int curidx; - }; - - struct dx_map_entry -@@ -142,6 +149,30 @@ - u32 offs; - }; - -+/* FIXME: this should be reworked using bb_spin_lock -+ * introduced in -mm tree -+ */ -+#define BH_DXLock 25 -+ -+static inline void dx_lock_bh(struct buffer_head volatile *bh) -+{ -+#ifdef CONFIG_SMP -+ while (test_and_set_bit(BH_DXLock, &bh->b_state)) { -+ while (test_bit(BH_DXLock, &bh->b_state)) -+ cpu_relax(); -+ } -+#endif -+} -+ -+static inline void dx_unlock_bh(struct buffer_head *bh) -+{ -+#ifdef CONFIG_SMP -+ smp_mb__before_clear_bit(); -+ clear_bit(BH_DXLock, &bh->b_state); -+#endif -+} -+ -+ - #ifdef CONFIG_EXT3_INDEX - static inline unsigned dx_get_block (struct dx_entry *entry); - static void dx_set_block (struct dx_entry *entry, unsigned value); -@@ -153,7 +184,7 @@ - static void dx_set_limit (struct dx_entry *entries, unsigned value); - static unsigned dx_root_limit (struct inode *dir, unsigned infosize); - static unsigned dx_node_limit (struct inode *dir); --static struct dx_frame *dx_probe(struct dentry *dentry, -+static struct dx_frame *dx_probe(struct qstr *name, - struct inode *dir, - struct dx_hash_info *hinfo, - struct dx_frame *frame, -@@ -165,15 +196,18 @@ - static struct ext3_dir_entry_2 *dx_move_dirents (char *from, char *to, - struct dx_map_entry *offsets, int count); - static struct ext3_dir_entry_2* dx_pack_dirents (char *base, int size); --static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block); -+static void dx_insert_block (struct inode *, struct dx_frame *, u32, u32, u32); - static int ext3_htree_next_block(struct inode *dir, __u32 hash, - struct dx_frame *frame, - struct dx_frame *frames, int *err, - __u32 *start_hash); - static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry, -- struct ext3_dir_entry_2 **res_dir, int *err); -+ struct ext3_dir_entry_2 **res_dir, int *err, -+ int rwlock, void **lock); - static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry, - struct inode *inode); -+static inline void *ext3_lock_htree(struct inode *, unsigned long, int); -+static inline void ext3_unlock_htree(struct inode *, void *); - - /* - * Future: use high four bits of block for coalesce-on-delete flags -@@ -306,6 +340,94 @@ - #endif /* DX_DEBUG */ - - /* -+ * dx_find_position -+ * -+ * search position of specified hash in index -+ * -+ */ -+ -+struct dx_entry * dx_find_position(struct dx_entry * entries, u32 hash) -+{ -+ struct dx_entry *p, *q, *m; -+ int count; -+ -+ count = dx_get_count(entries); -+ p = entries + 1; -+ q = entries + count - 1; -+ while (p <= q) -+ { -+ m = p + (q - p)/2; -+ if (dx_get_hash(m) > hash) -+ q = m - 1; -+ else -+ p = m + 1; -+ } -+ return p - 1; -+} -+ -+/* -+ * returns 1 if path is unchanged -+ */ -+int dx_check_path(struct dx_frame *frame, u32 hash) -+{ -+ struct dx_entry *p; -+ int ret = 1; -+ -+ dx_lock_bh(frame->bh); -+ p = dx_find_position(frame->entries, hash); -+ if (frame->leaf != dx_get_block(p)) -+ ret = 0; -+ dx_unlock_bh(frame->bh); -+ -+ return ret; -+} -+ -+/* -+ * 0 - changed -+ * 1 - hasn't changed -+ */ -+static int -+dx_check_full_path(struct dx_frame *frames, struct dx_hash_info *hinfo) -+{ -+ struct dx_entry *p; -+ struct dx_frame *frame = frames; -+ u32 leaf; -+ -+ /* check first level */ -+ dx_lock_bh(frame->bh); -+ p = dx_find_position(frame->entries, hinfo->hash); -+ leaf = dx_get_block(p); -+ dx_unlock_bh(frame->bh); -+ -+ if (leaf != frame->leaf) -+ return 0; -+ -+ /* is there 2nd level? */ -+ frame++; -+ if (frame->bh == NULL) -+ return 1; -+ -+ /* check second level */ -+ dx_lock_bh(frame->bh); -+ -+ /* probably 1st level got changed, check it */ -+ if (!dx_check_path(frames, hinfo->hash)) { -+ /* path changed */ -+ dx_unlock_bh(frame->bh); -+ return 0; -+ } -+ -+ p = dx_find_position(frame->entries, hinfo->hash); -+ leaf = dx_get_block(p); -+ dx_unlock_bh(frame->bh); -+ -+ if (leaf != frame->leaf) -+ return 0; -+ -+ return 1; -+} -+ -+/* - * Probe for a directory leaf block to search. - * - * dx_probe can return ERR_BAD_DX_DIR, which means there was a format -@@ -315,19 +437,20 @@ - * back to userspace. - */ - static struct dx_frame * --dx_probe(struct dentry *dentry, struct inode *dir, -+dx_probe(struct qstr *name, struct inode *dir, - struct dx_hash_info *hinfo, struct dx_frame *frame_in, int *err) - { -- unsigned count, indirect; -- struct dx_entry *at, *entries, *p, *q, *m; -+ unsigned indirect; -+ struct dx_entry *at, *entries; - struct dx_root *root; - struct buffer_head *bh; - struct dx_frame *frame = frame_in; - u32 hash; -+ unsigned int curidx; - - frame->bh = NULL; -- if (dentry) -- dir = dentry->d_parent->d_inode; -+ frame[1].bh = NULL; -+ - if (!(bh = ext3_bread (NULL,dir, 0, 0, err))) - goto fail; - root = (struct dx_root *) bh->b_data; -@@ -343,8 +466,8 @@ - } - hinfo->hash_version = root->info.hash_version; - hinfo->seed = dir->i_sb->u.ext3_sb.s_hash_seed; -- if (dentry) -- ext3fs_dirhash(dentry->d_name.name, dentry->d_name.len, hinfo); -+ if (name) -+ ext3fs_dirhash(name->name, name->len, hinfo); - hash = hinfo->hash; - - if (root->info.unused_flags & 1) { -@@ -356,7 +479,19 @@ - goto fail; - } - -+repeat: -+ curidx = 0; -+ entries = (struct dx_entry *) (((char *)&root->info) + -+ root->info.info_length); -+ assert(dx_get_limit(entries) == dx_root_limit(dir, -+ root->info.info_length)); -+ dxtrace (printk("Look up %x", hash)); -+ dx_lock_bh(bh); -+ /* indirect must be initialized under bh lock because -+ * 2nd level creation procedure may change it and dx_probe() -+ * will suggest htree is still single-level -bzzz */ - if ((indirect = root->info.indirect_levels) > 1) { -+ dx_unlock_bh(bh); - ext3_warning(dir->i_sb, __FUNCTION__, - "Unimplemented inode hash depth: %#06x", - root->info.indirect_levels); -@@ -364,56 +499,46 @@ - *err = ERR_BAD_DX_DIR; - goto fail; - } -- -- entries = (struct dx_entry *) (((char *)&root->info) + -- root->info.info_length); -- assert(dx_get_limit(entries) == dx_root_limit(dir, -- root->info.info_length)); -- dxtrace (printk("Look up %x", hash)); -+ - while (1) - { -- count = dx_get_count(entries); -- assert (count && count <= dx_get_limit(entries)); -- p = entries + 1; -- q = entries + count - 1; -- while (p <= q) -- { -- m = p + (q - p)/2; -- dxtrace(printk(".")); -- if (dx_get_hash(m) > hash) -- q = m - 1; -- else -- p = m + 1; -- } -- -- if (0) // linear search cross check -- { -- unsigned n = count - 1; -- at = entries; -- while (n--) -- { -- dxtrace(printk(",")); -- if (dx_get_hash(++at) > hash) -- { -- at--; -- break; -- } -- } -- assert (at == p - 1); -- } -- -- at = p - 1; -- dxtrace(printk(" %x->%u\n", at == entries? 0: dx_get_hash(at), dx_get_block(at))); -+ at = dx_find_position(entries, hinfo->hash); -+ dxtrace(printk(" %x->%u\n", -+ at == entries? 0: dx_get_hash(at), -+ dx_get_block(at))); - frame->bh = bh; - frame->entries = entries; - frame->at = at; -- if (!indirect--) return frame; -- if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0, err))) -+ frame->curidx = curidx; -+ frame->leaf = dx_get_block(at); -+ if (!indirect--) { -+ dx_unlock_bh(bh); -+ return frame; -+ } -+ -+ /* step into next htree level */ -+ curidx = dx_get_block(at); -+ dx_unlock_bh(bh); -+ if (!(bh = ext3_bread (NULL,dir, frame->leaf, 0, err))) - goto fail2; -+ -+ dx_lock_bh(bh); -+ /* splitting may change root index block and move -+ * hash we're looking for into another index block -+ * so, we have to check this situation and repeat -+ * from begining if path got changed -bzzz */ -+ if (!dx_check_path(frame, hash)) { -+ dx_unlock_bh(bh); -+ bh = frame->bh; -+ indirect++; -+ goto repeat; -+ } -+ - at = entries = ((struct dx_node *) bh->b_data)->entries; - assert (dx_get_limit(entries) == dx_node_limit (dir)); - frame++; - } -+ dx_unlock_bh(bh); - fail2: - while (frame >= frame_in) { - brelse(frame->bh); -@@ -427,8 +552,7 @@ - { - if (frames[0].bh == NULL) - return; -- -- if (((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels) -+ if (frames[1].bh != NULL) - brelse(frames[1].bh); - brelse(frames[0].bh); - } -@@ -470,8 +594,10 @@ - * nodes need to be read. - */ - while (1) { -- if (++(p->at) < p->entries + dx_get_count(p->entries)) -+ if (++(p->at) < p->entries + dx_get_count(p->entries)) { -+ p->leaf = dx_get_block(p->at); - break; -+ } - if (p == frames) - return 0; - num_frames++; -@@ -497,13 +623,17 @@ - * block so no check is necessary - */ - while (num_frames--) { -- if (!(bh = ext3_bread(NULL, dir, dx_get_block(p->at), -- 0, err))) -+ u32 idx; -+ -+ idx = p->leaf = dx_get_block(p->at); -+ if (!(bh = ext3_bread(NULL, dir, idx, 0, err))) - return -1; /* Failure */ - p++; - brelse (p->bh); - p->bh = bh; - p->at = p->entries = ((struct dx_node *) bh->b_data)->entries; -+ p->curidx = idx; -+ p->leaf = dx_get_block(p->at); - } - return 1; - } -@@ -543,7 +673,7 @@ - dir = dir_file->f_dentry->d_inode; - hinfo.hash = start_hash; - hinfo.minor_hash = 0; -- frame = dx_probe(0, dir_file->f_dentry->d_inode, &hinfo, frames, &err); -+ frame = dx_probe(NULL, dir_file->f_dentry->d_inode, &hinfo, frames, &err); - if (!frame) - return err; - -@@ -625,7 +755,8 @@ - count++; - } - /* XXX: do we need to check rec_len == 0 case? -Chris */ -- de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len)); -+ de = (struct ext3_dir_entry_2 *)((char*)de + -+ le16_to_cpu(de->rec_len)); - } - return count; - } -@@ -658,7 +789,8 @@ - } while(more); - } - --static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block) -+static void dx_insert_block(struct inode *dir, struct dx_frame *frame, -+ u32 hash, u32 block, u32 idx) - { - struct dx_entry *entries = frame->entries; - struct dx_entry *old = frame->at, *new = old + 1; -@@ -670,6 +802,7 @@ - dx_set_hash(new, hash); - dx_set_block(new, block); - dx_set_count(entries, count + 1); -+ - } - #endif - -@@ -752,7 +885,8 @@ - - - static struct buffer_head * ext3_find_entry (struct dentry *dentry, -- struct ext3_dir_entry_2 ** res_dir) -+ struct ext3_dir_entry_2 ** res_dir, -+ int rwlock, void **lock) - { - struct super_block * sb; - struct buffer_head * bh_use[NAMEI_RA_SIZE]; -@@ -768,6 +902,7 @@ - int namelen; - const u8 *name; - unsigned blocksize; -+ int do_not_use_dx = 0; - - *res_dir = NULL; - sb = dir->i_sb; -@@ -776,9 +911,10 @@ - name = dentry->d_name.name; - if (namelen > EXT3_NAME_LEN) - return NULL; -+repeat: - #ifdef CONFIG_EXT3_INDEX - if (is_dx(dir)) { -- bh = ext3_dx_find_entry(dentry, res_dir, &err); -+ bh = ext3_dx_find_entry(dentry, res_dir, &err, rwlock, lock); - /* - * On success, or if the error was file not found, - * return. Otherwise, fall back to doing a search the -@@ -787,8 +923,14 @@ - if (bh || (err != ERR_BAD_DX_DIR)) - return bh; - dxtrace(printk("ext3_find_entry: dx failed, falling back\n")); -+ do_not_use_dx = 1; - } - #endif -+ *lock = ext3_lock_htree(dir, 0, rwlock); -+ if (is_dx(dir) && !do_not_use_dx) { -+ ext3_unlock_htree(dir, *lock); -+ goto repeat; -+ } - nblocks = dir->i_size >> EXT3_BLOCK_SIZE_BITS(sb); - start = EXT3_I(dir)->i_dir_start_lookup; - if (start >= nblocks) -@@ -859,12 +1001,17 @@ - /* Clean up the read-ahead blocks */ - for (; ra_ptr < ra_max; ra_ptr++) - brelse (bh_use[ra_ptr]); -+ if (!ret) { -+ ext3_unlock_htree(dir, *lock); -+ *lock = NULL; -+ } - return ret; - } - - #ifdef CONFIG_EXT3_INDEX - static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry, -- struct ext3_dir_entry_2 **res_dir, int *err) -+ struct ext3_dir_entry_2 **res_dir, int *err, -+ int rwlock, void **lock) - { - struct super_block * sb; - struct dx_hash_info hinfo; -@@ -879,11 +1026,22 @@ - struct inode *dir = dentry->d_parent->d_inode; - - sb = dir->i_sb; -- if (!(frame = dx_probe (dentry, 0, &hinfo, frames, err))) -+repeat: -+ if (!(frame = dx_probe (&dentry->d_name, dir, &hinfo, frames, err))) - return NULL; -+ -+ *lock = ext3_lock_htree(dir, frame->leaf, rwlock); -+ /* while locking leaf we just found may get splitted -+ * so, we need another leaf. check this */ -+ if (!dx_check_full_path(frames, &hinfo)) { -+ ext3_unlock_htree(dir, *lock); -+ dx_release(frames); -+ goto repeat; -+ } -+ - hash = hinfo.hash; - do { -- block = dx_get_block(frame->at); -+ block = frame->leaf; - if (!(bh = ext3_bread (NULL,dir, block, 0, err))) - goto errout; - de = (struct ext3_dir_entry_2 *) bh->b_data; -@@ -917,6 +1075,8 @@ - *err = -ENOENT; - errout: - dxtrace(printk("%s not found\n", name)); -+ ext3_unlock_htree(dir, *lock); -+ *lock = NULL; - dx_release (frames); - return NULL; - } -@@ -927,6 +1087,7 @@ - struct inode * inode; - struct ext3_dir_entry_2 * de; - struct buffer_head * bh; -+ void *lock = NULL; - - if (dentry->d_name.len > EXT3_NAME_LEN) - return ERR_PTR(-ENAMETOOLONG); -@@ -934,10 +1095,11 @@ - if (ext3_check_for_iopen(dir, dentry)) - return NULL; - -- bh = ext3_find_entry(dentry, &de); -+ bh = ext3_find_entry(dentry, &de, 0, &lock); - inode = NULL; - if (bh) { - unsigned long ino = le32_to_cpu(de->inode); -+ ext3_unlock_htree(dir, lock); - brelse (bh); - inode = iget(dir->i_sb, ino); - -@@ -974,7 +1136,8 @@ - unsigned rec_len = 0; - - while (count--) { -- struct ext3_dir_entry_2 *de = (struct ext3_dir_entry_2 *) (from + map->offs); -+ struct ext3_dir_entry_2 *de = -+ (struct ext3_dir_entry_2 *) (from + map->offs); - rec_len = EXT3_DIR_REC_LEN(de->name_len); - memcpy (to, de, rec_len); - ((struct ext3_dir_entry_2 *)to)->rec_len = cpu_to_le16(rec_len); -@@ -987,7 +1150,8 @@ - - static struct ext3_dir_entry_2* dx_pack_dirents(char *base, int size) - { -- struct ext3_dir_entry_2 *next, *to, *prev, *de = (struct ext3_dir_entry_2 *) base; -+ struct ext3_dir_entry_2 *next, *to, *prev; -+ struct ext3_dir_entry_2 *de = (struct ext3_dir_entry_2 *) base; - unsigned rec_len = 0; - - prev = to = de; -@@ -1009,7 +1173,8 @@ - - static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir, - struct buffer_head **bh,struct dx_frame *frame, -- struct dx_hash_info *hinfo, int *error) -+ struct dx_hash_info *hinfo, void **target, -+ int *error) - { - unsigned blocksize = dir->i_sb->s_blocksize; - unsigned count, continued; -@@ -1056,23 +1221,30 @@ - hash2 = map[split].hash; - continued = hash2 == map[split - 1].hash; - dxtrace(printk("Split block %i at %x, %i/%i\n", -- dx_get_block(frame->at), hash2, split, count-split)); -- -+ frame->leaf, hash2, split, count-split)); -+ - /* Fancy dance to stay within two buffers */ - de2 = dx_move_dirents(data1, data2, map + split, count - split); - de = dx_pack_dirents(data1,blocksize); - de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de); - de2->rec_len = cpu_to_le16(data2 + blocksize - (char *) de2); -- dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data1, blocksize, 1)); -- dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data2, blocksize, 1)); -+ dxtrace(dx_show_leaf(hinfo,(struct ext3_dir_entry_2*) data1, blocksize, 1)); -+ dxtrace(dx_show_leaf(hinfo,(struct ext3_dir_entry_2*) data2, blocksize, 1)); - - /* Which block gets the new entry? */ -+ *target = NULL; - if (hinfo->hash >= hash2) - { - swap(*bh, bh2); - de = de2; -- } -- dx_insert_block (frame, hash2 + continued, newblock); -+ -+ /* entry will be stored into new block -+ * we have to lock it before add_dirent_to_buf */ -+ *target = ext3_lock_htree(dir, newblock, 1); -+ } -+ dx_lock_bh(frame->bh); -+ dx_insert_block (dir, frame, hash2 + continued, newblock, frame->curidx); -+ dx_unlock_bh(frame->bh); - err = ext3_journal_dirty_metadata (handle, bh2); - if (err) - goto journal_error; -@@ -1146,7 +1318,8 @@ - nlen = EXT3_DIR_REC_LEN(de->name_len); - rlen = le16_to_cpu(de->rec_len); - if (de->inode) { -- struct ext3_dir_entry_2 *de1 = (struct ext3_dir_entry_2 *)((char *)de + nlen); -+ struct ext3_dir_entry_2 *de1 = -+ (struct ext3_dir_entry_2 *)((char *)de + nlen); - de1->rec_len = cpu_to_le16(rlen - nlen); - de->rec_len = cpu_to_le16(nlen); - de = de1; -@@ -1204,7 +1377,8 @@ - unsigned blocksize; - struct dx_hash_info hinfo; - u32 block; -- -+ void *lock, *new_lock; -+ - blocksize = dir->i_sb->s_blocksize; - dxtrace(printk("Creating index\n")); - retval = ext3_journal_get_write_access(handle, bh); -@@ -1215,7 +1389,6 @@ - } - root = (struct dx_root *) bh->b_data; - -- EXT3_I(dir)->i_flags |= EXT3_INDEX_FL; - bh2 = ext3_append (handle, dir, &block, &retval); - if (!(bh2)) { - brelse(bh); -@@ -1223,6 +1396,8 @@ - } - data1 = bh2->b_data; - -+ lock = ext3_lock_htree(dir, block, 1); -+ - /* The 0th block becomes the root, move the dirents out */ - de = (struct ext3_dir_entry_2 *)&root->dotdot; - de = (struct ext3_dir_entry_2 *)((char *)de + le16_to_cpu(de->rec_len)); -@@ -1252,13 +1427,25 @@ - frame->entries = entries; - frame->at = entries; - frame->bh = bh; -+ frame->curidx = 0; -+ frame->leaf = 0; -+ frame[1].bh = NULL; - bh = bh2; -- de = do_split(handle,dir, &bh, frame, &hinfo, &retval); -+ de = do_split(handle,dir, &bh, frame, &hinfo, &new_lock, &retval); - dx_release (frames); - if (!(de)) -- return retval; -+ goto cleanup; -+ -+ retval = add_dirent_to_buf(handle, dentry, inode, de, bh); -+cleanup: -+ if (new_lock) -+ ext3_unlock_htree(dir, new_lock); -+ /* we mark directory indexed in order to -+ * avoid races while htree being created -bzzz */ -+ EXT3_I(dir)->i_flags |= EXT3_INDEX_FL; -+ ext3_unlock_htree(dir, lock); - -- return add_dirent_to_buf(handle, dentry, inode, de, bh); -+ return retval; - } - #endif - -@@ -1287,11 +1474,13 @@ - unsigned blocksize; - unsigned nlen, rlen; - u32 block, blocks; -+ void *lock; - - sb = dir->i_sb; - blocksize = sb->s_blocksize; - if (!dentry->d_name.len) - return -EINVAL; -+repeat: - #ifdef CONFIG_EXT3_INDEX - if (is_dx(dir)) { - retval = ext3_dx_add_entry(handle, dentry, inode); -@@ -1302,36 +1491,53 @@ - ext3_mark_inode_dirty(handle, dir); - } - #endif -+ lock = ext3_lock_htree(dir, 0, 1); -+ if (is_dx(dir)) { -+ /* we got lock for block 0 -+ * probably previous holder of the lock -+ * created htree -bzzz */ -+ ext3_unlock_htree(dir, lock); -+ goto repeat; -+ } -+ - blocks = dir->i_size >> sb->s_blocksize_bits; - for (block = 0, offset = 0; block < blocks; block++) { - bh = ext3_bread(handle, dir, block, 0, &retval); -- if(!bh) -+ if(!bh) { -+ ext3_unlock_htree(dir, lock); - return retval; -+ } - retval = add_dirent_to_buf(handle, dentry, inode, 0, bh); -- if (retval != -ENOSPC) -+ if (retval != -ENOSPC) { -+ ext3_unlock_htree(dir, lock); - return retval; -+ } - - #ifdef CONFIG_EXT3_INDEX - if (blocks == 1 && !dx_fallback && -- EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX)) -- return make_indexed_dir(handle, dentry, inode, bh); -+ EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX)) { -+ retval = make_indexed_dir(handle, dentry, inode, bh); -+ ext3_unlock_htree(dir, lock); -+ return retval; -+ } - #endif - brelse(bh); - } - bh = ext3_append(handle, dir, &block, &retval); -- if (!bh) -+ if (!bh) { -+ ext3_unlock_htree(dir, lock); - return retval; -+ } - de = (struct ext3_dir_entry_2 *) bh->b_data; - de->inode = 0; - de->rec_len = cpu_to_le16(rlen = blocksize); - nlen = 0; -- return add_dirent_to_buf(handle, dentry, inode, de, bh); -+ retval = add_dirent_to_buf(handle, dentry, inode, de, bh); -+ ext3_unlock_htree(dir, lock); -+ return retval; - } - - #ifdef CONFIG_EXT3_INDEX --/* -- * Returns 0 for success, or a negative error value -- */ - static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry, - struct inode *inode) - { -@@ -1343,15 +1549,28 @@ - struct super_block * sb = dir->i_sb; - struct ext3_dir_entry_2 *de; - int err; -- -- frame = dx_probe(dentry, 0, &hinfo, frames, &err); -+ int curidx; -+ void *idx_lock, *leaf_lock, *newleaf_lock; -+ -+repeat: -+ frame = dx_probe(&dentry->d_name, dir, &hinfo, frames, &err); - if (!frame) - return err; -- entries = frame->entries; -- at = frame->at; - -- if (!(bh = ext3_bread(handle,dir, dx_get_block(frame->at), 0, &err))) -+ /* we're going to chage leaf, so lock it first */ -+ leaf_lock = ext3_lock_htree(dir, frame->leaf, 1); -+ -+ /* while locking leaf we just found may get splitted -+ * so we need to check this */ -+ if (!dx_check_full_path(frames, &hinfo)) { -+ ext3_unlock_htree(dir, leaf_lock); -+ dx_release(frames); -+ goto repeat; -+ } -+ if (!(bh = ext3_bread(handle,dir, frame->leaf, 0, &err))) { -+ printk("can't ext3_bread(%d) = %d\n", (int) frame->leaf, err); - goto cleanup; -+ } - - BUFFER_TRACE(bh, "get_write_access"); - err = ext3_journal_get_write_access(handle, bh); -@@ -1364,6 +1583,35 @@ - goto cleanup; - } - -+ /* our leaf has no enough space. hence, we have to -+ * split it. so lock index for this leaf first */ -+ curidx = frame->curidx; -+ idx_lock = ext3_lock_htree(dir, curidx, 1); -+ -+ /* now check did path get changed? */ -+ dx_release(frames); -+ -+ frame = dx_probe(&dentry->d_name, dentry->d_parent->d_inode, -+ &hinfo, frames, &err); -+ if (!frame) { -+ /* FIXME: error handling here */ -+ brelse(bh); -+ ext3_unlock_htree(dir, idx_lock); -+ return err; -+ } -+ -+ if (frame->curidx != curidx) { -+ /* path has been changed. we have to drop old lock -+ * and repeat */ -+ brelse(bh); -+ ext3_unlock_htree(dir, idx_lock); -+ ext3_unlock_htree(dir, leaf_lock); -+ dx_release(frames); -+ goto repeat; -+ } -+ entries = frame->entries; -+ at = frame->at; -+ - /* Block full, should compress but for now just split */ - dxtrace(printk("using %u of %u node entries\n", - dx_get_count(entries), dx_get_limit(entries))); -@@ -1375,7 +1623,8 @@ - struct dx_entry *entries2; - struct dx_node *node2; - struct buffer_head *bh2; -- -+ void *nb_lock; -+ - if (levels && (dx_get_count(frames->entries) == - dx_get_limit(frames->entries))) { - ext3_warning(sb, __FUNCTION__, -@@ -1386,6 +1635,7 @@ - bh2 = ext3_append (handle, dir, &newblock, &err); - if (!(bh2)) - goto cleanup; -+ nb_lock = ext3_lock_htree(dir, newblock, 1); - node2 = (struct dx_node *)(bh2->b_data); - entries2 = node2->entries; - node2->fake.rec_len = cpu_to_le16(sb->s_blocksize); -@@ -1397,27 +1647,73 @@ - if (levels) { - unsigned icount1 = icount/2, icount2 = icount - icount1; - unsigned hash2 = dx_get_hash(entries + icount1); -+ void *ri_lock; -+ -+ /* we have to protect root htree index against -+ * another dx_add_entry() which would want to -+ * split it too -bzzz */ -+ ri_lock = ext3_lock_htree(dir, 0, 1); -+ -+ /* as root index block blocked we must repeat -+ * searching for current position of our 2nd index -bzzz */ -+ dx_lock_bh(frame->bh); -+ frames->at = dx_find_position(frames->entries, hinfo.hash); -+ dx_unlock_bh(frame->bh); -+ - dxtrace(printk("Split index %i/%i\n", icount1, icount2)); -- -- BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */ -+ -+ BUFFER_TRACE(frame->bh, "get_write_access"); - err = ext3_journal_get_write_access(handle, - frames[0].bh); - if (err) - goto journal_error; -- -+ -+ /* copy index into new one */ - memcpy ((char *) entries2, (char *) (entries + icount1), - icount2 * sizeof(struct dx_entry)); -- dx_set_count (entries, icount1); - dx_set_count (entries2, icount2); - dx_set_limit (entries2, dx_node_limit(dir)); - - /* Which index block gets the new entry? */ - if (at - entries >= icount1) { -+ /* unlock index we won't use */ -+ ext3_unlock_htree(dir, idx_lock); -+ idx_lock = nb_lock; - frame->at = at = at - entries - icount1 + entries2; -- frame->entries = entries = entries2; -+ frame->entries = entries2; -+ frame->curidx = curidx = newblock; - swap(frame->bh, bh2); -+ } else { -+ /* we'll use old index,so new one may be freed */ -+ ext3_unlock_htree(dir, nb_lock); - } -- dx_insert_block (frames + 0, hash2, newblock); -+ -+ /* NOTE: very subtle piece of code -+ * competing dx_probe() may find 2nd level index in root -+ * index, then we insert new index here and set new count -+ * in that 2nd level index. so, dx_probe() may see 2nd -+ * level index w/o hash it looks for. the solution is -+ * to check root index after we locked just founded 2nd -+ * level index -bzzz */ -+ dx_lock_bh(frames[0].bh); -+ dx_insert_block (dir, frames + 0, hash2, newblock, 0); -+ dx_unlock_bh(frames[0].bh); -+ -+ /* now old and new 2nd level index blocks contain -+ * all pointers, so dx_probe() may find it in the both. -+ * it's OK -bzzz */ -+ -+ dx_lock_bh(frame->bh); -+ dx_set_count(entries, icount1); -+ dx_unlock_bh(frame->bh); -+ -+ /* now old 2nd level index block points to first half -+ * of leafs. it's importand that dx_probe() must -+ * check root index block for changes under -+ * dx_lock_bh(frame->bh) -bzzz */ -+ -+ ext3_unlock_htree(dir, ri_lock); -+ - dxtrace(dx_show_index ("node", frames[1].entries)); - dxtrace(dx_show_index ("node", - ((struct dx_node *) bh2->b_data)->entries)); -@@ -1426,38 +1722,61 @@ - goto journal_error; - brelse (bh2); - } else { -+ unsigned long leaf = frame->leaf; -+ - dxtrace(printk("Creating second level index...\n")); - memcpy((char *) entries2, (char *) entries, - icount * sizeof(struct dx_entry)); - dx_set_limit(entries2, dx_node_limit(dir)); - - /* Set up root */ -+ dx_lock_bh(frames[0].bh); - dx_set_count(entries, 1); - dx_set_block(entries + 0, newblock); - ((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels = 1; -+ dx_unlock_bh(frames[0].bh); - - /* Add new access path frame */ - frame = frames + 1; - frame->at = at = at - entries + entries2; - frame->entries = entries = entries2; - frame->bh = bh2; -+ frame->curidx = newblock; -+ frame->leaf = leaf; - err = ext3_journal_get_write_access(handle, - frame->bh); - if (err) - goto journal_error; -+ -+ /* first level index was root. it's already initialized */ -+ /* we my unlock it now */ -+ ext3_unlock_htree(dir, idx_lock); -+ -+ /* current index is just created 2nd level index */ -+ curidx = newblock; -+ idx_lock = nb_lock; - } - ext3_journal_dirty_metadata(handle, frames[0].bh); - } -- de = do_split(handle, dir, &bh, frame, &hinfo, &err); -+ de = do_split(handle, dir, &bh, frame, &hinfo, &newleaf_lock, &err); - if (!de) - goto cleanup; -+ -+ /* index splitted */ -+ ext3_unlock_htree(dir, idx_lock); -+ - err = add_dirent_to_buf(handle, dentry, inode, de, bh); -+ -+ if (newleaf_lock) -+ ext3_unlock_htree(dir, newleaf_lock); -+ - bh = 0; - goto cleanup; - - journal_error: - ext3_std_error(dir->i_sb, err); - cleanup: -+ ext3_unlock_htree(dir, leaf_lock); - if (bh) - brelse(bh); - dx_release(frames); -@@ -1905,6 +2224,7 @@ - struct buffer_head * bh; - struct ext3_dir_entry_2 * de; - handle_t *handle; -+ void *lock; - - handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS); - if (IS_ERR(handle)) { -@@ -1912,7 +2232,7 @@ - } - - retval = -ENOENT; -- bh = ext3_find_entry (dentry, &de); -+ bh = ext3_find_entry (dentry, &de, 1, &lock); - if (!bh) - goto end_rmdir; - -@@ -1923,14 +2243,19 @@ - DQUOT_INIT(inode); - - retval = -EIO; -- if (le32_to_cpu(de->inode) != inode->i_ino) -+ if (le32_to_cpu(de->inode) != inode->i_ino) { -+ ext3_unlock_htree(dir, lock); - goto end_rmdir; -+ } - - retval = -ENOTEMPTY; -- if (!empty_dir (inode)) -+ if (!empty_dir (inode)) { -+ ext3_unlock_htree(dir, lock); - goto end_rmdir; -+ } - - retval = ext3_delete_entry(handle, dir, de, bh); -+ ext3_unlock_htree(dir, lock); - if (retval) - goto end_rmdir; - if (inode->i_nlink != 2) -@@ -1989,6 +2314,7 @@ - struct buffer_head * bh; - struct ext3_dir_entry_2 * de; - handle_t *handle; -+ void *lock; - - handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS); - if (IS_ERR(handle)) { -@@ -1999,7 +2325,7 @@ - handle->h_sync = 1; - - retval = -ENOENT; -- bh = ext3_find_entry (dentry, &de); -+ bh = ext3_find_entry (dentry, &de, 1, &lock); - if (!bh) - goto end_unlink; - -@@ -2007,8 +2333,10 @@ - DQUOT_INIT(inode); - - retval = -EIO; -- if (le32_to_cpu(de->inode) != inode->i_ino) -+ if (le32_to_cpu(de->inode) != inode->i_ino) { -+ ext3_unlock_htree(dir, lock); - goto end_unlink; -+ } - - if (!inode->i_nlink) { - ext3_warning (inode->i_sb, "ext3_unlink", -@@ -2017,6 +2345,7 @@ - inode->i_nlink = 1; - } - retval = ext3_delete_entry(handle, dir, de, bh); -+ ext3_unlock_htree(dir, lock); - if (retval) - goto end_unlink; - dir->i_ctime = dir->i_mtime = CURRENT_TIME; -@@ -2155,6 +2484,7 @@ - struct buffer_head * old_bh, * new_bh, * dir_bh; - struct ext3_dir_entry_2 * old_de, * new_de; - int retval; -+ void *lock1 = NULL, *lock2 = NULL, *lock3 = NULL; - - old_bh = new_bh = dir_bh = NULL; - -@@ -2167,7 +2497,10 @@ - if (IS_SYNC(old_dir) || IS_SYNC(new_dir)) - handle->h_sync = 1; - -- old_bh = ext3_find_entry (old_dentry, &old_de); -+ if (old_dentry->d_parent == new_dentry->d_parent) -+ down(&EXT3_I(old_dentry->d_parent->d_inode)->i_rename_sem); -+ -+ old_bh = ext3_find_entry (old_dentry, &old_de, 1, &lock1 /* FIXME */); - /* - * Check for inode number is _not_ due to possible IO errors. - * We might rmdir the source, keep it as pwd of some process -@@ -2180,7 +2513,7 @@ - goto end_rename; - - new_inode = new_dentry->d_inode; -- new_bh = ext3_find_entry (new_dentry, &new_de); -+ new_bh = ext3_find_entry (new_dentry, &new_de, 1, &lock2 /* FIXME */); - if (new_bh) { - if (!new_inode) { - brelse (new_bh); -@@ -2247,7 +2580,7 @@ - struct buffer_head *old_bh2; - struct ext3_dir_entry_2 *old_de2; - -- old_bh2 = ext3_find_entry(old_dentry, &old_de2); -+ old_bh2 = ext3_find_entry(old_dentry, &old_de2, 1, &lock3 /* FIXME */); - if (old_bh2) { - retval = ext3_delete_entry(handle, old_dir, - old_de2, old_bh2); -@@ -2290,6 +2623,14 @@ - retval = 0; - - end_rename: -+ if (lock1) -+ ext3_unlock_htree(old_dentry->d_parent->d_inode, lock1); -+ if (lock2) -+ ext3_unlock_htree(new_dentry->d_parent->d_inode, lock2); -+ if (lock3) -+ ext3_unlock_htree(old_dentry->d_parent->d_inode, lock3); -+ if (old_dentry->d_parent == new_dentry->d_parent) -+ up(&EXT3_I(old_dentry->d_parent->d_inode)->i_rename_sem); - brelse (dir_bh); - brelse (old_bh); - brelse (new_bh); -@@ -2298,6 +2639,29 @@ - } - - /* -+ * this locking primitives are used to protect parts -+ * of dir's htree. protection unit is block: leaf or index -+ */ -+static inline void *ext3_lock_htree(struct inode *dir, -+ unsigned long value, int rwlock) -+{ -+ void *lock; -+ -+ if (!test_opt(dir->i_sb, PDIROPS)) -+ return NULL; -+ lock = dynlock_lock(&EXT3_I(dir)->i_htree_lock, value, 1, GFP_KERNEL); -+ return lock; -+} -+ -+static inline void ext3_unlock_htree(struct inode *dir, -+ void *lock) -+{ -+ if (!test_opt(dir->i_sb, PDIROPS) || !lock) -+ return; -+ dynlock_unlock(&EXT3_I(dir)->i_htree_lock, lock); -+} -+ -+/* - * directories can handle most operations... - */ - struct inode_operations ext3_dir_inode_operations = { -Index: lum/fs/ext3/super.c -=================================================================== ---- lum.orig/fs/ext3/super.c 2004-06-03 16:32:28.000000000 -0400 -+++ lum/fs/ext3/super.c 2004-06-03 16:37:15.000000000 -0400 -@@ -733,6 +733,9 @@ - if (want_numeric(value, "sb", sb_block)) - return 0; - } -+ else if (!strcmp (this_char, "pdirops")) { -+ set_opt (sbi->s_mount_opt, PDIROPS); -+ } - #ifdef CONFIG_JBD_DEBUG - else if (!strcmp (this_char, "ro-after")) { - unsigned long v; -@@ -896,6 +899,10 @@ - ext3_check_inodes_bitmap (sb); - } - #endif -+#ifdef S_PDIROPS -+ if (test_opt (sb, PDIROPS)) -+ sb->s_flags |= S_PDIROPS; -+#endif - setup_ro_after(sb); - return res; - } -@@ -1400,6 +1407,11 @@ - - ext3_ext_init(sb); - -+ if (test_opt(sb, PDIROPS)) { -+ printk (KERN_INFO "EXT3-fs: mounted filesystem with parallel dirops\n"); -+ sb->s_flags |= S_PDIROPS; -+ } -+ - return sb; - - failed_mount3: -Index: lum/fs/ext3/inode.c -=================================================================== ---- lum.orig/fs/ext3/inode.c 2004-06-03 16:32:29.000000000 -0400 -+++ lum/fs/ext3/inode.c 2004-06-03 16:37:15.000000000 -0400 -@@ -2251,6 +2251,9 @@ - } else if (S_ISDIR(inode->i_mode)) { - inode->i_op = &ext3_dir_inode_operations; - inode->i_fop = &ext3_dir_operations; -+ dynlock_init(&EXT3_I(inode)->i_htree_lock); -+ sema_init(&EXT3_I(inode)->i_rename_sem, 1); -+ sema_init(&EXT3_I(inode)->i_append_sem, 1); - } else if (S_ISLNK(inode->i_mode)) { - if (ext3_inode_is_fast_symlink(inode)) - inode->i_op = &ext3_fast_symlink_inode_operations; -Index: lum/fs/ext3/ialloc.c -=================================================================== ---- lum.orig/fs/ext3/ialloc.c 2004-06-03 16:32:28.000000000 -0400 -+++ lum/fs/ext3/ialloc.c 2004-06-03 16:37:15.000000000 -0400 -@@ -609,6 +609,9 @@ - return ERR_PTR(-EDQUOT); - } - ext3_debug ("allocating inode %lu\n", inode->i_ino); -+ dynlock_init(&EXT3_I(inode)->i_htree_lock); -+ sema_init(&EXT3_I(inode)->i_rename_sem, 1); -+ sema_init(&EXT3_I(inode)->i_append_sem, 1); - return inode; - - fail: -Index: lum/include/linux/ext3_fs.h -=================================================================== ---- lum.orig/include/linux/ext3_fs.h 2004-06-03 16:32:28.000000000 -0400 -+++ lum/include/linux/ext3_fs.h 2004-06-03 16:37:15.000000000 -0400 -@@ -320,6 +320,7 @@ - /* - * Mount flags - */ -+#define EXT3_MOUNT_PDIROPS 0x800000/* Parallel dir operations */ - #define EXT3_MOUNT_CHECK 0x0001 /* Do mount-time checks */ - #define EXT3_MOUNT_GRPID 0x0004 /* Create files with directory's group */ - #define EXT3_MOUNT_DEBUG 0x0008 /* Some debugging messages */ -Index: lum/include/linux/ext3_fs_i.h -=================================================================== ---- lum.orig/include/linux/ext3_fs_i.h 2004-06-03 16:32:28.000000000 -0400 -+++ lum/include/linux/ext3_fs_i.h 2004-06-03 16:37:15.000000000 -0400 -@@ -17,6 +17,7 @@ - #define _LINUX_EXT3_FS_I - - #include -+#include - - /* - * second extended file system inode data in memory -@@ -76,6 +77,11 @@ - * by other means, so we have truncate_sem. - */ - struct rw_semaphore truncate_sem; -+ -+ /* following fields for parallel directory operations -bzzz */ -+ struct dynlock i_htree_lock; -+ struct semaphore i_append_sem; -+ struct semaphore i_rename_sem; - - __u32 i_cached_extent[3]; - }; diff --git a/lustre/kernel_patches/patches/ext3-pdirops-2.4.24.patch b/lustre/kernel_patches/patches/ext3-pdirops-2.4.24.patch deleted file mode 100644 index dc1ea62..0000000 --- a/lustre/kernel_patches/patches/ext3-pdirops-2.4.24.patch +++ /dev/null @@ -1,1248 +0,0 @@ - fs/ext3/ialloc.c | 3 - fs/ext3/inode.c | 3 - fs/ext3/namei.c | 582 +++++++++++++++++++++++++++++++++++++--------- - fs/ext3/super.c | 14 + - include/linux/ext3_fs.h | 1 - include/linux/ext3_fs_i.h | 6 - 6 files changed, 500 insertions(+), 109 deletions(-) - -Index: linux-2.4.24/fs/ext3/namei.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/namei.c 2004-04-01 20:22:17.000000000 +0400 -+++ linux-2.4.24/fs/ext3/namei.c 2004-04-01 20:24:48.000000000 +0400 -@@ -51,6 +51,9 @@ - { - struct buffer_head *bh; - -+ /* with parallel dir operations all appends -+ * have to be serialized -bzzz */ -+ down(&EXT3_I(inode)->i_append_sem); - *block = inode->i_size >> inode->i_sb->s_blocksize_bits; - - if ((bh = ext3_bread(handle, inode, *block, 1, err))) { -@@ -58,6 +61,8 @@ - EXT3_I(inode)->i_disksize = inode->i_size; - ext3_journal_get_write_access(handle,bh); - } -+ up(&EXT3_I(inode)->i_append_sem); -+ - return bh; - } - -@@ -134,6 +139,8 @@ - struct buffer_head *bh; - struct dx_entry *entries; - struct dx_entry *at; -+ unsigned long leaf; -+ unsigned int curidx; - }; - - struct dx_map_entry -@@ -142,6 +149,30 @@ - u32 offs; - }; - -+/* FIXME: this should be reworked using bb_spin_lock -+ * introduced in -mm tree -+ */ -+#define BH_DXLock 25 -+ -+static inline void dx_lock_bh(struct buffer_head volatile *bh) -+{ -+#ifdef CONFIG_SMP -+ while (test_and_set_bit(BH_DXLock, &bh->b_state)) { -+ while (test_bit(BH_DXLock, &bh->b_state)) -+ cpu_relax(); -+ } -+#endif -+} -+ -+static inline void dx_unlock_bh(struct buffer_head *bh) -+{ -+#ifdef CONFIG_SMP -+ smp_mb__before_clear_bit(); -+ clear_bit(BH_DXLock, &bh->b_state); -+#endif -+} -+ -+ - #ifdef CONFIG_EXT3_INDEX - static inline unsigned dx_get_block (struct dx_entry *entry); - static void dx_set_block (struct dx_entry *entry, unsigned value); -@@ -153,7 +184,7 @@ - static void dx_set_limit (struct dx_entry *entries, unsigned value); - static unsigned dx_root_limit (struct inode *dir, unsigned infosize); - static unsigned dx_node_limit (struct inode *dir); --static struct dx_frame *dx_probe(struct dentry *dentry, -+static struct dx_frame *dx_probe(struct qstr *name, - struct inode *dir, - struct dx_hash_info *hinfo, - struct dx_frame *frame, -@@ -165,15 +196,18 @@ - static struct ext3_dir_entry_2 *dx_move_dirents (char *from, char *to, - struct dx_map_entry *offsets, int count); - static struct ext3_dir_entry_2* dx_pack_dirents (char *base, int size); --static void dx_insert_block (struct dx_frame *frame, u32 hash, u32 block); -+static void dx_insert_block (struct inode *, struct dx_frame *, u32, u32, u32); - static int ext3_htree_next_block(struct inode *dir, __u32 hash, - struct dx_frame *frame, - struct dx_frame *frames, int *err, - __u32 *start_hash); - static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry, -- struct ext3_dir_entry_2 **res_dir, int *err); -+ struct ext3_dir_entry_2 **res_dir, int *err, -+ int rwlock, void **lock); - static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry, - struct inode *inode); -+static inline void *ext3_lock_htree(struct inode *, unsigned long, int); -+static inline void ext3_unlock_htree(struct inode *, void *); - - /* - * Future: use high four bits of block for coalesce-on-delete flags -@@ -306,6 +340,94 @@ - #endif /* DX_DEBUG */ - - /* -+ * dx_find_position -+ * -+ * search position of specified hash in index -+ * -+ */ -+ -+struct dx_entry * dx_find_position(struct dx_entry * entries, u32 hash) -+{ -+ struct dx_entry *p, *q, *m; -+ int count; -+ -+ count = dx_get_count(entries); -+ p = entries + 1; -+ q = entries + count - 1; -+ while (p <= q) -+ { -+ m = p + (q - p)/2; -+ if (dx_get_hash(m) > hash) -+ q = m - 1; -+ else -+ p = m + 1; -+ } -+ return p - 1; -+} -+ -+/* -+ * returns 1 if path is unchanged -+ */ -+int dx_check_path(struct dx_frame *frame, u32 hash) -+{ -+ struct dx_entry *p; -+ int ret = 1; -+ -+ dx_lock_bh(frame->bh); -+ p = dx_find_position(frame->entries, hash); -+ if (frame->leaf != dx_get_block(p)) -+ ret = 0; -+ dx_unlock_bh(frame->bh); -+ -+ return ret; -+} -+ -+/* -+ * 0 - changed -+ * 1 - hasn't changed -+ */ -+static int -+dx_check_full_path(struct dx_frame *frames, struct dx_hash_info *hinfo) -+{ -+ struct dx_entry *p; -+ struct dx_frame *frame = frames; -+ u32 leaf; -+ -+ /* check first level */ -+ dx_lock_bh(frame->bh); -+ p = dx_find_position(frame->entries, hinfo->hash); -+ leaf = dx_get_block(p); -+ dx_unlock_bh(frame->bh); -+ -+ if (leaf != frame->leaf) -+ return 0; -+ -+ /* is there 2nd level? */ -+ frame++; -+ if (frame->bh == NULL) -+ return 1; -+ -+ /* check second level */ -+ dx_lock_bh(frame->bh); -+ -+ /* probably 1st level got changed, check it */ -+ if (!dx_check_path(frames, hinfo->hash)) { -+ /* path changed */ -+ dx_unlock_bh(frame->bh); -+ return 0; -+ } -+ -+ p = dx_find_position(frame->entries, hinfo->hash); -+ leaf = dx_get_block(p); -+ dx_unlock_bh(frame->bh); -+ -+ if (leaf != frame->leaf) -+ return 0; -+ -+ return 1; -+} -+ -+/* - * Probe for a directory leaf block to search. - * - * dx_probe can return ERR_BAD_DX_DIR, which means there was a format -@@ -315,19 +437,20 @@ - * back to userspace. - */ - static struct dx_frame * --dx_probe(struct dentry *dentry, struct inode *dir, -+dx_probe(struct qstr *name, struct inode *dir, - struct dx_hash_info *hinfo, struct dx_frame *frame_in, int *err) - { -- unsigned count, indirect; -- struct dx_entry *at, *entries, *p, *q, *m; -+ unsigned indirect; -+ struct dx_entry *at, *entries; - struct dx_root *root; - struct buffer_head *bh; - struct dx_frame *frame = frame_in; - u32 hash; -+ unsigned int curidx; - - frame->bh = NULL; -- if (dentry) -- dir = dentry->d_parent->d_inode; -+ frame[1].bh = NULL; -+ - if (!(bh = ext3_bread (NULL,dir, 0, 0, err))) - goto fail; - root = (struct dx_root *) bh->b_data; -@@ -343,8 +466,8 @@ - } - hinfo->hash_version = root->info.hash_version; - hinfo->seed = dir->i_sb->u.ext3_sb.s_hash_seed; -- if (dentry) -- ext3fs_dirhash(dentry->d_name.name, dentry->d_name.len, hinfo); -+ if (name) -+ ext3fs_dirhash(name->name, name->len, hinfo); - hash = hinfo->hash; - - if (root->info.unused_flags & 1) { -@@ -356,7 +479,19 @@ - goto fail; - } - -+repeat: -+ curidx = 0; -+ entries = (struct dx_entry *) (((char *)&root->info) + -+ root->info.info_length); -+ assert(dx_get_limit(entries) == dx_root_limit(dir, -+ root->info.info_length)); -+ dxtrace (printk("Look up %x", hash)); -+ dx_lock_bh(bh); -+ /* indirect must be initialized under bh lock because -+ * 2nd level creation procedure may change it and dx_probe() -+ * will suggest htree is still single-level -bzzz */ - if ((indirect = root->info.indirect_levels) > 1) { -+ dx_unlock_bh(bh); - ext3_warning(dir->i_sb, __FUNCTION__, - "Unimplemented inode hash depth: %#06x", - root->info.indirect_levels); -@@ -364,56 +499,46 @@ - *err = ERR_BAD_DX_DIR; - goto fail; - } -- -- entries = (struct dx_entry *) (((char *)&root->info) + -- root->info.info_length); -- assert(dx_get_limit(entries) == dx_root_limit(dir, -- root->info.info_length)); -- dxtrace (printk("Look up %x", hash)); -+ - while (1) - { -- count = dx_get_count(entries); -- assert (count && count <= dx_get_limit(entries)); -- p = entries + 1; -- q = entries + count - 1; -- while (p <= q) -- { -- m = p + (q - p)/2; -- dxtrace(printk(".")); -- if (dx_get_hash(m) > hash) -- q = m - 1; -- else -- p = m + 1; -- } -- -- if (0) // linear search cross check -- { -- unsigned n = count - 1; -- at = entries; -- while (n--) -- { -- dxtrace(printk(",")); -- if (dx_get_hash(++at) > hash) -- { -- at--; -- break; -- } -- } -- assert (at == p - 1); -- } -- -- at = p - 1; -- dxtrace(printk(" %x->%u\n", at == entries? 0: dx_get_hash(at), dx_get_block(at))); -+ at = dx_find_position(entries, hinfo->hash); -+ dxtrace(printk(" %x->%u\n", -+ at == entries? 0: dx_get_hash(at), -+ dx_get_block(at))); - frame->bh = bh; - frame->entries = entries; - frame->at = at; -- if (!indirect--) return frame; -- if (!(bh = ext3_bread (NULL,dir, dx_get_block(at), 0, err))) -+ frame->curidx = curidx; -+ frame->leaf = dx_get_block(at); -+ if (!indirect--) { -+ dx_unlock_bh(bh); -+ return frame; -+ } -+ -+ /* step into next htree level */ -+ curidx = dx_get_block(at); -+ dx_unlock_bh(bh); -+ if (!(bh = ext3_bread (NULL,dir, frame->leaf, 0, err))) - goto fail2; -+ -+ dx_lock_bh(bh); -+ /* splitting may change root index block and move -+ * hash we're looking for into another index block -+ * so, we have to check this situation and repeat -+ * from begining if path got changed -bzzz */ -+ if (!dx_check_path(frame, hash)) { -+ dx_unlock_bh(bh); -+ bh = frame->bh; -+ indirect++; -+ goto repeat; -+ } -+ - at = entries = ((struct dx_node *) bh->b_data)->entries; - assert (dx_get_limit(entries) == dx_node_limit (dir)); - frame++; - } -+ dx_unlock_bh(bh); - fail2: - while (frame >= frame_in) { - brelse(frame->bh); -@@ -427,8 +552,7 @@ - { - if (frames[0].bh == NULL) - return; -- -- if (((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels) -+ if (frames[1].bh != NULL) - brelse(frames[1].bh); - brelse(frames[0].bh); - } -@@ -470,8 +594,10 @@ - * nodes need to be read. - */ - while (1) { -- if (++(p->at) < p->entries + dx_get_count(p->entries)) -+ if (++(p->at) < p->entries + dx_get_count(p->entries)) { -+ p->leaf = dx_get_block(p->at); - break; -+ } - if (p == frames) - return 0; - num_frames++; -@@ -497,13 +623,17 @@ - * block so no check is necessary - */ - while (num_frames--) { -- if (!(bh = ext3_bread(NULL, dir, dx_get_block(p->at), -- 0, err))) -+ u32 idx; -+ -+ idx = p->leaf = dx_get_block(p->at); -+ if (!(bh = ext3_bread(NULL, dir, idx, 0, err))) - return -1; /* Failure */ - p++; - brelse (p->bh); - p->bh = bh; - p->at = p->entries = ((struct dx_node *) bh->b_data)->entries; -+ p->curidx = idx; -+ p->leaf = dx_get_block(p->at); - } - return 1; - } -@@ -543,7 +673,7 @@ - dir = dir_file->f_dentry->d_inode; - hinfo.hash = start_hash; - hinfo.minor_hash = 0; -- frame = dx_probe(0, dir_file->f_dentry->d_inode, &hinfo, frames, &err); -+ frame = dx_probe(NULL, dir_file->f_dentry->d_inode, &hinfo, frames, &err); - if (!frame) - return err; - -@@ -625,7 +755,8 @@ - count++; - } - /* XXX: do we need to check rec_len == 0 case? -Chris */ -- de = (struct ext3_dir_entry_2 *) ((char *) de + le16_to_cpu(de->rec_len)); -+ de = (struct ext3_dir_entry_2 *)((char*)de + -+ le16_to_cpu(de->rec_len)); - } - return count; - } -@@ -658,7 +789,8 @@ - } while(more); - } - --static void dx_insert_block(struct dx_frame *frame, u32 hash, u32 block) -+static void dx_insert_block(struct inode *dir, struct dx_frame *frame, -+ u32 hash, u32 block, u32 idx) - { - struct dx_entry *entries = frame->entries; - struct dx_entry *old = frame->at, *new = old + 1; -@@ -670,6 +802,7 @@ - dx_set_hash(new, hash); - dx_set_block(new, block); - dx_set_count(entries, count + 1); -+ - } - #endif - -@@ -752,7 +885,8 @@ - - - static struct buffer_head * ext3_find_entry (struct dentry *dentry, -- struct ext3_dir_entry_2 ** res_dir) -+ struct ext3_dir_entry_2 ** res_dir, -+ int rwlock, void **lock) - { - struct super_block * sb; - struct buffer_head * bh_use[NAMEI_RA_SIZE]; -@@ -768,6 +902,7 @@ - int namelen; - const u8 *name; - unsigned blocksize; -+ int do_not_use_dx = 0; - - *res_dir = NULL; - sb = dir->i_sb; -@@ -776,9 +911,10 @@ - name = dentry->d_name.name; - if (namelen > EXT3_NAME_LEN) - return NULL; -+repeat: - #ifdef CONFIG_EXT3_INDEX - if (is_dx(dir)) { -- bh = ext3_dx_find_entry(dentry, res_dir, &err); -+ bh = ext3_dx_find_entry(dentry, res_dir, &err, rwlock, lock); - /* - * On success, or if the error was file not found, - * return. Otherwise, fall back to doing a search the -@@ -787,8 +923,14 @@ - if (bh || (err != ERR_BAD_DX_DIR)) - return bh; - dxtrace(printk("ext3_find_entry: dx failed, falling back\n")); -+ do_not_use_dx = 1; - } - #endif -+ *lock = ext3_lock_htree(dir, 0, rwlock); -+ if (is_dx(dir) && !do_not_use_dx) { -+ ext3_unlock_htree(dir, *lock); -+ goto repeat; -+ } - nblocks = dir->i_size >> EXT3_BLOCK_SIZE_BITS(sb); - start = EXT3_I(dir)->i_dir_start_lookup; - if (start >= nblocks) -@@ -859,12 +1001,17 @@ - /* Clean up the read-ahead blocks */ - for (; ra_ptr < ra_max; ra_ptr++) - brelse (bh_use[ra_ptr]); -+ if (!ret) { -+ ext3_unlock_htree(dir, *lock); -+ *lock = NULL; -+ } - return ret; - } - - #ifdef CONFIG_EXT3_INDEX - static struct buffer_head * ext3_dx_find_entry(struct dentry *dentry, -- struct ext3_dir_entry_2 **res_dir, int *err) -+ struct ext3_dir_entry_2 **res_dir, int *err, -+ int rwlock, void **lock) - { - struct super_block * sb; - struct dx_hash_info hinfo; -@@ -879,11 +1026,22 @@ - struct inode *dir = dentry->d_parent->d_inode; - - sb = dir->i_sb; -- if (!(frame = dx_probe (dentry, 0, &hinfo, frames, err))) -+repeat: -+ if (!(frame = dx_probe (&dentry->d_name, dir, &hinfo, frames, err))) - return NULL; -+ -+ *lock = ext3_lock_htree(dir, frame->leaf, rwlock); -+ /* while locking leaf we just found may get splitted -+ * so, we need another leaf. check this */ -+ if (!dx_check_full_path(frames, &hinfo)) { -+ ext3_unlock_htree(dir, *lock); -+ dx_release(frames); -+ goto repeat; -+ } -+ - hash = hinfo.hash; - do { -- block = dx_get_block(frame->at); -+ block = frame->leaf; - if (!(bh = ext3_bread (NULL,dir, block, 0, err))) - goto errout; - de = (struct ext3_dir_entry_2 *) bh->b_data; -@@ -917,6 +1075,8 @@ - *err = -ENOENT; - errout: - dxtrace(printk("%s not found\n", name)); -+ ext3_unlock_htree(dir, *lock); -+ *lock = NULL; - dx_release (frames); - return NULL; - } -@@ -927,6 +1087,7 @@ - struct inode * inode; - struct ext3_dir_entry_2 * de; - struct buffer_head * bh; -+ void *lock = NULL; - - if (dentry->d_name.len > EXT3_NAME_LEN) - return ERR_PTR(-ENAMETOOLONG); -@@ -934,10 +1095,11 @@ - if (ext3_check_for_iopen(dir, dentry)) - return NULL; - -- bh = ext3_find_entry(dentry, &de); -+ bh = ext3_find_entry(dentry, &de, 0, &lock); - inode = NULL; - if (bh) { - unsigned long ino = le32_to_cpu(de->inode); -+ ext3_unlock_htree(dir, lock); - brelse (bh); - inode = iget(dir->i_sb, ino); - -@@ -974,7 +1136,8 @@ - unsigned rec_len = 0; - - while (count--) { -- struct ext3_dir_entry_2 *de = (struct ext3_dir_entry_2 *) (from + map->offs); -+ struct ext3_dir_entry_2 *de = -+ (struct ext3_dir_entry_2 *) (from + map->offs); - rec_len = EXT3_DIR_REC_LEN(de->name_len); - memcpy (to, de, rec_len); - ((struct ext3_dir_entry_2 *) to)->rec_len = rec_len; -@@ -987,7 +1150,8 @@ - - static struct ext3_dir_entry_2* dx_pack_dirents(char *base, int size) - { -- struct ext3_dir_entry_2 *next, *to, *prev, *de = (struct ext3_dir_entry_2 *) base; -+ struct ext3_dir_entry_2 *next, *to, *prev; -+ struct ext3_dir_entry_2 *de = (struct ext3_dir_entry_2 *) base; - unsigned rec_len = 0; - - prev = to = de; -@@ -1009,7 +1173,8 @@ - - static struct ext3_dir_entry_2 *do_split(handle_t *handle, struct inode *dir, - struct buffer_head **bh,struct dx_frame *frame, -- struct dx_hash_info *hinfo, int *error) -+ struct dx_hash_info *hinfo, void **target, -+ int *error) - { - unsigned blocksize = dir->i_sb->s_blocksize; - unsigned count, continued; -@@ -1056,23 +1221,30 @@ - hash2 = map[split].hash; - continued = hash2 == map[split - 1].hash; - dxtrace(printk("Split block %i at %x, %i/%i\n", -- dx_get_block(frame->at), hash2, split, count-split)); -- -+ frame->leaf, hash2, split, count-split)); -+ - /* Fancy dance to stay within two buffers */ - de2 = dx_move_dirents(data1, data2, map + split, count - split); - de = dx_pack_dirents(data1,blocksize); - de->rec_len = cpu_to_le16(data1 + blocksize - (char *) de); - de2->rec_len = cpu_to_le16(data2 + blocksize - (char *) de2); -- dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data1, blocksize, 1)); -- dxtrace(dx_show_leaf (hinfo, (struct ext3_dir_entry_2 *) data2, blocksize, 1)); -+ dxtrace(dx_show_leaf(hinfo,(struct ext3_dir_entry_2*) data1, blocksize, 1)); -+ dxtrace(dx_show_leaf(hinfo,(struct ext3_dir_entry_2*) data2, blocksize, 1)); - - /* Which block gets the new entry? */ -+ *target = NULL; - if (hinfo->hash >= hash2) - { - swap(*bh, bh2); - de = de2; -- } -- dx_insert_block (frame, hash2 + continued, newblock); -+ -+ /* entry will be stored into new block -+ * we have to lock it before add_dirent_to_buf */ -+ *target = ext3_lock_htree(dir, newblock, 1); -+ } -+ dx_lock_bh(frame->bh); -+ dx_insert_block (dir, frame, hash2 + continued, newblock, frame->curidx); -+ dx_unlock_bh(frame->bh); - err = ext3_journal_dirty_metadata (handle, bh2); - if (err) - goto journal_error; -@@ -1146,7 +1318,8 @@ - nlen = EXT3_DIR_REC_LEN(de->name_len); - rlen = le16_to_cpu(de->rec_len); - if (de->inode) { -- struct ext3_dir_entry_2 *de1 = (struct ext3_dir_entry_2 *)((char *)de + nlen); -+ struct ext3_dir_entry_2 *de1 = -+ (struct ext3_dir_entry_2 *)((char *)de + nlen); - de1->rec_len = cpu_to_le16(rlen - nlen); - de->rec_len = cpu_to_le16(nlen); - de = de1; -@@ -1204,7 +1377,8 @@ - unsigned blocksize; - struct dx_hash_info hinfo; - u32 block; -- -+ void *lock, *new_lock; -+ - blocksize = dir->i_sb->s_blocksize; - dxtrace(printk("Creating index\n")); - retval = ext3_journal_get_write_access(handle, bh); -@@ -1215,7 +1389,6 @@ - } - root = (struct dx_root *) bh->b_data; - -- EXT3_I(dir)->i_flags |= EXT3_INDEX_FL; - bh2 = ext3_append (handle, dir, &block, &retval); - if (!(bh2)) { - brelse(bh); -@@ -1223,6 +1396,8 @@ - } - data1 = bh2->b_data; - -+ lock = ext3_lock_htree(dir, block, 1); -+ - /* The 0th block becomes the root, move the dirents out */ - de = (struct ext3_dir_entry_2 *) &root->dotdot; - de = (struct ext3_dir_entry_2 *) ((char *)de + de->rec_len); -@@ -1252,13 +1427,25 @@ - frame->entries = entries; - frame->at = entries; - frame->bh = bh; -+ frame->curidx = 0; -+ frame->leaf = 0; -+ frame[1].bh = NULL; - bh = bh2; -- de = do_split(handle,dir, &bh, frame, &hinfo, &retval); -+ de = do_split(handle,dir, &bh, frame, &hinfo, &new_lock, &retval); - dx_release (frames); - if (!(de)) -- return retval; -+ goto cleanup; -+ -+ retval = add_dirent_to_buf(handle, dentry, inode, de, bh); -+cleanup: -+ if (new_lock) -+ ext3_unlock_htree(dir, new_lock); -+ /* we mark directory indexed in order to -+ * avoid races while htree being created -bzzz */ -+ EXT3_I(dir)->i_flags |= EXT3_INDEX_FL; -+ ext3_unlock_htree(dir, lock); - -- return add_dirent_to_buf(handle, dentry, inode, de, bh); -+ return retval; - } - #endif - -@@ -1287,11 +1474,13 @@ - unsigned blocksize; - unsigned nlen, rlen; - u32 block, blocks; -+ void *lock; - - sb = dir->i_sb; - blocksize = sb->s_blocksize; - if (!dentry->d_name.len) - return -EINVAL; -+repeat: - #ifdef CONFIG_EXT3_INDEX - if (is_dx(dir)) { - retval = ext3_dx_add_entry(handle, dentry, inode); -@@ -1302,36 +1491,53 @@ - ext3_mark_inode_dirty(handle, dir); - } - #endif -+ lock = ext3_lock_htree(dir, 0, 1); -+ if (is_dx(dir)) { -+ /* we got lock for block 0 -+ * probably previous holder of the lock -+ * created htree -bzzz */ -+ ext3_unlock_htree(dir, lock); -+ goto repeat; -+ } -+ - blocks = dir->i_size >> sb->s_blocksize_bits; - for (block = 0, offset = 0; block < blocks; block++) { - bh = ext3_bread(handle, dir, block, 0, &retval); -- if(!bh) -+ if(!bh) { -+ ext3_unlock_htree(dir, lock); - return retval; -+ } - retval = add_dirent_to_buf(handle, dentry, inode, 0, bh); -- if (retval != -ENOSPC) -+ if (retval != -ENOSPC) { -+ ext3_unlock_htree(dir, lock); - return retval; -+ } - - #ifdef CONFIG_EXT3_INDEX - if (blocks == 1 && !dx_fallback && -- EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX)) -- return make_indexed_dir(handle, dentry, inode, bh); -+ EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_DIR_INDEX)) { -+ retval = make_indexed_dir(handle, dentry, inode, bh); -+ ext3_unlock_htree(dir, lock); -+ return retval; -+ } - #endif - brelse(bh); - } - bh = ext3_append(handle, dir, &block, &retval); -- if (!bh) -+ if (!bh) { -+ ext3_unlock_htree(dir, lock); - return retval; -+ } - de = (struct ext3_dir_entry_2 *) bh->b_data; - de->inode = 0; - de->rec_len = cpu_to_le16(rlen = blocksize); - nlen = 0; -- return add_dirent_to_buf(handle, dentry, inode, de, bh); -+ retval = add_dirent_to_buf(handle, dentry, inode, de, bh); -+ ext3_unlock_htree(dir, lock); -+ return retval; - } - - #ifdef CONFIG_EXT3_INDEX --/* -- * Returns 0 for success, or a negative error value -- */ - static int ext3_dx_add_entry(handle_t *handle, struct dentry *dentry, - struct inode *inode) - { -@@ -1343,15 +1549,28 @@ - struct super_block * sb = dir->i_sb; - struct ext3_dir_entry_2 *de; - int err; -- -- frame = dx_probe(dentry, 0, &hinfo, frames, &err); -+ int curidx; -+ void *idx_lock, *leaf_lock, *newleaf_lock; -+ -+repeat: -+ frame = dx_probe(&dentry->d_name, dir, &hinfo, frames, &err); - if (!frame) - return err; -- entries = frame->entries; -- at = frame->at; - -- if (!(bh = ext3_bread(handle,dir, dx_get_block(frame->at), 0, &err))) -+ /* we're going to chage leaf, so lock it first */ -+ leaf_lock = ext3_lock_htree(dir, frame->leaf, 1); -+ -+ /* while locking leaf we just found may get splitted -+ * so we need to check this */ -+ if (!dx_check_full_path(frames, &hinfo)) { -+ ext3_unlock_htree(dir, leaf_lock); -+ dx_release(frames); -+ goto repeat; -+ } -+ if (!(bh = ext3_bread(handle,dir, frame->leaf, 0, &err))) { -+ printk("can't ext3_bread(%d) = %d\n", (int) frame->leaf, err); - goto cleanup; -+ } - - BUFFER_TRACE(bh, "get_write_access"); - err = ext3_journal_get_write_access(handle, bh); -@@ -1364,6 +1583,35 @@ - goto cleanup; - } - -+ /* our leaf has no enough space. hence, we have to -+ * split it. so lock index for this leaf first */ -+ curidx = frame->curidx; -+ idx_lock = ext3_lock_htree(dir, curidx, 1); -+ -+ /* now check did path get changed? */ -+ dx_release(frames); -+ -+ frame = dx_probe(&dentry->d_name, dentry->d_parent->d_inode, -+ &hinfo, frames, &err); -+ if (!frame) { -+ /* FIXME: error handling here */ -+ brelse(bh); -+ ext3_unlock_htree(dir, idx_lock); -+ return err; -+ } -+ -+ if (frame->curidx != curidx) { -+ /* path has been changed. we have to drop old lock -+ * and repeat */ -+ brelse(bh); -+ ext3_unlock_htree(dir, idx_lock); -+ ext3_unlock_htree(dir, leaf_lock); -+ dx_release(frames); -+ goto repeat; -+ } -+ entries = frame->entries; -+ at = frame->at; -+ - /* Block full, should compress but for now just split */ - dxtrace(printk("using %u of %u node entries\n", - dx_get_count(entries), dx_get_limit(entries))); -@@ -1375,7 +1623,8 @@ - struct dx_entry *entries2; - struct dx_node *node2; - struct buffer_head *bh2; -- -+ void *nb_lock; -+ - if (levels && (dx_get_count(frames->entries) == - dx_get_limit(frames->entries))) { - ext3_warning(sb, __FUNCTION__, -@@ -1386,6 +1635,7 @@ - bh2 = ext3_append (handle, dir, &newblock, &err); - if (!(bh2)) - goto cleanup; -+ nb_lock = ext3_lock_htree(dir, newblock, 1); - node2 = (struct dx_node *)(bh2->b_data); - entries2 = node2->entries; - node2->fake.rec_len = cpu_to_le16(sb->s_blocksize); -@@ -1397,27 +1647,73 @@ - if (levels) { - unsigned icount1 = icount/2, icount2 = icount - icount1; - unsigned hash2 = dx_get_hash(entries + icount1); -+ void *ri_lock; -+ -+ /* we have to protect root htree index against -+ * another dx_add_entry() which would want to -+ * split it too -bzzz */ -+ ri_lock = ext3_lock_htree(dir, 0, 1); -+ -+ /* as root index block blocked we must repeat -+ * searching for current position of our 2nd index -bzzz */ -+ dx_lock_bh(frame->bh); -+ frames->at = dx_find_position(frames->entries, hinfo.hash); -+ dx_unlock_bh(frame->bh); -+ - dxtrace(printk("Split index %i/%i\n", icount1, icount2)); -- -- BUFFER_TRACE(frame->bh, "get_write_access"); /* index root */ -+ -+ BUFFER_TRACE(frame->bh, "get_write_access"); - err = ext3_journal_get_write_access(handle, - frames[0].bh); - if (err) - goto journal_error; -- -+ -+ /* copy index into new one */ - memcpy ((char *) entries2, (char *) (entries + icount1), - icount2 * sizeof(struct dx_entry)); -- dx_set_count (entries, icount1); - dx_set_count (entries2, icount2); - dx_set_limit (entries2, dx_node_limit(dir)); - - /* Which index block gets the new entry? */ - if (at - entries >= icount1) { -+ /* unlock index we won't use */ -+ ext3_unlock_htree(dir, idx_lock); -+ idx_lock = nb_lock; - frame->at = at = at - entries - icount1 + entries2; -- frame->entries = entries = entries2; -+ frame->entries = entries2; -+ frame->curidx = curidx = newblock; - swap(frame->bh, bh2); -+ } else { -+ /* we'll use old index,so new one may be freed */ -+ ext3_unlock_htree(dir, nb_lock); - } -- dx_insert_block (frames + 0, hash2, newblock); -+ -+ /* NOTE: very subtle piece of code -+ * competing dx_probe() may find 2nd level index in root -+ * index, then we insert new index here and set new count -+ * in that 2nd level index. so, dx_probe() may see 2nd -+ * level index w/o hash it looks for. the solution is -+ * to check root index after we locked just founded 2nd -+ * level index -bzzz */ -+ dx_lock_bh(frames[0].bh); -+ dx_insert_block (dir, frames + 0, hash2, newblock, 0); -+ dx_unlock_bh(frames[0].bh); -+ -+ /* now old and new 2nd level index blocks contain -+ * all pointers, so dx_probe() may find it in the both. -+ * it's OK -bzzz */ -+ -+ dx_lock_bh(frame->bh); -+ dx_set_count(entries, icount1); -+ dx_unlock_bh(frame->bh); -+ -+ /* now old 2nd level index block points to first half -+ * of leafs. it's importand that dx_probe() must -+ * check root index block for changes under -+ * dx_lock_bh(frame->bh) -bzzz */ -+ -+ ext3_unlock_htree(dir, ri_lock); -+ - dxtrace(dx_show_index ("node", frames[1].entries)); - dxtrace(dx_show_index ("node", - ((struct dx_node *) bh2->b_data)->entries)); -@@ -1426,38 +1722,61 @@ - goto journal_error; - brelse (bh2); - } else { -+ unsigned long leaf = frame->leaf; -+ - dxtrace(printk("Creating second level index...\n")); - memcpy((char *) entries2, (char *) entries, - icount * sizeof(struct dx_entry)); - dx_set_limit(entries2, dx_node_limit(dir)); - - /* Set up root */ -+ dx_lock_bh(frames[0].bh); - dx_set_count(entries, 1); - dx_set_block(entries + 0, newblock); - ((struct dx_root *) frames[0].bh->b_data)->info.indirect_levels = 1; -+ dx_unlock_bh(frames[0].bh); - - /* Add new access path frame */ - frame = frames + 1; - frame->at = at = at - entries + entries2; - frame->entries = entries = entries2; - frame->bh = bh2; -+ frame->curidx = newblock; -+ frame->leaf = leaf; - err = ext3_journal_get_write_access(handle, - frame->bh); - if (err) - goto journal_error; -+ -+ /* first level index was root. it's already initialized */ -+ /* we my unlock it now */ -+ ext3_unlock_htree(dir, idx_lock); -+ -+ /* current index is just created 2nd level index */ -+ curidx = newblock; -+ idx_lock = nb_lock; - } - ext3_journal_dirty_metadata(handle, frames[0].bh); - } -- de = do_split(handle, dir, &bh, frame, &hinfo, &err); -+ de = do_split(handle, dir, &bh, frame, &hinfo, &newleaf_lock, &err); - if (!de) - goto cleanup; -+ -+ /* index splitted */ -+ ext3_unlock_htree(dir, idx_lock); -+ - err = add_dirent_to_buf(handle, dentry, inode, de, bh); -+ -+ if (newleaf_lock) -+ ext3_unlock_htree(dir, newleaf_lock); -+ - bh = 0; - goto cleanup; - - journal_error: - ext3_std_error(dir->i_sb, err); - cleanup: -+ ext3_unlock_htree(dir, leaf_lock); - if (bh) - brelse(bh); - dx_release(frames); -@@ -1901,6 +2220,7 @@ - struct buffer_head * bh; - struct ext3_dir_entry_2 * de; - handle_t *handle; -+ void *lock; - - handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS); - if (IS_ERR(handle)) { -@@ -1908,7 +2228,7 @@ - } - - retval = -ENOENT; -- bh = ext3_find_entry (dentry, &de); -+ bh = ext3_find_entry (dentry, &de, 1, &lock); - if (!bh) - goto end_rmdir; - -@@ -1919,14 +2239,19 @@ - DQUOT_INIT(inode); - - retval = -EIO; -- if (le32_to_cpu(de->inode) != inode->i_ino) -+ if (le32_to_cpu(de->inode) != inode->i_ino) { -+ ext3_unlock_htree(dir, lock); - goto end_rmdir; -+ } - - retval = -ENOTEMPTY; -- if (!empty_dir (inode)) -+ if (!empty_dir (inode)) { -+ ext3_unlock_htree(dir, lock); - goto end_rmdir; -+ } - - retval = ext3_delete_entry(handle, dir, de, bh); -+ ext3_unlock_htree(dir, lock); - if (retval) - goto end_rmdir; - if (inode->i_nlink != 2) -@@ -1985,6 +2310,7 @@ - struct buffer_head * bh; - struct ext3_dir_entry_2 * de; - handle_t *handle; -+ void *lock; - - handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS); - if (IS_ERR(handle)) { -@@ -1995,7 +2321,7 @@ - handle->h_sync = 1; - - retval = -ENOENT; -- bh = ext3_find_entry (dentry, &de); -+ bh = ext3_find_entry (dentry, &de, 1, &lock); - if (!bh) - goto end_unlink; - -@@ -2003,8 +2329,10 @@ - DQUOT_INIT(inode); - - retval = -EIO; -- if (le32_to_cpu(de->inode) != inode->i_ino) -+ if (le32_to_cpu(de->inode) != inode->i_ino) { -+ ext3_unlock_htree(dir, lock); - goto end_unlink; -+ } - - if (!inode->i_nlink) { - ext3_warning (inode->i_sb, "ext3_unlink", -@@ -2013,6 +2341,7 @@ - inode->i_nlink = 1; - } - retval = ext3_delete_entry(handle, dir, de, bh); -+ ext3_unlock_htree(dir, lock); - if (retval) - goto end_unlink; - dir->i_ctime = dir->i_mtime = CURRENT_TIME; -@@ -2151,6 +2480,7 @@ - struct buffer_head * old_bh, * new_bh, * dir_bh; - struct ext3_dir_entry_2 * old_de, * new_de; - int retval; -+ void *lock1 = NULL, *lock2 = NULL, *lock3 = NULL; - - old_bh = new_bh = dir_bh = NULL; - -@@ -2163,7 +2493,10 @@ - if (IS_SYNC(old_dir) || IS_SYNC(new_dir)) - handle->h_sync = 1; - -- old_bh = ext3_find_entry (old_dentry, &old_de); -+ if (old_dentry->d_parent == new_dentry->d_parent) -+ down(&EXT3_I(old_dentry->d_parent->d_inode)->i_rename_sem); -+ -+ old_bh = ext3_find_entry (old_dentry, &old_de, 1, &lock1 /* FIXME */); - /* - * Check for inode number is _not_ due to possible IO errors. - * We might rmdir the source, keep it as pwd of some process -@@ -2176,7 +2509,7 @@ - goto end_rename; - - new_inode = new_dentry->d_inode; -- new_bh = ext3_find_entry (new_dentry, &new_de); -+ new_bh = ext3_find_entry (new_dentry, &new_de, 1, &lock2 /* FIXME */); - if (new_bh) { - if (!new_inode) { - brelse (new_bh); -@@ -2239,7 +2572,7 @@ - struct buffer_head *old_bh2; - struct ext3_dir_entry_2 *old_de2; - -- old_bh2 = ext3_find_entry(old_dentry, &old_de2); -+ old_bh2 = ext3_find_entry(old_dentry, &old_de2, 1, &lock3 /* FIXME */); - if (old_bh2) { - retval = ext3_delete_entry(handle, old_dir, - old_de2, old_bh2); -@@ -2282,6 +2615,14 @@ - retval = 0; - - end_rename: -+ if (lock1) -+ ext3_unlock_htree(old_dentry->d_parent->d_inode, lock1); -+ if (lock2) -+ ext3_unlock_htree(new_dentry->d_parent->d_inode, lock2); -+ if (lock3) -+ ext3_unlock_htree(old_dentry->d_parent->d_inode, lock3); -+ if (old_dentry->d_parent == new_dentry->d_parent) -+ up(&EXT3_I(old_dentry->d_parent->d_inode)->i_rename_sem); - brelse (dir_bh); - brelse (old_bh); - brelse (new_bh); -@@ -2290,6 +2631,29 @@ - } - - /* -+ * this locking primitives are used to protect parts -+ * of dir's htree. protection unit is block: leaf or index -+ */ -+static inline void *ext3_lock_htree(struct inode *dir, -+ unsigned long value, int rwlock) -+{ -+ void *lock; -+ -+ if (!test_opt(dir->i_sb, PDIROPS)) -+ return NULL; -+ lock = dynlock_lock(&EXT3_I(dir)->i_htree_lock, value, 1, GFP_KERNEL); -+ return lock; -+} -+ -+static inline void ext3_unlock_htree(struct inode *dir, -+ void *lock) -+{ -+ if (!test_opt(dir->i_sb, PDIROPS) || !lock) -+ return; -+ dynlock_unlock(&EXT3_I(dir)->i_htree_lock, lock); -+} -+ -+/* - * directories can handle most operations... - */ - struct inode_operations ext3_dir_inode_operations = { -Index: linux-2.4.24/fs/ext3/super.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/super.c 2004-04-01 20:22:17.000000000 +0400 -+++ linux-2.4.24/fs/ext3/super.c 2004-04-01 20:24:48.000000000 +0400 -@@ -702,6 +702,8 @@ - return 0; - } - } -+ else if (!strcmp (this_char, "pdirops")) -+ set_opt (sbi->s_mount_opt, PDIROPS); - else if (!strcmp (this_char, "grpid") || - !strcmp (this_char, "bsdgroups")) - set_opt (*mount_options, GRPID); -@@ -728,6 +730,9 @@ - if (want_numeric(value, "sb", sb_block)) - return 0; - } -+ else if (!strcmp (this_char, "pdirops")) { -+ set_opt (sbi->s_mount_opt, PDIROPS); -+ } - #ifdef CONFIG_JBD_DEBUG - else if (!strcmp (this_char, "ro-after")) { - unsigned long v; -@@ -891,6 +896,10 @@ - ext3_check_inodes_bitmap (sb); - } - #endif -+#ifdef S_PDIROPS -+ if (test_opt (sb, PDIROPS)) -+ sb->s_flags |= S_PDIROPS; -+#endif - setup_ro_after(sb); - return res; - } -@@ -1393,6 +1402,11 @@ - test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered": - "writeback"); - -+ if (test_opt(sb, PDIROPS)) { -+ printk (KERN_INFO "EXT3-fs: mounted filesystem with parallel dirops\n"); -+ sb->s_flags |= S_PDIROPS; -+ } -+ - return sb; - - failed_mount3: -Index: linux-2.4.24/fs/ext3/inode.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/inode.c 2004-04-01 20:22:18.000000000 +0400 -+++ linux-2.4.24/fs/ext3/inode.c 2004-04-01 20:24:48.000000000 +0400 -@@ -2239,6 +2239,9 @@ - } else if (S_ISDIR(inode->i_mode)) { - inode->i_op = &ext3_dir_inode_operations; - inode->i_fop = &ext3_dir_operations; -+ dynlock_init(&EXT3_I(inode)->i_htree_lock); -+ sema_init(&EXT3_I(inode)->i_rename_sem, 1); -+ sema_init(&EXT3_I(inode)->i_append_sem, 1); - } else if (S_ISLNK(inode->i_mode)) { - if (ext3_inode_is_fast_symlink(inode)) - inode->i_op = &ext3_fast_symlink_inode_operations; -Index: linux-2.4.24/fs/ext3/ialloc.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/ialloc.c 2004-04-01 20:22:17.000000000 +0400 -+++ linux-2.4.24/fs/ext3/ialloc.c 2004-04-01 20:24:48.000000000 +0400 -@@ -606,6 +606,9 @@ - return ERR_PTR(-EDQUOT); - } - ext3_debug ("allocating inode %lu\n", inode->i_ino); -+ dynlock_init(&EXT3_I(inode)->i_htree_lock); -+ sema_init(&EXT3_I(inode)->i_rename_sem, 1); -+ sema_init(&EXT3_I(inode)->i_append_sem, 1); - return inode; - - fail: -Index: linux-2.4.24/include/linux/ext3_fs.h -=================================================================== ---- linux-2.4.24.orig/include/linux/ext3_fs.h 2004-04-01 20:22:17.000000000 +0400 -+++ linux-2.4.24/include/linux/ext3_fs.h 2004-04-01 20:24:48.000000000 +0400 -@@ -308,6 +308,7 @@ - /* - * Mount flags - */ -+#define EXT3_MOUNT_PDIROPS 0x800000/* Parallel dir operations */ - #define EXT3_MOUNT_CHECK 0x0001 /* Do mount-time checks */ - #define EXT3_MOUNT_GRPID 0x0004 /* Create files with directory's group */ - #define EXT3_MOUNT_DEBUG 0x0008 /* Some debugging messages */ -Index: linux-2.4.24/include/linux/ext3_fs_i.h -=================================================================== ---- linux-2.4.24.orig/include/linux/ext3_fs_i.h 2004-04-01 20:22:17.000000000 +0400 -+++ linux-2.4.24/include/linux/ext3_fs_i.h 2004-04-01 20:24:48.000000000 +0400 -@@ -17,6 +17,7 @@ - #define _LINUX_EXT3_FS_I - - #include -+#include - - /* - * second extended file system inode data in memory -@@ -76,6 +77,11 @@ - * by other means, so we have truncate_sem. - */ - struct rw_semaphore truncate_sem; -+ -+ /* following fields for parallel directory operations -bzzz */ -+ struct dynlock i_htree_lock; -+ struct semaphore i_append_sem; -+ struct semaphore i_rename_sem; - }; - - #endif /* _LINUX_EXT3_FS_I */ diff --git a/lustre/kernel_patches/patches/ext3-raw-lookup-pdirops-2.4.24.patch b/lustre/kernel_patches/patches/ext3-raw-lookup-pdirops-2.4.24.patch deleted file mode 100644 index 3d4235b..0000000 --- a/lustre/kernel_patches/patches/ext3-raw-lookup-pdirops-2.4.24.patch +++ /dev/null @@ -1,65 +0,0 @@ - fs/ext3/namei.c | 31 +++++++++++++++++++++++++++++++ - include/linux/fs.h | 1 + - 2 files changed, 32 insertions(+) - -Index: lum/include/linux/fs.h -=================================================================== ---- lum.orig/include/linux/fs.h 2004-06-07 17:52:41.000000000 -0400 -+++ lum/include/linux/fs.h 2004-06-07 17:56:55.000000000 -0400 -@@ -904,6 +904,7 @@ - int (*create) (struct inode *,struct dentry *,int); - int (*create_it) (struct inode *,struct dentry *,int, struct lookup_intent *); - struct dentry * (*lookup) (struct inode *,struct dentry *); -+ int (*lookup_raw) (struct inode *, const char *, int, ino_t *); - struct dentry * (*lookup_it) (struct inode *,struct dentry *, struct nameidata *, struct lookup_intent *, int flags); - int (*link) (struct dentry *,struct inode *,struct dentry *); - int (*link_raw) (struct nameidata *,struct nameidata *); -Index: lum/fs/ext3/namei.c -=================================================================== ---- lum.orig/fs/ext3/namei.c 2004-06-07 17:52:41.000000000 -0400 -+++ lum/fs/ext3/namei.c 2004-06-07 17:56:31.000000000 -0400 -@@ -1128,6 +1128,36 @@ - return iopen_connect_dentry(dentry, inode, 1); - } - -+static int ext3_lookup_raw(struct inode *dir, const char *name, -+ int len, ino_t *data) -+{ -+ struct ext3_dir_entry_2 *de; -+ struct buffer_head *bh; -+ struct dentry parent; -+ struct dentry dentry; -+ void *lock = NULL; -+ -+ if (len > EXT3_NAME_LEN) -+ return -ENAMETOOLONG; -+ -+ parent.d_inode = dir; -+ dentry.d_parent = &parent; -+ dentry.d_name.name = name; -+ dentry.d_name.len = len; -+ -+ bh = ext3_find_entry(&dentry, &de, 0, &lock); -+ if (bh) { -+ unsigned long ino = le32_to_cpu(de->inode); -+ ext3_unlock_htree(dir, lock); -+ brelse (bh); -+ if (data) -+ *data = ino; -+ return 0; /* found name */ -+ } -+ -+ return -ENOENT; -+} -+ - #define S_SHIFT 12 - static unsigned char ext3_type_by_mode[S_IFMT >> S_SHIFT] = { - [S_IFREG >> S_SHIFT] EXT3_FT_REG_FILE, -@@ -2772,6 +2802,7 @@ - struct inode_operations ext3_dir_inode_operations = { - create: ext3_create, /* BKL held */ - lookup: ext3_lookup, /* BKL held */ -+ lookup_raw: ext3_lookup_raw, /* BKL held */ - link: ext3_link, /* BKL held */ - unlink: ext3_unlink, /* BKL held */ - symlink: ext3_symlink, /* BKL held */ diff --git a/lustre/kernel_patches/patches/ext3-san-2.4.24.patch b/lustre/kernel_patches/patches/ext3-san-2.4.24.patch deleted file mode 100644 index 148f4e3..0000000 --- a/lustre/kernel_patches/patches/ext3-san-2.4.24.patch +++ /dev/null @@ -1,117 +0,0 @@ - fs/ext3/ext3-exports.c | 9 ++++- - fs/ext3/inode.c | 81 +++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 89 insertions(+), 1 deletion(-) - ---- linux/fs/ext3/inode.c~ext3-san-2.4.20-hp Tue Apr 29 11:01:52 2003 -+++ linux-mmonroe/fs/ext3/inode.c Tue Apr 29 11:01:53 2003 -@@ -2734,3 +2734,84 @@ int ext3_change_inode_journal_flag(struc - * here, in ext3_aops_journal_start() to ensure that the forthcoming "see if we - * need to extend" test in ext3_prepare_write() succeeds. - */ -+ -+/* for each block: 1 ind + 1 dind + 1 tind -+ * for each block: 3 bitmap blocks -+ * for each block: 3 group descriptor blocks -+ * i inode block -+ * 1 superblock -+ * 2 * EXT3_SINGLEDATA_TRANS_BLOCKS for the quote files -+ * ((1+1+1) * 3 * nblocks) + 1 + 1 + 2 * EXT3_SINGLEDATA_TRANS_BLOCKS -+ * -+ * XXX assuming: -+ * (1) fs logic block size == page size -+ * (2) ext3 in writeback mode -+ */ -+static inline int ext3_san_write_trans_blocks(int nblocks) -+{ -+ int ret; -+ -+ ret = (1 + 1 + 1) * 3 * nblocks + 1 + 1; -+ -+#ifdef CONFIG_QUOTA -+ ret += 2 * EXT3_SINGLEDATA_TRANS_BLOCKS; -+#endif -+ -+ return ret; -+} -+ -+/* Alloc blocks for an inode, while don't create any buffer/page -+ * for data I/O; set the inode size if file is extended. -+ * -+ * @inode: target inode -+ * @blocks: array of logic block number -+ * @nblocks: how many blocks need be alloced -+ * @newsize: new filesize we should set -+ * -+ * return: 0 success, otherwise failed -+ * (*blocks) contains physical block number alloced -+ * -+ * XXX this assume the fs block size == page size -+ */ -+int ext3_prep_san_write(struct inode *inode, long *blocks, -+ int nblocks, loff_t newsize) -+{ -+ handle_t *handle; -+ struct buffer_head bh_tmp; -+ int needed_blocks; -+ int i, ret = 0, ret2; -+ -+ needed_blocks = ext3_san_write_trans_blocks(nblocks); -+ -+ lock_kernel(); -+ handle = ext3_journal_start(inode, needed_blocks); -+ if (IS_ERR(handle)) { -+ unlock_kernel(); -+ return PTR_ERR(handle); -+ } -+ unlock_kernel(); -+ -+ /* alloc blocks one by one */ -+ for (i = 0; i < nblocks; i++) { -+ ret = ext3_get_block_handle(handle, inode, blocks[i], -+ &bh_tmp, 1); -+ if (ret) -+ break; -+ -+ blocks[i] = bh_tmp.b_blocknr; -+ } -+ -+ /* set inode size if needed */ -+ if (!ret && (newsize > inode->i_size)) { -+ inode->i_size = newsize; -+ ext3_mark_inode_dirty(handle, inode); -+ } -+ -+ lock_kernel(); -+ ret2 = ext3_journal_stop(handle, inode); -+ unlock_kernel(); -+ -+ if (!ret) -+ ret = ret2; -+ return ret; -+} ---- linux/fs/ext3/ext3-exports.c~ext3-san-2.4.20-hp Tue Apr 29 11:01:51 2003 -+++ linux-mmonroe/fs/ext3/ext3-exports.c Tue Apr 29 11:07:19 2003 -@@ -1,9 +1,15 @@ - #include - #include --#include -+#include -+#include -+#include - #include -+#include - #include - -+int ext3_prep_san_write(struct inode *inode, long *blocks, -+ int nblocks, loff_t newsize); -+ - EXPORT_SYMBOL(ext3_force_commit); - EXPORT_SYMBOL(ext3_bread); - EXPORT_SYMBOL(ext3_xattr_register); -@@ -11,3 +17,4 @@ EXPORT_SYMBOL(ext3_xattr_unregister); - EXPORT_SYMBOL(ext3_xattr_get); - EXPORT_SYMBOL(ext3_xattr_list); - EXPORT_SYMBOL(ext3_xattr_set); -+EXPORT_SYMBOL(ext3_prep_san_write); - -_ diff --git a/lustre/kernel_patches/patches/ext3-truncate-buffer-head-2.4.24.patch b/lustre/kernel_patches/patches/ext3-truncate-buffer-head-2.4.24.patch deleted file mode 100644 index 3741213..0000000 --- a/lustre/kernel_patches/patches/ext3-truncate-buffer-head-2.4.24.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- lum/fs/ext3/inode.c~ 2004-01-30 16:47:12.000000000 -0800 -+++ lum/fs/ext3/inode.c 2004-01-30 16:46:14.000000000 -0800 -@@ -1485,6 +1485,7 @@ - if (ext3_should_order_data(inode)) - err = ext3_journal_dirty_data(handle, bh, 0); - __mark_buffer_dirty(bh); -+ buffer_insert_inode_data_queue(bh, inode); - } - - unlock: diff --git a/lustre/kernel_patches/patches/ext3-trusted_ea-2.4.24.patch b/lustre/kernel_patches/patches/ext3-trusted_ea-2.4.24.patch deleted file mode 100644 index 0a3bdb8..0000000 --- a/lustre/kernel_patches/patches/ext3-trusted_ea-2.4.24.patch +++ /dev/null @@ -1,180 +0,0 @@ - fs/ext3/xattr.c | 12 +++++- - fs/ext3/xattr_trusted.c | 86 +++++++++++++++++++++++++++++++++++++++++++++ - include/linux/ext3_xattr.h | 6 +++ - 3 files changed, 102 insertions(+), 2 deletions(-) - -Index: linux-2.4.20/fs/ext3/xattr.c -=================================================================== ---- linux-2.4.20.orig/fs/ext3/xattr.c 2003-10-22 02:29:40.000000000 +0400 -+++ linux-2.4.20/fs/ext3/xattr.c 2003-10-24 01:03:22.000000000 +0400 -@@ -1771,18 +1771,25 @@ - int __init - init_ext3_xattr(void) - { -+ int error; -+ - ext3_xattr_cache = mb_cache_create("ext3_xattr", NULL, - sizeof(struct mb_cache_entry) + - sizeof(struct mb_cache_entry_index), 1, 61); - if (!ext3_xattr_cache) - return -ENOMEM; - -- return 0; -+ error = init_ext3_xattr_trusted(); -+ if (error) -+ mb_cache_destroy(ext3_xattr_cache); -+ -+ return error; - } - - void - exit_ext3_xattr(void) - { -+ exit_ext3_xattr_trusted(); - if (ext3_xattr_cache) - mb_cache_destroy(ext3_xattr_cache); - ext3_xattr_cache = NULL; -@@ -1793,12 +1800,13 @@ - int __init - init_ext3_xattr(void) - { -- return 0; -+ return init_ext3_xattr_trusted(); - } - - void - exit_ext3_xattr(void) - { -+ exit_ext3_xattr_trusted(); - } - - #endif /* CONFIG_EXT3_FS_XATTR_SHARING */ -Index: linux-2.4.20/fs/ext3/xattr_trusted.c -=================================================================== ---- linux-2.4.20.orig/fs/ext3/xattr_trusted.c 2003-10-24 01:03:22.000000000 +0400 -+++ linux-2.4.20/fs/ext3/xattr_trusted.c 2003-10-24 01:03:22.000000000 +0400 -@@ -0,0 +1,86 @@ -+/* -+ * linux/fs/ext3/xattr_trusted.c -+ * Handler for trusted extended attributes. -+ * -+ * Copyright (C) 2003 by Andreas Gruenbacher, -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define XATTR_TRUSTED_PREFIX "trusted." -+ -+static size_t -+ext3_xattr_trusted_list(char *list, struct inode *inode, -+ const char *name, int name_len) -+{ -+ const int prefix_len = sizeof(XATTR_TRUSTED_PREFIX)-1; -+ -+ if (!capable(CAP_SYS_ADMIN)) -+ return 0; -+ -+ if (list) { -+ memcpy(list, XATTR_TRUSTED_PREFIX, prefix_len); -+ memcpy(list+prefix_len, name, name_len); -+ list[prefix_len + name_len] = '\0'; -+ } -+ return prefix_len + name_len + 1; -+} -+ -+static int -+ext3_xattr_trusted_get(struct inode *inode, const char *name, -+ void *buffer, size_t size) -+{ -+ if (strcmp(name, "") == 0) -+ return -EINVAL; -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EPERM; -+ return ext3_xattr_get(inode, EXT3_XATTR_INDEX_TRUSTED, name, -+ buffer, size); -+} -+ -+static int -+ext3_xattr_trusted_set(struct inode *inode, const char *name, -+ const void *value, size_t size, int flags) -+{ -+ handle_t *handle; -+ int error; -+ -+ if (strcmp(name, "") == 0) -+ return -EINVAL; -+ if (!capable(CAP_SYS_ADMIN)) -+ return -EPERM; -+ handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS); -+ if (IS_ERR(handle)) -+ return PTR_ERR(handle); -+ error = ext3_xattr_set(handle, inode, EXT3_XATTR_INDEX_TRUSTED, name, -+ value, size, flags); -+ ext3_journal_stop(handle, inode); -+ -+ return error; -+} -+ -+struct ext3_xattr_handler ext3_xattr_trusted_handler = { -+ .prefix = XATTR_TRUSTED_PREFIX, -+ .list = ext3_xattr_trusted_list, -+ .get = ext3_xattr_trusted_get, -+ .set = ext3_xattr_trusted_set, -+}; -+ -+int __init -+init_ext3_xattr_trusted(void) -+{ -+ return ext3_xattr_register(EXT3_XATTR_INDEX_TRUSTED, -+ &ext3_xattr_trusted_handler); -+} -+ -+void -+exit_ext3_xattr_trusted(void) -+{ -+ ext3_xattr_unregister(EXT3_XATTR_INDEX_TRUSTED, -+ &ext3_xattr_trusted_handler); -+} -Index: linux-2.4.20/include/linux/ext3_xattr.h -=================================================================== ---- linux-2.4.20.orig/include/linux/ext3_xattr.h 2003-10-22 02:29:39.000000000 +0400 -+++ linux-2.4.20/include/linux/ext3_xattr.h 2003-10-24 01:03:22.000000000 +0400 -@@ -21,6 +21,9 @@ - #define EXT3_XATTR_INDEX_USER 1 - #define EXT3_XATTR_INDEX_POSIX_ACL_ACCESS 2 - #define EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT 3 -+#define EXT3_XATTR_INDEX_TRUSTED 4 -+#define EXT3_XATTR_INDEX_LUSTRE 5 -+#define EXT3_XATTR_INDEX_SECURITY 6 - - struct ext3_xattr_header { - __u32 h_magic; /* magic number for identification */ -@@ -84,6 +87,9 @@ - extern int init_ext3_xattr(void) __init; - extern void exit_ext3_xattr(void); - -+extern int init_ext3_xattr_trusted(void) __init; -+extern void exit_ext3_xattr_trusted(void); -+ - # else /* CONFIG_EXT3_FS_XATTR */ - # define ext3_setxattr NULL - # define ext3_getxattr NULL -Index: linux-2.4.20/fs/ext3/Makefile -=================================================================== ---- linux-2.4.20.orig/fs/ext3/Makefile 2003-10-22 02:29:40.000000000 +0400 -+++ linux-2.4.20/fs/ext3/Makefile 2003-10-24 01:03:47.000000000 +0400 -@@ -12,7 +12,8 @@ - export-objs := ext3-exports.o - - obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \ -- ioctl.o namei.o super.o symlink.o hash.o ext3-exports.o -+ ioctl.o namei.o super.o symlink.o hash.o ext3-exports.o \ -+ xattr_trusted.o - obj-m := $(O_TARGET) - - export-objs += xattr.o diff --git a/lustre/kernel_patches/patches/ext3-xattr-ptr-arith-fix-2.4.24.patch b/lustre/kernel_patches/patches/ext3-xattr-ptr-arith-fix-2.4.24.patch deleted file mode 100644 index 818596c..0000000 --- a/lustre/kernel_patches/patches/ext3-xattr-ptr-arith-fix-2.4.24.patch +++ /dev/null @@ -1,18 +0,0 @@ -Index: linux-2.4.20/fs/ext3/xattr.c -=================================================================== ---- linux-2.4.20.orig/fs/ext3/xattr.c 2003-11-13 10:59:33.000000000 +0800 -+++ linux-2.4.20/fs/ext3/xattr.c 2003-11-25 21:16:51.000000000 +0800 -@@ -1293,9 +1293,10 @@ - goto cleanup; - memcpy(header, HDR(bh), bh->b_size); - header->h_refcount = cpu_to_le32(1); -- offset = (char *)header - bh->b_data; -- here = ENTRY((char *)here + offset); -- last = ENTRY((char *)last + offset); -+ offset = (char *)here - bh->b_data; -+ here = ENTRY((char *)header + offset); -+ offset = (char *)last - bh->b_data; -+ last = ENTRY((char *)header + offset); - } - } else { - /* Allocate a buffer where we construct the new block. */ diff --git a/lustre/kernel_patches/patches/extN-wantedi-2.4.24.patch b/lustre/kernel_patches/patches/extN-wantedi-2.4.24.patch deleted file mode 100644 index cf095c8..0000000 --- a/lustre/kernel_patches/patches/extN-wantedi-2.4.24.patch +++ /dev/null @@ -1,231 +0,0 @@ - fs/ext3/ialloc.c | 40 ++++++++++++++++++++++++++++++++++++++-- - fs/ext3/inode.c | 2 +- - fs/ext3/ioctl.c | 25 +++++++++++++++++++++++++ - fs/ext3/namei.c | 21 +++++++++++++++++---- - include/linux/dcache.h | 5 +++++ - include/linux/ext3_fs.h | 5 ++++- - 6 files changed, 90 insertions(+), 8 deletions(-) - -Index: linux-2.4.24/fs/ext3/namei.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/namei.c 2004-05-19 13:58:43.000000000 +0400 -+++ linux-2.4.24/fs/ext3/namei.c 2004-05-21 18:26:43.000000000 +0400 -@@ -1533,6 +1533,23 @@ - return err; - } - -+static struct inode * ext3_new_inode_wantedi(handle_t *handle, struct inode *dir, -+ int mode, struct dentry *dentry) -+{ -+ struct dentry_params *param = (struct dentry_params *) dentry->d_fsdata; -+ unsigned long inum = 0; -+ struct inode *inode; -+ -+ if (param != NULL) -+ inum = param->p_inum; -+ inode = ext3_new_inode(handle, dir, mode, inum); -+ if (inode && param && inum && param->p_generation) { -+ inode->i_generation = param->p_generation; -+ ext3_mark_inode_dirty(handle, inode); -+ } -+ return inode; -+} -+ - /* - * By the time this is called, we already have created - * the directory cache entry for the new file, but it -@@ -1556,7 +1573,7 @@ - if (IS_SYNC(dir)) - handle->h_sync = 1; - -- inode = ext3_new_inode (handle, dir, mode); -+ inode = ext3_new_inode_wantedi (handle, dir, mode, dentry); - err = PTR_ERR(inode); - if (!IS_ERR(inode)) { - inode->i_op = &ext3_file_inode_operations; -@@ -1584,7 +1601,7 @@ - if (IS_SYNC(dir)) - handle->h_sync = 1; - -- inode = ext3_new_inode (handle, dir, mode); -+ inode = ext3_new_inode_wantedi (handle, dir, mode, dentry); - err = PTR_ERR(inode); - if (!IS_ERR(inode)) { - init_special_inode(inode, mode, rdev); -@@ -1614,7 +1631,7 @@ - if (IS_SYNC(dir)) - handle->h_sync = 1; - -- inode = ext3_new_inode (handle, dir, S_IFDIR | mode); -+ inode = ext3_new_inode_wantedi (handle, dir, S_IFDIR | mode, dentry); - err = PTR_ERR(inode); - if (IS_ERR(inode)) - goto out_stop; -@@ -2041,7 +2058,7 @@ - if (IS_SYNC(dir)) - handle->h_sync = 1; - -- inode = ext3_new_inode (handle, dir, S_IFLNK|S_IRWXUGO); -+ inode = ext3_new_inode_wantedi (handle, dir, S_IFLNK|S_IRWXUGO, dentry); - err = PTR_ERR(inode); - if (IS_ERR(inode)) - goto out_stop; -Index: linux-2.4.24/fs/ext3/ialloc.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/ialloc.c 2004-05-19 13:58:43.000000000 +0400 -+++ linux-2.4.24/fs/ext3/ialloc.c 2004-05-19 13:58:43.000000000 +0400 -@@ -330,7 +330,8 @@ - * group to find a free inode. - */ - struct inode * ext3_new_inode (handle_t *handle, -- const struct inode * dir, int mode) -+ const struct inode * dir, int mode, -+ unsigned long goal) - { - struct super_block * sb; - struct buffer_head * bh; -@@ -355,7 +356,41 @@ - init_rwsem(&inode->u.ext3_i.truncate_sem); - - lock_super (sb); -- es = sb->u.ext3_sb.s_es; -+ es = EXT3_SB(sb)->s_es; -+ -+ if (goal) { -+ i = (goal - 1) / EXT3_INODES_PER_GROUP(sb); -+ j = (goal - 1) % EXT3_INODES_PER_GROUP(sb); -+ gdp = ext3_get_group_desc(sb, i, &bh2); -+ -+ bitmap_nr = load_inode_bitmap (sb, i); -+ if (bitmap_nr < 0) { -+ err = bitmap_nr; -+ goto fail; -+ } -+ -+ bh = EXT3_SB(sb)->s_inode_bitmap[bitmap_nr]; -+ -+ BUFFER_TRACE(bh, "get_write_access"); -+ err = ext3_journal_get_write_access(handle, bh); -+ if (err) goto fail; -+ -+ if (ext3_set_bit(j, bh->b_data)) { -+ printk(KERN_ERR "goal inode %lu unavailable\n", goal); -+ /* Oh well, we tried. */ -+ goto repeat; -+ } -+ -+ BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata"); -+ err = ext3_journal_dirty_metadata(handle, bh); -+ if (err) goto fail; -+ -+ /* We've shortcircuited the allocation system successfully, -+ * now finish filling in the inode. -+ */ -+ goto have_bit_and_group; -+ } -+ - repeat: - gdp = NULL; - i = 0; -@@ -470,6 +505,7 @@ - } - goto repeat; - } -+ have_bit_and_group: - j += i * EXT3_INODES_PER_GROUP(sb) + 1; - if (j < EXT3_FIRST_INO(sb) || j > le32_to_cpu(es->s_inodes_count)) { - ext3_error (sb, "ext3_new_inode", -Index: linux-2.4.24/fs/ext3/inode.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/inode.c 2004-05-19 13:58:43.000000000 +0400 -+++ linux-2.4.24/fs/ext3/inode.c 2004-05-19 13:58:43.000000000 +0400 -@@ -2605,7 +2605,7 @@ - if (IS_ERR(handle)) - goto out_truncate; - -- new_inode = ext3_new_inode(handle, old_inode, old_inode->i_mode); -+ new_inode = ext3_new_inode(handle, old_inode, old_inode->i_mode, 0); - if (IS_ERR(new_inode)) { - ext3_debug("truncate inode %lu directly (no new inodes)\n", - old_inode->i_ino); -Index: linux-2.4.24/fs/ext3/ioctl.c -=================================================================== ---- linux-2.4.24.orig/fs/ext3/ioctl.c 2004-01-10 17:04:42.000000000 +0300 -+++ linux-2.4.24/fs/ext3/ioctl.c 2004-05-19 13:58:43.000000000 +0400 -@@ -23,6 +23,31 @@ - ext3_debug ("cmd = %u, arg = %lu\n", cmd, arg); - - switch (cmd) { -+ case EXT3_IOC_CREATE_INUM: { -+ char name[32]; -+ struct dentry *dchild, *dparent; -+ int rc = 0; -+ -+ dparent = list_entry(inode->i_dentry.next, struct dentry, -+ d_alias); -+ snprintf(name, sizeof name, "%lu", arg); -+ dchild = lookup_one_len(name, dparent, strlen(name)); -+ if (dchild->d_inode) { -+ printk(KERN_ERR "%*s/%lu already exists (ino %lu)\n", -+ dparent->d_name.len, dparent->d_name.name, arg, -+ dchild->d_inode->i_ino); -+ rc = -EEXIST; -+ } else { -+ dchild->d_fsdata = (void *)arg; -+ rc = vfs_create(inode, dchild, 0644); -+ if (rc) -+ printk(KERN_ERR "vfs_create: %d\n", rc); -+ else if (dchild->d_inode->i_ino != arg) -+ rc = -EEXIST; -+ } -+ dput(dchild); -+ return rc; -+ } - case EXT3_IOC_GETFLAGS: - flags = inode->u.ext3_i.i_flags & EXT3_FL_USER_VISIBLE; - return put_user(flags, (int *) arg); -Index: linux-2.4.24/include/linux/ext3_fs.h -=================================================================== ---- linux-2.4.24.orig/include/linux/ext3_fs.h 2004-05-19 13:58:43.000000000 +0400 -+++ linux-2.4.24/include/linux/ext3_fs.h 2004-05-19 13:58:43.000000000 +0400 -@@ -202,6 +202,7 @@ - #define EXT3_IOC_SETFLAGS _IOW('f', 2, long) - #define EXT3_IOC_GETVERSION _IOR('f', 3, long) - #define EXT3_IOC_SETVERSION _IOW('f', 4, long) -+/* EXT3_IOC_CREATE_INUM at bottom of file (visible to kernel and user). */ - #define EXT3_IOC_GETVERSION_OLD _IOR('v', 1, long) - #define EXT3_IOC_SETVERSION_OLD _IOW('v', 2, long) - #ifdef CONFIG_JBD_DEBUG -@@ -674,7 +675,8 @@ - dx_hash_info *hinfo); - - /* ialloc.c */ --extern struct inode * ext3_new_inode (handle_t *, const struct inode *, int); -+extern struct inode * ext3_new_inode (handle_t *, const struct inode *, int, -+ unsigned long); - extern void ext3_free_inode (handle_t *, struct inode *); - extern struct inode * ext3_orphan_get (struct super_block *, unsigned long); - extern unsigned long ext3_count_free_inodes (struct super_block *); -@@ -766,4 +768,5 @@ - - #endif /* __KERNEL__ */ - -+#define EXT3_IOC_CREATE_INUM _IOW('f', 5, long) - #endif /* _LINUX_EXT3_FS_H */ -Index: linux-2.4.24/include/linux/dcache.h -=================================================================== ---- linux-2.4.24.orig/include/linux/dcache.h 2004-05-19 13:58:42.000000000 +0400 -+++ linux-2.4.24/include/linux/dcache.h 2004-05-21 18:20:34.000000000 +0400 -@@ -63,6 +63,12 @@ - - #define IS_ROOT(x) ((x) == (x)->d_parent) - -+struct dentry_params { -+ unsigned long p_inum; -+ unsigned long p_generation; -+ void *p_ptr; -+}; -+ - /* - * "quick string" -- eases parameter passing, but more importantly - * saves "metadata" about the string (ie length and the hash). diff --git a/lustre/kernel_patches/patches/gfp_memalloc-2.4.24.patch b/lustre/kernel_patches/patches/gfp_memalloc-2.4.24.patch deleted file mode 100644 index 5780b1b..0000000 --- a/lustre/kernel_patches/patches/gfp_memalloc-2.4.24.patch +++ /dev/null @@ -1,59 +0,0 @@ -Index: linux-2.4.21-suse2/include/linux/mm.h -=================================================================== ---- linux-2.4.21-suse2.orig/include/linux/mm.h 2004-01-10 15:51:22.000000000 +0300 -+++ linux-2.4.21-suse2/include/linux/mm.h 2004-01-10 16:02:42.000000000 +0300 -@@ -661,6 +661,7 @@ - #define __GFP_IO 0x40 /* Can start low memory physical IO? */ - #define __GFP_HIGHIO 0x80 /* Can start high mem physical IO? */ - #define __GFP_FS 0x100 /* Can call down to low-level FS? */ -+#define __GFP_MEMALLOC 0x200 /* like PF_MEMALLOC: see __alloc_pages */ - - #define GFP_NOHIGHIO (__GFP_HIGH | __GFP_WAIT | __GFP_IO) - #define GFP_NOIO (__GFP_HIGH | __GFP_WAIT) -@@ -671,6 +672,7 @@ - #define GFP_KERNEL (__GFP_HIGH | __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS) - #define GFP_NFS (__GFP_HIGH | __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS) - #define GFP_KSWAPD ( __GFP_WAIT | __GFP_IO | __GFP_HIGHIO | __GFP_FS) -+#define GFP_MEMALLOC __GFP_MEMALLOC - - /* Flag - indicates that the buffer will be suitable for DMA. Ignored on some - platforms, used as appropriate on others */ -Index: linux-2.4.21-suse2/include/linux/slab.h -=================================================================== ---- linux-2.4.21-suse2.orig/include/linux/slab.h 2004-01-10 12:48:36.000000000 +0300 -+++ linux-2.4.21-suse2/include/linux/slab.h 2004-01-10 16:02:42.000000000 +0300 -@@ -23,6 +23,7 @@ - #define SLAB_KERNEL GFP_KERNEL - #define SLAB_NFS GFP_NFS - #define SLAB_DMA GFP_DMA -+#define SLAB_MEMALLOC GFP_MEMALLOC - - #define SLAB_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_HIGHIO|__GFP_FS) - #define SLAB_NO_GROW 0x00001000UL /* don't grow a cache */ -Index: linux-2.4.21-suse2/mm/page_alloc.c -=================================================================== ---- linux-2.4.21-suse2.orig/mm/page_alloc.c 2004-01-10 14:56:13.000000000 +0300 -+++ linux-2.4.21-suse2/mm/page_alloc.c 2004-01-10 16:03:20.000000000 +0300 -@@ -448,7 +448,8 @@ - - /* here we're in the low on memory slow path */ - -- if (current->flags & PF_MEMALLOC && !in_interrupt()) { -+ if (((current->flags & PF_MEMALLOC) || (gfp_mask & __GFP_MEMALLOC)) -+ && !in_interrupt()) { - zone = zonelist->zones; - for (;;) { - zone_t *z = *(zone++); -Index: linux-2.4.21-suse2/mm/slab.c -=================================================================== ---- linux-2.4.21-suse2.orig/mm/slab.c 2003-10-28 21:33:57.000000000 +0300 -+++ linux-2.4.21-suse2/mm/slab.c 2004-01-10 16:02:42.000000000 +0300 -@@ -1115,7 +1115,7 @@ - /* Be lazy and only check for valid flags here, - * keeping it out of the critical path in kmem_cache_alloc(). - */ -- if (flags & ~(SLAB_DMA|SLAB_LEVEL_MASK|SLAB_NO_GROW)) -+ if (flags & ~(SLAB_DMA|SLAB_LEVEL_MASK|SLAB_NO_GROW|SLAB_MEMALLOC)) - BUG(); - if (flags & SLAB_NO_GROW) - return 0; diff --git a/lustre/kernel_patches/patches/inode-max-readahead-2.4.24.patch b/lustre/kernel_patches/patches/inode-max-readahead-2.4.24.patch deleted file mode 100644 index 9203859..0000000 --- a/lustre/kernel_patches/patches/inode-max-readahead-2.4.24.patch +++ /dev/null @@ -1,22 +0,0 @@ ---- linux-2.4.24-l32/mm/filemap.c.inode_ramax 2004-03-14 13:16:21.000000000 -0800 -+++ linux-2.4.24-l32/mm/filemap.c 2004-03-16 10:57:14.000000000 -0800 -@@ -1226,6 +1226,8 @@ - - static inline int get_max_readahead(struct inode * inode) - { -+ if (inode->i_mapping->a_ops->max_readahead) -+ return inode->i_mapping->a_ops->max_readahead(inode); - if (!inode->i_dev || !max_readahead[MAJOR(inode->i_dev)]) - return vm_max_readahead; - return max_readahead[MAJOR(inode->i_dev)][MINOR(inode->i_dev)]; ---- linux-2.4.24-l32/include/linux/fs.h.inode_ramax 2004-03-14 13:15:49.000000000 -0800 -+++ linux-2.4.24-l32/include/linux/fs.h 2004-03-15 11:56:56.000000000 -0800 -@@ -410,6 +410,8 @@ - #define KERNEL_HAS_DIRECT_FILEIO /* Unfortunate kludge due to lack of foresight */ - int (*direct_fileIO)(int, struct file *, struct kiobuf *, unsigned long, int); - void (*removepage)(struct page *); /* called when page gets removed from the inode */ -+#define KERNEL_HAS_AS_MAX_READAHEAD -+ int (*max_readahead)(struct inode *); - }; - - struct address_space { diff --git a/lustre/kernel_patches/patches/invalidate_show-2.4.24.patch b/lustre/kernel_patches/patches/invalidate_show-2.4.24.patch deleted file mode 100644 index 9273c5c..0000000 --- a/lustre/kernel_patches/patches/invalidate_show-2.4.24.patch +++ /dev/null @@ -1,115 +0,0 @@ - - - - fs/inode.c | 21 ++++++++++++++------- - fs/smbfs/inode.c | 2 +- - fs/super.c | 4 ++-- - include/linux/fs.h | 2 +- - 4 files changed, 18 insertions(+), 11 deletions(-) - ---- linux-rh-2.4.20-8/fs/inode.c~invalidate_show 2003-04-11 14:04:56.000000000 +0800 -+++ linux-rh-2.4.20-8-root/fs/inode.c 2003-04-16 20:59:35.000000000 +0800 -@@ -604,7 +604,8 @@ static void dispose_list(struct list_hea - /* - * Invalidate all inodes for a device. - */ --static int invalidate_list(struct list_head *head, struct super_block * sb, struct list_head * dispose) -+static int invalidate_list(struct list_head *head, struct super_block * sb, -+ struct list_head * dispose, int show) - { - struct list_head *next; - int busy = 0, count = 0; -@@ -629,6 +630,11 @@ static int invalidate_list(struct list_h - count++; - continue; - } -+ if (show) -+ printk(KERN_ERR -+ "inode busy: dev %s:%lu (%p) mode %o count %u\n", -+ kdevname(sb->s_dev), inode->i_ino, inode, -+ inode->i_mode, atomic_read(&inode->i_count)); - busy = 1; - } - /* only unused inodes may be cached with i_count zero */ -@@ -647,22 +653,23 @@ static int invalidate_list(struct list_h - /** - * invalidate_inodes - discard the inodes on a device - * @sb: superblock -+ * @show: whether we should display any busy inodes found - * - * Discard all of the inodes for a given superblock. If the discard - * fails because there are busy inodes then a non zero value is returned. - * If the discard is successful all the inodes have been discarded. - */ - --int invalidate_inodes(struct super_block * sb) -+int invalidate_inodes(struct super_block * sb, int show) - { - int busy; - LIST_HEAD(throw_away); - - spin_lock(&inode_lock); -- busy = invalidate_list(&inode_in_use, sb, &throw_away); -- busy |= invalidate_list(&inode_unused, sb, &throw_away); -- busy |= invalidate_list(&sb->s_dirty, sb, &throw_away); -- busy |= invalidate_list(&sb->s_locked_inodes, sb, &throw_away); -+ busy = invalidate_list(&inode_in_use, sb, &throw_away, show); -+ busy |= invalidate_list(&inode_unused, sb, &throw_away, show); -+ busy |= invalidate_list(&sb->s_dirty, sb, &throw_away, show); -+ busy |= invalidate_list(&sb->s_locked_inodes, sb, &throw_away, show); - spin_unlock(&inode_lock); - - dispose_list(&throw_away); -@@ -688,7 +695,7 @@ int invalidate_device(kdev_t dev, int do - * hold). - */ - shrink_dcache_sb(sb); -- res = invalidate_inodes(sb); -+ res = invalidate_inodes(sb, 0); - drop_super(sb); - } - invalidate_buffers(dev); ---- linux-rh-2.4.20-8/fs/super.c~invalidate_show 2003-04-11 14:04:57.000000000 +0800 -+++ linux-rh-2.4.20-8-root/fs/super.c 2003-04-16 20:59:35.000000000 +0800 -@@ -943,7 +943,7 @@ void kill_super(struct super_block *sb) - lock_super(sb); - lock_kernel(); - sb->s_flags &= ~MS_ACTIVE; -- invalidate_inodes(sb); /* bad name - it should be evict_inodes() */ -+ invalidate_inodes(sb, 0); /* bad name - it should be evict_inodes() */ - if (sop) { - if (sop->write_super && sb->s_dirt) - sop->write_super(sb); -@@ -952,7 +952,7 @@ void kill_super(struct super_block *sb) - } - - /* Forget any remaining inodes */ -- if (invalidate_inodes(sb)) { -+ if (invalidate_inodes(sb, 1)) { - printk(KERN_ERR "VFS: Busy inodes after unmount. " - "Self-destruct in 5 seconds. Have a nice day...\n"); - } ---- linux-rh-2.4.20-8/include/linux/fs.h~invalidate_show 2003-04-16 20:55:35.000000000 +0800 -+++ linux-rh-2.4.20-8-root/include/linux/fs.h 2003-04-16 20:59:35.000000000 +0800 -@@ -1283,7 +1283,7 @@ static inline void mark_buffer_dirty_ino - extern void set_buffer_flushtime(struct buffer_head *); - extern void balance_dirty(void); - extern int check_disk_change(kdev_t); --extern int invalidate_inodes(struct super_block *); -+extern int invalidate_inodes(struct super_block *, int); - extern int invalidate_device(kdev_t, int); - extern void invalidate_inode_pages(struct inode *); - extern void invalidate_inode_pages2(struct address_space *); ---- linux-rh-2.4.20-8/fs/smbfs/inode.c~invalidate_show 2003-04-16 20:59:48.000000000 +0800 -+++ linux-rh-2.4.20-8-root/fs/smbfs/inode.c 2003-04-16 21:00:43.000000000 +0800 -@@ -167,7 +167,7 @@ smb_invalidate_inodes(struct smb_sb_info - { - VERBOSE("\n"); - shrink_dcache_sb(SB_of(server)); -- invalidate_inodes(SB_of(server)); -+ invalidate_inodes(SB_of(server), 0); - } - - /* - -_ diff --git a/lustre/kernel_patches/patches/iod-stock-24-exports.patch b/lustre/kernel_patches/patches/iod-stock-24-exports.patch deleted file mode 100644 index 2070377..0000000 --- a/lustre/kernel_patches/patches/iod-stock-24-exports.patch +++ /dev/null @@ -1,48 +0,0 @@ - fs/Makefile | 2 +- - fs/inode.c | 4 +++- - mm/page_alloc.c | 1 + - 3 files changed, 5 insertions(+), 2 deletions(-) - ---- linux-2.4.20/fs/inode.c~iod-stock-24-exports Wed Apr 2 23:21:20 2003 -+++ linux-2.4.20-braam/fs/inode.c Wed Apr 2 23:21:20 2003 -@@ -5,6 +5,7 @@ - */ - - #include -+#include - #include - #include - #include -@@ -66,7 +67,8 @@ static LIST_HEAD(anon_hash_chain); /* fo - * NOTE! You also have to own the lock if you change - * the i_state of an inode while it is in use.. - */ --static spinlock_t inode_lock = SPIN_LOCK_UNLOCKED; -+spinlock_t inode_lock = SPIN_LOCK_UNLOCKED; -+EXPORT_SYMBOL(inode_lock); - - /* - * Statistics gathering.. ---- linux-2.4.20/fs/Makefile~iod-stock-24-exports Wed Apr 2 23:21:20 2003 -+++ linux-2.4.20-braam/fs/Makefile Wed Apr 2 23:21:53 2003 -@@ -7,7 +7,7 @@ - - O_TARGET := fs.o - --export-objs := filesystems.o open.o dcache.o buffer.o -+export-objs := filesystems.o open.o dcache.o buffer.o inode.o - mod-subdirs := nls - - obj-y := open.o read_write.o devices.o file_table.o buffer.o \ ---- linux-2.4.20/mm/page_alloc.c~iod-stock-24-exports Wed Apr 2 23:21:20 2003 -+++ linux-2.4.20-braam/mm/page_alloc.c Wed Apr 2 23:21:20 2003 -@@ -28,6 +28,7 @@ int nr_inactive_pages; - LIST_HEAD(inactive_list); - LIST_HEAD(active_list); - pg_data_t *pgdat_list; -+EXPORT_SYMBOL(pgdat_list); - - /* - * - -_ diff --git a/lustre/kernel_patches/patches/iod-stock-exports-2.4.24.patch b/lustre/kernel_patches/patches/iod-stock-exports-2.4.24.patch deleted file mode 100644 index 47a6ff9..0000000 --- a/lustre/kernel_patches/patches/iod-stock-exports-2.4.24.patch +++ /dev/null @@ -1,52 +0,0 @@ - fs/Makefile | 2 +- - fs/inode.c | 4 +++- - mm/page_alloc.c | 1 + - 3 files changed, 5 insertions(+), 2 deletions(-) - -Index: linux-2.4.22-vanilla/fs/inode.c -=================================================================== ---- linux-2.4.22-vanilla.orig/fs/inode.c 2003-11-03 23:22:24.000000000 +0300 -+++ linux-2.4.22-vanilla/fs/inode.c 2003-11-03 23:25:00.000000000 +0300 -@@ -5,6 +5,7 @@ - */ - - #include -+#include - #include - #include - #include -@@ -66,7 +67,8 @@ - * NOTE! You also have to own the lock if you change - * the i_state of an inode while it is in use.. - */ --static spinlock_t inode_lock = SPIN_LOCK_UNLOCKED; -+spinlock_t inode_lock = SPIN_LOCK_UNLOCKED; -+EXPORT_SYMBOL(inode_lock); - - /* - * Statistics gathering.. -Index: linux-2.4.22-vanilla/fs/Makefile -=================================================================== ---- linux-2.4.22-vanilla.orig/fs/Makefile 2003-11-03 23:22:11.000000000 +0300 -+++ linux-2.4.22-vanilla/fs/Makefile 2003-11-03 23:25:24.000000000 +0300 -@@ -7,7 +7,7 @@ - - O_TARGET := fs.o - --export-objs := filesystems.o open.o dcache.o buffer.o dquot.o -+export-objs := filesystems.o open.o dcache.o buffer.o dquot.o inode.o - mod-subdirs := nls - - obj-y := open.o read_write.o devices.o file_table.o buffer.o \ -Index: linux-2.4.22-vanilla/mm/page_alloc.c -=================================================================== ---- linux-2.4.22-vanilla.orig/mm/page_alloc.c 2003-11-03 23:21:29.000000000 +0300 -+++ linux-2.4.22-vanilla/mm/page_alloc.c 2003-11-03 23:25:00.000000000 +0300 -@@ -28,6 +28,7 @@ - LIST_HEAD(inactive_list); - LIST_HEAD(active_list); - pg_data_t *pgdat_list; -+EXPORT_SYMBOL(pgdat_list); - - /* - * diff --git a/lustre/kernel_patches/patches/iopen-2.4.24.patch b/lustre/kernel_patches/patches/iopen-2.4.24.patch deleted file mode 100644 index dc860ee..0000000 --- a/lustre/kernel_patches/patches/iopen-2.4.24.patch +++ /dev/null @@ -1,492 +0,0 @@ - Documentation/filesystems/ext2.txt | 16 ++ - fs/ext3/Makefile | 2 - fs/ext3/inode.c | 4 - fs/ext3/iopen.c | 259 +++++++++++++++++++++++++++++++++++++ - fs/ext3/iopen.h | 13 + - fs/ext3/namei.c | 13 + - fs/ext3/super.c | 11 + - include/linux/ext3_fs.h | 2 - 8 files changed, 318 insertions(+), 2 deletions(-) - -Index: lum/Documentation/filesystems/ext2.txt -=================================================================== ---- lum.orig/Documentation/filesystems/ext2.txt 2001-07-11 16:44:45.000000000 -0600 -+++ lum/Documentation/filesystems/ext2.txt 2004-03-09 16:46:38.000000000 -0700 -@@ -35,6 +35,22 @@ - - sb=n Use alternate superblock at this location. - -+iopen Makes an invisible pseudo-directory called -+ __iopen__ available in the root directory -+ of the filesystem. Allows open-by-inode- -+ number. i.e., inode 3145 can be accessed -+ via /mntpt/__iopen__/3145 -+ -+iopen_nopriv This option makes the iopen directory be -+ world-readable. This may be safer since it -+ allows daemons to run as an unprivileged user, -+ however it significantly changes the security -+ model of a Unix filesystem, since previously -+ all files under a mode 700 directory were not -+ generally avilable even if the -+ permissions on the file itself is -+ world-readable. -+ - grpquota,noquota,quota,usrquota Quota options are silently ignored by ext2. - - -Index: lum/fs/ext3/Makefile -=================================================================== ---- lum.orig/fs/ext3/Makefile 2004-01-30 14:54:50.000000000 -0700 -+++ lum/fs/ext3/Makefile 2004-03-09 16:46:39.000000000 -0700 -@@ -11,7 +11,7 @@ - - export-objs := ext3-exports.o - --obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ -+obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \ - ioctl.o namei.o super.o symlink.o hash.o ext3-exports.o - obj-m := $(O_TARGET) - -Index: lum/fs/ext3/inode.c -=================================================================== ---- lum.orig/fs/ext3/inode.c 2004-01-30 14:54:55.000000000 -0700 -+++ lum/fs/ext3/inode.c 2004-03-09 16:46:41.000000000 -0700 -@@ -31,6 +31,7 @@ - #include - #include - #include -+#include "iopen.h" - - /* - * SEARCH_FROM_ZERO forces each block allocation to search from the start -@@ -2153,6 +2154,9 @@ - struct buffer_head *bh; - int block; - -+ if (ext3_iopen_get_inode(inode)) -+ return; -+ - if(ext3_get_inode_loc(inode, &iloc)) - goto bad_inode; - bh = iloc.bh; -Index: lum/fs/ext3/iopen.c -=================================================================== ---- lum.orig/fs/ext3/iopen.c 2004-03-09 16:46:37.000000000 -0700 -+++ lum/fs/ext3/iopen.c 2004-03-09 16:48:03.000000000 -0700 -@@ -0,0 +1,282 @@ -+/* -+ * linux/fs/ext3/iopen.c -+ * -+ * Special support for open by inode number -+ * -+ * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu). -+ * -+ * This file may be redistributed under the terms of the GNU General -+ * Public License. -+ * -+ * -+ * Invariants: -+ * - there is only ever a single DCACHE_NFSD_DISCONNECTED dentry alias -+ * for an inode at one time. -+ * - there are never both connected and DCACHE_NFSD_DISCONNECTED dentry -+ * aliases on an inode at the same time. -+ * -+ * If we have any connected dentry aliases for an inode, use one of those -+ * in iopen_lookup(). Otherwise, we instantiate a single NFSD_DISCONNECTED -+ * dentry for this inode, which thereafter will be found by the dcache -+ * when looking up this inode number in __iopen__, so we don't return here -+ * until it is gone. -+ * -+ * If we get an inode via a regular name lookup, then we "rename" the -+ * NFSD_DISCONNECTED dentry to the proper name and parent. This ensures -+ * existing users of the disconnected dentry will continue to use the same -+ * dentry as the connected users, and there will never be both kinds of -+ * dentry aliases at one time. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "iopen.h" -+ -+#ifndef assert -+#define assert(test) J_ASSERT(test) -+#endif -+ -+#define IOPEN_NAME_LEN 32 -+ -+/* -+ * This implements looking up an inode by number. -+ */ -+static struct dentry *iopen_lookup(struct inode *dir, struct dentry *dentry) -+{ -+ struct inode *inode; -+ unsigned long ino; -+ struct list_head *lp; -+ struct dentry *alternate; -+ char buf[IOPEN_NAME_LEN]; -+ -+ if (dentry->d_name.len >= IOPEN_NAME_LEN) -+ return ERR_PTR(-ENAMETOOLONG); -+ -+ memcpy(buf, dentry->d_name.name, dentry->d_name.len); -+ buf[dentry->d_name.len] = 0; -+ -+ if (strcmp(buf, ".") == 0) -+ ino = dir->i_ino; -+ else if (strcmp(buf, "..") == 0) -+ ino = EXT3_ROOT_INO; -+ else -+ ino = simple_strtoul(buf, 0, 0); -+ -+ if ((ino != EXT3_ROOT_INO && -+ //ino != EXT3_ACL_IDX_INO && -+ //ino != EXT3_ACL_DATA_INO && -+ ino < EXT3_FIRST_INO(dir->i_sb)) || -+ ino > le32_to_cpu(dir->i_sb->u.ext3_sb.s_es->s_inodes_count)) -+ return ERR_PTR(-ENOENT); -+ -+ inode = iget(dir->i_sb, ino); -+ if (!inode) -+ return ERR_PTR(-EACCES); -+ if (is_bad_inode(inode)) { -+ iput(inode); -+ return ERR_PTR(-ENOENT); -+ } -+ -+ assert(list_empty(&dentry->d_alias)); /* d_instantiate */ -+ assert(list_empty(&dentry->d_hash)); /* d_rehash */ -+ -+ /* preferrably return a connected dentry */ -+ spin_lock(&dcache_lock); -+ list_for_each(lp, &inode->i_dentry) { -+ alternate = list_entry(lp, struct dentry, d_alias); -+ assert(!(alternate->d_flags & DCACHE_NFSD_DISCONNECTED)); -+ } -+ -+ if (!list_empty(&inode->i_dentry)) { -+ alternate = list_entry(inode->i_dentry.next, -+ struct dentry, d_alias); -+ dget_locked(alternate); -+ alternate->d_vfs_flags |= DCACHE_REFERENCED; -+ iput(inode); -+ spin_unlock(&dcache_lock); -+ return alternate; -+ } -+ dentry->d_flags |= DCACHE_NFSD_DISCONNECTED; -+ -+ /* d_add(), but don't drop dcache_lock before adding dentry to inode */ -+ list_add(&dentry->d_alias, &inode->i_dentry); /* d_instantiate */ -+ dentry->d_inode = inode; -+ -+ __d_rehash(dentry, 0); /* d_rehash */ -+ spin_unlock(&dcache_lock); -+ -+ return NULL; -+} -+ -+#define do_switch(x,y) do { \ -+ __typeof__ (x) __tmp = x; \ -+ x = y; y = __tmp; } while (0) -+ -+static inline void switch_names(struct dentry *dentry, struct dentry *target) -+{ -+ const unsigned char *old_name, *new_name; -+ -+ memcpy(dentry->d_iname, target->d_iname, DNAME_INLINE_LEN); -+ old_name = target->d_name.name; -+ new_name = dentry->d_name.name; -+ if (old_name == target->d_iname) -+ old_name = dentry->d_iname; -+ if (new_name == dentry->d_iname) -+ new_name = target->d_iname; -+ target->d_name.name = new_name; -+ dentry->d_name.name = old_name; -+} -+ -+/* This function is spliced into ext3_lookup and does the move of a -+ * disconnected dentry (if it exists) to a connected dentry. -+ */ -+struct dentry *iopen_connect_dentry(struct dentry *dentry, struct inode *inode, -+ int rehash) -+{ -+ struct dentry *tmp, *goal = NULL; -+ struct list_head *lp; -+ -+ /* verify this dentry is really new */ -+ assert(dentry->d_inode == NULL); -+ assert(list_empty(&dentry->d_alias)); /* d_instantiate */ -+ if (rehash) -+ assert(list_empty(&dentry->d_hash)); /* d_rehash */ -+ assert(list_empty(&dentry->d_subdirs)); -+ -+ spin_lock(&dcache_lock); -+ if (!inode) -+ goto do_rehash; -+ -+ /* preferrably return a connected dentry */ -+ list_for_each(lp, &inode->i_dentry) { -+ tmp = list_entry(lp, struct dentry, d_alias); -+ if (tmp->d_flags & DCACHE_NFSD_DISCONNECTED) { -+ assert(tmp->d_alias.next == &inode->i_dentry); -+ assert(tmp->d_alias.prev == &inode->i_dentry); -+ goal = tmp; -+ dget_locked(goal); -+ break; -+ } -+ } -+ -+ if (!goal) -+ goto do_instantiate; -+ -+ /* Move the goal to the de hash queue - like d_move() */ -+ goal->d_flags &= ~DCACHE_NFSD_DISCONNECTED; -+ list_del_init(&goal->d_hash); -+ -+ list_del(&goal->d_child); -+ list_del(&dentry->d_child); -+ -+ /* Switch the parents and the names.. */ -+ switch_names(goal, dentry); -+ do_switch(goal->d_parent, dentry->d_parent); -+ do_switch(goal->d_name.len, dentry->d_name.len); -+ do_switch(goal->d_name.hash, dentry->d_name.hash); -+ -+ /* And add them back to the (new) parent lists */ -+ list_add(&goal->d_child, &goal->d_parent->d_subdirs); -+ list_add(&dentry->d_child, &dentry->d_parent->d_subdirs); -+ __d_rehash(goal, 0); -+ spin_unlock(&dcache_lock); -+ iput(inode); -+ -+ return goal; -+ -+ /* d_add(), but don't drop dcache_lock before adding dentry to inode */ -+do_instantiate: -+ list_add(&dentry->d_alias, &inode->i_dentry); /* d_instantiate */ -+ dentry->d_inode = inode; -+do_rehash: -+ if (rehash) -+ __d_rehash(dentry, 0); /* d_rehash */ -+ spin_unlock(&dcache_lock); -+ -+ return NULL; -+} -+ -+/* -+ * These are the special structures for the iopen pseudo directory. -+ */ -+ -+static struct inode_operations iopen_inode_operations = { -+ lookup: iopen_lookup, /* BKL held */ -+}; -+ -+static struct file_operations iopen_file_operations = { -+ read: generic_read_dir, -+}; -+ -+static int match_dentry(struct dentry *dentry, const char *name) -+{ -+ int len; -+ -+ len = strlen(name); -+ if (dentry->d_name.len != len) -+ return 0; -+ if (strncmp(dentry->d_name.name, name, len)) -+ return 0; -+ return 1; -+} -+ -+/* -+ * This function is spliced into ext3_lookup and returns 1 the file -+ * name is __iopen__ and dentry has been filled in appropriately. -+ */ -+int ext3_check_for_iopen(struct inode *dir, struct dentry *dentry) -+{ -+ struct inode *inode; -+ -+ if (dir->i_ino != EXT3_ROOT_INO || -+ !test_opt(dir->i_sb, IOPEN) || -+ !match_dentry(dentry, "__iopen__")) -+ return 0; -+ -+ inode = iget(dir->i_sb, EXT3_BAD_INO); -+ -+ if (!inode) -+ return 0; -+ d_add(dentry, inode); -+ return 1; -+} -+ -+/* -+ * This function is spliced into read_inode; it returns 1 if inode -+ * number is the one for /__iopen__, in which case the inode is filled -+ * in appropriately. Otherwise, this fuction returns 0. -+ */ -+int ext3_iopen_get_inode(struct inode *inode) -+{ -+ if (inode->i_ino != EXT3_BAD_INO) -+ return 0; -+ -+ inode->i_mode = S_IFDIR | S_IRUSR | S_IXUSR; -+ if (test_opt(inode->i_sb, IOPEN_NOPRIV)) -+ inode->i_mode |= 0777; -+ inode->i_uid = 0; -+ inode->i_gid = 0; -+ inode->i_nlink = 1; -+ inode->i_size = 4096; -+ inode->i_atime = CURRENT_TIME; -+ inode->i_ctime = CURRENT_TIME; -+ inode->i_mtime = CURRENT_TIME; -+ inode->u.ext3_i.i_dtime = 0; -+ inode->i_blksize = PAGE_SIZE; /* This is the optimal IO size -+ * (for stat), not the fs block -+ * size */ -+ inode->i_blocks = 0; -+ inode->i_version = 1; -+ inode->i_generation = 0; -+ -+ inode->i_op = &iopen_inode_operations; -+ inode->i_fop = &iopen_file_operations; -+ inode->i_mapping->a_ops = 0; -+ -+ return 1; -+} -Index: lum/fs/ext3/iopen.h -=================================================================== ---- lum.orig/fs/ext3/iopen.h 2004-03-09 16:46:37.000000000 -0700 -+++ lum/fs/ext3/iopen.h 2004-03-09 16:48:03.000000000 -0700 -@@ -0,0 +1,15 @@ -+/* -+ * iopen.h -+ * -+ * Special support for opening files by inode number. -+ * -+ * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu). -+ * -+ * This file may be redistributed under the terms of the GNU General -+ * Public License. -+ */ -+ -+extern int ext3_check_for_iopen(struct inode *dir, struct dentry *dentry); -+extern int ext3_iopen_get_inode(struct inode *inode); -+extern struct dentry *iopen_connect_dentry(struct dentry *dentry, -+ struct inode *inode, int rehash); -Index: lum/fs/ext3/namei.c -=================================================================== ---- lum.orig/fs/ext3/namei.c 2004-01-30 14:54:53.000000000 -0700 -+++ lum/fs/ext3/namei.c 2004-03-09 16:49:25.000000000 -0700 -@@ -35,7 +35,7 @@ - #include - #include - #include -- -+#include "iopen.h" - - /* - * define how far ahead to read directories while searching them. -@@ -931,6 +931,9 @@ - if (dentry->d_name.len > EXT3_NAME_LEN) - return ERR_PTR(-ENAMETOOLONG); - -+ if (ext3_check_for_iopen(dir, dentry)) -+ return NULL; -+ - bh = ext3_find_entry(dentry, &de); - inode = NULL; - if (bh) { -@@ -942,8 +945,8 @@ - return ERR_PTR(-EACCES); - } - } -- d_add(dentry, inode); -- return NULL; -+ -+ return iopen_connect_dentry(dentry, inode, 1); - } - - #define S_SHIFT 12 -@@ -1932,10 +1935,6 @@ - inode->i_nlink); - inode->i_version = ++event; - inode->i_nlink = 0; -- /* There's no need to set i_disksize: the fact that i_nlink is -- * zero will ensure that the right thing happens during any -- * recovery. */ -- inode->i_size = 0; - ext3_orphan_add(handle, inode); - dir->i_nlink--; - inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; -@@ -2086,6 +2085,23 @@ - return err; - } - -+/* Like ext3_add_nondir() except for call to iopen_connect_dentry */ -+static int ext3_add_link(handle_t *handle, struct dentry *dentry, -+ struct inode *inode) -+{ -+ int err = ext3_add_entry(handle, dentry, inode); -+ if (!err) { -+ err = ext3_mark_inode_dirty(handle, inode); -+ if (err == 0) { -+ dput(iopen_connect_dentry(dentry, inode, 0)); -+ return 0; -+ } -+ } -+ ext3_dec_count(handle, inode); -+ iput(inode); -+ return err; -+} -+ - static int ext3_link (struct dentry * old_dentry, - struct inode * dir, struct dentry *dentry) - { -@@ -2113,7 +2129,8 @@ - ext3_inc_count(handle, inode); - atomic_inc(&inode->i_count); - -- err = ext3_add_nondir(handle, dentry, inode); -+ err = ext3_add_link(handle, dentry, inode); -+ ext3_orphan_del(handle, inode); - ext3_journal_stop(handle, dir); - return err; - } -Index: lum/fs/ext3/super.c -=================================================================== ---- lum.orig/fs/ext3/super.c 2004-01-30 14:54:53.000000000 -0700 -+++ lum/fs/ext3/super.c 2004-03-09 16:46:45.000000000 -0700 -@@ -742,6 +742,18 @@ - || !strcmp (this_char, "quota") - || !strcmp (this_char, "usrquota")) - /* Don't do anything ;-) */ ; -+ else if (!strcmp (this_char, "iopen")) { -+ set_opt (sbi->s_mount_opt, IOPEN); -+ clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV); -+ } -+ else if (!strcmp (this_char, "noiopen")) { -+ clear_opt (sbi->s_mount_opt, IOPEN); -+ clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV); -+ } -+ else if (!strcmp (this_char, "iopen_nopriv")) { -+ set_opt (sbi->s_mount_opt, IOPEN); -+ set_opt (sbi->s_mount_opt, IOPEN_NOPRIV); -+ } - else if (!strcmp (this_char, "journal")) { - /* @@@ FIXME */ - /* Eventually we will want to be able to create -Index: lum/include/linux/ext3_fs.h -=================================================================== ---- lum.orig/include/linux/ext3_fs.h 2004-01-30 14:54:53.000000000 -0700 -+++ lum/include/linux/ext3_fs.h 2004-03-09 16:46:46.000000000 -0700 -@@ -324,4 +324,6 @@ - #define EXT3_MOUNT_XATTR_USER 0x4000 /* Extended user attributes */ - #define EXT3_MOUNT_ASYNCDEL 0x20000 /* Delayed deletion */ -+#define EXT3_MOUNT_IOPEN 0x40000 /* Allow access via iopen */ -+#define EXT3_MOUNT_IOPEN_NOPRIV 0x80000 /* Make iopen world-readable */ - - /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ diff --git a/lustre/kernel_patches/patches/jbd-commit-tricks-2.4.24.patch b/lustre/kernel_patches/patches/jbd-commit-tricks-2.4.24.patch deleted file mode 100644 index 467c29f..0000000 --- a/lustre/kernel_patches/patches/jbd-commit-tricks-2.4.24.patch +++ /dev/null @@ -1,132 +0,0 @@ - ---- linux-2.4.18/fs/jbd/checkpoint.c~jbd-commit-tricks Mon Jul 28 13:52:05 2003 -+++ linux-2.4.18-alexey/fs/jbd/checkpoint.c Mon Jul 28 14:03:59 2003 -@@ -77,19 +77,23 @@ static int __try_to_free_cp_buf(struct j - * to wait for a checkpoint to free up some space in the log. - */ - --void log_wait_for_space(journal_t *journal, int nblocks) -+void log_wait_for_space(journal_t *journal) - { -+ int nblocks; -+ -+ nblocks = jbd_space_needed(journal); - while (log_space_left(journal) < nblocks) { - if (journal->j_flags & JFS_ABORT) - return; - unlock_journal(journal); - down(&journal->j_checkpoint_sem); - lock_journal(journal); -+ nblocks = jbd_space_needed(journal); - - /* Test again, another process may have checkpointed - * while we were waiting for the checkpoint lock */ - if (log_space_left(journal) < nblocks) { -- log_do_checkpoint(journal, nblocks); -+ log_do_checkpoint(journal); - } - up(&journal->j_checkpoint_sem); - } -@@ -260,8 +264,7 @@ static int __flush_buffer(journal_t *jou - * The journal should be locked before calling this function. - */ - --/* @@@ `nblocks' is unused. Should it be used? */ --int log_do_checkpoint (journal_t *journal, int nblocks) -+int log_do_checkpoint (journal_t *journal) - { - transaction_t *transaction, *last_transaction, *next_transaction; - int result; -@@ -315,6 +318,8 @@ repeat: - retry = __flush_buffer(journal, jh, bhs, &batch_count, - &drop_count); - } while (jh != last_jh && !retry); -+ if (journal->j_checkpoint_transactions != transaction) -+ goto done; - if (batch_count) { - __flush_batch(bhs, &batch_count); - goto repeat; -@@ -328,6 +333,8 @@ repeat: - */ - cleanup_ret = __cleanup_transaction(journal, transaction); - J_ASSERT(drop_count != 0 || cleanup_ret != 0); -+ if (journal->j_checkpoint_transactions != transaction) -+ goto done; - goto repeat; /* __cleanup may have dropped lock */ - } while (transaction != last_transaction); - ---- linux-2.4.18/fs/jbd/journal.c~jbd-commit-tricks Mon Jul 28 13:52:05 2003 -+++ linux-2.4.18-alexey/fs/jbd/journal.c Mon Jul 28 14:03:59 2003 -@@ -1115,7 +1115,7 @@ void journal_destroy (journal_t *journal - /* Force any old transactions to disk */ - lock_journal(journal); - while (journal->j_checkpoint_transactions != NULL) -- log_do_checkpoint(journal, 1); -+ log_do_checkpoint(journal); - - J_ASSERT(journal->j_running_transaction == NULL); - J_ASSERT(journal->j_committing_transaction == NULL); -@@ -1302,7 +1302,7 @@ int journal_flush (journal_t *journal) - /* ...and flush everything in the log out to disk. */ - lock_journal(journal); - while (!err && journal->j_checkpoint_transactions != NULL) -- err = log_do_checkpoint(journal, journal->j_maxlen); -+ err = log_do_checkpoint(journal); - cleanup_journal_tail(journal); - - /* Finally, mark the journal as really needing no recovery. ---- linux-2.4.18/fs/jbd/transaction.c~jbd-commit-tricks Mon Jul 28 13:52:05 2003 -+++ linux-2.4.18-alexey/fs/jbd/transaction.c Mon Jul 28 14:03:59 2003 -@@ -182,14 +182,9 @@ repeat_locked: - * Also, this test is inconsitent with the matching one in - * journal_extend(). - */ -- needed = journal->j_max_transaction_buffers; -- if (journal->j_committing_transaction) -- needed += journal->j_committing_transaction-> -- t_outstanding_credits; -- -- if (log_space_left(journal) < needed) { -+ if (log_space_left(journal) < jbd_space_needed(journal)) { - jbd_debug(2, "Handle %p waiting for checkpoint...\n", handle); -- log_wait_for_space(journal, needed); -+ log_wait_for_space(journal); - goto repeat_locked; - } - ---- linux-2.4.18/include/linux/jbd.h~jbd-commit-tricks Mon Jul 28 13:52:17 2003 -+++ linux-2.4.18-alexey/include/linux/jbd.h Mon Jul 28 14:03:59 2003 -@@ -740,9 +740,9 @@ extern void journal_brelse_array(stru - extern int log_space_left (journal_t *); /* Called with journal locked */ - extern tid_t log_start_commit (journal_t *, transaction_t *); - extern void log_wait_commit (journal_t *, tid_t); --extern int log_do_checkpoint (journal_t *, int); -+extern int log_do_checkpoint (journal_t *); - --extern void log_wait_for_space(journal_t *, int nblocks); -+extern void log_wait_for_space(journal_t *); - extern void __journal_drop_transaction(journal_t *, transaction_t *); - extern int cleanup_journal_tail(journal_t *); - -@@ -815,6 +815,19 @@ static inline int tid_geq(tid_t x, tid_t - } - - extern int journal_blocks_per_page(struct inode *inode); -+ -+/* -+ * Return the minimum number of blocks which must be free in the journal -+ * before a new transaction may be started. Must be called under j_state_lock. -+ */ -+static inline int jbd_space_needed(journal_t *journal) -+{ -+ int nblocks = journal->j_max_transaction_buffers; -+ if (journal->j_committing_transaction) -+ nblocks += journal->j_committing_transaction-> -+ t_outstanding_credits; -+ return nblocks; -+} - - /* - * Definitions which augment the buffer_head layer - -_ diff --git a/lustre/kernel_patches/patches/jbd-dont-account-blocks-twice-2.4.24.patch b/lustre/kernel_patches/patches/jbd-dont-account-blocks-twice-2.4.24.patch deleted file mode 100644 index d1be6f02..0000000 --- a/lustre/kernel_patches/patches/jbd-dont-account-blocks-twice-2.4.24.patch +++ /dev/null @@ -1,17 +0,0 @@ - ---- linux-2.4.18/fs/jbd/commit.c~jbd-dont-account-blocks-twice Mon Jul 28 13:52:05 2003 -+++ linux-2.4.18-alexey/fs/jbd/commit.c Mon Jul 28 14:03:53 2003 -@@ -407,6 +407,11 @@ sync_datalist_empty: - continue; - } - -+ /* start_this_handle() accounts t_outstanding_credits -+ * to know free space in log, but this counter is changed -+ * by journal_next_log_block() also. */ -+ commit_transaction->t_outstanding_credits--; -+ - /* Bump b_count to prevent truncate from stumbling over - the shadowed buffer! @@@ This can go if we ever get - rid of the BJ_IO/BJ_Shadow pairing of buffers. */ - -_ diff --git a/lustre/kernel_patches/patches/kernel_text_address-2.4.24-vanilla.patch b/lustre/kernel_patches/patches/kernel_text_address-2.4.24-vanilla.patch deleted file mode 100644 index 1f32684..0000000 --- a/lustre/kernel_patches/patches/kernel_text_address-2.4.24-vanilla.patch +++ /dev/null @@ -1,54 +0,0 @@ -Index: linux-2.4.22-vanilla/arch/i386/kernel/traps.c -=================================================================== ---- linux-2.4.22-vanilla.orig/arch/i386/kernel/traps.c 2003-05-16 05:28:59.000000000 +0400 -+++ linux-2.4.22-vanilla/arch/i386/kernel/traps.c 2003-11-14 00:35:36.000000000 +0300 -@@ -1004,3 +1004,35 @@ - cobalt_init(); - #endif - } -+#ifdef CONFIG_MODULES -+extern struct module *module_list; -+extern struct module kernel_module; -+#endif -+ -+int is_kernel_text_address(unsigned long addr) -+{ -+ int retval = 0; -+#ifdef CONFIG_MODULES -+ struct module *mod; -+#endif -+ if (addr >= (unsigned long) &_stext && -+ addr <= (unsigned long) &_etext); -+ return 1; -+ -+#ifdef CONFIG_MODULES -+ for (mod = module_list; mod != &kernel_module; mod = mod->next) { -+ /* mod_bound tests for addr being inside the vmalloc'ed -+ * module area. Of course it'd be better to test only -+ * for the .text subset... */ -+ if (mod_bound(addr, 0, mod)) { -+ retval = 1; -+ break; -+ } -+ } -+#endif -+ -+ return retval; -+} -+ -+EXPORT_SYMBOL_GPL(is_kernel_text_address); -+EXPORT_SYMBOL_GPL(lookup_symbol); -Index: linux-2.4.22-vanilla/arch/i386/kernel/Makefile -=================================================================== ---- linux-2.4.22-vanilla.orig/arch/i386/kernel/Makefile 2003-11-03 23:22:06.000000000 +0300 -+++ linux-2.4.22-vanilla/arch/i386/kernel/Makefile 2003-11-14 00:30:28.000000000 +0300 -@@ -14,7 +14,8 @@ - - O_TARGET := kernel.o - --export-objs := mca.o mtrr.o msr.o cpuid.o microcode.o i386_ksyms.o time.o setup.o -+export-objs := mca.o mtrr.o msr.o cpuid.o microcode.o i386_ksyms.o time.o \ -+ setup.o traps.o - - obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \ - ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \ diff --git a/lustre/kernel_patches/patches/kksymoops-2.4.24.vanilla.patch b/lustre/kernel_patches/patches/kksymoops-2.4.24.vanilla.patch deleted file mode 100644 index ad05611..0000000 --- a/lustre/kernel_patches/patches/kksymoops-2.4.24.vanilla.patch +++ /dev/null @@ -1,713 +0,0 @@ -Index: linux-2.4.24-b1_4/arch/i386/kernel/process.c -=================================================================== ---- linux-2.4.24-b1_4.orig/arch/i386/kernel/process.c 2003-11-29 02:26:19.000000000 +0800 -+++ linux-2.4.24-b1_4/arch/i386/kernel/process.c 2004-09-06 17:53:50.000000000 +0800 -@@ -33,6 +33,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -447,10 +448,14 @@ - void show_regs(struct pt_regs * regs) - { - unsigned long cr0 = 0L, cr2 = 0L, cr3 = 0L, cr4 = 0L; -+ static char buffer[512]; -+ -+ lookup_symbol(regs->eip,buffer,512); - - printk("\n"); - printk("Pid: %d, comm: %20s\n", current->pid, current->comm); - printk("EIP: %04x:[<%08lx>] CPU: %d",0xffff & regs->xcs,regs->eip, smp_processor_id()); -+ printk("\nEIP is at %s (" UTS_RELEASE ")\n",buffer); - if (regs->xcs & 3) - printk(" ESP: %04x:%08lx",0xffff & regs->xss,regs->esp); - printk(" EFLAGS: %08lx %s\n",regs->eflags, print_tainted()); -Index: linux-2.4.24-b1_4/arch/i386/kernel/traps.c -=================================================================== ---- linux-2.4.24-b1_4.orig/arch/i386/kernel/traps.c 2004-09-06 17:53:35.000000000 +0800 -+++ linux-2.4.24-b1_4/arch/i386/kernel/traps.c 2004-09-06 17:53:50.000000000 +0800 -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - - #ifdef CONFIG_MCA - #include -@@ -135,6 +136,8 @@ - { - int i; - unsigned long addr; -+ /* static to not take up stackspace; if we race here too bad */ -+ static char buffer[512]; - - if (!stack) - stack = (unsigned long*)&stack; -@@ -144,9 +147,8 @@ - while (((long) stack & (THREAD_SIZE-1)) != 0) { - addr = *stack++; - if (kernel_text_address(addr)) { -- if (i && ((i % 6) == 0)) -- printk("\n "); -- printk(" [<%08lx>]", addr); -+ lookup_symbol(addr, buffer, 512); -+ printk("[<%08lx>] %s (0x%x))\n", addr,buffer,stack-1); - i++; - } - } -@@ -194,12 +196,17 @@ - show_stack(0); - } - -+ -+void print_modules(void); -+ -+ - void show_registers(struct pt_regs *regs) - { - int i; - int in_kernel = 1; - unsigned long esp; - unsigned short ss; -+ static char buffer[512]; - - esp = (unsigned long) (®s->esp); - ss = __KERNEL_DS; -@@ -208,8 +215,12 @@ - esp = regs->esp; - ss = regs->xss & 0xffff; - } -+ -+ print_modules(); -+ lookup_symbol(regs->eip, buffer, 512); - printk("CPU: %d\nEIP: %04x:[<%08lx>] %s\nEFLAGS: %08lx\n", - smp_processor_id(), 0xffff & regs->xcs, regs->eip, print_tainted(), regs->eflags); -+ printk("\nEIP is at %s (" UTS_RELEASE ")\n",buffer); - printk("eax: %08lx ebx: %08lx ecx: %08lx edx: %08lx\n", - regs->eax, regs->ebx, regs->ecx, regs->edx); - printk("esi: %08lx edi: %08lx ebp: %08lx esp: %08lx\n", -@@ -269,7 +280,7 @@ - if (__get_user(file, (char **)(eip + 4)) || - (unsigned long)file < PAGE_OFFSET || __get_user(c, file)) - file = ""; -- -+ printk("------------[ cut here ]------------\n"); - printk("kernel BUG at %s:%d!\n", file, line); - - no_bug: -Index: linux-2.4.24-b1_4/arch/i386/config.in -=================================================================== ---- linux-2.4.24-b1_4.orig/arch/i386/config.in 2004-09-06 17:53:39.000000000 +0800 -+++ linux-2.4.24-b1_4/arch/i386/config.in 2004-09-06 17:53:50.000000000 +0800 -@@ -8,6 +8,7 @@ - define_bool CONFIG_SBUS n - - define_bool CONFIG_UID16 y -+define_bool CONFIG_KALLSYMS y - - mainmenu_option next_comment - comment 'Code maturity level options' -Index: linux-2.4.24-b1_4/arch/i386/vmlinux.lds.S -=================================================================== ---- linux-2.4.24-b1_4.orig/arch/i386/vmlinux.lds.S 2004-09-06 17:53:39.000000000 +0800 -+++ linux-2.4.24-b1_4/arch/i386/vmlinux.lds.S 2004-09-06 17:53:50.000000000 +0800 -@@ -28,6 +28,11 @@ - __ksymtab : { *(__ksymtab) } - __stop___ksymtab = .; - -+ __start___kallsyms = .; /* All kernel symbols */ -+ __kallsyms : { *(__kallsyms) } -+ __stop___kallsyms = .; -+ -+ - .data : { /* Data */ - *(.data) - CONSTRUCTORS -Index: linux-2.4.24-b1_4/include/linux/kernel.h -=================================================================== ---- linux-2.4.24-b1_4.orig/include/linux/kernel.h 2004-09-06 17:44:47.000000000 +0800 -+++ linux-2.4.24-b1_4/include/linux/kernel.h 2004-09-06 17:55:19.000000000 +0800 -@@ -110,6 +110,8 @@ - - extern void dump_stack(void); - -+extern int lookup_symbol(unsigned long address, char *buffer, int buflen); -+ - #if DEBUG - #define pr_debug(fmt,arg...) \ - printk(KERN_DEBUG fmt,##arg) -Index: linux-2.4.24-b1_4/include/linux/kallsyms.h -=================================================================== ---- linux-2.4.24-b1_4.orig/include/linux/kallsyms.h 2003-01-30 18:24:37.000000000 +0800 -+++ linux-2.4.24-b1_4/include/linux/kallsyms.h 2004-09-06 17:53:50.000000000 +0800 -@@ -0,0 +1,164 @@ -+/* kallsyms headers -+ Copyright 2000 Keith Owens -+ -+ This file is part of the Linux modutils. It is exported to kernel -+ space so debuggers can access the kallsyms data. -+ -+ The kallsyms data contains all the non-stack symbols from a kernel -+ or a module. The kernel symbols are held between __start___kallsyms -+ and __stop___kallsyms. The symbols for a module are accessed via -+ the struct module chain which is based at module_list. -+ -+ This program is free software; you can redistribute it and/or modify it -+ under the terms of the GNU General Public License as published by the -+ Free Software Foundation; either version 2 of the License, or (at your -+ option) any later version. -+ -+ This program is distributed in the hope that it will be useful, but -+ WITHOUT ANY WARRANTY; without even the implied warranty of -+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ General Public License for more details. -+ -+ You should have received a copy of the GNU General Public License -+ along with this program; if not, write to the Free Software Foundation, -+ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -+ */ -+ -+#ident "$Id: kksymoops-2.4.24.vanilla.patch,v 1.11 2004/11/11 11:34:26 yury Exp $" -+ -+#ifndef MODUTILS_KALLSYMS_H -+#define MODUTILS_KALLSYMS_H 1 -+ -+/* Have to (re)define these ElfW entries here because external kallsyms -+ * code does not have access to modutils/include/obj.h. This code is -+ * included from user spaces tools (modutils) and kernel, they need -+ * different includes. -+ */ -+ -+#ifndef ELFCLASS32 -+#ifdef __KERNEL__ -+#include -+#else /* __KERNEL__ */ -+#include -+#endif /* __KERNEL__ */ -+#endif /* ELFCLASS32 */ -+ -+#ifndef ELFCLASSM -+#define ELFCLASSM ELF_CLASS -+#endif -+ -+#ifndef ElfW -+# if ELFCLASSM == ELFCLASS32 -+# define ElfW(x) Elf32_ ## x -+# define ELFW(x) ELF32_ ## x -+# else -+# define ElfW(x) Elf64_ ## x -+# define ELFW(x) ELF64_ ## x -+# endif -+#endif -+ -+/* Format of data in the kallsyms section. -+ * Most of the fields are small numbers but the total size and all -+ * offsets can be large so use the 32/64 bit types for these fields. -+ * -+ * Do not use sizeof() on these structures, modutils may be using extra -+ * fields. Instead use the size fields in the header to access the -+ * other bits of data. -+ */ -+ -+struct kallsyms_header { -+ int size; /* Size of this header */ -+ ElfW(Word) total_size; /* Total size of kallsyms data */ -+ int sections; /* Number of section entries */ -+ ElfW(Off) section_off; /* Offset to first section entry */ -+ int section_size; /* Size of one section entry */ -+ int symbols; /* Number of symbol entries */ -+ ElfW(Off) symbol_off; /* Offset to first symbol entry */ -+ int symbol_size; /* Size of one symbol entry */ -+ ElfW(Off) string_off; /* Offset to first string */ -+ ElfW(Addr) start; /* Start address of first section */ -+ ElfW(Addr) end; /* End address of last section */ -+}; -+ -+struct kallsyms_section { -+ ElfW(Addr) start; /* Start address of section */ -+ ElfW(Word) size; /* Size of this section */ -+ ElfW(Off) name_off; /* Offset to section name */ -+ ElfW(Word) flags; /* Flags from section */ -+}; -+ -+struct kallsyms_symbol { -+ ElfW(Off) section_off; /* Offset to section that owns this symbol */ -+ ElfW(Addr) symbol_addr; /* Address of symbol */ -+ ElfW(Off) name_off; /* Offset to symbol name */ -+}; -+ -+#define KALLSYMS_SEC_NAME "__kallsyms" -+#define KALLSYMS_IDX 2 /* obj_kallsyms creates kallsyms as section 2 */ -+ -+#define kallsyms_next_sec(h,s) \ -+ ((s) = (struct kallsyms_section *)((char *)(s) + (h)->section_size)) -+#define kallsyms_next_sym(h,s) \ -+ ((s) = (struct kallsyms_symbol *)((char *)(s) + (h)->symbol_size)) -+ -+#ifdef CONFIG_KALLSYMS -+ -+int kallsyms_symbol_to_address( -+ const char *name, /* Name to lookup */ -+ unsigned long *token, /* Which module to start with */ -+ const char **mod_name, /* Set to module name or "kernel" */ -+ unsigned long *mod_start, /* Set to start address of module */ -+ unsigned long *mod_end, /* Set to end address of module */ -+ const char **sec_name, /* Set to section name */ -+ unsigned long *sec_start, /* Set to start address of section */ -+ unsigned long *sec_end, /* Set to end address of section */ -+ const char **sym_name, /* Set to full symbol name */ -+ unsigned long *sym_start, /* Set to start address of symbol */ -+ unsigned long *sym_end /* Set to end address of symbol */ -+ ); -+ -+int kallsyms_address_to_symbol( -+ unsigned long address, /* Address to lookup */ -+ const char **mod_name, /* Set to module name */ -+ unsigned long *mod_start, /* Set to start address of module */ -+ unsigned long *mod_end, /* Set to end address of module */ -+ const char **sec_name, /* Set to section name */ -+ unsigned long *sec_start, /* Set to start address of section */ -+ unsigned long *sec_end, /* Set to end address of section */ -+ const char **sym_name, /* Set to full symbol name */ -+ unsigned long *sym_start, /* Set to start address of symbol */ -+ unsigned long *sym_end /* Set to end address of symbol */ -+ ); -+ -+int kallsyms_sections(void *token, -+ int (*callback)(void *, /* token */ -+ const char *, /* module name */ -+ const char *, /* section name */ -+ ElfW(Addr), /* Section start */ -+ ElfW(Addr), /* Section end */ -+ ElfW(Word) /* Section flags */ -+ ) -+ ); -+ -+#else -+ -+static inline int kallsyms_address_to_symbol( -+ unsigned long address, /* Address to lookup */ -+ const char **mod_name, /* Set to module name */ -+ unsigned long *mod_start, /* Set to start address of module */ -+ unsigned long *mod_end, /* Set to end address of module */ -+ const char **sec_name, /* Set to section name */ -+ unsigned long *sec_start, /* Set to start address of section */ -+ unsigned long *sec_end, /* Set to end address of section */ -+ const char **sym_name, /* Set to full symbol name */ -+ unsigned long *sym_start, /* Set to start address of symbol */ -+ unsigned long *sym_end /* Set to end address of symbol */ -+ ) -+{ -+ return -ESRCH; -+} -+ -+#endif -+ -+#endif /* kallsyms.h */ -+ -Index: linux-2.4.24-b1_4/kernel/kksymoops.c -=================================================================== ---- linux-2.4.24-b1_4.orig/kernel/kksymoops.c 2003-01-30 18:24:37.000000000 +0800 -+++ linux-2.4.24-b1_4/kernel/kksymoops.c 2004-09-06 17:53:50.000000000 +0800 -@@ -0,0 +1,82 @@ -+#include -+#include -+#include -+#include -+#include -+#ifdef CONFIG_KALLSYMS -+#include -+#endif -+ -+ -+ -+int lookup_symbol(unsigned long address, char *buffer, int buflen) -+{ -+ struct module *this_mod; -+ unsigned long bestsofar; -+ -+ const char *mod_name = NULL, *sec_name = NULL, *sym_name = NULL; -+ unsigned long mod_start,mod_end,sec_start,sec_end,sym_start,sym_end; -+ -+ if (!buffer) -+ return -EFAULT; -+ -+ if (buflen<256) -+ return -ENOMEM; -+ -+ memset(buffer,0,buflen); -+ -+#ifdef CONFIG_KALLSYMS -+ if (!kallsyms_address_to_symbol(address,&mod_name,&mod_start,&mod_end,&sec_name, -+ &sec_start, &sec_end, &sym_name, &sym_start, &sym_end)) { -+ /* kallsyms doesn't have a clue; lets try harder */ -+ bestsofar = 0; -+ snprintf(buffer,buflen-1,"[unresolved]"); -+ -+ this_mod = module_list; -+ -+ while (this_mod != NULL) { -+ int i; -+ /* walk the symbol list of this module. Only symbols -+ who's address is smaller than the searched for address -+ are relevant; and only if it's better than the best so far */ -+ for (i=0; i< this_mod->nsyms; i++) -+ if ((this_mod->syms[i].value<=address) && -+ (bestsofarsyms[i].value)) { -+ snprintf(buffer,buflen-1,"%s [%s] 0x%x", -+ this_mod->syms[i].name, -+ this_mod->name, -+ (unsigned int)(address - this_mod->syms[i].value)); -+ bestsofar = this_mod->syms[i].value; -+ } -+ this_mod = this_mod->next; -+ } -+ -+ } else { /* kallsyms success */ -+ snprintf(buffer,buflen-1,"%s [%s] 0x%x",sym_name,mod_name,(unsigned int)(address-sym_start)); -+ } -+#endif -+ return strlen(buffer); -+} -+ -+static char modlist[4096]; -+/* this function isn't smp safe but that's not really a problem; it's called from -+ * oops context only and any locking could actually prevent the oops from going out; -+ * the line that is generated is informational only and should NEVER prevent the real oops -+ * from going out. -+ */ -+void print_modules(void) -+{ -+ struct module *this_mod; -+ int pos = 0; -+ memset(modlist,0,4096); -+ -+#ifdef CONFIG_KALLSYMS -+ this_mod = module_list; -+ while (this_mod != NULL) { -+ if (this_mod->name != NULL) -+ pos +=snprintf(modlist+pos,160-pos-1,"%s ",this_mod->name); -+ this_mod = this_mod->next; -+ } -+ printk("%s\n",modlist); -+#endif -+} -Index: linux-2.4.24-b1_4/kernel/Makefile -=================================================================== ---- linux-2.4.24-b1_4.orig/kernel/Makefile 2001-09-17 12:22:40.000000000 +0800 -+++ linux-2.4.24-b1_4/kernel/Makefile 2004-09-06 17:56:17.000000000 +0800 -@@ -29,4 +29,7 @@ - CFLAGS_sched.o := $(PROFILING) -fno-omit-frame-pointer - endif - -+obj-$(CONFIG_KALLSYMS) += kksymoops.o -+obj-$(CONFIG_KALLSYMS) += kallsyms.o -+ - include $(TOPDIR)/Rules.make -Index: linux-2.4.24-b1_4/kernel/kallsyms.c -=================================================================== ---- linux-2.4.24-b1_4.orig/kernel/kallsyms.c 2003-01-30 18:24:37.000000000 +0800 -+++ linux-2.4.24-b1_4/kernel/kallsyms.c 2004-09-06 17:53:50.000000000 +0800 -@@ -0,0 +1,227 @@ -+/* -+ * kksymoops.c: in-kernel printing of symbolic oopses and stack traces. -+ * -+ * Copyright 2000 Keith Owens April 2000 -+ * Copyright 2002 Arjan van de Ven -+ * -+ This code uses the list of all kernel and module symbols to :- -+ -+ * Find any non-stack symbol in a kernel or module. Symbols do -+ not have to be exported for debugging. -+ -+ * Convert an address to the module (or kernel) that owns it, the -+ section it is in and the nearest symbol. This finds all non-stack -+ symbols, not just exported ones. -+ -+ */ -+ -+#include -+#include -+#include -+ -+/* A symbol can appear in more than one module. A token is used to -+ * restart the scan at the next module, set the token to 0 for the -+ * first scan of each symbol. -+ */ -+ -+int kallsyms_symbol_to_address( -+ const char *name, /* Name to lookup */ -+ unsigned long *token, /* Which module to start at */ -+ const char **mod_name, /* Set to module name */ -+ unsigned long *mod_start, /* Set to start address of module */ -+ unsigned long *mod_end, /* Set to end address of module */ -+ const char **sec_name, /* Set to section name */ -+ unsigned long *sec_start, /* Set to start address of section */ -+ unsigned long *sec_end, /* Set to end address of section */ -+ const char **sym_name, /* Set to full symbol name */ -+ unsigned long *sym_start, /* Set to start address of symbol */ -+ unsigned long *sym_end /* Set to end address of symbol */ -+ ) -+{ -+ const struct kallsyms_header *ka_hdr = NULL; /* stupid gcc */ -+ const struct kallsyms_section *ka_sec; -+ const struct kallsyms_symbol *ka_sym = NULL; -+ const char *ka_str = NULL; -+ const struct module *m; -+ int i = 0, l; -+ const char *p, *pt_R; -+ char *p2; -+ -+ /* Restart? */ -+ m = module_list; -+ if (token && *token) { -+ for (; m; m = m->next) -+ if ((unsigned long)m == *token) -+ break; -+ if (m) -+ m = m->next; -+ } -+ -+ for (; m; m = m->next) { -+ if (!mod_member_present(m, kallsyms_start) || -+ !mod_member_present(m, kallsyms_end) || -+ m->kallsyms_start >= m->kallsyms_end) -+ continue; -+ ka_hdr = (struct kallsyms_header *)m->kallsyms_start; -+ ka_sym = (struct kallsyms_symbol *) -+ ((char *)(ka_hdr) + ka_hdr->symbol_off); -+ ka_str = -+ ((char *)(ka_hdr) + ka_hdr->string_off); -+ for (i = 0; i < ka_hdr->symbols; ++i, kallsyms_next_sym(ka_hdr, ka_sym)) { -+ p = ka_str + ka_sym->name_off; -+ if (strcmp(p, name) == 0) -+ break; -+ /* Unversioned requests match versioned names */ -+ if (!(pt_R = strstr(p, "_R"))) -+ continue; -+ l = strlen(pt_R); -+ if (l < 10) -+ continue; /* Not _R.*xxxxxxxx */ -+ (void)simple_strtoul(pt_R+l-8, &p2, 16); -+ if (*p2) -+ continue; /* Not _R.*xxxxxxxx */ -+ if (strncmp(p, name, pt_R-p) == 0) -+ break; /* Match with version */ -+ } -+ if (i < ka_hdr->symbols) -+ break; -+ } -+ -+ if (token) -+ *token = (unsigned long)m; -+ if (!m) -+ return(0); /* not found */ -+ -+ ka_sec = (const struct kallsyms_section *) -+ ((char *)ka_hdr + ka_hdr->section_off + ka_sym->section_off); -+ *mod_name = m->name; -+ *mod_start = ka_hdr->start; -+ *mod_end = ka_hdr->end; -+ *sec_name = ka_sec->name_off + ka_str; -+ *sec_start = ka_sec->start; -+ *sec_end = ka_sec->start + ka_sec->size; -+ *sym_name = ka_sym->name_off + ka_str; -+ *sym_start = ka_sym->symbol_addr; -+ if (i < ka_hdr->symbols-1) { -+ const struct kallsyms_symbol *ka_symn = ka_sym; -+ kallsyms_next_sym(ka_hdr, ka_symn); -+ *sym_end = ka_symn->symbol_addr; -+ } -+ else -+ *sym_end = *sec_end; -+ return(1); -+} -+ -+int kallsyms_address_to_symbol( -+ unsigned long address, /* Address to lookup */ -+ const char **mod_name, /* Set to module name */ -+ unsigned long *mod_start, /* Set to start address of module */ -+ unsigned long *mod_end, /* Set to end address of module */ -+ const char **sec_name, /* Set to section name */ -+ unsigned long *sec_start, /* Set to start address of section */ -+ unsigned long *sec_end, /* Set to end address of section */ -+ const char **sym_name, /* Set to full symbol name */ -+ unsigned long *sym_start, /* Set to start address of symbol */ -+ unsigned long *sym_end /* Set to end address of symbol */ -+ ) -+{ -+ const struct kallsyms_header *ka_hdr = NULL; /* stupid gcc */ -+ const struct kallsyms_section *ka_sec = NULL; -+ const struct kallsyms_symbol *ka_sym; -+ const char *ka_str; -+ const struct module *m; -+ int i; -+ unsigned long end; -+ -+ for (m = module_list; m; m = m->next) { -+ -+ if (!mod_member_present(m, kallsyms_start) || -+ !mod_member_present(m, kallsyms_end) || -+ m->kallsyms_start >= m->kallsyms_end) -+ continue; -+ ka_hdr = (struct kallsyms_header *)m->kallsyms_start; -+ ka_sec = (const struct kallsyms_section *) -+ ((char *)ka_hdr + ka_hdr->section_off); -+ /* Is the address in any section in this module? */ -+ for (i = 0; i < ka_hdr->sections; ++i, kallsyms_next_sec(ka_hdr, ka_sec)) { -+ if (ka_sec->start <= address && -+ (ka_sec->start + ka_sec->size) > address) -+ break; -+ } -+ if (i < ka_hdr->sections) -+ break; /* Found a matching section */ -+ } -+ -+ if (!m) -+ return(0); /* not found */ -+ -+ ka_sym = (struct kallsyms_symbol *) -+ ((char *)(ka_hdr) + ka_hdr->symbol_off); -+ ka_str = -+ ((char *)(ka_hdr) + ka_hdr->string_off); -+ *mod_name = m->name; -+ *mod_start = ka_hdr->start; -+ *mod_end = ka_hdr->end; -+ *sec_name = ka_sec->name_off + ka_str; -+ *sec_start = ka_sec->start; -+ *sec_end = ka_sec->start + ka_sec->size; -+ *sym_name = *sec_name; /* In case we find no matching symbol */ -+ *sym_start = *sec_start; -+ *sym_end = *sec_end; -+ -+ for (i = 0; i < ka_hdr->symbols; ++i, kallsyms_next_sym(ka_hdr, ka_sym)) { -+ if (ka_sym->symbol_addr > address) -+ continue; -+ if (i < ka_hdr->symbols-1) { -+ const struct kallsyms_symbol *ka_symn = ka_sym; -+ kallsyms_next_sym(ka_hdr, ka_symn); -+ end = ka_symn->symbol_addr; -+ } -+ else -+ end = *sec_end; -+ if (end <= address) -+ continue; -+ if ((char *)ka_hdr + ka_hdr->section_off + ka_sym->section_off -+ != (char *)ka_sec) -+ continue; /* wrong section */ -+ *sym_name = ka_str + ka_sym->name_off; -+ *sym_start = ka_sym->symbol_addr; -+ *sym_end = end; -+ break; -+ } -+ return(1); -+} -+ -+/* List all sections in all modules. The callback routine is invoked with -+ * token, module name, section name, section start, section end, section flags. -+ */ -+int kallsyms_sections(void *token, -+ int (*callback)(void *, const char *, const char *, ElfW(Addr), ElfW(Addr), ElfW(Word))) -+{ -+ const struct kallsyms_header *ka_hdr = NULL; /* stupid gcc */ -+ const struct kallsyms_section *ka_sec = NULL; -+ const char *ka_str; -+ const struct module *m; -+ int i; -+ -+ for (m = module_list; m; m = m->next) { -+ if (!mod_member_present(m, kallsyms_start) || -+ !mod_member_present(m, kallsyms_end) || -+ m->kallsyms_start >= m->kallsyms_end) -+ continue; -+ ka_hdr = (struct kallsyms_header *)m->kallsyms_start; -+ ka_sec = (const struct kallsyms_section *) ((char *)ka_hdr + ka_hdr->section_off); -+ ka_str = ((char *)(ka_hdr) + ka_hdr->string_off); -+ for (i = 0; i < ka_hdr->sections; ++i, kallsyms_next_sec(ka_hdr, ka_sec)) { -+ if (callback( -+ token, -+ *(m->name) ? m->name : "kernel", -+ ka_sec->name_off + ka_str, -+ ka_sec->start, -+ ka_sec->start + ka_sec->size, -+ ka_sec->flags)) -+ return(0); -+ } -+ } -+ return(1); -+} -Index: linux-2.4.24-b1_4/Makefile -=================================================================== ---- linux-2.4.24-b1_4.orig/Makefile 2004-09-06 17:44:47.000000000 +0800 -+++ linux-2.4.24-b1_4/Makefile 2004-09-06 17:53:50.000000000 +0800 -@@ -45,6 +45,7 @@ - MAKEFILES = $(TOPDIR)/.config - GENKSYMS = /sbin/genksyms - DEPMOD = /sbin/depmod -+KALLSYMS = /sbin/kallsyms - MODFLAGS = -DMODULE - CFLAGS_KERNEL = - PERL = perl -@@ -211,7 +212,7 @@ - CLEAN_FILES = \ - kernel/ksyms.lst include/linux/compile.h \ - vmlinux System.map \ -- .tmp* \ -+ $(TMPPREFIX).tmp* \ - drivers/char/consolemap_deftbl.c drivers/video/promcon_tbl.c \ - drivers/char/conmakehash \ - drivers/char/drm/*-mod.c \ -@@ -292,16 +293,42 @@ - boot: vmlinux - @$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" -C arch/$(ARCH)/boot - -+LD_VMLINUX := $(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o init/do_mounts.o \ -+ --start-group \ -+ $(CORE_FILES) \ -+ $(DRIVERS) \ -+ $(NETWORKS) \ -+ $(LIBS) \ -+ --end-group -+ifeq ($(CONFIG_KALLSYMS),y) -+LD_VMLINUX_KALLSYMS := $(TMPPREFIX).tmp_kallsyms3.o -+else -+LD_VMLINUX_KALLSYMS := -+endif -+ - vmlinux: include/linux/version.h $(CONFIGURATION) init/main.o init/version.o init/do_mounts.o linuxsubdirs -- $(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o init/do_mounts.o \ -- --start-group \ -- $(CORE_FILES) \ -- $(DRIVERS) \ -- $(NETWORKS) \ -- $(LIBS) \ -- --end-group \ -- -o vmlinux -+ @$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" kallsyms -+ -+.PHONY: kallsyms -+ -+kallsyms: -+ifeq ($(CONFIG_KALLSYMS),y) -+ @echo kallsyms pass 1 -+ $(LD_VMLINUX) -o $(TMPPREFIX).tmp_vmlinux1 -+ @$(KALLSYMS) $(TMPPREFIX).tmp_vmlinux1 > $(TMPPREFIX).tmp_kallsyms1.o -+ @echo kallsyms pass 2 -+ @$(LD_VMLINUX) $(TMPPREFIX).tmp_kallsyms1.o -o $(TMPPREFIX).tmp_vmlinux2 -+ @$(KALLSYMS) $(TMPPREFIX).tmp_vmlinux2 > $(TMPPREFIX).tmp_kallsyms2.o -+ @echo kallsyms pass 3 -+ @$(LD_VMLINUX) $(TMPPREFIX).tmp_kallsyms2.o -o $(TMPPREFIX).tmp_vmlinux3 -+ @$(KALLSYMS) $(TMPPREFIX).tmp_vmlinux3 > $(TMPPREFIX).tmp_kallsyms3.o -+endif -+ $(LD_VMLINUX) $(LD_VMLINUX_KALLSYMS) -o $(TMPPREFIX)vmlinux -+ifneq ($(TMPPREFIX),) -+ mv $(TMPPREFIX)vmlinux vmlinux -+endif - $(NM) vmlinux | grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | sort > System.map -+ @rm -f $(TMPPREFIX).tmp_vmlinux* $(TMPPREFIX).tmp_kallsyms* - - symlinks: - rm -f include/asm diff --git a/lustre/kernel_patches/patches/linux-2.4.24-xattr-0.8.54.patch b/lustre/kernel_patches/patches/linux-2.4.24-xattr-0.8.54.patch deleted file mode 100644 index 4cf5c2c..0000000 --- a/lustre/kernel_patches/patches/linux-2.4.24-xattr-0.8.54.patch +++ /dev/null @@ -1,5474 +0,0 @@ - Documentation/Configure.help | 66 ++ - arch/alpha/defconfig | 7 - arch/alpha/kernel/entry.S | 12 - arch/arm/defconfig | 7 - arch/arm/kernel/calls.S | 24 - arch/i386/defconfig | 7 - arch/ia64/defconfig | 7 - arch/ia64/kernel/entry.S | 24 - arch/m68k/defconfig | 7 - arch/mips/defconfig | 7 - arch/mips64/defconfig | 7 - arch/ppc/defconfig | 14 - arch/ppc64/kernel/misc.S | 2 - arch/s390/defconfig | 7 - arch/s390/kernel/entry.S | 24 - arch/s390x/defconfig | 7 - arch/s390x/kernel/entry.S | 24 - arch/s390x/kernel/wrapper32.S | 92 +++ - arch/sparc/defconfig | 7 - arch/sparc/kernel/systbls.S | 10 - arch/sparc64/defconfig | 7 - arch/sparc64/kernel/systbls.S | 20 - fs/Config.in | 14 - fs/Makefile | 3 - fs/ext2/Makefile | 4 - fs/ext2/file.c | 5 - fs/ext2/ialloc.c | 2 - fs/ext2/inode.c | 34 - - fs/ext2/namei.c | 14 - fs/ext2/super.c | 29 - fs/ext2/symlink.c | 14 - fs/ext2/xattr.c | 1212 +++++++++++++++++++++++++++++++++++++++++ - fs/ext2/xattr_user.c | 103 +++ - fs/ext3/Makefile | 10 - fs/ext3/file.c | 5 - fs/ext3/ialloc.c | 2 - fs/ext3/inode.c | 35 - - fs/ext3/namei.c | 21 - fs/ext3/super.c | 36 + - fs/ext3/symlink.c | 14 - fs/ext3/xattr.c | 1225 ++++++++++++++++++++++++++++++++++++++++++ - fs/ext3/xattr_user.c | 111 +++ - fs/jfs/jfs_xattr.h | 6 - fs/jfs/xattr.c | 6 - fs/mbcache.c | 648 ++++++++++++++++++++++ - include/asm-arm/unistd.h | 2 - include/asm-ia64/unistd.h | 13 - include/asm-ppc64/unistd.h | 2 - include/asm-s390/unistd.h | 15 - include/asm-s390x/unistd.h | 15 - include/asm-sparc/unistd.h | 24 - include/asm-sparc64/unistd.h | 24 - include/linux/cache_def.h | 15 - include/linux/errno.h | 4 - include/linux/ext2_fs.h | 31 - - include/linux/ext2_xattr.h | 157 +++++ - include/linux/ext3_fs.h | 31 - - include/linux/ext3_jbd.h | 8 - include/linux/ext3_xattr.h | 157 +++++ - include/linux/fs.h | 2 - include/linux/mbcache.h | 69 ++ - kernel/ksyms.c | 4 - mm/vmscan.c | 35 + - fs/ext3/ext3-exports.c | 14 + - 64 files changed, 4355 insertions(+), 195 deletions(-) - -Index: linux-2.4.24-vanilla/Documentation/Configure.help -=================================================================== ---- linux-2.4.24-vanilla.orig/Documentation/Configure.help 2004-01-10 17:05:37.000000000 +0300 -+++ linux-2.4.24-vanilla/Documentation/Configure.help 2004-01-10 17:20:28.000000000 +0300 -@@ -16295,6 +16295,39 @@ - be compiled as a module, and so this could be dangerous. Most - everyone wants to say Y here. - -+Ext2 extended attributes -+CONFIG_EXT2_FS_XATTR -+ Extended attributes are name:value pairs associated with inodes by -+ the kernel or by users (see the attr(5) manual page, or visit -+ for details). -+ -+ If unsure, say N. -+ -+Ext2 extended attribute block sharing -+CONFIG_EXT2_FS_XATTR_SHARING -+ This options enables code for sharing identical extended attribute -+ blocks among multiple inodes. -+ -+ Usually, say Y. -+ -+Ext2 extended user attributes -+CONFIG_EXT2_FS_XATTR_USER -+ This option enables extended user attributes on ext2. Processes can -+ associate extended user attributes with inodes to store additional -+ information such as the character encoding of files, etc. (see the -+ attr(5) manual page, or visit for details). -+ -+ If unsure, say N. -+ -+Ext2 trusted extended attributes -+CONFIG_EXT2_FS_XATTR_TRUSTED -+ This option enables extended attributes on ext2 that are accessible -+ (and visible) only to users capable of CAP_SYS_ADMIN. Usually this -+ is only the super user. Trusted extended attributes are meant for -+ implementing system/security services. -+ -+ If unsure, say N. -+ - Ext3 journalling file system support (EXPERIMENTAL) - CONFIG_EXT3_FS - This is the journalling version of the Second extended file system -@@ -16327,6 +16360,39 @@ - of your root partition (the one containing the directory /) cannot - be compiled as a module, and so this may be dangerous. - -+Ext3 extended attributes -+CONFIG_EXT3_FS_XATTR -+ Extended attributes are name:value pairs associated with inodes by -+ the kernel or by users (see the attr(5) manual page, or visit -+ for details). -+ -+ If unsure, say N. -+ -+Ext3 extended attribute block sharing -+CONFIG_EXT3_FS_XATTR_SHARING -+ This options enables code for sharing identical extended attribute -+ blocks among multiple inodes. -+ -+ Usually, say Y. -+ -+Ext3 extended user attributes -+CONFIG_EXT3_FS_XATTR_USER -+ This option enables extended user attributes on ext3. Processes can -+ associate extended user attributes with inodes to store additional -+ information such as the character encoding of files, etc. (see the -+ attr(5) manual page, or visit for details). -+ -+ If unsure, say N. -+ -+Ext3 trusted extended attributes -+CONFIG_EXT3_FS_XATTR_TRUSTED -+ This option enables extended attributes on ext3 that are accessible -+ (and visible) only to users capable of CAP_SYS_ADMIN. Usually this -+ is only the super user. Trusted extended attributes are meant for -+ implementing system/security services. -+ -+ If unsure, say N. -+ - Journal Block Device support (JBD for ext3) (EXPERIMENTAL) - CONFIG_JBD - This is a generic journalling layer for block devices. It is -Index: linux-2.4.24-vanilla/arch/alpha/defconfig -=================================================================== ---- linux-2.4.24-vanilla.orig/arch/alpha/defconfig 2004-01-10 17:04:37.000000000 +0300 -+++ linux-2.4.24-vanilla/arch/alpha/defconfig 2004-01-10 17:20:28.000000000 +0300 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# CONFIG_EXT3_FS_XATTR_SHARING is not set -+# CONFIG_EXT3_FS_XATTR_USER is not set -+# CONFIG_EXT2_FS_XATTR is not set -+# CONFIG_EXT2_FS_XATTR_SHARING is not set -+# CONFIG_EXT2_FS_XATTR_USER is not set -+# CONFIG_FS_MBCACHE is not set - CONFIG_ALPHA=y - # CONFIG_UID16 is not set - # CONFIG_RWSEM_GENERIC_SPINLOCK is not set -Index: linux-2.4.24-vanilla/arch/alpha/kernel/entry.S -=================================================================== ---- linux-2.4.24-vanilla.orig/arch/alpha/kernel/entry.S 2004-01-10 17:04:37.000000000 +0300 -+++ linux-2.4.24-vanilla/arch/alpha/kernel/entry.S 2004-01-10 17:20:28.000000000 +0300 -@@ -1154,6 +1154,18 @@ - .quad sys_readahead - .quad sys_ni_syscall /* 380, sys_security */ - .quad sys_tkill -+ .quad sys_setxattr -+ .quad sys_lsetxattr -+ .quad sys_fsetxattr -+ .quad sys_getxattr /* 385 */ -+ .quad sys_lgetxattr -+ .quad sys_fgetxattr -+ .quad sys_listxattr -+ .quad sys_llistxattr -+ .quad sys_flistxattr /* 390 */ -+ .quad sys_removexattr -+ .quad sys_lremovexattr -+ .quad sys_fremovexattr - - /* Remember to update everything, kids. */ - .ifne (. - sys_call_table) - (NR_SYSCALLS * 8) -Index: linux-2.4.24-vanilla/arch/arm/defconfig -=================================================================== ---- linux-2.4.24-vanilla.orig/arch/arm/defconfig 2001-05-20 04:43:05.000000000 +0400 -+++ linux-2.4.24-vanilla/arch/arm/defconfig 2004-01-10 17:20:28.000000000 +0300 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# CONFIG_EXT3_FS_XATTR_SHARING is not set -+# CONFIG_EXT3_FS_XATTR_USER is not set -+# CONFIG_EXT2_FS_XATTR is not set -+# CONFIG_EXT2_FS_XATTR_SHARING is not set -+# CONFIG_EXT2_FS_XATTR_USER is not set -+# CONFIG_FS_MBCACHE is not set - CONFIG_ARM=y - # CONFIG_EISA is not set - # CONFIG_SBUS is not set -Index: linux-2.4.24-vanilla/arch/arm/kernel/calls.S -=================================================================== ---- linux-2.4.24-vanilla.orig/arch/arm/kernel/calls.S 2004-01-10 17:04:58.000000000 +0300 -+++ linux-2.4.24-vanilla/arch/arm/kernel/calls.S 2004-01-10 17:20:28.000000000 +0300 -@@ -240,18 +240,18 @@ - .long SYMBOL_NAME(sys_ni_syscall) /* Security */ - .long SYMBOL_NAME(sys_gettid) - /* 225 */ .long SYMBOL_NAME(sys_readahead) -- .long SYMBOL_NAME(sys_ni_syscall) /* setxattr */ -- .long SYMBOL_NAME(sys_ni_syscall) /* lsetxattr */ -- .long SYMBOL_NAME(sys_ni_syscall) /* fsetxattr */ -- .long SYMBOL_NAME(sys_ni_syscall) /* getxattr */ --/* 230 */ .long SYMBOL_NAME(sys_ni_syscall) /* lgetxattr */ -- .long SYMBOL_NAME(sys_ni_syscall) /* fgetxattr */ -- .long SYMBOL_NAME(sys_ni_syscall) /* listxattr */ -- .long SYMBOL_NAME(sys_ni_syscall) /* llistxattr */ -- .long SYMBOL_NAME(sys_ni_syscall) /* flistxattr */ --/* 235 */ .long SYMBOL_NAME(sys_ni_syscall) /* removexattr */ -- .long SYMBOL_NAME(sys_ni_syscall) /* lremovexattr */ -- .long SYMBOL_NAME(sys_ni_syscall) /* fremovexattr */ -+ .long SYMBOL_NAME(sys_setxattr) -+ .long SYMBOL_NAME(sys_lsetxattr) -+ .long SYMBOL_NAME(sys_fsetxattr) -+ .long SYMBOL_NAME(sys_getxattr) -+/* 230 */ .long SYMBOL_NAME(sys_lgetxattr) -+ .long SYMBOL_NAME(sys_fgetxattr) -+ .long SYMBOL_NAME(sys_listxattr) -+ .long SYMBOL_NAME(sys_llistxattr) -+ .long SYMBOL_NAME(sys_flistxattr) -+/* 235 */ .long SYMBOL_NAME(sys_removexattr) -+ .long SYMBOL_NAME(sys_lremovexattr) -+ .long SYMBOL_NAME(sys_fremovexattr) - .long SYMBOL_NAME(sys_tkill) - .long SYMBOL_NAME(sys_ni_syscall) /* sendfile64 */ - /* 240 */ .long SYMBOL_NAME(sys_ni_syscall) /* futex */ -Index: linux-2.4.24-vanilla/arch/i386/defconfig -=================================================================== ---- linux-2.4.24-vanilla.orig/arch/i386/defconfig 2004-01-10 17:05:45.000000000 +0300 -+++ linux-2.4.24-vanilla/arch/i386/defconfig 2004-01-10 17:20:28.000000000 +0300 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# CONFIG_EXT3_FS_XATTR_SHARING is not set -+# CONFIG_EXT3_FS_XATTR_USER is not set -+# CONFIG_EXT2_FS_XATTR is not set -+# CONFIG_EXT2_FS_XATTR_SHARING is not set -+# CONFIG_EXT2_FS_XATTR_USER is not set -+# CONFIG_FS_MBCACHE is not set - CONFIG_X86=y - CONFIG_ISA=y - # CONFIG_SBUS is not set -Index: linux-2.4.24-vanilla/arch/ia64/defconfig -=================================================================== ---- linux-2.4.24-vanilla.orig/arch/ia64/defconfig 2004-01-10 17:05:52.000000000 +0300 -+++ linux-2.4.24-vanilla/arch/ia64/defconfig 2004-01-10 17:20:28.000000000 +0300 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# CONFIG_EXT3_FS_XATTR_SHARING is not set -+# CONFIG_EXT3_FS_XATTR_USER is not set -+# CONFIG_EXT2_FS_XATTR is not set -+# CONFIG_EXT2_FS_XATTR_SHARING is not set -+# CONFIG_EXT2_FS_XATTR_USER is not set -+# CONFIG_FS_MBCACHE is not set - - # - # Code maturity level options -Index: linux-2.4.24-vanilla/arch/m68k/defconfig -=================================================================== ---- linux-2.4.24-vanilla.orig/arch/m68k/defconfig 2004-01-10 17:05:52.000000000 +0300 -+++ linux-2.4.24-vanilla/arch/m68k/defconfig 2004-01-10 17:20:28.000000000 +0300 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# CONFIG_EXT3_FS_XATTR_SHARING is not set -+# CONFIG_EXT3_FS_XATTR_USER is not set -+# CONFIG_EXT2_FS_XATTR is not set -+# CONFIG_EXT2_FS_XATTR_SHARING is not set -+# CONFIG_EXT2_FS_XATTR_USER is not set -+# CONFIG_FS_MBCACHE is not set - CONFIG_UID16=y - - # -Index: linux-2.4.24-vanilla/arch/mips/defconfig -=================================================================== ---- linux-2.4.24-vanilla.orig/arch/mips/defconfig 2004-01-10 17:04:59.000000000 +0300 -+++ linux-2.4.24-vanilla/arch/mips/defconfig 2004-01-10 17:20:28.000000000 +0300 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# CONFIG_EXT3_FS_XATTR_SHARING is not set -+# CONFIG_EXT3_FS_XATTR_USER is not set -+# CONFIG_EXT2_FS_XATTR is not set -+# CONFIG_EXT2_FS_XATTR_SHARING is not set -+# CONFIG_EXT2_FS_XATTR_USER is not set -+# CONFIG_FS_MBCACHE is not set - CONFIG_MIPS=y - CONFIG_MIPS32=y - # CONFIG_MIPS64 is not set -Index: linux-2.4.24-vanilla/arch/mips64/defconfig -=================================================================== ---- linux-2.4.24-vanilla.orig/arch/mips64/defconfig 2004-01-10 17:05:52.000000000 +0300 -+++ linux-2.4.24-vanilla/arch/mips64/defconfig 2004-01-10 17:20:28.000000000 +0300 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# CONFIG_EXT3_FS_XATTR_SHARING is not set -+# CONFIG_EXT3_FS_XATTR_USER is not set -+# CONFIG_EXT2_FS_XATTR is not set -+# CONFIG_EXT2_FS_XATTR_SHARING is not set -+# CONFIG_EXT2_FS_XATTR_USER is not set -+# CONFIG_FS_MBCACHE is not set - CONFIG_MIPS=y - # CONFIG_MIPS32 is not set - CONFIG_MIPS64=y -Index: linux-2.4.24-vanilla/arch/s390/defconfig -=================================================================== ---- linux-2.4.24-vanilla.orig/arch/s390/defconfig 2004-01-10 17:05:52.000000000 +0300 -+++ linux-2.4.24-vanilla/arch/s390/defconfig 2004-01-10 17:20:28.000000000 +0300 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# CONFIG_EXT3_FS_XATTR_SHARING is not set -+# CONFIG_EXT3_FS_XATTR_USER is not set -+# CONFIG_EXT2_FS_XATTR is not set -+# CONFIG_EXT2_FS_XATTR_SHARING is not set -+# CONFIG_EXT2_FS_XATTR_USER is not set -+# CONFIG_FS_MBCACHE is not set - # CONFIG_ISA is not set - # CONFIG_EISA is not set - # CONFIG_MCA is not set -Index: linux-2.4.24-vanilla/arch/s390/kernel/entry.S -=================================================================== ---- linux-2.4.24-vanilla.orig/arch/s390/kernel/entry.S 2004-01-10 17:04:39.000000000 +0300 -+++ linux-2.4.24-vanilla/arch/s390/kernel/entry.S 2004-01-10 17:20:28.000000000 +0300 -@@ -558,18 +558,18 @@ - .long sys_fcntl64 - .long sys_readahead - .long sys_ni_syscall -- .long sys_ni_syscall /* 224 - reserved for setxattr */ -- .long sys_ni_syscall /* 225 - reserved for lsetxattr */ -- .long sys_ni_syscall /* 226 - reserved for fsetxattr */ -- .long sys_ni_syscall /* 227 - reserved for getxattr */ -- .long sys_ni_syscall /* 228 - reserved for lgetxattr */ -- .long sys_ni_syscall /* 229 - reserved for fgetxattr */ -- .long sys_ni_syscall /* 230 - reserved for listxattr */ -- .long sys_ni_syscall /* 231 - reserved for llistxattr */ -- .long sys_ni_syscall /* 232 - reserved for flistxattr */ -- .long sys_ni_syscall /* 233 - reserved for removexattr */ -- .long sys_ni_syscall /* 234 - reserved for lremovexattr */ -- .long sys_ni_syscall /* 235 - reserved for fremovexattr */ -+ .long sys_setxattr -+ .long sys_lsetxattr /* 225 */ -+ .long sys_fsetxattr -+ .long sys_getxattr -+ .long sys_lgetxattr -+ .long sys_fgetxattr -+ .long sys_listxattr /* 230 */ -+ .long sys_llistxattr -+ .long sys_flistxattr -+ .long sys_removexattr -+ .long sys_lremovexattr -+ .long sys_fremovexattr /* 235 */ - .long sys_gettid - .long sys_tkill - .rept 255-237 -Index: linux-2.4.24-vanilla/arch/s390x/defconfig -=================================================================== ---- linux-2.4.24-vanilla.orig/arch/s390x/defconfig 2004-01-10 17:05:52.000000000 +0300 -+++ linux-2.4.24-vanilla/arch/s390x/defconfig 2004-01-10 17:20:28.000000000 +0300 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# CONFIG_EXT3_FS_XATTR_SHARING is not set -+# CONFIG_EXT3_FS_XATTR_USER is not set -+# CONFIG_EXT2_FS_XATTR is not set -+# CONFIG_EXT2_FS_XATTR_SHARING is not set -+# CONFIG_EXT2_FS_XATTR_USER is not set -+# CONFIG_FS_MBCACHE is not set - # CONFIG_ISA is not set - # CONFIG_EISA is not set - # CONFIG_MCA is not set -Index: linux-2.4.24-vanilla/arch/s390x/kernel/entry.S -=================================================================== ---- linux-2.4.24-vanilla.orig/arch/s390x/kernel/entry.S 2004-01-10 17:05:00.000000000 +0300 -+++ linux-2.4.24-vanilla/arch/s390x/kernel/entry.S 2004-01-10 17:20:28.000000000 +0300 -@@ -591,18 +591,18 @@ - .long SYSCALL(sys_ni_syscall,sys32_fcntl64_wrapper) - .long SYSCALL(sys_readahead,sys32_readahead) - .long SYSCALL(sys_ni_syscall,sys_ni_syscall) -- .long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 224 - reserved for setxattr */ -- .long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 225 - reserved for lsetxattr */ -- .long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 226 - reserved for fsetxattr */ -- .long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 227 - reserved for getxattr */ -- .long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 228 - reserved for lgetxattr */ -- .long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 229 - reserved for fgetxattr */ -- .long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 230 - reserved for listxattr */ -- .long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 231 - reserved for llistxattr */ -- .long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 232 - reserved for flistxattr */ -- .long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 233 - reserved for removexattr */ -- .long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 234 - reserved for lremovexattr */ -- .long SYSCALL(sys_ni_syscall,sys_ni_syscall) /* 235 - reserved for fremovexattr */ -+ .long SYSCALL(sys_setxattr,sys32_setxattr_wrapper) -+ .long SYSCALL(sys_lsetxattr,sys32_lsetxattr_wrapper) /* 225 */ -+ .long SYSCALL(sys_fsetxattr,sys32_fsetxattr_wrapper) -+ .long SYSCALL(sys_getxattr,sys32_getxattr_wrapper) -+ .long SYSCALL(sys_lgetxattr,sys32_lgetxattr_wrapper) -+ .long SYSCALL(sys_fgetxattr,sys32_fgetxattr_wrapper) -+ .long SYSCALL(sys_listxattr,sys32_listxattr_wrapper) /* 230 */ -+ .long SYSCALL(sys_llistxattr,sys32_llistxattr_wrapper) -+ .long SYSCALL(sys_flistxattr,sys32_flistxattr_wrapper) -+ .long SYSCALL(sys_removexattr,sys32_removexattr_wrapper) -+ .long SYSCALL(sys_lremovexattr,sys32_lremovexattr_wrapper) -+ .long SYSCALL(sys_fremovexattr,sys32_fremovexattr_wrapper)/* 235 */ - .long SYSCALL(sys_gettid,sys_gettid) - .long SYSCALL(sys_tkill,sys_tkill) - .rept 255-237 -Index: linux-2.4.24-vanilla/arch/s390x/kernel/wrapper32.S -=================================================================== ---- linux-2.4.24-vanilla.orig/arch/s390x/kernel/wrapper32.S 2004-01-10 17:05:00.000000000 +0300 -+++ linux-2.4.24-vanilla/arch/s390x/kernel/wrapper32.S 2004-01-10 17:20:28.000000000 +0300 -@@ -1098,6 +1098,98 @@ - llgfr %r4,%r4 # long - jg sys32_fstat64 # branch to system call - -+ .globl sys32_setxattr_wrapper -+sys32_setxattr_wrapper: -+ llgtr %r2,%r2 # char * -+ llgtr %r3,%r3 # char * -+ llgtr %r4,%r4 # void * -+ llgfr %r5,%r5 # size_t -+ lgfr %r6,%r6 # int -+ jg sys_setxattr -+ -+ .globl sys32_lsetxattr_wrapper -+sys32_lsetxattr_wrapper: -+ llgtr %r2,%r2 # char * -+ llgtr %r3,%r3 # char * -+ llgtr %r4,%r4 # void * -+ llgfr %r5,%r5 # size_t -+ lgfr %r6,%r6 # int -+ jg sys_lsetxattr -+ -+ .globl sys32_fsetxattr_wrapper -+sys32_fsetxattr_wrapper: -+ lgfr %r2,%r2 # int -+ llgtr %r3,%r3 # char * -+ llgtr %r4,%r4 # void * -+ llgfr %r5,%r5 # size_t -+ lgfr %r6,%r6 # int -+ jg sys_fsetxattr -+ -+ .globl sys32_getxattr_wrapper -+sys32_getxattr_wrapper: -+ llgtr %r2,%r2 # char * -+ llgtr %r3,%r3 # char * -+ llgtr %r4,%r4 # void * -+ llgfr %r5,%r5 # size_t -+ jg sys_getxattr -+ -+ .globl sys32_lgetxattr_wrapper -+sys32_lgetxattr_wrapper: -+ llgtr %r2,%r2 # char * -+ llgtr %r3,%r3 # char * -+ llgtr %r4,%r4 # void * -+ llgfr %r5,%r5 # size_t -+ jg sys_lgetxattr -+ -+ .globl sys32_fgetxattr_wrapper -+sys32_fgetxattr_wrapper: -+ lgfr %r2,%r2 # int -+ llgtr %r3,%r3 # char * -+ llgtr %r4,%r4 # void * -+ llgfr %r5,%r5 # size_t -+ jg sys_fgetxattr -+ -+ .globl sys32_listxattr_wrapper -+sys32_listxattr_wrapper: -+ llgtr %r2,%r2 # char * -+ llgtr %r3,%r3 # char * -+ llgfr %r4,%r4 # size_t -+ jg sys_listxattr -+ -+ .globl sys32_llistxattr_wrapper -+sys32_llistxattr_wrapper: -+ llgtr %r2,%r2 # char * -+ llgtr %r3,%r3 # char * -+ llgfr %r4,%r4 # size_t -+ jg sys_llistxattr -+ -+ .globl sys32_flistxattr_wrapper -+sys32_flistxattr_wrapper: -+ lgfr %r2,%r2 # int -+ llgtr %r3,%r3 # char * -+ llgfr %r4,%r4 # size_t -+ jg sys_flistxattr -+ -+ .globl sys32_removexattr_wrapper -+sys32_removexattr_wrapper: -+ llgtr %r2,%r2 # char * -+ llgtr %r3,%r3 # char * -+ jg sys_removexattr -+ -+ .globl sys32_lremovexattr_wrapper -+sys32_lremovexattr_wrapper: -+ llgtr %r2,%r2 # char * -+ llgtr %r3,%r3 # char * -+ jg sys_lremovexattr -+ -+ .globl sys32_fremovexattr_wrapper -+sys32_fremovexattr_wrapper: -+ lgfr %r2,%r2 # int -+ llgtr %r3,%r3 # char * -+ jg sys_fremovexattr -+ -+ -+ - .globl sys32_stime_wrapper - sys32_stime_wrapper: - llgtr %r2,%r2 # int * -Index: linux-2.4.24-vanilla/arch/sparc64/defconfig -=================================================================== ---- linux-2.4.24-vanilla.orig/arch/sparc64/defconfig 2004-01-10 17:05:52.000000000 +0300 -+++ linux-2.4.24-vanilla/arch/sparc64/defconfig 2004-01-10 17:20:28.000000000 +0300 -@@ -1,6 +1,13 @@ - # - # Automatically generated make config: don't edit - # -+CONFIG_EXT3_FS_XATTR=y -+# CONFIG_EXT3_FS_XATTR_SHARING is not set -+# CONFIG_EXT3_FS_XATTR_USER is not set -+# CONFIG_EXT2_FS_XATTR is not set -+# CONFIG_EXT2_FS_XATTR_SHARING is not set -+# CONFIG_EXT2_FS_XATTR_USER is not set -+# CONFIG_FS_MBCACHE is not set - - # - # Code maturity level options -Index: linux-2.4.24-vanilla/fs/Config.in -=================================================================== ---- linux-2.4.24-vanilla.orig/fs/Config.in 2004-01-10 17:05:55.000000000 +0300 -+++ linux-2.4.24-vanilla/fs/Config.in 2004-01-10 17:20:28.000000000 +0300 -@@ -29,6 +29,11 @@ - dep_tristate 'BFS file system support (EXPERIMENTAL)' CONFIG_BFS_FS $CONFIG_EXPERIMENTAL - - tristate 'Ext3 journalling file system support' CONFIG_EXT3_FS -+dep_mbool ' Ext3 extended attributes' CONFIG_EXT3_FS_XATTR $CONFIG_EXT3_FS -+dep_bool ' Ext3 extended attribute block sharing' \ -+ CONFIG_EXT3_FS_XATTR_SHARING $CONFIG_EXT3_FS_XATTR -+dep_bool ' Ext3 extended user attributes' \ -+ CONFIG_EXT3_FS_XATTR_USER $CONFIG_EXT3_FS_XATTR - # CONFIG_JBD could be its own option (even modular), but until there are - # other users than ext3, we will simply make it be the same as CONFIG_EXT3_FS - # dep_tristate ' Journal Block Device support (JBD for ext3)' CONFIG_JBD $CONFIG_EXT3_FS -@@ -92,6 +97,11 @@ - tristate 'ROM file system support' CONFIG_ROMFS_FS - - tristate 'Second extended fs support' CONFIG_EXT2_FS -+dep_mbool ' Ext2 extended attributes' CONFIG_EXT2_FS_XATTR $CONFIG_EXT2_FS -+dep_bool ' Ext2 extended attribute block sharing' \ -+ CONFIG_EXT2_FS_XATTR_SHARING $CONFIG_EXT2_FS_XATTR -+dep_bool ' Ext2 extended user attributes' \ -+ CONFIG_EXT2_FS_XATTR_USER $CONFIG_EXT2_FS_XATTR - - tristate 'System V/Xenix/V7/Coherent file system support' CONFIG_SYSV_FS - -@@ -164,6 +174,10 @@ - define_tristate CONFIG_ZISOFS_FS n - fi - -+# Meta block cache for Extended Attributes (ext2/ext3) -+#tristate 'Meta block cache' CONFIG_FS_MBCACHE -+define_tristate CONFIG_FS_MBCACHE y -+ - mainmenu_option next_comment - comment 'Partition Types' - source fs/partitions/Config.in -Index: linux-2.4.24-vanilla/fs/Makefile -=================================================================== ---- linux-2.4.24-vanilla.orig/fs/Makefile 2004-01-10 17:11:48.000000000 +0300 -+++ linux-2.4.24-vanilla/fs/Makefile 2004-01-10 17:20:28.000000000 +0300 -@@ -77,6 +77,9 @@ - - obj-$(CONFIG_BINFMT_ELF) += binfmt_elf.o - -+export-objs += mbcache.o -+obj-$(CONFIG_FS_MBCACHE) += mbcache.o -+ - # persistent filesystems - obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o)) - -Index: linux-2.4.24-vanilla/fs/ext2/Makefile -=================================================================== ---- linux-2.4.24-vanilla.orig/fs/ext2/Makefile 2001-10-11 19:05:18.000000000 +0400 -+++ linux-2.4.24-vanilla/fs/ext2/Makefile 2004-01-10 17:20:28.000000000 +0300 -@@ -13,4 +13,8 @@ - ioctl.o namei.o super.o symlink.o - obj-m := $(O_TARGET) - -+export-objs += xattr.o -+obj-$(CONFIG_EXT2_FS_XATTR) += xattr.o -+obj-$(CONFIG_EXT2_FS_XATTR_USER) += xattr_user.o -+ - include $(TOPDIR)/Rules.make -Index: linux-2.4.24-vanilla/fs/ext2/file.c -=================================================================== ---- linux-2.4.24-vanilla.orig/fs/ext2/file.c 2001-10-11 19:05:18.000000000 +0400 -+++ linux-2.4.24-vanilla/fs/ext2/file.c 2004-01-10 17:20:28.000000000 +0300 -@@ -20,6 +20,7 @@ - - #include - #include -+#include - #include - - /* -@@ -51,4 +52,8 @@ - - struct inode_operations ext2_file_inode_operations = { - truncate: ext2_truncate, -+ setxattr: ext2_setxattr, -+ getxattr: ext2_getxattr, -+ listxattr: ext2_listxattr, -+ removexattr: ext2_removexattr, - }; -Index: linux-2.4.24-vanilla/fs/ext2/ialloc.c -=================================================================== ---- linux-2.4.24-vanilla.orig/fs/ext2/ialloc.c 2004-01-10 17:04:42.000000000 +0300 -+++ linux-2.4.24-vanilla/fs/ext2/ialloc.c 2004-01-10 17:20:28.000000000 +0300 -@@ -15,6 +15,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -167,6 +168,7 @@ - */ - if (!is_bad_inode(inode)) { - /* Quota is already initialized in iput() */ -+ ext2_xattr_delete_inode(inode); - DQUOT_FREE_INODE(inode); - DQUOT_DROP(inode); - } -Index: linux-2.4.24-vanilla/fs/ext2/inode.c -=================================================================== ---- linux-2.4.24-vanilla.orig/fs/ext2/inode.c 2004-01-10 17:04:42.000000000 +0300 -+++ linux-2.4.24-vanilla/fs/ext2/inode.c 2004-01-10 17:20:28.000000000 +0300 -@@ -39,6 +39,18 @@ - static int ext2_update_inode(struct inode * inode, int do_sync); - - /* -+ * Test whether an inode is a fast symlink. -+ */ -+static inline int ext2_inode_is_fast_symlink(struct inode *inode) -+{ -+ int ea_blocks = inode->u.ext2_i.i_file_acl ? -+ (inode->i_sb->s_blocksize >> 9) : 0; -+ -+ return (S_ISLNK(inode->i_mode) && -+ inode->i_blocks - ea_blocks == 0); -+} -+ -+/* - * Called at each iput() - */ - void ext2_put_inode (struct inode * inode) -@@ -53,9 +65,7 @@ - { - lock_kernel(); - -- if (is_bad_inode(inode) || -- inode->i_ino == EXT2_ACL_IDX_INO || -- inode->i_ino == EXT2_ACL_DATA_INO) -+ if (is_bad_inode(inode)) - goto no_delete; - inode->u.ext2_i.i_dtime = CURRENT_TIME; - mark_inode_dirty(inode); -@@ -801,6 +811,8 @@ - if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || - S_ISLNK(inode->i_mode))) - return; -+ if (ext2_inode_is_fast_symlink(inode)) -+ return; - if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) - return; - -@@ -903,8 +915,7 @@ - unsigned long offset; - struct ext2_group_desc * gdp; - -- if ((inode->i_ino != EXT2_ROOT_INO && inode->i_ino != EXT2_ACL_IDX_INO && -- inode->i_ino != EXT2_ACL_DATA_INO && -+ if ((inode->i_ino != EXT2_ROOT_INO && - inode->i_ino < EXT2_FIRST_INO(inode->i_sb)) || - inode->i_ino > le32_to_cpu(inode->i_sb->u.ext2_sb.s_es->s_inodes_count)) { - ext2_error (inode->i_sb, "ext2_read_inode", -@@ -989,10 +1000,7 @@ - for (block = 0; block < EXT2_N_BLOCKS; block++) - inode->u.ext2_i.i_data[block] = raw_inode->i_block[block]; - -- if (inode->i_ino == EXT2_ACL_IDX_INO || -- inode->i_ino == EXT2_ACL_DATA_INO) -- /* Nothing to do */ ; -- else if (S_ISREG(inode->i_mode)) { -+ if (S_ISREG(inode->i_mode)) { - inode->i_op = &ext2_file_inode_operations; - inode->i_fop = &ext2_file_operations; - inode->i_mapping->a_ops = &ext2_aops; -@@ -1001,15 +1009,17 @@ - inode->i_fop = &ext2_dir_operations; - inode->i_mapping->a_ops = &ext2_aops; - } else if (S_ISLNK(inode->i_mode)) { -- if (!inode->i_blocks) -+ if (ext2_inode_is_fast_symlink(inode)) - inode->i_op = &ext2_fast_symlink_inode_operations; - else { -- inode->i_op = &page_symlink_inode_operations; -+ inode->i_op = &ext2_symlink_inode_operations; - inode->i_mapping->a_ops = &ext2_aops; - } -- } else -+ } else { -+ inode->i_op = &ext2_special_inode_operations; - init_special_inode(inode, inode->i_mode, - le32_to_cpu(raw_inode->i_block[0])); -+ } - brelse (bh); - inode->i_attr_flags = 0; - ext2_set_inode_flags(inode); -Index: linux-2.4.24-vanilla/fs/ext2/namei.c -=================================================================== ---- linux-2.4.24-vanilla.orig/fs/ext2/namei.c 2001-10-04 09:57:36.000000000 +0400 -+++ linux-2.4.24-vanilla/fs/ext2/namei.c 2004-01-10 17:20:28.000000000 +0300 -@@ -31,6 +31,7 @@ - - #include - #include -+#include - #include - - /* -@@ -136,7 +137,7 @@ - - if (l > sizeof (inode->u.ext2_i.i_data)) { - /* slow symlink */ -- inode->i_op = &page_symlink_inode_operations; -+ inode->i_op = &ext2_symlink_inode_operations; - inode->i_mapping->a_ops = &ext2_aops; - err = block_symlink(inode, symname, l); - if (err) -@@ -345,4 +346,15 @@ - rmdir: ext2_rmdir, - mknod: ext2_mknod, - rename: ext2_rename, -+ setxattr: ext2_setxattr, -+ getxattr: ext2_getxattr, -+ listxattr: ext2_listxattr, -+ removexattr: ext2_removexattr, -+}; -+ -+struct inode_operations ext2_special_inode_operations = { -+ setxattr: ext2_setxattr, -+ getxattr: ext2_getxattr, -+ listxattr: ext2_listxattr, -+ removexattr: ext2_removexattr, - }; -Index: linux-2.4.24-vanilla/fs/ext2/super.c -=================================================================== ---- linux-2.4.24-vanilla.orig/fs/ext2/super.c 2003-05-16 05:29:12.000000000 +0400 -+++ linux-2.4.24-vanilla/fs/ext2/super.c 2004-01-10 17:20:28.000000000 +0300 -@@ -21,6 +21,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -125,6 +126,7 @@ - int db_count; - int i; - -+ ext2_xattr_put_super(sb); - if (!(sb->s_flags & MS_RDONLY)) { - struct ext2_super_block *es = EXT2_SB(sb)->s_es; - -@@ -175,6 +177,13 @@ - this_char = strtok (NULL, ",")) { - if ((value = strchr (this_char, '=')) != NULL) - *value++ = 0; -+#ifdef CONFIG_EXT2_FS_XATTR_USER -+ if (!strcmp (this_char, "user_xattr")) -+ set_opt (*mount_options, XATTR_USER); -+ else if (!strcmp (this_char, "nouser_xattr")) -+ clear_opt (*mount_options, XATTR_USER); -+ else -+#endif - if (!strcmp (this_char, "bsddf")) - clear_opt (*mount_options, MINIX_DF); - else if (!strcmp (this_char, "nouid32")) { -@@ -424,6 +433,9 @@ - blocksize = BLOCK_SIZE; - - sb->u.ext2_sb.s_mount_opt = 0; -+#ifdef CONFIG_EXT2_FS_XATTR_USER -+ /* set_opt (sb->u.ext2_sb.s_mount_opt, XATTR_USER); */ -+#endif - if (!parse_options ((char *) data, &sb_block, &resuid, &resgid, - &sb->u.ext2_sb.s_mount_opt)) { - return NULL; -@@ -813,12 +825,27 @@ - - static int __init init_ext2_fs(void) - { -- return register_filesystem(&ext2_fs_type); -+ int error = init_ext2_xattr(); -+ if (error) -+ return error; -+ error = init_ext2_xattr_user(); -+ if (error) -+ goto fail; -+ error = register_filesystem(&ext2_fs_type); -+ if (!error) -+ return 0; -+ -+ exit_ext2_xattr_user(); -+fail: -+ exit_ext2_xattr(); -+ return error; - } - - static void __exit exit_ext2_fs(void) - { - unregister_filesystem(&ext2_fs_type); -+ exit_ext2_xattr_user(); -+ exit_ext2_xattr(); - } - - EXPORT_NO_SYMBOLS; -Index: linux-2.4.24-vanilla/fs/ext2/symlink.c -=================================================================== ---- linux-2.4.24-vanilla.orig/fs/ext2/symlink.c 2000-09-28 00:41:33.000000000 +0400 -+++ linux-2.4.24-vanilla/fs/ext2/symlink.c 2004-01-10 17:20:28.000000000 +0300 -@@ -19,6 +19,7 @@ - - #include - #include -+#include - - static int ext2_readlink(struct dentry *dentry, char *buffer, int buflen) - { -@@ -32,7 +33,20 @@ - return vfs_follow_link(nd, s); - } - -+struct inode_operations ext2_symlink_inode_operations = { -+ readlink: page_readlink, -+ follow_link: page_follow_link, -+ setxattr: ext2_setxattr, -+ getxattr: ext2_getxattr, -+ listxattr: ext2_listxattr, -+ removexattr: ext2_removexattr, -+}; -+ - struct inode_operations ext2_fast_symlink_inode_operations = { - readlink: ext2_readlink, - follow_link: ext2_follow_link, -+ setxattr: ext2_setxattr, -+ getxattr: ext2_getxattr, -+ listxattr: ext2_listxattr, -+ removexattr: ext2_removexattr, - }; -Index: linux-2.4.24-vanilla/fs/ext2/xattr.c -=================================================================== ---- linux-2.4.24-vanilla.orig/fs/ext2/xattr.c 2003-01-30 13:24:37.000000000 +0300 -+++ linux-2.4.24-vanilla/fs/ext2/xattr.c 2004-01-10 17:20:28.000000000 +0300 -@@ -0,0 +1,1212 @@ -+/* -+ * linux/fs/ext2/xattr.c -+ * -+ * Copyright (C) 2001 by Andreas Gruenbacher, -+ * -+ * Fix by Harrison Xing . -+ * Extended attributes for symlinks and special files added per -+ * suggestion of Luka Renko . -+ */ -+ -+/* -+ * Extended attributes are stored on disk blocks allocated outside of -+ * any inode. The i_file_acl field is then made to point to this allocated -+ * block. If all extended attributes of an inode are identical, these -+ * inodes may share the same extended attribute block. Such situations -+ * are automatically detected by keeping a cache of recent attribute block -+ * numbers and hashes over the block's contents in memory. -+ * -+ * -+ * Extended attribute block layout: -+ * -+ * +------------------+ -+ * | header | -+ * | entry 1 | | -+ * | entry 2 | | growing downwards -+ * | entry 3 | v -+ * | four null bytes | -+ * | . . . | -+ * | value 1 | ^ -+ * | value 3 | | growing upwards -+ * | value 2 | | -+ * +------------------+ -+ * -+ * The block header is followed by multiple entry descriptors. These entry -+ * descriptors are variable in size, and alligned to EXT2_XATTR_PAD -+ * byte boundaries. The entry descriptors are sorted by attribute name, -+ * so that two extended attribute blocks can be compared efficiently. -+ * -+ * Attribute values are aligned to the end of the block, stored in -+ * no specific order. They are also padded to EXT2_XATTR_PAD byte -+ * boundaries. No additional gaps are left between them. -+ * -+ * Locking strategy -+ * ---------------- -+ * The VFS already holds the BKL and the inode->i_sem semaphore when any of -+ * the xattr inode operations are called, so we are guaranteed that only one -+ * processes accesses extended attributes of an inode at any time. -+ * -+ * For writing we also grab the ext2_xattr_sem semaphore. This ensures that -+ * only a single process is modifying an extended attribute block, even -+ * if the block is shared among inodes. -+ * -+ * Note for porting to 2.5 -+ * ----------------------- -+ * The BKL will no longer be held in the xattr inode operations. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* These symbols may be needed by a module. */ -+EXPORT_SYMBOL(ext2_xattr_register); -+EXPORT_SYMBOL(ext2_xattr_unregister); -+EXPORT_SYMBOL(ext2_xattr_get); -+EXPORT_SYMBOL(ext2_xattr_list); -+EXPORT_SYMBOL(ext2_xattr_set); -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) -+# define mark_buffer_dirty(bh) mark_buffer_dirty(bh, 1) -+#endif -+ -+#define HDR(bh) ((struct ext2_xattr_header *)((bh)->b_data)) -+#define ENTRY(ptr) ((struct ext2_xattr_entry *)(ptr)) -+#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1) -+#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0) -+ -+#ifdef EXT2_XATTR_DEBUG -+# define ea_idebug(inode, f...) do { \ -+ printk(KERN_DEBUG "inode %s:%ld: ", \ -+ kdevname(inode->i_dev), inode->i_ino); \ -+ printk(f); \ -+ printk("\n"); \ -+ } while (0) -+# define ea_bdebug(bh, f...) do { \ -+ printk(KERN_DEBUG "block %s:%ld: ", \ -+ kdevname(bh->b_dev), bh->b_blocknr); \ -+ printk(f); \ -+ printk("\n"); \ -+ } while (0) -+#else -+# define ea_idebug(f...) -+# define ea_bdebug(f...) -+#endif -+ -+static int ext2_xattr_set2(struct inode *, struct buffer_head *, -+ struct ext2_xattr_header *); -+ -+#ifdef CONFIG_EXT2_FS_XATTR_SHARING -+ -+static int ext2_xattr_cache_insert(struct buffer_head *); -+static struct buffer_head *ext2_xattr_cache_find(struct inode *, -+ struct ext2_xattr_header *); -+static void ext2_xattr_cache_remove(struct buffer_head *); -+static void ext2_xattr_rehash(struct ext2_xattr_header *, -+ struct ext2_xattr_entry *); -+ -+static struct mb_cache *ext2_xattr_cache; -+ -+#else -+# define ext2_xattr_cache_insert(bh) 0 -+# define ext2_xattr_cache_find(inode, header) NULL -+# define ext2_xattr_cache_remove(bh) while(0) {} -+# define ext2_xattr_rehash(header, entry) while(0) {} -+#endif -+ -+/* -+ * If a file system does not share extended attributes among inodes, -+ * we should not need the ext2_xattr_sem semaphore. However, the -+ * filesystem may still contain shared blocks, so we always take -+ * the lock. -+ */ -+ -+DECLARE_MUTEX(ext2_xattr_sem); -+ -+static inline int -+ext2_xattr_new_block(struct inode *inode, int * errp, int force) -+{ -+ struct super_block *sb = inode->i_sb; -+ int goal = le32_to_cpu(EXT2_SB(sb)->s_es->s_first_data_block) + -+ EXT2_I(inode)->i_block_group * EXT2_BLOCKS_PER_GROUP(sb); -+ -+ /* How can we enforce the allocation? */ -+ int block = ext2_new_block(inode, goal, 0, 0, errp); -+#ifdef OLD_QUOTAS -+ if (!*errp) -+ inode->i_blocks += inode->i_sb->s_blocksize >> 9; -+#endif -+ return block; -+} -+ -+static inline int -+ext2_xattr_quota_alloc(struct inode *inode, int force) -+{ -+ /* How can we enforce the allocation? */ -+#ifdef OLD_QUOTAS -+ int error = DQUOT_ALLOC_BLOCK(inode->i_sb, inode, 1); -+ if (!error) -+ inode->i_blocks += inode->i_sb->s_blocksize >> 9; -+#else -+ int error = DQUOT_ALLOC_BLOCK(inode, 1); -+#endif -+ return error; -+} -+ -+#ifdef OLD_QUOTAS -+ -+static inline void -+ext2_xattr_quota_free(struct inode *inode) -+{ -+ DQUOT_FREE_BLOCK(inode->i_sb, inode, 1); -+ inode->i_blocks -= inode->i_sb->s_blocksize >> 9; -+} -+ -+static inline void -+ext2_xattr_free_block(struct inode * inode, unsigned long block) -+{ -+ ext2_free_blocks(inode, block, 1); -+ inode->i_blocks -= inode->i_sb->s_blocksize >> 9; -+} -+ -+#else -+# define ext2_xattr_quota_free(inode) \ -+ DQUOT_FREE_BLOCK(inode, 1) -+# define ext2_xattr_free_block(inode, block) \ -+ ext2_free_blocks(inode, block, 1) -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) -+ -+static inline struct buffer_head * -+sb_bread(struct super_block *sb, int block) -+{ -+ return bread(sb->s_dev, block, sb->s_blocksize); -+} -+ -+static inline struct buffer_head * -+sb_getblk(struct super_block *sb, int block) -+{ -+ return getblk(sb->s_dev, block, sb->s_blocksize); -+} -+ -+#endif -+ -+struct ext2_xattr_handler *ext2_xattr_handlers[EXT2_XATTR_INDEX_MAX]; -+rwlock_t ext2_handler_lock = RW_LOCK_UNLOCKED; -+ -+int -+ext2_xattr_register(int name_index, struct ext2_xattr_handler *handler) -+{ -+ int error = -EINVAL; -+ -+ if (name_index > 0 && name_index <= EXT2_XATTR_INDEX_MAX) { -+ write_lock(&ext2_handler_lock); -+ if (!ext2_xattr_handlers[name_index-1]) { -+ ext2_xattr_handlers[name_index-1] = handler; -+ error = 0; -+ } -+ write_unlock(&ext2_handler_lock); -+ } -+ return error; -+} -+ -+void -+ext2_xattr_unregister(int name_index, struct ext2_xattr_handler *handler) -+{ -+ if (name_index > 0 || name_index <= EXT2_XATTR_INDEX_MAX) { -+ write_lock(&ext2_handler_lock); -+ ext2_xattr_handlers[name_index-1] = NULL; -+ write_unlock(&ext2_handler_lock); -+ } -+} -+ -+static inline const char * -+strcmp_prefix(const char *a, const char *a_prefix) -+{ -+ while (*a_prefix && *a == *a_prefix) { -+ a++; -+ a_prefix++; -+ } -+ return *a_prefix ? NULL : a; -+} -+ -+/* -+ * Decode the extended attribute name, and translate it into -+ * the name_index and name suffix. -+ */ -+static struct ext2_xattr_handler * -+ext2_xattr_resolve_name(const char **name) -+{ -+ struct ext2_xattr_handler *handler = NULL; -+ int i; -+ -+ if (!*name) -+ return NULL; -+ read_lock(&ext2_handler_lock); -+ for (i=0; iprefix); -+ if (n) { -+ handler = ext2_xattr_handlers[i]; -+ *name = n; -+ break; -+ } -+ } -+ } -+ read_unlock(&ext2_handler_lock); -+ return handler; -+} -+ -+static inline struct ext2_xattr_handler * -+ext2_xattr_handler(int name_index) -+{ -+ struct ext2_xattr_handler *handler = NULL; -+ if (name_index > 0 && name_index <= EXT2_XATTR_INDEX_MAX) { -+ read_lock(&ext2_handler_lock); -+ handler = ext2_xattr_handlers[name_index-1]; -+ read_unlock(&ext2_handler_lock); -+ } -+ return handler; -+} -+ -+/* -+ * Inode operation getxattr() -+ * -+ * dentry->d_inode->i_sem down -+ * BKL held [before 2.5.x] -+ */ -+ssize_t -+ext2_getxattr(struct dentry *dentry, const char *name, -+ void *buffer, size_t size) -+{ -+ struct ext2_xattr_handler *handler; -+ struct inode *inode = dentry->d_inode; -+ -+ handler = ext2_xattr_resolve_name(&name); -+ if (!handler) -+ return -ENOTSUP; -+ return handler->get(inode, name, buffer, size); -+} -+ -+/* -+ * Inode operation listxattr() -+ * -+ * dentry->d_inode->i_sem down -+ * BKL held [before 2.5.x] -+ */ -+ssize_t -+ext2_listxattr(struct dentry *dentry, char *buffer, size_t size) -+{ -+ return ext2_xattr_list(dentry->d_inode, buffer, size); -+} -+ -+/* -+ * Inode operation setxattr() -+ * -+ * dentry->d_inode->i_sem down -+ * BKL held [before 2.5.x] -+ */ -+int -+ext2_setxattr(struct dentry *dentry, const char *name, -+ const void *value, size_t size, int flags) -+{ -+ struct ext2_xattr_handler *handler; -+ struct inode *inode = dentry->d_inode; -+ -+ if (size == 0) -+ value = ""; /* empty EA, do not remove */ -+ handler = ext2_xattr_resolve_name(&name); -+ if (!handler) -+ return -ENOTSUP; -+ return handler->set(inode, name, value, size, flags); -+} -+ -+/* -+ * Inode operation removexattr() -+ * -+ * dentry->d_inode->i_sem down -+ * BKL held [before 2.5.x] -+ */ -+int -+ext2_removexattr(struct dentry *dentry, const char *name) -+{ -+ struct ext2_xattr_handler *handler; -+ struct inode *inode = dentry->d_inode; -+ -+ handler = ext2_xattr_resolve_name(&name); -+ if (!handler) -+ return -ENOTSUP; -+ return handler->set(inode, name, NULL, 0, XATTR_REPLACE); -+} -+ -+/* -+ * ext2_xattr_get() -+ * -+ * Copy an extended attribute into the buffer -+ * provided, or compute the buffer size required. -+ * Buffer is NULL to compute the size of the buffer required. -+ * -+ * Returns a negative error number on failure, or the number of bytes -+ * used / required on success. -+ */ -+int -+ext2_xattr_get(struct inode *inode, int name_index, const char *name, -+ void *buffer, size_t buffer_size) -+{ -+ struct buffer_head *bh = NULL; -+ struct ext2_xattr_entry *entry; -+ unsigned int block, size; -+ char *end; -+ int name_len, error; -+ -+ ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld", -+ name_index, name, buffer, (long)buffer_size); -+ -+ if (name == NULL) -+ return -EINVAL; -+ if (!EXT2_I(inode)->i_file_acl) -+ return -ENOATTR; -+ block = EXT2_I(inode)->i_file_acl; -+ ea_idebug(inode, "reading block %d", block); -+ bh = sb_bread(inode->i_sb, block); -+ if (!bh) -+ return -EIO; -+ ea_bdebug(bh, "b_count=%d, refcount=%d", -+ atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount)); -+ end = bh->b_data + bh->b_size; -+ if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) || -+ HDR(bh)->h_blocks != cpu_to_le32(1)) { -+bad_block: ext2_error(inode->i_sb, "ext2_xattr_get", -+ "inode %ld: bad block %d", inode->i_ino, block); -+ error = -EIO; -+ goto cleanup; -+ } -+ /* find named attribute */ -+ name_len = strlen(name); -+ -+ error = -ERANGE; -+ if (name_len > 255) -+ goto cleanup; -+ entry = FIRST_ENTRY(bh); -+ while (!IS_LAST_ENTRY(entry)) { -+ struct ext2_xattr_entry *next = -+ EXT2_XATTR_NEXT(entry); -+ if ((char *)next >= end) -+ goto bad_block; -+ if (name_index == entry->e_name_index && -+ name_len == entry->e_name_len && -+ memcmp(name, entry->e_name, name_len) == 0) -+ goto found; -+ entry = next; -+ } -+ /* Check the remaining name entries */ -+ while (!IS_LAST_ENTRY(entry)) { -+ struct ext2_xattr_entry *next = -+ EXT2_XATTR_NEXT(entry); -+ if ((char *)next >= end) -+ goto bad_block; -+ entry = next; -+ } -+ if (ext2_xattr_cache_insert(bh)) -+ ea_idebug(inode, "cache insert failed"); -+ error = -ENOATTR; -+ goto cleanup; -+found: -+ /* check the buffer size */ -+ if (entry->e_value_block != 0) -+ goto bad_block; -+ size = le32_to_cpu(entry->e_value_size); -+ if (size > inode->i_sb->s_blocksize || -+ le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize) -+ goto bad_block; -+ -+ if (ext2_xattr_cache_insert(bh)) -+ ea_idebug(inode, "cache insert failed"); -+ if (buffer) { -+ error = -ERANGE; -+ if (size > buffer_size) -+ goto cleanup; -+ /* return value of attribute */ -+ memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs), -+ size); -+ } -+ error = size; -+ -+cleanup: -+ brelse(bh); -+ -+ return error; -+} -+ -+/* -+ * ext2_xattr_list() -+ * -+ * Copy a list of attribute names into the buffer -+ * provided, or compute the buffer size required. -+ * Buffer is NULL to compute the size of the buffer required. -+ * -+ * Returns a negative error number on failure, or the number of bytes -+ * used / required on success. -+ */ -+int -+ext2_xattr_list(struct inode *inode, char *buffer, size_t buffer_size) -+{ -+ struct buffer_head *bh = NULL; -+ struct ext2_xattr_entry *entry; -+ unsigned int block, size = 0; -+ char *buf, *end; -+ int error; -+ -+ ea_idebug(inode, "buffer=%p, buffer_size=%ld", -+ buffer, (long)buffer_size); -+ -+ if (!EXT2_I(inode)->i_file_acl) -+ return 0; -+ block = EXT2_I(inode)->i_file_acl; -+ ea_idebug(inode, "reading block %d", block); -+ bh = sb_bread(inode->i_sb, block); -+ if (!bh) -+ return -EIO; -+ ea_bdebug(bh, "b_count=%d, refcount=%d", -+ atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount)); -+ end = bh->b_data + bh->b_size; -+ if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) || -+ HDR(bh)->h_blocks != cpu_to_le32(1)) { -+bad_block: ext2_error(inode->i_sb, "ext2_xattr_list", -+ "inode %ld: bad block %d", inode->i_ino, block); -+ error = -EIO; -+ goto cleanup; -+ } -+ /* compute the size required for the list of attribute names */ -+ for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry); -+ entry = EXT2_XATTR_NEXT(entry)) { -+ struct ext2_xattr_handler *handler; -+ struct ext2_xattr_entry *next = -+ EXT2_XATTR_NEXT(entry); -+ if ((char *)next >= end) -+ goto bad_block; -+ -+ handler = ext2_xattr_handler(entry->e_name_index); -+ if (handler) -+ size += handler->list(NULL, inode, entry->e_name, -+ entry->e_name_len); -+ } -+ -+ if (ext2_xattr_cache_insert(bh)) -+ ea_idebug(inode, "cache insert failed"); -+ if (!buffer) { -+ error = size; -+ goto cleanup; -+ } else { -+ error = -ERANGE; -+ if (size > buffer_size) -+ goto cleanup; -+ } -+ -+ /* list the attribute names */ -+ buf = buffer; -+ for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry); -+ entry = EXT2_XATTR_NEXT(entry)) { -+ struct ext2_xattr_handler *handler; -+ -+ handler = ext2_xattr_handler(entry->e_name_index); -+ if (handler) -+ buf += handler->list(buf, inode, entry->e_name, -+ entry->e_name_len); -+ } -+ error = size; -+ -+cleanup: -+ brelse(bh); -+ -+ return error; -+} -+ -+/* -+ * If the EXT2_FEATURE_COMPAT_EXT_ATTR feature of this file system is -+ * not set, set it. -+ */ -+static void ext2_xattr_update_super_block(struct super_block *sb) -+{ -+ if (EXT2_HAS_COMPAT_FEATURE(sb, EXT2_FEATURE_COMPAT_EXT_ATTR)) -+ return; -+ -+ lock_super(sb); -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) -+ EXT2_SB(sb)->s_feature_compat |= EXT2_FEATURE_COMPAT_EXT_ATTR; -+#endif -+ EXT2_SB(sb)->s_es->s_feature_compat |= -+ cpu_to_le32(EXT2_FEATURE_COMPAT_EXT_ATTR); -+ sb->s_dirt = 1; -+ mark_buffer_dirty(EXT2_SB(sb)->s_sbh); -+ unlock_super(sb); -+} -+ -+/* -+ * ext2_xattr_set() -+ * -+ * Create, replace or remove an extended attribute for this inode. Buffer -+ * is NULL to remove an existing extended attribute, and non-NULL to -+ * either replace an existing extended attribute, or create a new extended -+ * attribute. The flags XATTR_REPLACE and XATTR_CREATE -+ * specify that an extended attribute must exist and must not exist -+ * previous to the call, respectively. -+ * -+ * Returns 0, or a negative error number on failure. -+ */ -+int -+ext2_xattr_set(struct inode *inode, int name_index, const char *name, -+ const void *value, size_t value_len, int flags) -+{ -+ struct super_block *sb = inode->i_sb; -+ struct buffer_head *bh = NULL; -+ struct ext2_xattr_header *header = NULL; -+ struct ext2_xattr_entry *here, *last; -+ unsigned int name_len; -+ int block = EXT2_I(inode)->i_file_acl; -+ int min_offs = sb->s_blocksize, not_found = 1, free, error; -+ char *end; -+ -+ /* -+ * header -- Points either into bh, or to a temporarily -+ * allocated buffer. -+ * here -- The named entry found, or the place for inserting, within -+ * the block pointed to by header. -+ * last -- Points right after the last named entry within the block -+ * pointed to by header. -+ * min_offs -- The offset of the first value (values are aligned -+ * towards the end of the block). -+ * end -- Points right after the block pointed to by header. -+ */ -+ -+ ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld", -+ name_index, name, value, (long)value_len); -+ -+ if (IS_RDONLY(inode)) -+ return -EROFS; -+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) -+ return -EPERM; -+ if (value == NULL) -+ value_len = 0; -+ if (name == NULL) -+ return -EINVAL; -+ name_len = strlen(name); -+ if (name_len > 255 || value_len > sb->s_blocksize) -+ return -ERANGE; -+ down(&ext2_xattr_sem); -+ -+ if (block) { -+ /* The inode already has an extended attribute block. */ -+ -+ bh = sb_bread(sb, block); -+ error = -EIO; -+ if (!bh) -+ goto cleanup; -+ ea_bdebug(bh, "b_count=%d, refcount=%d", -+ atomic_read(&(bh->b_count)), -+ le32_to_cpu(HDR(bh)->h_refcount)); -+ header = HDR(bh); -+ end = bh->b_data + bh->b_size; -+ if (header->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) || -+ header->h_blocks != cpu_to_le32(1)) { -+bad_block: ext2_error(sb, "ext2_xattr_set", -+ "inode %ld: bad block %d", inode->i_ino, block); -+ error = -EIO; -+ goto cleanup; -+ } -+ /* Find the named attribute. */ -+ here = FIRST_ENTRY(bh); -+ while (!IS_LAST_ENTRY(here)) { -+ struct ext2_xattr_entry *next = EXT2_XATTR_NEXT(here); -+ if ((char *)next >= end) -+ goto bad_block; -+ if (!here->e_value_block && here->e_value_size) { -+ int offs = le16_to_cpu(here->e_value_offs); -+ if (offs < min_offs) -+ min_offs = offs; -+ } -+ not_found = name_index - here->e_name_index; -+ if (!not_found) -+ not_found = name_len - here->e_name_len; -+ if (!not_found) -+ not_found = memcmp(name, here->e_name,name_len); -+ if (not_found <= 0) -+ break; -+ here = next; -+ } -+ last = here; -+ /* We still need to compute min_offs and last. */ -+ while (!IS_LAST_ENTRY(last)) { -+ struct ext2_xattr_entry *next = EXT2_XATTR_NEXT(last); -+ if ((char *)next >= end) -+ goto bad_block; -+ if (!last->e_value_block && last->e_value_size) { -+ int offs = le16_to_cpu(last->e_value_offs); -+ if (offs < min_offs) -+ min_offs = offs; -+ } -+ last = next; -+ } -+ -+ /* Check whether we have enough space left. */ -+ free = min_offs - ((char*)last - (char*)header) - sizeof(__u32); -+ } else { -+ /* We will use a new extended attribute block. */ -+ free = sb->s_blocksize - -+ sizeof(struct ext2_xattr_header) - sizeof(__u32); -+ here = last = NULL; /* avoid gcc uninitialized warning. */ -+ } -+ -+ if (not_found) { -+ /* Request to remove a nonexistent attribute? */ -+ error = -ENOATTR; -+ if (flags & XATTR_REPLACE) -+ goto cleanup; -+ error = 0; -+ if (value == NULL) -+ goto cleanup; -+ else -+ free -= EXT2_XATTR_LEN(name_len); -+ } else { -+ /* Request to create an existing attribute? */ -+ error = -EEXIST; -+ if (flags & XATTR_CREATE) -+ goto cleanup; -+ if (!here->e_value_block && here->e_value_size) { -+ unsigned int size = le32_to_cpu(here->e_value_size); -+ -+ if (le16_to_cpu(here->e_value_offs) + size > -+ sb->s_blocksize || size > sb->s_blocksize) -+ goto bad_block; -+ free += EXT2_XATTR_SIZE(size); -+ } -+ } -+ free -= EXT2_XATTR_SIZE(value_len); -+ error = -ENOSPC; -+ if (free < 0) -+ goto cleanup; -+ -+ /* Here we know that we can set the new attribute. */ -+ -+ if (header) { -+ if (header->h_refcount == cpu_to_le32(1)) { -+ ea_bdebug(bh, "modifying in-place"); -+ ext2_xattr_cache_remove(bh); -+ } else { -+ int offset; -+ -+ ea_bdebug(bh, "cloning"); -+ header = kmalloc(bh->b_size, GFP_KERNEL); -+ error = -ENOMEM; -+ if (header == NULL) -+ goto cleanup; -+ memcpy(header, HDR(bh), bh->b_size); -+ header->h_refcount = cpu_to_le32(1); -+ offset = (char *)header - bh->b_data; -+ here = ENTRY((char *)here + offset); -+ last = ENTRY((char *)last + offset); -+ } -+ } else { -+ /* Allocate a buffer where we construct the new block. */ -+ header = kmalloc(sb->s_blocksize, GFP_KERNEL); -+ error = -ENOMEM; -+ if (header == NULL) -+ goto cleanup; -+ memset(header, 0, sb->s_blocksize); -+ end = (char *)header + sb->s_blocksize; -+ header->h_magic = cpu_to_le32(EXT2_XATTR_MAGIC); -+ header->h_blocks = header->h_refcount = cpu_to_le32(1); -+ last = here = ENTRY(header+1); -+ } -+ -+ if (not_found) { -+ /* Insert the new name. */ -+ int size = EXT2_XATTR_LEN(name_len); -+ int rest = (char *)last - (char *)here; -+ memmove((char *)here + size, here, rest); -+ memset(here, 0, size); -+ here->e_name_index = name_index; -+ here->e_name_len = name_len; -+ memcpy(here->e_name, name, name_len); -+ } else { -+ /* Remove the old value. */ -+ if (!here->e_value_block && here->e_value_size) { -+ char *first_val = (char *)header + min_offs; -+ int offs = le16_to_cpu(here->e_value_offs); -+ char *val = (char *)header + offs; -+ size_t size = EXT2_XATTR_SIZE( -+ le32_to_cpu(here->e_value_size)); -+ memmove(first_val + size, first_val, val - first_val); -+ memset(first_val, 0, size); -+ here->e_value_offs = 0; -+ min_offs += size; -+ -+ /* Adjust all value offsets. */ -+ last = ENTRY(header+1); -+ while (!IS_LAST_ENTRY(last)) { -+ int o = le16_to_cpu(last->e_value_offs); -+ if (!last->e_value_block && o < offs) -+ last->e_value_offs = -+ cpu_to_le16(o + size); -+ last = EXT2_XATTR_NEXT(last); -+ } -+ } -+ if (value == NULL) { -+ /* Remove this attribute. */ -+ if (EXT2_XATTR_NEXT(ENTRY(header+1)) == last) { -+ /* This block is now empty. */ -+ error = ext2_xattr_set2(inode, bh, NULL); -+ goto cleanup; -+ } else { -+ /* Remove the old name. */ -+ int size = EXT2_XATTR_LEN(name_len); -+ last = ENTRY((char *)last - size); -+ memmove(here, (char*)here + size, -+ (char*)last - (char*)here); -+ memset(last, 0, size); -+ } -+ } -+ } -+ -+ if (value != NULL) { -+ /* Insert the new value. */ -+ here->e_value_size = cpu_to_le32(value_len); -+ if (value_len) { -+ size_t size = EXT2_XATTR_SIZE(value_len); -+ char *val = (char *)header + min_offs - size; -+ here->e_value_offs = -+ cpu_to_le16((char *)val - (char *)header); -+ memset(val + size - EXT2_XATTR_PAD, 0, -+ EXT2_XATTR_PAD); /* Clear the pad bytes. */ -+ memcpy(val, value, value_len); -+ } -+ } -+ ext2_xattr_rehash(header, here); -+ -+ error = ext2_xattr_set2(inode, bh, header); -+ -+cleanup: -+ brelse(bh); -+ if (!(bh && header == HDR(bh))) -+ kfree(header); -+ up(&ext2_xattr_sem); -+ -+ return error; -+} -+ -+/* -+ * Second half of ext2_xattr_set(): Update the file system. -+ */ -+static int -+ext2_xattr_set2(struct inode *inode, struct buffer_head *old_bh, -+ struct ext2_xattr_header *header) -+{ -+ struct super_block *sb = inode->i_sb; -+ struct buffer_head *new_bh = NULL; -+ int error; -+ -+ if (header) { -+ new_bh = ext2_xattr_cache_find(inode, header); -+ if (new_bh) { -+ /* -+ * We found an identical block in the cache. -+ * The old block will be released after updating -+ * the inode. -+ */ -+ ea_bdebug(old_bh, "reusing block %ld", -+ new_bh->b_blocknr); -+ -+ error = -EDQUOT; -+ if (ext2_xattr_quota_alloc(inode, 1)) -+ goto cleanup; -+ -+ HDR(new_bh)->h_refcount = cpu_to_le32( -+ le32_to_cpu(HDR(new_bh)->h_refcount) + 1); -+ ea_bdebug(new_bh, "refcount now=%d", -+ le32_to_cpu(HDR(new_bh)->h_refcount)); -+ } else if (old_bh && header == HDR(old_bh)) { -+ /* Keep this block. */ -+ new_bh = old_bh; -+ (void)ext2_xattr_cache_insert(new_bh); -+ } else { -+ /* We need to allocate a new block */ -+ int force = EXT2_I(inode)->i_file_acl != 0; -+ int block = ext2_xattr_new_block(inode, &error, force); -+ if (error) -+ goto cleanup; -+ ea_idebug(inode, "creating block %d", block); -+ -+ new_bh = sb_getblk(sb, block); -+ if (!new_bh) { -+ ext2_xattr_free_block(inode, block); -+ error = -EIO; -+ goto cleanup; -+ } -+ lock_buffer(new_bh); -+ memcpy(new_bh->b_data, header, new_bh->b_size); -+ mark_buffer_uptodate(new_bh, 1); -+ unlock_buffer(new_bh); -+ (void)ext2_xattr_cache_insert(new_bh); -+ -+ ext2_xattr_update_super_block(sb); -+ } -+ mark_buffer_dirty(new_bh); -+ if (IS_SYNC(inode)) { -+ ll_rw_block(WRITE, 1, &new_bh); -+ wait_on_buffer(new_bh); -+ error = -EIO; -+ if (buffer_req(new_bh) && !buffer_uptodate(new_bh)) -+ goto cleanup; -+ } -+ } -+ -+ /* Update the inode. */ -+ EXT2_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0; -+ inode->i_ctime = CURRENT_TIME; -+ if (IS_SYNC(inode)) { -+ error = ext2_sync_inode (inode); -+ if (error) -+ goto cleanup; -+ } else -+ mark_inode_dirty(inode); -+ -+ error = 0; -+ if (old_bh && old_bh != new_bh) { -+ /* -+ * If there was an old block, and we are not still using it, -+ * we now release the old block. -+ */ -+ unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount); -+ -+ if (refcount == 1) { -+ /* Free the old block. */ -+ ea_bdebug(old_bh, "freeing"); -+ ext2_xattr_free_block(inode, old_bh->b_blocknr); -+ mark_buffer_clean(old_bh); -+ } else { -+ /* Decrement the refcount only. */ -+ refcount--; -+ HDR(old_bh)->h_refcount = cpu_to_le32(refcount); -+ ext2_xattr_quota_free(inode); -+ mark_buffer_dirty(old_bh); -+ ea_bdebug(old_bh, "refcount now=%d", refcount); -+ } -+ } -+ -+cleanup: -+ if (old_bh != new_bh) -+ brelse(new_bh); -+ -+ return error; -+} -+ -+/* -+ * ext2_xattr_delete_inode() -+ * -+ * Free extended attribute resources associated with this inode. This -+ * is called immediately before an inode is freed. -+ */ -+void -+ext2_xattr_delete_inode(struct inode *inode) -+{ -+ struct buffer_head *bh; -+ unsigned int block = EXT2_I(inode)->i_file_acl; -+ -+ if (!block) -+ return; -+ down(&ext2_xattr_sem); -+ -+ bh = sb_bread(inode->i_sb, block); -+ if (!bh) { -+ ext2_error(inode->i_sb, "ext2_xattr_delete_inode", -+ "inode %ld: block %d read error", inode->i_ino, block); -+ goto cleanup; -+ } -+ ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count))); -+ if (HDR(bh)->h_magic != cpu_to_le32(EXT2_XATTR_MAGIC) || -+ HDR(bh)->h_blocks != cpu_to_le32(1)) { -+ ext2_error(inode->i_sb, "ext2_xattr_delete_inode", -+ "inode %ld: bad block %d", inode->i_ino, block); -+ goto cleanup; -+ } -+ ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1); -+ if (HDR(bh)->h_refcount == cpu_to_le32(1)) { -+ ext2_xattr_cache_remove(bh); -+ ext2_xattr_free_block(inode, block); -+ bforget(bh); -+ bh = NULL; -+ } else { -+ HDR(bh)->h_refcount = cpu_to_le32( -+ le32_to_cpu(HDR(bh)->h_refcount) - 1); -+ mark_buffer_dirty(bh); -+ if (IS_SYNC(inode)) { -+ ll_rw_block(WRITE, 1, &bh); -+ wait_on_buffer(bh); -+ } -+ ext2_xattr_quota_free(inode); -+ } -+ EXT2_I(inode)->i_file_acl = 0; -+ -+cleanup: -+ brelse(bh); -+ up(&ext2_xattr_sem); -+} -+ -+/* -+ * ext2_xattr_put_super() -+ * -+ * This is called when a file system is unmounted. -+ */ -+void -+ext2_xattr_put_super(struct super_block *sb) -+{ -+#ifdef CONFIG_EXT2_FS_XATTR_SHARING -+ mb_cache_shrink(ext2_xattr_cache, sb->s_dev); -+#endif -+} -+ -+#ifdef CONFIG_EXT2_FS_XATTR_SHARING -+ -+/* -+ * ext2_xattr_cache_insert() -+ * -+ * Create a new entry in the extended attribute cache, and insert -+ * it unless such an entry is already in the cache. -+ * -+ * Returns 0, or a negative error number on failure. -+ */ -+static int -+ext2_xattr_cache_insert(struct buffer_head *bh) -+{ -+ __u32 hash = le32_to_cpu(HDR(bh)->h_hash); -+ struct mb_cache_entry *ce; -+ int error; -+ -+ ce = mb_cache_entry_alloc(ext2_xattr_cache); -+ if (!ce) -+ return -ENOMEM; -+ error = mb_cache_entry_insert(ce, bh->b_dev, bh->b_blocknr, &hash); -+ if (error) { -+ mb_cache_entry_free(ce); -+ if (error == -EBUSY) { -+ ea_bdebug(bh, "already in cache (%d cache entries)", -+ atomic_read(&ext2_xattr_cache->c_entry_count)); -+ error = 0; -+ } -+ } else { -+ ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash, -+ atomic_read(&ext2_xattr_cache->c_entry_count)); -+ mb_cache_entry_release(ce); -+ } -+ return error; -+} -+ -+/* -+ * ext2_xattr_cmp() -+ * -+ * Compare two extended attribute blocks for equality. -+ * -+ * Returns 0 if the blocks are equal, 1 if they differ, and -+ * a negative error number on errors. -+ */ -+static int -+ext2_xattr_cmp(struct ext2_xattr_header *header1, -+ struct ext2_xattr_header *header2) -+{ -+ struct ext2_xattr_entry *entry1, *entry2; -+ -+ entry1 = ENTRY(header1+1); -+ entry2 = ENTRY(header2+1); -+ while (!IS_LAST_ENTRY(entry1)) { -+ if (IS_LAST_ENTRY(entry2)) -+ return 1; -+ if (entry1->e_hash != entry2->e_hash || -+ entry1->e_name_len != entry2->e_name_len || -+ entry1->e_value_size != entry2->e_value_size || -+ memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len)) -+ return 1; -+ if (entry1->e_value_block != 0 || entry2->e_value_block != 0) -+ return -EIO; -+ if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs), -+ (char *)header2 + le16_to_cpu(entry2->e_value_offs), -+ le32_to_cpu(entry1->e_value_size))) -+ return 1; -+ -+ entry1 = EXT2_XATTR_NEXT(entry1); -+ entry2 = EXT2_XATTR_NEXT(entry2); -+ } -+ if (!IS_LAST_ENTRY(entry2)) -+ return 1; -+ return 0; -+} -+ -+/* -+ * ext2_xattr_cache_find() -+ * -+ * Find an identical extended attribute block. -+ * -+ * Returns a pointer to the block found, or NULL if such a block was -+ * not found or an error occurred. -+ */ -+static struct buffer_head * -+ext2_xattr_cache_find(struct inode *inode, struct ext2_xattr_header *header) -+{ -+ __u32 hash = le32_to_cpu(header->h_hash); -+ struct mb_cache_entry *ce; -+ -+ if (!header->h_hash) -+ return NULL; /* never share */ -+ ea_idebug(inode, "looking for cached blocks [%x]", (int)hash); -+ ce = mb_cache_entry_find_first(ext2_xattr_cache, 0, inode->i_dev, hash); -+ while (ce) { -+ struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block); -+ -+ if (!bh) { -+ ext2_error(inode->i_sb, "ext2_xattr_cache_find", -+ "inode %ld: block %ld read error", -+ inode->i_ino, ce->e_block); -+ } else if (le32_to_cpu(HDR(bh)->h_refcount) > -+ EXT2_XATTR_REFCOUNT_MAX) { -+ ea_idebug(inode, "block %ld refcount %d>%d",ce->e_block, -+ le32_to_cpu(HDR(bh)->h_refcount), -+ EXT2_XATTR_REFCOUNT_MAX); -+ } else if (!ext2_xattr_cmp(header, HDR(bh))) { -+ ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count))); -+ mb_cache_entry_release(ce); -+ return bh; -+ } -+ brelse(bh); -+ ce = mb_cache_entry_find_next(ce, 0, inode->i_dev, hash); -+ } -+ return NULL; -+} -+ -+/* -+ * ext2_xattr_cache_remove() -+ * -+ * Remove the cache entry of a block from the cache. Called when a -+ * block becomes invalid. -+ */ -+static void -+ext2_xattr_cache_remove(struct buffer_head *bh) -+{ -+ struct mb_cache_entry *ce; -+ -+ ce = mb_cache_entry_get(ext2_xattr_cache, bh->b_dev, bh->b_blocknr); -+ if (ce) { -+ ea_bdebug(bh, "removing (%d cache entries remaining)", -+ atomic_read(&ext2_xattr_cache->c_entry_count)-1); -+ mb_cache_entry_free(ce); -+ } else -+ ea_bdebug(bh, "no cache entry"); -+} -+ -+#define NAME_HASH_SHIFT 5 -+#define VALUE_HASH_SHIFT 16 -+ -+/* -+ * ext2_xattr_hash_entry() -+ * -+ * Compute the hash of an extended attribute. -+ */ -+static inline void ext2_xattr_hash_entry(struct ext2_xattr_header *header, -+ struct ext2_xattr_entry *entry) -+{ -+ __u32 hash = 0; -+ char *name = entry->e_name; -+ int n; -+ -+ for (n=0; n < entry->e_name_len; n++) { -+ hash = (hash << NAME_HASH_SHIFT) ^ -+ (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^ -+ *name++; -+ } -+ -+ if (entry->e_value_block == 0 && entry->e_value_size != 0) { -+ __u32 *value = (__u32 *)((char *)header + -+ le16_to_cpu(entry->e_value_offs)); -+ for (n = (le32_to_cpu(entry->e_value_size) + -+ EXT2_XATTR_ROUND) >> EXT2_XATTR_PAD_BITS; n; n--) { -+ hash = (hash << VALUE_HASH_SHIFT) ^ -+ (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^ -+ le32_to_cpu(*value++); -+ } -+ } -+ entry->e_hash = cpu_to_le32(hash); -+} -+ -+#undef NAME_HASH_SHIFT -+#undef VALUE_HASH_SHIFT -+ -+#define BLOCK_HASH_SHIFT 16 -+ -+/* -+ * ext2_xattr_rehash() -+ * -+ * Re-compute the extended attribute hash value after an entry has changed. -+ */ -+static void ext2_xattr_rehash(struct ext2_xattr_header *header, -+ struct ext2_xattr_entry *entry) -+{ -+ struct ext2_xattr_entry *here; -+ __u32 hash = 0; -+ -+ ext2_xattr_hash_entry(header, entry); -+ here = ENTRY(header+1); -+ while (!IS_LAST_ENTRY(here)) { -+ if (!here->e_hash) { -+ /* Block is not shared if an entry's hash value == 0 */ -+ hash = 0; -+ break; -+ } -+ hash = (hash << BLOCK_HASH_SHIFT) ^ -+ (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^ -+ le32_to_cpu(here->e_hash); -+ here = EXT2_XATTR_NEXT(here); -+ } -+ header->h_hash = cpu_to_le32(hash); -+} -+ -+#undef BLOCK_HASH_SHIFT -+ -+int __init -+init_ext2_xattr(void) -+{ -+ ext2_xattr_cache = mb_cache_create("ext2_xattr", NULL, -+ sizeof(struct mb_cache_entry) + -+ sizeof(struct mb_cache_entry_index), 1, 61); -+ if (!ext2_xattr_cache) -+ return -ENOMEM; -+ -+ return 0; -+} -+ -+void -+exit_ext2_xattr(void) -+{ -+ mb_cache_destroy(ext2_xattr_cache); -+} -+ -+#else /* CONFIG_EXT2_FS_XATTR_SHARING */ -+ -+int __init -+init_ext2_xattr(void) -+{ -+ return 0; -+} -+ -+void -+exit_ext2_xattr(void) -+{ -+} -+ -+#endif /* CONFIG_EXT2_FS_XATTR_SHARING */ -Index: linux-2.4.24-vanilla/fs/ext2/xattr_user.c -=================================================================== ---- linux-2.4.24-vanilla.orig/fs/ext2/xattr_user.c 2003-01-30 13:24:37.000000000 +0300 -+++ linux-2.4.24-vanilla/fs/ext2/xattr_user.c 2004-01-10 17:20:28.000000000 +0300 -@@ -0,0 +1,103 @@ -+/* -+ * linux/fs/ext2/xattr_user.c -+ * Handler for extended user attributes. -+ * -+ * Copyright (C) 2001 by Andreas Gruenbacher, -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_EXT2_FS_POSIX_ACL -+# include -+#endif -+ -+#define XATTR_USER_PREFIX "user." -+ -+static size_t -+ext2_xattr_user_list(char *list, struct inode *inode, -+ const char *name, int name_len) -+{ -+ const int prefix_len = sizeof(XATTR_USER_PREFIX)-1; -+ -+ if (!test_opt(inode->i_sb, XATTR_USER)) -+ return 0; -+ -+ if (list) { -+ memcpy(list, XATTR_USER_PREFIX, prefix_len); -+ memcpy(list+prefix_len, name, name_len); -+ list[prefix_len + name_len] = '\0'; -+ } -+ return prefix_len + name_len + 1; -+} -+ -+static int -+ext2_xattr_user_get(struct inode *inode, const char *name, -+ void *buffer, size_t size) -+{ -+ int error; -+ -+ if (strcmp(name, "") == 0) -+ return -EINVAL; -+ if (!test_opt(inode->i_sb, XATTR_USER)) -+ return -ENOTSUP; -+#ifdef CONFIG_EXT2_FS_POSIX_ACL -+ error = ext2_permission_locked(inode, MAY_READ); -+#else -+ error = permission(inode, MAY_READ); -+#endif -+ if (error) -+ return error; -+ -+ return ext2_xattr_get(inode, EXT2_XATTR_INDEX_USER, name, -+ buffer, size); -+} -+ -+static int -+ext2_xattr_user_set(struct inode *inode, const char *name, -+ const void *value, size_t size, int flags) -+{ -+ int error; -+ -+ if (strcmp(name, "") == 0) -+ return -EINVAL; -+ if (!test_opt(inode->i_sb, XATTR_USER)) -+ return -ENOTSUP; -+ if ( !S_ISREG(inode->i_mode) && -+ (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX)) -+ return -EPERM; -+#ifdef CONFIG_EXT2_FS_POSIX_ACL -+ error = ext2_permission_locked(inode, MAY_WRITE); -+#else -+ error = permission(inode, MAY_WRITE); -+#endif -+ if (error) -+ return error; -+ -+ return ext2_xattr_set(inode, EXT2_XATTR_INDEX_USER, name, -+ value, size, flags); -+} -+ -+struct ext2_xattr_handler ext2_xattr_user_handler = { -+ prefix: XATTR_USER_PREFIX, -+ list: ext2_xattr_user_list, -+ get: ext2_xattr_user_get, -+ set: ext2_xattr_user_set, -+}; -+ -+int __init -+init_ext2_xattr_user(void) -+{ -+ return ext2_xattr_register(EXT2_XATTR_INDEX_USER, -+ &ext2_xattr_user_handler); -+} -+ -+void -+exit_ext2_xattr_user(void) -+{ -+ ext2_xattr_unregister(EXT2_XATTR_INDEX_USER, -+ &ext2_xattr_user_handler); -+} -Index: linux-2.4.24-vanilla/fs/ext3/Makefile -=================================================================== ---- linux-2.4.24-vanilla.orig/fs/ext3/Makefile 2004-01-10 17:11:50.000000000 +0300 -+++ linux-2.4.24-vanilla/fs/ext3/Makefile 2004-01-10 17:20:28.000000000 +0300 -@@ -1,5 +1,5 @@ - # --# Makefile for the linux ext2-filesystem routines. -+# Makefile for the linux ext3-filesystem routines. - # - # Note! Dependencies are done automagically by 'make dep', which also - # removes any old dependencies. DON'T put your own dependencies here -@@ -9,10 +9,14 @@ - - O_TARGET := ext3.o - --export-objs := super.o inode.o -+export-objs := ext3-exports.o - - obj-y := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o \ -- ioctl.o namei.o super.o symlink.o hash.o -+ ioctl.o namei.o super.o symlink.o hash.o ext3-exports.o - obj-m := $(O_TARGET) - -+export-objs += xattr.o -+obj-$(CONFIG_EXT3_FS_XATTR) += xattr.o -+obj-$(CONFIG_EXT3_FS_XATTR_USER) += xattr_user.o -+ - include $(TOPDIR)/Rules.make -Index: linux-2.4.24-vanilla/fs/ext3/file.c -=================================================================== ---- linux-2.4.24-vanilla.orig/fs/ext3/file.c 2004-01-10 17:11:50.000000000 +0300 -+++ linux-2.4.24-vanilla/fs/ext3/file.c 2004-01-10 17:20:28.000000000 +0300 -@@ -23,6 +23,7 @@ - #include - #include - #include -+#include - #include - #include - -@@ -127,5 +128,9 @@ - struct inode_operations ext3_file_inode_operations = { - truncate: ext3_truncate, /* BKL held */ - setattr: ext3_setattr, /* BKL held */ -+ setxattr: ext3_setxattr, /* BKL held */ -+ getxattr: ext3_getxattr, /* BKL held */ -+ listxattr: ext3_listxattr, /* BKL held */ -+ removexattr: ext3_removexattr, /* BKL held */ - }; - -Index: linux-2.4.24-vanilla/fs/ext3/ialloc.c -=================================================================== ---- linux-2.4.24-vanilla.orig/fs/ext3/ialloc.c 2004-01-10 17:04:42.000000000 +0300 -+++ linux-2.4.24-vanilla/fs/ext3/ialloc.c 2004-01-10 17:20:28.000000000 +0300 -@@ -17,6 +17,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -216,6 +217,7 @@ - * as writing the quota to disk may need the lock as well. - */ - DQUOT_INIT(inode); -+ ext3_xattr_delete_inode(handle, inode); - DQUOT_FREE_INODE(inode); - DQUOT_DROP(inode); - -Index: linux-2.4.24-vanilla/fs/ext3/inode.c -=================================================================== ---- linux-2.4.24-vanilla.orig/fs/ext3/inode.c 2004-01-10 17:05:05.000000000 +0300 -+++ linux-2.4.24-vanilla/fs/ext3/inode.c 2004-01-10 17:20:28.000000000 +0300 -@@ -39,6 +39,18 @@ - */ - #undef SEARCH_FROM_ZERO - -+/* -+ * Test whether an inode is a fast symlink. -+ */ -+static inline int ext3_inode_is_fast_symlink(struct inode *inode) -+{ -+ int ea_blocks = inode->u.ext3_i.i_file_acl ? -+ (inode->i_sb->s_blocksize >> 9) : 0; -+ -+ return (S_ISLNK(inode->i_mode) && -+ inode->i_blocks - ea_blocks == 0); -+} -+ - /* The ext3 forget function must perform a revoke if we are freeing data - * which has been journaled. Metadata (eg. indirect blocks) must be - * revoked in all cases. -@@ -48,7 +60,7 @@ - * still needs to be revoked. - */ - --static int ext3_forget(handle_t *handle, int is_metadata, -+int ext3_forget(handle_t *handle, int is_metadata, - struct inode *inode, struct buffer_head *bh, - int blocknr) - { -@@ -179,9 +191,7 @@ - { - handle_t *handle; - -- if (is_bad_inode(inode) || -- inode->i_ino == EXT3_ACL_IDX_INO || -- inode->i_ino == EXT3_ACL_DATA_INO) -+ if (is_bad_inode(inode)) - goto no_delete; - - lock_kernel(); -@@ -1870,6 +1880,8 @@ - if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || - S_ISLNK(inode->i_mode))) - return; -+ if (ext3_inode_is_fast_symlink(inode)) -+ return; - if (IS_APPEND(inode) || IS_IMMUTABLE(inode)) - return; - -@@ -2017,8 +2029,6 @@ - struct ext3_group_desc * gdp; - - if ((inode->i_ino != EXT3_ROOT_INO && -- inode->i_ino != EXT3_ACL_IDX_INO && -- inode->i_ino != EXT3_ACL_DATA_INO && - inode->i_ino != EXT3_JOURNAL_INO && - inode->i_ino < EXT3_FIRST_INO(inode->i_sb)) || - inode->i_ino > le32_to_cpu( -@@ -2159,10 +2169,7 @@ - inode->u.ext3_i.i_data[block] = iloc.raw_inode->i_block[block]; - INIT_LIST_HEAD(&inode->u.ext3_i.i_orphan); - -- if (inode->i_ino == EXT3_ACL_IDX_INO || -- inode->i_ino == EXT3_ACL_DATA_INO) -- /* Nothing to do */ ; -- else if (S_ISREG(inode->i_mode)) { -+ if (S_ISREG(inode->i_mode)) { - inode->i_op = &ext3_file_inode_operations; - inode->i_fop = &ext3_file_operations; - inode->i_mapping->a_ops = &ext3_aops; -@@ -2170,15 +2177,17 @@ - inode->i_op = &ext3_dir_inode_operations; - inode->i_fop = &ext3_dir_operations; - } else if (S_ISLNK(inode->i_mode)) { -- if (!inode->i_blocks) -+ if (ext3_inode_is_fast_symlink(inode)) - inode->i_op = &ext3_fast_symlink_inode_operations; - else { -- inode->i_op = &page_symlink_inode_operations; -+ inode->i_op = &ext3_symlink_inode_operations; - inode->i_mapping->a_ops = &ext3_aops; - } -- } else -+ } else { -+ inode->i_op = &ext3_special_inode_operations; - init_special_inode(inode, inode->i_mode, - le32_to_cpu(iloc.raw_inode->i_block[0])); -+ } - brelse(iloc.bh); - ext3_set_inode_flags(inode); - return; -Index: linux-2.4.24-vanilla/fs/ext3/namei.c -=================================================================== ---- linux-2.4.24-vanilla.orig/fs/ext3/namei.c 2004-01-10 17:11:50.000000000 +0300 -+++ linux-2.4.24-vanilla/fs/ext3/namei.c 2004-01-10 17:20:28.000000000 +0300 -@@ -29,6 +29,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -1613,7 +1614,7 @@ - if (IS_SYNC(dir)) - handle->h_sync = 1; - -- inode = ext3_new_inode (handle, dir, S_IFDIR); -+ inode = ext3_new_inode (handle, dir, S_IFDIR | mode); - err = PTR_ERR(inode); - if (IS_ERR(inode)) - goto out_stop; -@@ -1621,7 +1622,6 @@ - inode->i_op = &ext3_dir_inode_operations; - inode->i_fop = &ext3_dir_operations; - inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize; -- inode->i_blocks = 0; - dir_block = ext3_bread (handle, inode, 0, 1, &err); - if (!dir_block) { - inode->i_nlink--; /* is this nlink == 0? */ -@@ -1648,9 +1648,6 @@ - BUFFER_TRACE(dir_block, "call ext3_journal_dirty_metadata"); - ext3_journal_dirty_metadata(handle, dir_block); - brelse (dir_block); -- inode->i_mode = S_IFDIR | mode; -- if (dir->i_mode & S_ISGID) -- inode->i_mode |= S_ISGID; - ext3_mark_inode_dirty(handle, inode); - err = ext3_add_entry (handle, dentry, inode); - if (err) { -@@ -2019,7 +2016,7 @@ - goto out_stop; - - if (l > sizeof (EXT3_I(inode)->i_data)) { -- inode->i_op = &page_symlink_inode_operations; -+ inode->i_op = &ext3_symlink_inode_operations; - inode->i_mapping->a_ops = &ext3_aops; - /* - * block_symlink() calls back into ext3_prepare/commit_write. -@@ -2244,4 +2241,16 @@ - rmdir: ext3_rmdir, /* BKL held */ - mknod: ext3_mknod, /* BKL held */ - rename: ext3_rename, /* BKL held */ -+ setxattr: ext3_setxattr, /* BKL held */ -+ getxattr: ext3_getxattr, /* BKL held */ -+ listxattr: ext3_listxattr, /* BKL held */ -+ removexattr: ext3_removexattr, /* BKL held */ - }; -+ -+struct inode_operations ext3_special_inode_operations = { -+ setxattr: ext3_setxattr, /* BKL held */ -+ getxattr: ext3_getxattr, /* BKL held */ -+ listxattr: ext3_listxattr, /* BKL held */ -+ removexattr: ext3_removexattr, /* BKL held */ -+}; -+ -Index: linux-2.4.24-vanilla/fs/ext3/super.c -=================================================================== ---- linux-2.4.24-vanilla.orig/fs/ext3/super.c 2004-01-10 17:11:50.000000000 +0300 -+++ linux-2.4.24-vanilla/fs/ext3/super.c 2004-01-10 17:20:28.000000000 +0300 -@@ -24,6 +24,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -406,6 +407,7 @@ - kdev_t j_dev = sbi->s_journal->j_dev; - int i; - -+ ext3_xattr_put_super(sb); - journal_destroy(sbi->s_journal); - if (!(sb->s_flags & MS_RDONLY)) { - EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER); -@@ -505,6 +507,7 @@ - int is_remount) - { - unsigned long *mount_options = &sbi->s_mount_opt; -+ - uid_t *resuid = &sbi->s_resuid; - gid_t *resgid = &sbi->s_resgid; - char * this_char; -@@ -517,6 +520,13 @@ - this_char = strtok (NULL, ",")) { - if ((value = strchr (this_char, '=')) != NULL) - *value++ = 0; -+#ifdef CONFIG_EXT3_FS_XATTR_USER -+ if (!strcmp (this_char, "user_xattr")) -+ set_opt (*mount_options, XATTR_USER); -+ else if (!strcmp (this_char, "nouser_xattr")) -+ clear_opt (*mount_options, XATTR_USER); -+ else -+#endif - if (!strcmp (this_char, "bsddf")) - clear_opt (*mount_options, MINIX_DF); - else if (!strcmp (this_char, "nouid32")) { -@@ -934,6 +944,12 @@ - sbi->s_mount_opt = 0; - sbi->s_resuid = EXT3_DEF_RESUID; - sbi->s_resgid = EXT3_DEF_RESGID; -+ -+ /* Default extended attribute flags */ -+#ifdef CONFIG_EXT3_FS_XATTR_USER -+ /* set_opt(sbi->s_mount_opt, XATTR_USER); */ -+#endif -+ - if (!parse_options ((char *) data, &sb_block, sbi, &journal_inum, 0)) { - sb->s_dev = 0; - goto out_fail; -@@ -1822,22 +1838,35 @@ - - static int __init init_ext3_fs(void) - { -+ int error; - #ifdef CONFIG_QUOTA - init_dquot_operations(&ext3_qops); - old_sync_dquot = ext3_qops.sync_dquot; - ext3_qops.sync_dquot = ext3_sync_dquot; - #endif -- return register_filesystem(&ext3_fs_type); -+ error = init_ext3_xattr(); -+ if (error) -+ return error; -+ error = init_ext3_xattr_user(); -+ if (error) -+ goto fail; -+ error = register_filesystem(&ext3_fs_type); -+ if (!error) -+ return 0; -+ -+ exit_ext3_xattr_user(); -+fail: -+ exit_ext3_xattr(); -+ return error; - } - - static void __exit exit_ext3_fs(void) - { - unregister_filesystem(&ext3_fs_type); -+ exit_ext3_xattr_user(); -+ exit_ext3_xattr(); - } - --EXPORT_SYMBOL(ext3_force_commit); --EXPORT_SYMBOL(ext3_bread); -- - MODULE_AUTHOR("Remy Card, Stephen Tweedie, Andrew Morton, Andreas Dilger, Theodore Ts'o and others"); - MODULE_DESCRIPTION("Second Extended Filesystem with journaling extensions"); - MODULE_LICENSE("GPL"); -Index: linux-2.4.24-vanilla/fs/ext3/symlink.c -=================================================================== ---- linux-2.4.24-vanilla.orig/fs/ext3/symlink.c 2001-11-10 01:25:04.000000000 +0300 -+++ linux-2.4.24-vanilla/fs/ext3/symlink.c 2004-01-10 17:20:28.000000000 +0300 -@@ -20,6 +20,7 @@ - #include - #include - #include -+#include - - static int ext3_readlink(struct dentry *dentry, char *buffer, int buflen) - { -@@ -33,7 +34,20 @@ - return vfs_follow_link(nd, s); - } - -+struct inode_operations ext3_symlink_inode_operations = { -+ readlink: page_readlink, /* BKL not held. Don't need */ -+ follow_link: page_follow_link, /* BKL not held. Don't need */ -+ setxattr: ext3_setxattr, /* BKL held */ -+ getxattr: ext3_getxattr, /* BKL held */ -+ listxattr: ext3_listxattr, /* BKL held */ -+ removexattr: ext3_removexattr, /* BKL held */ -+}; -+ - struct inode_operations ext3_fast_symlink_inode_operations = { - readlink: ext3_readlink, /* BKL not held. Don't need */ - follow_link: ext3_follow_link, /* BKL not held. Don't need */ -+ setxattr: ext3_setxattr, /* BKL held */ -+ getxattr: ext3_getxattr, /* BKL held */ -+ listxattr: ext3_listxattr, /* BKL held */ -+ removexattr: ext3_removexattr, /* BKL held */ - }; -Index: linux-2.4.24-vanilla/fs/ext3/xattr.c -=================================================================== ---- linux-2.4.24-vanilla.orig/fs/ext3/xattr.c 2003-01-30 13:24:37.000000000 +0300 -+++ linux-2.4.24-vanilla/fs/ext3/xattr.c 2004-01-10 17:20:28.000000000 +0300 -@@ -0,0 +1,1225 @@ -+/* -+ * linux/fs/ext3/xattr.c -+ * -+ * Copyright (C) 2001 by Andreas Gruenbacher, -+ * -+ * Fix by Harrison Xing . -+ * Ext3 code with a lot of help from Eric Jarman . -+ * Extended attributes for symlinks and special files added per -+ * suggestion of Luka Renko . -+ */ -+ -+/* -+ * Extended attributes are stored on disk blocks allocated outside of -+ * any inode. The i_file_acl field is then made to point to this allocated -+ * block. If all extended attributes of an inode are identical, these -+ * inodes may share the same extended attribute block. Such situations -+ * are automatically detected by keeping a cache of recent attribute block -+ * numbers and hashes over the block's contents in memory. -+ * -+ * -+ * Extended attribute block layout: -+ * -+ * +------------------+ -+ * | header | -+ * | entry 1 | | -+ * | entry 2 | | growing downwards -+ * | entry 3 | v -+ * | four null bytes | -+ * | . . . | -+ * | value 1 | ^ -+ * | value 3 | | growing upwards -+ * | value 2 | | -+ * +------------------+ -+ * -+ * The block header is followed by multiple entry descriptors. These entry -+ * descriptors are variable in size, and alligned to EXT3_XATTR_PAD -+ * byte boundaries. The entry descriptors are sorted by attribute name, -+ * so that two extended attribute blocks can be compared efficiently. -+ * -+ * Attribute values are aligned to the end of the block, stored in -+ * no specific order. They are also padded to EXT3_XATTR_PAD byte -+ * boundaries. No additional gaps are left between them. -+ * -+ * Locking strategy -+ * ---------------- -+ * The VFS already holds the BKL and the inode->i_sem semaphore when any of -+ * the xattr inode operations are called, so we are guaranteed that only one -+ * processes accesses extended attributes of an inode at any time. -+ * -+ * For writing we also grab the ext3_xattr_sem semaphore. This ensures that -+ * only a single process is modifying an extended attribute block, even -+ * if the block is shared among inodes. -+ * -+ * Note for porting to 2.5 -+ * ----------------------- -+ * The BKL will no longer be held in the xattr inode operations. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define EXT3_EA_USER "user." -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) -+# define mark_buffer_dirty(bh) mark_buffer_dirty(bh, 1) -+#endif -+ -+#define HDR(bh) ((struct ext3_xattr_header *)((bh)->b_data)) -+#define ENTRY(ptr) ((struct ext3_xattr_entry *)(ptr)) -+#define FIRST_ENTRY(bh) ENTRY(HDR(bh)+1) -+#define IS_LAST_ENTRY(entry) (*(__u32 *)(entry) == 0) -+ -+#ifdef EXT3_XATTR_DEBUG -+# define ea_idebug(inode, f...) do { \ -+ printk(KERN_DEBUG "inode %s:%ld: ", \ -+ kdevname(inode->i_dev), inode->i_ino); \ -+ printk(f); \ -+ printk("\n"); \ -+ } while (0) -+# define ea_bdebug(bh, f...) do { \ -+ printk(KERN_DEBUG "block %s:%ld: ", \ -+ kdevname(bh->b_dev), bh->b_blocknr); \ -+ printk(f); \ -+ printk("\n"); \ -+ } while (0) -+#else -+# define ea_idebug(f...) -+# define ea_bdebug(f...) -+#endif -+ -+static int ext3_xattr_set2(handle_t *, struct inode *, struct buffer_head *, -+ struct ext3_xattr_header *); -+ -+#ifdef CONFIG_EXT3_FS_XATTR_SHARING -+ -+static int ext3_xattr_cache_insert(struct buffer_head *); -+static struct buffer_head *ext3_xattr_cache_find(struct inode *, -+ struct ext3_xattr_header *); -+static void ext3_xattr_cache_remove(struct buffer_head *); -+static void ext3_xattr_rehash(struct ext3_xattr_header *, -+ struct ext3_xattr_entry *); -+ -+static struct mb_cache *ext3_xattr_cache; -+ -+#else -+# define ext3_xattr_cache_insert(bh) 0 -+# define ext3_xattr_cache_find(inode, header) NULL -+# define ext3_xattr_cache_remove(bh) while(0) {} -+# define ext3_xattr_rehash(header, entry) while(0) {} -+#endif -+ -+/* -+ * If a file system does not share extended attributes among inodes, -+ * we should not need the ext3_xattr_sem semaphore. However, the -+ * filesystem may still contain shared blocks, so we always take -+ * the lock. -+ */ -+ -+DECLARE_MUTEX(ext3_xattr_sem); -+ -+static inline int -+ext3_xattr_new_block(handle_t *handle, struct inode *inode, -+ int * errp, int force) -+{ -+ struct super_block *sb = inode->i_sb; -+ int goal = le32_to_cpu(EXT3_SB(sb)->s_es->s_first_data_block) + -+ EXT3_I(inode)->i_block_group * EXT3_BLOCKS_PER_GROUP(sb); -+ -+ /* How can we enforce the allocation? */ -+ int block = ext3_new_block(handle, inode, goal, 0, 0, errp); -+#ifdef OLD_QUOTAS -+ if (!*errp) -+ inode->i_blocks += inode->i_sb->s_blocksize >> 9; -+#endif -+ return block; -+} -+ -+static inline int -+ext3_xattr_quota_alloc(struct inode *inode, int force) -+{ -+ /* How can we enforce the allocation? */ -+#ifdef OLD_QUOTAS -+ int error = DQUOT_ALLOC_BLOCK(inode->i_sb, inode, 1); -+ if (!error) -+ inode->i_blocks += inode->i_sb->s_blocksize >> 9; -+#else -+ int error = DQUOT_ALLOC_BLOCK(inode, 1); -+#endif -+ return error; -+} -+ -+#ifdef OLD_QUOTAS -+ -+static inline void -+ext3_xattr_quota_free(struct inode *inode) -+{ -+ DQUOT_FREE_BLOCK(inode->i_sb, inode, 1); -+ inode->i_blocks -= inode->i_sb->s_blocksize >> 9; -+} -+ -+static inline void -+ext3_xattr_free_block(handle_t *handle, struct inode * inode, -+ unsigned long block) -+{ -+ ext3_free_blocks(handle, inode, block, 1); -+ inode->i_blocks -= inode->i_sb->s_blocksize >> 9; -+} -+ -+#else -+# define ext3_xattr_quota_free(inode) \ -+ DQUOT_FREE_BLOCK(inode, 1) -+# define ext3_xattr_free_block(handle, inode, block) \ -+ ext3_free_blocks(handle, inode, block, 1) -+#endif -+ -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,18) -+ -+static inline struct buffer_head * -+sb_bread(struct super_block *sb, int block) -+{ -+ return bread(sb->s_dev, block, sb->s_blocksize); -+} -+ -+static inline struct buffer_head * -+sb_getblk(struct super_block *sb, int block) -+{ -+ return getblk(sb->s_dev, block, sb->s_blocksize); -+} -+ -+#endif -+ -+struct ext3_xattr_handler *ext3_xattr_handlers[EXT3_XATTR_INDEX_MAX]; -+rwlock_t ext3_handler_lock = RW_LOCK_UNLOCKED; -+ -+int -+ext3_xattr_register(int name_index, struct ext3_xattr_handler *handler) -+{ -+ int error = -EINVAL; -+ -+ if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) { -+ write_lock(&ext3_handler_lock); -+ if (!ext3_xattr_handlers[name_index-1]) { -+ ext3_xattr_handlers[name_index-1] = handler; -+ error = 0; -+ } -+ write_unlock(&ext3_handler_lock); -+ } -+ return error; -+} -+ -+void -+ext3_xattr_unregister(int name_index, struct ext3_xattr_handler *handler) -+{ -+ if (name_index > 0 || name_index <= EXT3_XATTR_INDEX_MAX) { -+ write_lock(&ext3_handler_lock); -+ ext3_xattr_handlers[name_index-1] = NULL; -+ write_unlock(&ext3_handler_lock); -+ } -+} -+ -+static inline const char * -+strcmp_prefix(const char *a, const char *a_prefix) -+{ -+ while (*a_prefix && *a == *a_prefix) { -+ a++; -+ a_prefix++; -+ } -+ return *a_prefix ? NULL : a; -+} -+ -+/* -+ * Decode the extended attribute name, and translate it into -+ * the name_index and name suffix. -+ */ -+static inline struct ext3_xattr_handler * -+ext3_xattr_resolve_name(const char **name) -+{ -+ struct ext3_xattr_handler *handler = NULL; -+ int i; -+ -+ if (!*name) -+ return NULL; -+ read_lock(&ext3_handler_lock); -+ for (i=0; iprefix); -+ if (n) { -+ handler = ext3_xattr_handlers[i]; -+ *name = n; -+ break; -+ } -+ } -+ } -+ read_unlock(&ext3_handler_lock); -+ return handler; -+} -+ -+static inline struct ext3_xattr_handler * -+ext3_xattr_handler(int name_index) -+{ -+ struct ext3_xattr_handler *handler = NULL; -+ if (name_index > 0 && name_index <= EXT3_XATTR_INDEX_MAX) { -+ read_lock(&ext3_handler_lock); -+ handler = ext3_xattr_handlers[name_index-1]; -+ read_unlock(&ext3_handler_lock); -+ } -+ return handler; -+} -+ -+/* -+ * Inode operation getxattr() -+ * -+ * dentry->d_inode->i_sem down -+ * BKL held [before 2.5.x] -+ */ -+ssize_t -+ext3_getxattr(struct dentry *dentry, const char *name, -+ void *buffer, size_t size) -+{ -+ struct ext3_xattr_handler *handler; -+ struct inode *inode = dentry->d_inode; -+ -+ handler = ext3_xattr_resolve_name(&name); -+ if (!handler) -+ return -ENOTSUP; -+ return handler->get(inode, name, buffer, size); -+} -+ -+/* -+ * Inode operation listxattr() -+ * -+ * dentry->d_inode->i_sem down -+ * BKL held [before 2.5.x] -+ */ -+ssize_t -+ext3_listxattr(struct dentry *dentry, char *buffer, size_t size) -+{ -+ return ext3_xattr_list(dentry->d_inode, buffer, size); -+} -+ -+/* -+ * Inode operation setxattr() -+ * -+ * dentry->d_inode->i_sem down -+ * BKL held [before 2.5.x] -+ */ -+int -+ext3_setxattr(struct dentry *dentry, const char *name, -+ const void *value, size_t size, int flags) -+{ -+ struct ext3_xattr_handler *handler; -+ struct inode *inode = dentry->d_inode; -+ -+ if (size == 0) -+ value = ""; /* empty EA, do not remove */ -+ handler = ext3_xattr_resolve_name(&name); -+ if (!handler) -+ return -ENOTSUP; -+ return handler->set(inode, name, value, size, flags); -+} -+ -+/* -+ * Inode operation removexattr() -+ * -+ * dentry->d_inode->i_sem down -+ * BKL held [before 2.5.x] -+ */ -+int -+ext3_removexattr(struct dentry *dentry, const char *name) -+{ -+ struct ext3_xattr_handler *handler; -+ struct inode *inode = dentry->d_inode; -+ -+ handler = ext3_xattr_resolve_name(&name); -+ if (!handler) -+ return -ENOTSUP; -+ return handler->set(inode, name, NULL, 0, XATTR_REPLACE); -+} -+ -+/* -+ * ext3_xattr_get() -+ * -+ * Copy an extended attribute into the buffer -+ * provided, or compute the buffer size required. -+ * Buffer is NULL to compute the size of the buffer required. -+ * -+ * Returns a negative error number on failure, or the number of bytes -+ * used / required on success. -+ */ -+int -+ext3_xattr_get(struct inode *inode, int name_index, const char *name, -+ void *buffer, size_t buffer_size) -+{ -+ struct buffer_head *bh = NULL; -+ struct ext3_xattr_entry *entry; -+ unsigned int block, size; -+ char *end; -+ int name_len, error; -+ -+ ea_idebug(inode, "name=%d.%s, buffer=%p, buffer_size=%ld", -+ name_index, name, buffer, (long)buffer_size); -+ -+ if (name == NULL) -+ return -EINVAL; -+ if (!EXT3_I(inode)->i_file_acl) -+ return -ENOATTR; -+ block = EXT3_I(inode)->i_file_acl; -+ ea_idebug(inode, "reading block %d", block); -+ bh = sb_bread(inode->i_sb, block); -+ if (!bh) -+ return -EIO; -+ ea_bdebug(bh, "b_count=%d, refcount=%d", -+ atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount)); -+ end = bh->b_data + bh->b_size; -+ if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || -+ HDR(bh)->h_blocks != cpu_to_le32(1)) { -+bad_block: ext3_error(inode->i_sb, "ext3_xattr_get", -+ "inode %ld: bad block %d", inode->i_ino, block); -+ error = -EIO; -+ goto cleanup; -+ } -+ /* find named attribute */ -+ name_len = strlen(name); -+ -+ error = -ERANGE; -+ if (name_len > 255) -+ goto cleanup; -+ entry = FIRST_ENTRY(bh); -+ while (!IS_LAST_ENTRY(entry)) { -+ struct ext3_xattr_entry *next = -+ EXT3_XATTR_NEXT(entry); -+ if ((char *)next >= end) -+ goto bad_block; -+ if (name_index == entry->e_name_index && -+ name_len == entry->e_name_len && -+ memcmp(name, entry->e_name, name_len) == 0) -+ goto found; -+ entry = next; -+ } -+ /* Check the remaining name entries */ -+ while (!IS_LAST_ENTRY(entry)) { -+ struct ext3_xattr_entry *next = -+ EXT3_XATTR_NEXT(entry); -+ if ((char *)next >= end) -+ goto bad_block; -+ entry = next; -+ } -+ if (ext3_xattr_cache_insert(bh)) -+ ea_idebug(inode, "cache insert failed"); -+ error = -ENOATTR; -+ goto cleanup; -+found: -+ /* check the buffer size */ -+ if (entry->e_value_block != 0) -+ goto bad_block; -+ size = le32_to_cpu(entry->e_value_size); -+ if (size > inode->i_sb->s_blocksize || -+ le16_to_cpu(entry->e_value_offs) + size > inode->i_sb->s_blocksize) -+ goto bad_block; -+ -+ if (ext3_xattr_cache_insert(bh)) -+ ea_idebug(inode, "cache insert failed"); -+ if (buffer) { -+ error = -ERANGE; -+ if (size > buffer_size) -+ goto cleanup; -+ /* return value of attribute */ -+ memcpy(buffer, bh->b_data + le16_to_cpu(entry->e_value_offs), -+ size); -+ } -+ error = size; -+ -+cleanup: -+ brelse(bh); -+ -+ return error; -+} -+ -+/* -+ * ext3_xattr_list() -+ * -+ * Copy a list of attribute names into the buffer -+ * provided, or compute the buffer size required. -+ * Buffer is NULL to compute the size of the buffer required. -+ * -+ * Returns a negative error number on failure, or the number of bytes -+ * used / required on success. -+ */ -+int -+ext3_xattr_list(struct inode *inode, char *buffer, size_t buffer_size) -+{ -+ struct buffer_head *bh = NULL; -+ struct ext3_xattr_entry *entry; -+ unsigned int block, size = 0; -+ char *buf, *end; -+ int error; -+ -+ ea_idebug(inode, "buffer=%p, buffer_size=%ld", -+ buffer, (long)buffer_size); -+ -+ if (!EXT3_I(inode)->i_file_acl) -+ return 0; -+ block = EXT3_I(inode)->i_file_acl; -+ ea_idebug(inode, "reading block %d", block); -+ bh = sb_bread(inode->i_sb, block); -+ if (!bh) -+ return -EIO; -+ ea_bdebug(bh, "b_count=%d, refcount=%d", -+ atomic_read(&(bh->b_count)), le32_to_cpu(HDR(bh)->h_refcount)); -+ end = bh->b_data + bh->b_size; -+ if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || -+ HDR(bh)->h_blocks != cpu_to_le32(1)) { -+bad_block: ext3_error(inode->i_sb, "ext3_xattr_list", -+ "inode %ld: bad block %d", inode->i_ino, block); -+ error = -EIO; -+ goto cleanup; -+ } -+ /* compute the size required for the list of attribute names */ -+ for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry); -+ entry = EXT3_XATTR_NEXT(entry)) { -+ struct ext3_xattr_handler *handler; -+ struct ext3_xattr_entry *next = -+ EXT3_XATTR_NEXT(entry); -+ if ((char *)next >= end) -+ goto bad_block; -+ -+ handler = ext3_xattr_handler(entry->e_name_index); -+ if (handler) -+ size += handler->list(NULL, inode, entry->e_name, -+ entry->e_name_len); -+ } -+ -+ if (ext3_xattr_cache_insert(bh)) -+ ea_idebug(inode, "cache insert failed"); -+ if (!buffer) { -+ error = size; -+ goto cleanup; -+ } else { -+ error = -ERANGE; -+ if (size > buffer_size) -+ goto cleanup; -+ } -+ -+ /* list the attribute names */ -+ buf = buffer; -+ for (entry = FIRST_ENTRY(bh); !IS_LAST_ENTRY(entry); -+ entry = EXT3_XATTR_NEXT(entry)) { -+ struct ext3_xattr_handler *handler; -+ -+ handler = ext3_xattr_handler(entry->e_name_index); -+ if (handler) -+ buf += handler->list(buf, inode, entry->e_name, -+ entry->e_name_len); -+ } -+ error = size; -+ -+cleanup: -+ brelse(bh); -+ -+ return error; -+} -+ -+/* -+ * If the EXT3_FEATURE_COMPAT_EXT_ATTR feature of this file system is -+ * not set, set it. -+ */ -+static void ext3_xattr_update_super_block(handle_t *handle, -+ struct super_block *sb) -+{ -+ if (EXT3_HAS_COMPAT_FEATURE(sb, EXT3_FEATURE_COMPAT_EXT_ATTR)) -+ return; -+ -+ lock_super(sb); -+ ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh); -+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0) -+ EXT3_SB(sb)->s_feature_compat |= EXT3_FEATURE_COMPAT_EXT_ATTR; -+#endif -+ EXT3_SB(sb)->s_es->s_feature_compat |= -+ cpu_to_le32(EXT3_FEATURE_COMPAT_EXT_ATTR); -+ sb->s_dirt = 1; -+ ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh); -+ unlock_super(sb); -+} -+ -+/* -+ * ext3_xattr_set() -+ * -+ * Create, replace or remove an extended attribute for this inode. Buffer -+ * is NULL to remove an existing extended attribute, and non-NULL to -+ * either replace an existing extended attribute, or create a new extended -+ * attribute. The flags XATTR_REPLACE and XATTR_CREATE -+ * specify that an extended attribute must exist and must not exist -+ * previous to the call, respectively. -+ * -+ * Returns 0, or a negative error number on failure. -+ */ -+int -+ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index, -+ const char *name, const void *value, size_t value_len, int flags) -+{ -+ struct super_block *sb = inode->i_sb; -+ struct buffer_head *bh = NULL; -+ struct ext3_xattr_header *header = NULL; -+ struct ext3_xattr_entry *here, *last; -+ unsigned int name_len; -+ int block = EXT3_I(inode)->i_file_acl; -+ int min_offs = sb->s_blocksize, not_found = 1, free, error; -+ char *end; -+ -+ /* -+ * header -- Points either into bh, or to a temporarily -+ * allocated buffer. -+ * here -- The named entry found, or the place for inserting, within -+ * the block pointed to by header. -+ * last -- Points right after the last named entry within the block -+ * pointed to by header. -+ * min_offs -- The offset of the first value (values are aligned -+ * towards the end of the block). -+ * end -- Points right after the block pointed to by header. -+ */ -+ -+ ea_idebug(inode, "name=%d.%s, value=%p, value_len=%ld", -+ name_index, name, value, (long)value_len); -+ -+ if (IS_RDONLY(inode)) -+ return -EROFS; -+ if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) -+ return -EPERM; -+ if (value == NULL) -+ value_len = 0; -+ if (name == NULL) -+ return -EINVAL; -+ name_len = strlen(name); -+ if (name_len > 255 || value_len > sb->s_blocksize) -+ return -ERANGE; -+ down(&ext3_xattr_sem); -+ -+ if (block) { -+ /* The inode already has an extended attribute block. */ -+ bh = sb_bread(sb, block); -+ error = -EIO; -+ if (!bh) -+ goto cleanup; -+ ea_bdebug(bh, "b_count=%d, refcount=%d", -+ atomic_read(&(bh->b_count)), -+ le32_to_cpu(HDR(bh)->h_refcount)); -+ header = HDR(bh); -+ end = bh->b_data + bh->b_size; -+ if (header->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || -+ header->h_blocks != cpu_to_le32(1)) { -+bad_block: ext3_error(sb, "ext3_xattr_set", -+ "inode %ld: bad block %d", inode->i_ino, block); -+ error = -EIO; -+ goto cleanup; -+ } -+ /* Find the named attribute. */ -+ here = FIRST_ENTRY(bh); -+ while (!IS_LAST_ENTRY(here)) { -+ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(here); -+ if ((char *)next >= end) -+ goto bad_block; -+ if (!here->e_value_block && here->e_value_size) { -+ int offs = le16_to_cpu(here->e_value_offs); -+ if (offs < min_offs) -+ min_offs = offs; -+ } -+ not_found = name_index - here->e_name_index; -+ if (!not_found) -+ not_found = name_len - here->e_name_len; -+ if (!not_found) -+ not_found = memcmp(name, here->e_name,name_len); -+ if (not_found <= 0) -+ break; -+ here = next; -+ } -+ last = here; -+ /* We still need to compute min_offs and last. */ -+ while (!IS_LAST_ENTRY(last)) { -+ struct ext3_xattr_entry *next = EXT3_XATTR_NEXT(last); -+ if ((char *)next >= end) -+ goto bad_block; -+ if (!last->e_value_block && last->e_value_size) { -+ int offs = le16_to_cpu(last->e_value_offs); -+ if (offs < min_offs) -+ min_offs = offs; -+ } -+ last = next; -+ } -+ -+ /* Check whether we have enough space left. */ -+ free = min_offs - ((char*)last - (char*)header) - sizeof(__u32); -+ } else { -+ /* We will use a new extended attribute block. */ -+ free = sb->s_blocksize - -+ sizeof(struct ext3_xattr_header) - sizeof(__u32); -+ here = last = NULL; /* avoid gcc uninitialized warning. */ -+ } -+ -+ if (not_found) { -+ /* Request to remove a nonexistent attribute? */ -+ error = -ENOATTR; -+ if (flags & XATTR_REPLACE) -+ goto cleanup; -+ error = 0; -+ if (value == NULL) -+ goto cleanup; -+ else -+ free -= EXT3_XATTR_LEN(name_len); -+ } else { -+ /* Request to create an existing attribute? */ -+ error = -EEXIST; -+ if (flags & XATTR_CREATE) -+ goto cleanup; -+ if (!here->e_value_block && here->e_value_size) { -+ unsigned int size = le32_to_cpu(here->e_value_size); -+ -+ if (le16_to_cpu(here->e_value_offs) + size > -+ sb->s_blocksize || size > sb->s_blocksize) -+ goto bad_block; -+ free += EXT3_XATTR_SIZE(size); -+ } -+ } -+ free -= EXT3_XATTR_SIZE(value_len); -+ error = -ENOSPC; -+ if (free < 0) -+ goto cleanup; -+ -+ /* Here we know that we can set the new attribute. */ -+ -+ if (header) { -+ if (header->h_refcount == cpu_to_le32(1)) { -+ ea_bdebug(bh, "modifying in-place"); -+ ext3_xattr_cache_remove(bh); -+ error = ext3_journal_get_write_access(handle, bh); -+ if (error) -+ goto cleanup; -+ } else { -+ int offset; -+ -+ ea_bdebug(bh, "cloning"); -+ header = kmalloc(bh->b_size, GFP_KERNEL); -+ error = -ENOMEM; -+ if (header == NULL) -+ goto cleanup; -+ memcpy(header, HDR(bh), bh->b_size); -+ header->h_refcount = cpu_to_le32(1); -+ offset = (char *)header - bh->b_data; -+ here = ENTRY((char *)here + offset); -+ last = ENTRY((char *)last + offset); -+ } -+ } else { -+ /* Allocate a buffer where we construct the new block. */ -+ header = kmalloc(sb->s_blocksize, GFP_KERNEL); -+ error = -ENOMEM; -+ if (header == NULL) -+ goto cleanup; -+ memset(header, 0, sb->s_blocksize); -+ end = (char *)header + sb->s_blocksize; -+ header->h_magic = cpu_to_le32(EXT3_XATTR_MAGIC); -+ header->h_blocks = header->h_refcount = cpu_to_le32(1); -+ last = here = ENTRY(header+1); -+ } -+ -+ if (not_found) { -+ /* Insert the new name. */ -+ int size = EXT3_XATTR_LEN(name_len); -+ int rest = (char *)last - (char *)here; -+ memmove((char *)here + size, here, rest); -+ memset(here, 0, size); -+ here->e_name_index = name_index; -+ here->e_name_len = name_len; -+ memcpy(here->e_name, name, name_len); -+ } else { -+ /* Remove the old value. */ -+ if (!here->e_value_block && here->e_value_size) { -+ char *first_val = (char *)header + min_offs; -+ int offs = le16_to_cpu(here->e_value_offs); -+ char *val = (char *)header + offs; -+ size_t size = EXT3_XATTR_SIZE( -+ le32_to_cpu(here->e_value_size)); -+ memmove(first_val + size, first_val, val - first_val); -+ memset(first_val, 0, size); -+ here->e_value_offs = 0; -+ min_offs += size; -+ -+ /* Adjust all value offsets. */ -+ last = ENTRY(header+1); -+ while (!IS_LAST_ENTRY(last)) { -+ int o = le16_to_cpu(last->e_value_offs); -+ if (!last->e_value_block && o < offs) -+ last->e_value_offs = -+ cpu_to_le16(o + size); -+ last = EXT3_XATTR_NEXT(last); -+ } -+ } -+ if (value == NULL) { -+ /* Remove this attribute. */ -+ if (EXT3_XATTR_NEXT(ENTRY(header+1)) == last) { -+ /* This block is now empty. */ -+ error = ext3_xattr_set2(handle, inode, bh,NULL); -+ goto cleanup; -+ } else { -+ /* Remove the old name. */ -+ int size = EXT3_XATTR_LEN(name_len); -+ last = ENTRY((char *)last - size); -+ memmove(here, (char*)here + size, -+ (char*)last - (char*)here); -+ memset(last, 0, size); -+ } -+ } -+ } -+ -+ if (value != NULL) { -+ /* Insert the new value. */ -+ here->e_value_size = cpu_to_le32(value_len); -+ if (value_len) { -+ size_t size = EXT3_XATTR_SIZE(value_len); -+ char *val = (char *)header + min_offs - size; -+ here->e_value_offs = -+ cpu_to_le16((char *)val - (char *)header); -+ memset(val + size - EXT3_XATTR_PAD, 0, -+ EXT3_XATTR_PAD); /* Clear the pad bytes. */ -+ memcpy(val, value, value_len); -+ } -+ } -+ ext3_xattr_rehash(header, here); -+ -+ error = ext3_xattr_set2(handle, inode, bh, header); -+ -+cleanup: -+ brelse(bh); -+ if (!(bh && header == HDR(bh))) -+ kfree(header); -+ up(&ext3_xattr_sem); -+ -+ return error; -+} -+ -+/* -+ * Second half of ext3_xattr_set(): Update the file system. -+ */ -+static int -+ext3_xattr_set2(handle_t *handle, struct inode *inode, -+ struct buffer_head *old_bh, struct ext3_xattr_header *header) -+{ -+ struct super_block *sb = inode->i_sb; -+ struct buffer_head *new_bh = NULL; -+ int error; -+ -+ if (header) { -+ new_bh = ext3_xattr_cache_find(inode, header); -+ if (new_bh) { -+ /* -+ * We found an identical block in the cache. -+ * The old block will be released after updating -+ * the inode. -+ */ -+ ea_bdebug(old_bh, "reusing block %ld", -+ new_bh->b_blocknr); -+ -+ error = -EDQUOT; -+ if (ext3_xattr_quota_alloc(inode, 1)) -+ goto cleanup; -+ -+ error = ext3_journal_get_write_access(handle, new_bh); -+ if (error) -+ goto cleanup; -+ HDR(new_bh)->h_refcount = cpu_to_le32( -+ le32_to_cpu(HDR(new_bh)->h_refcount) + 1); -+ ea_bdebug(new_bh, "refcount now=%d", -+ le32_to_cpu(HDR(new_bh)->h_refcount)); -+ } else if (old_bh && header == HDR(old_bh)) { -+ /* Keep this block. */ -+ new_bh = old_bh; -+ (void)ext3_xattr_cache_insert(new_bh); -+ } else { -+ /* We need to allocate a new block */ -+ int force = EXT3_I(inode)->i_file_acl != 0; -+ int block = ext3_xattr_new_block(handle, inode, -+ &error, force); -+ if (error) -+ goto cleanup; -+ ea_idebug(inode, "creating block %d", block); -+ -+ new_bh = sb_getblk(sb, block); -+ if (!new_bh) { -+getblk_failed: ext3_xattr_free_block(handle, inode, block); -+ error = -EIO; -+ goto cleanup; -+ } -+ lock_buffer(new_bh); -+ error = ext3_journal_get_create_access(handle, new_bh); -+ if (error) { -+ unlock_buffer(new_bh); -+ goto getblk_failed; -+ } -+ memcpy(new_bh->b_data, header, new_bh->b_size); -+ mark_buffer_uptodate(new_bh, 1); -+ unlock_buffer(new_bh); -+ (void)ext3_xattr_cache_insert(new_bh); -+ -+ ext3_xattr_update_super_block(handle, sb); -+ } -+ error = ext3_journal_dirty_metadata(handle, new_bh); -+ if (error) -+ goto cleanup; -+ } -+ -+ /* Update the inode. */ -+ EXT3_I(inode)->i_file_acl = new_bh ? new_bh->b_blocknr : 0; -+ inode->i_ctime = CURRENT_TIME; -+ ext3_mark_inode_dirty(handle, inode); -+ if (IS_SYNC(inode)) -+ handle->h_sync = 1; -+ -+ error = 0; -+ if (old_bh && old_bh != new_bh) { -+ /* -+ * If there was an old block, and we are not still using it, -+ * we now release the old block. -+ */ -+ unsigned int refcount = le32_to_cpu(HDR(old_bh)->h_refcount); -+ -+ error = ext3_journal_get_write_access(handle, old_bh); -+ if (error) -+ goto cleanup; -+ if (refcount == 1) { -+ /* Free the old block. */ -+ ea_bdebug(old_bh, "freeing"); -+ ext3_xattr_free_block(handle, inode, old_bh->b_blocknr); -+ -+ /* ext3_forget() calls bforget() for us, but we -+ let our caller release old_bh, so we need to -+ duplicate the handle before. */ -+ get_bh(old_bh); -+ ext3_forget(handle, 1, inode, old_bh,old_bh->b_blocknr); -+ } else { -+ /* Decrement the refcount only. */ -+ refcount--; -+ HDR(old_bh)->h_refcount = cpu_to_le32(refcount); -+ ext3_xattr_quota_free(inode); -+ ext3_journal_dirty_metadata(handle, old_bh); -+ ea_bdebug(old_bh, "refcount now=%d", refcount); -+ } -+ } -+ -+cleanup: -+ if (old_bh != new_bh) -+ brelse(new_bh); -+ -+ return error; -+} -+ -+/* -+ * ext3_xattr_delete_inode() -+ * -+ * Free extended attribute resources associated with this inode. This -+ * is called immediately before an inode is freed. -+ */ -+void -+ext3_xattr_delete_inode(handle_t *handle, struct inode *inode) -+{ -+ struct buffer_head *bh; -+ unsigned int block = EXT3_I(inode)->i_file_acl; -+ -+ if (!block) -+ return; -+ down(&ext3_xattr_sem); -+ -+ bh = sb_bread(inode->i_sb, block); -+ if (!bh) { -+ ext3_error(inode->i_sb, "ext3_xattr_delete_inode", -+ "inode %ld: block %d read error", inode->i_ino, block); -+ goto cleanup; -+ } -+ ea_bdebug(bh, "b_count=%d", atomic_read(&(bh->b_count))); -+ if (HDR(bh)->h_magic != cpu_to_le32(EXT3_XATTR_MAGIC) || -+ HDR(bh)->h_blocks != cpu_to_le32(1)) { -+ ext3_error(inode->i_sb, "ext3_xattr_delete_inode", -+ "inode %ld: bad block %d", inode->i_ino, block); -+ goto cleanup; -+ } -+ ext3_journal_get_write_access(handle, bh); -+ ea_bdebug(bh, "refcount now=%d", le32_to_cpu(HDR(bh)->h_refcount) - 1); -+ if (HDR(bh)->h_refcount == cpu_to_le32(1)) { -+ ext3_xattr_cache_remove(bh); -+ ext3_xattr_free_block(handle, inode, block); -+ ext3_forget(handle, 1, inode, bh, block); -+ bh = NULL; -+ } else { -+ HDR(bh)->h_refcount = cpu_to_le32( -+ le32_to_cpu(HDR(bh)->h_refcount) - 1); -+ ext3_journal_dirty_metadata(handle, bh); -+ if (IS_SYNC(inode)) -+ handle->h_sync = 1; -+ ext3_xattr_quota_free(inode); -+ } -+ EXT3_I(inode)->i_file_acl = 0; -+ -+cleanup: -+ brelse(bh); -+ up(&ext3_xattr_sem); -+} -+ -+/* -+ * ext3_xattr_put_super() -+ * -+ * This is called when a file system is unmounted. -+ */ -+void -+ext3_xattr_put_super(struct super_block *sb) -+{ -+#ifdef CONFIG_EXT3_FS_XATTR_SHARING -+ mb_cache_shrink(ext3_xattr_cache, sb->s_dev); -+#endif -+} -+ -+#ifdef CONFIG_EXT3_FS_XATTR_SHARING -+ -+/* -+ * ext3_xattr_cache_insert() -+ * -+ * Create a new entry in the extended attribute cache, and insert -+ * it unless such an entry is already in the cache. -+ * -+ * Returns 0, or a negative error number on failure. -+ */ -+static int -+ext3_xattr_cache_insert(struct buffer_head *bh) -+{ -+ __u32 hash = le32_to_cpu(HDR(bh)->h_hash); -+ struct mb_cache_entry *ce; -+ int error; -+ -+ ce = mb_cache_entry_alloc(ext3_xattr_cache); -+ if (!ce) -+ return -ENOMEM; -+ error = mb_cache_entry_insert(ce, bh->b_dev, bh->b_blocknr, &hash); -+ if (error) { -+ mb_cache_entry_free(ce); -+ if (error == -EBUSY) { -+ ea_bdebug(bh, "already in cache (%d cache entries)", -+ atomic_read(&ext3_xattr_cache->c_entry_count)); -+ error = 0; -+ } -+ } else { -+ ea_bdebug(bh, "inserting [%x] (%d cache entries)", (int)hash, -+ atomic_read(&ext3_xattr_cache->c_entry_count)); -+ mb_cache_entry_release(ce); -+ } -+ return error; -+} -+ -+/* -+ * ext3_xattr_cmp() -+ * -+ * Compare two extended attribute blocks for equality. -+ * -+ * Returns 0 if the blocks are equal, 1 if they differ, and -+ * a negative error number on errors. -+ */ -+static int -+ext3_xattr_cmp(struct ext3_xattr_header *header1, -+ struct ext3_xattr_header *header2) -+{ -+ struct ext3_xattr_entry *entry1, *entry2; -+ -+ entry1 = ENTRY(header1+1); -+ entry2 = ENTRY(header2+1); -+ while (!IS_LAST_ENTRY(entry1)) { -+ if (IS_LAST_ENTRY(entry2)) -+ return 1; -+ if (entry1->e_hash != entry2->e_hash || -+ entry1->e_name_len != entry2->e_name_len || -+ entry1->e_value_size != entry2->e_value_size || -+ memcmp(entry1->e_name, entry2->e_name, entry1->e_name_len)) -+ return 1; -+ if (entry1->e_value_block != 0 || entry2->e_value_block != 0) -+ return -EIO; -+ if (memcmp((char *)header1 + le16_to_cpu(entry1->e_value_offs), -+ (char *)header2 + le16_to_cpu(entry2->e_value_offs), -+ le32_to_cpu(entry1->e_value_size))) -+ return 1; -+ -+ entry1 = EXT3_XATTR_NEXT(entry1); -+ entry2 = EXT3_XATTR_NEXT(entry2); -+ } -+ if (!IS_LAST_ENTRY(entry2)) -+ return 1; -+ return 0; -+} -+ -+/* -+ * ext3_xattr_cache_find() -+ * -+ * Find an identical extended attribute block. -+ * -+ * Returns a pointer to the block found, or NULL if such a block was -+ * not found or an error occurred. -+ */ -+static struct buffer_head * -+ext3_xattr_cache_find(struct inode *inode, struct ext3_xattr_header *header) -+{ -+ __u32 hash = le32_to_cpu(header->h_hash); -+ struct mb_cache_entry *ce; -+ -+ if (!header->h_hash) -+ return NULL; /* never share */ -+ ea_idebug(inode, "looking for cached blocks [%x]", (int)hash); -+ ce = mb_cache_entry_find_first(ext3_xattr_cache, 0, inode->i_dev, hash); -+ while (ce) { -+ struct buffer_head *bh = sb_bread(inode->i_sb, ce->e_block); -+ -+ if (!bh) { -+ ext3_error(inode->i_sb, "ext3_xattr_cache_find", -+ "inode %ld: block %ld read error", -+ inode->i_ino, ce->e_block); -+ } else if (le32_to_cpu(HDR(bh)->h_refcount) > -+ EXT3_XATTR_REFCOUNT_MAX) { -+ ea_idebug(inode, "block %ld refcount %d>%d",ce->e_block, -+ le32_to_cpu(HDR(bh)->h_refcount), -+ EXT3_XATTR_REFCOUNT_MAX); -+ } else if (!ext3_xattr_cmp(header, HDR(bh))) { -+ ea_bdebug(bh, "b_count=%d",atomic_read(&(bh->b_count))); -+ mb_cache_entry_release(ce); -+ return bh; -+ } -+ brelse(bh); -+ ce = mb_cache_entry_find_next(ce, 0, inode->i_dev, hash); -+ } -+ return NULL; -+} -+ -+/* -+ * ext3_xattr_cache_remove() -+ * -+ * Remove the cache entry of a block from the cache. Called when a -+ * block becomes invalid. -+ */ -+static void -+ext3_xattr_cache_remove(struct buffer_head *bh) -+{ -+ struct mb_cache_entry *ce; -+ -+ ce = mb_cache_entry_get(ext3_xattr_cache, bh->b_dev, bh->b_blocknr); -+ if (ce) { -+ ea_bdebug(bh, "removing (%d cache entries remaining)", -+ atomic_read(&ext3_xattr_cache->c_entry_count)-1); -+ mb_cache_entry_free(ce); -+ } else -+ ea_bdebug(bh, "no cache entry"); -+} -+ -+#define NAME_HASH_SHIFT 5 -+#define VALUE_HASH_SHIFT 16 -+ -+/* -+ * ext3_xattr_hash_entry() -+ * -+ * Compute the hash of an extended attribute. -+ */ -+static inline void ext3_xattr_hash_entry(struct ext3_xattr_header *header, -+ struct ext3_xattr_entry *entry) -+{ -+ __u32 hash = 0; -+ char *name = entry->e_name; -+ int n; -+ -+ for (n=0; n < entry->e_name_len; n++) { -+ hash = (hash << NAME_HASH_SHIFT) ^ -+ (hash >> (8*sizeof(hash) - NAME_HASH_SHIFT)) ^ -+ *name++; -+ } -+ -+ if (entry->e_value_block == 0 && entry->e_value_size != 0) { -+ __u32 *value = (__u32 *)((char *)header + -+ le16_to_cpu(entry->e_value_offs)); -+ for (n = (le32_to_cpu(entry->e_value_size) + -+ EXT3_XATTR_ROUND) >> EXT3_XATTR_PAD_BITS; n; n--) { -+ hash = (hash << VALUE_HASH_SHIFT) ^ -+ (hash >> (8*sizeof(hash) - VALUE_HASH_SHIFT)) ^ -+ le32_to_cpu(*value++); -+ } -+ } -+ entry->e_hash = cpu_to_le32(hash); -+} -+ -+#undef NAME_HASH_SHIFT -+#undef VALUE_HASH_SHIFT -+ -+#define BLOCK_HASH_SHIFT 16 -+ -+/* -+ * ext3_xattr_rehash() -+ * -+ * Re-compute the extended attribute hash value after an entry has changed. -+ */ -+static void ext3_xattr_rehash(struct ext3_xattr_header *header, -+ struct ext3_xattr_entry *entry) -+{ -+ struct ext3_xattr_entry *here; -+ __u32 hash = 0; -+ -+ ext3_xattr_hash_entry(header, entry); -+ here = ENTRY(header+1); -+ while (!IS_LAST_ENTRY(here)) { -+ if (!here->e_hash) { -+ /* Block is not shared if an entry's hash value == 0 */ -+ hash = 0; -+ break; -+ } -+ hash = (hash << BLOCK_HASH_SHIFT) ^ -+ (hash >> (8*sizeof(hash) - BLOCK_HASH_SHIFT)) ^ -+ le32_to_cpu(here->e_hash); -+ here = EXT3_XATTR_NEXT(here); -+ } -+ header->h_hash = cpu_to_le32(hash); -+} -+ -+#undef BLOCK_HASH_SHIFT -+ -+int __init -+init_ext3_xattr(void) -+{ -+ ext3_xattr_cache = mb_cache_create("ext3_xattr", NULL, -+ sizeof(struct mb_cache_entry) + -+ sizeof(struct mb_cache_entry_index), 1, 61); -+ if (!ext3_xattr_cache) -+ return -ENOMEM; -+ -+ return 0; -+} -+ -+void -+exit_ext3_xattr(void) -+{ -+ if (ext3_xattr_cache) -+ mb_cache_destroy(ext3_xattr_cache); -+ ext3_xattr_cache = NULL; -+} -+ -+#else /* CONFIG_EXT3_FS_XATTR_SHARING */ -+ -+int __init -+init_ext3_xattr(void) -+{ -+ return 0; -+} -+ -+void -+exit_ext3_xattr(void) -+{ -+} -+ -+#endif /* CONFIG_EXT3_FS_XATTR_SHARING */ -Index: linux-2.4.24-vanilla/fs/ext3/xattr_user.c -=================================================================== ---- linux-2.4.24-vanilla.orig/fs/ext3/xattr_user.c 2003-01-30 13:24:37.000000000 +0300 -+++ linux-2.4.24-vanilla/fs/ext3/xattr_user.c 2004-01-10 17:20:28.000000000 +0300 -@@ -0,0 +1,111 @@ -+/* -+ * linux/fs/ext3/xattr_user.c -+ * Handler for extended user attributes. -+ * -+ * Copyright (C) 2001 by Andreas Gruenbacher, -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef CONFIG_EXT3_FS_POSIX_ACL -+# include -+#endif -+ -+#define XATTR_USER_PREFIX "user." -+ -+static size_t -+ext3_xattr_user_list(char *list, struct inode *inode, -+ const char *name, int name_len) -+{ -+ const int prefix_len = sizeof(XATTR_USER_PREFIX)-1; -+ -+ if (!test_opt(inode->i_sb, XATTR_USER)) -+ return 0; -+ -+ if (list) { -+ memcpy(list, XATTR_USER_PREFIX, prefix_len); -+ memcpy(list+prefix_len, name, name_len); -+ list[prefix_len + name_len] = '\0'; -+ } -+ return prefix_len + name_len + 1; -+} -+ -+static int -+ext3_xattr_user_get(struct inode *inode, const char *name, -+ void *buffer, size_t size) -+{ -+ int error; -+ -+ if (strcmp(name, "") == 0) -+ return -EINVAL; -+ if (!test_opt(inode->i_sb, XATTR_USER)) -+ return -ENOTSUP; -+#ifdef CONFIG_EXT3_FS_POSIX_ACL -+ error = ext3_permission_locked(inode, MAY_READ); -+#else -+ error = permission(inode, MAY_READ); -+#endif -+ if (error) -+ return error; -+ -+ return ext3_xattr_get(inode, EXT3_XATTR_INDEX_USER, name, -+ buffer, size); -+} -+ -+static int -+ext3_xattr_user_set(struct inode *inode, const char *name, -+ const void *value, size_t size, int flags) -+{ -+ handle_t *handle; -+ int error; -+ -+ if (strcmp(name, "") == 0) -+ return -EINVAL; -+ if (!test_opt(inode->i_sb, XATTR_USER)) -+ return -ENOTSUP; -+ if ( !S_ISREG(inode->i_mode) && -+ (!S_ISDIR(inode->i_mode) || inode->i_mode & S_ISVTX)) -+ return -EPERM; -+#ifdef CONFIG_EXT3_FS_POSIX_ACL -+ error = ext3_permission_locked(inode, MAY_WRITE); -+#else -+ error = permission(inode, MAY_WRITE); -+#endif -+ if (error) -+ return error; -+ -+ handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS); -+ if (IS_ERR(handle)) -+ return PTR_ERR(handle); -+ error = ext3_xattr_set(handle, inode, EXT3_XATTR_INDEX_USER, name, -+ value, size, flags); -+ ext3_journal_stop(handle, inode); -+ -+ return error; -+} -+ -+struct ext3_xattr_handler ext3_xattr_user_handler = { -+ prefix: XATTR_USER_PREFIX, -+ list: ext3_xattr_user_list, -+ get: ext3_xattr_user_get, -+ set: ext3_xattr_user_set, -+}; -+ -+int __init -+init_ext3_xattr_user(void) -+{ -+ return ext3_xattr_register(EXT3_XATTR_INDEX_USER, -+ &ext3_xattr_user_handler); -+} -+ -+void -+exit_ext3_xattr_user(void) -+{ -+ ext3_xattr_unregister(EXT3_XATTR_INDEX_USER, -+ &ext3_xattr_user_handler); -+} -Index: linux-2.4.24-vanilla/fs/ext3/ext3-exports.c -=================================================================== ---- linux-2.4.24-vanilla.orig/fs/ext3/ext3-exports.c 2003-01-30 13:24:37.000000000 +0300 -+++ linux-2.4.24-vanilla/fs/ext3/ext3-exports.c 2004-01-10 17:20:28.000000000 +0300 -@@ -0,0 +1,13 @@ -+#include -+#include -+#include -+#include -+#include -+ -+EXPORT_SYMBOL(ext3_force_commit); -+EXPORT_SYMBOL(ext3_bread); -+EXPORT_SYMBOL(ext3_xattr_register); -+EXPORT_SYMBOL(ext3_xattr_unregister); -+EXPORT_SYMBOL(ext3_xattr_get); -+EXPORT_SYMBOL(ext3_xattr_list); -+EXPORT_SYMBOL(ext3_xattr_set); -Index: linux-2.4.24-vanilla/fs/jfs/jfs_xattr.h -=================================================================== ---- linux-2.4.24-vanilla.orig/fs/jfs/jfs_xattr.h 2003-05-16 05:29:12.000000000 +0400 -+++ linux-2.4.24-vanilla/fs/jfs/jfs_xattr.h 2004-01-10 17:20:28.000000000 +0300 -@@ -52,8 +52,10 @@ - #define END_EALIST(ealist) \ - ((struct jfs_ea *) (((char *) (ealist)) + EALIST_SIZE(ealist))) - --extern int __jfs_setxattr(struct inode *, const char *, void *, size_t, int); --extern int jfs_setxattr(struct dentry *, const char *, void *, size_t, int); -+extern int __jfs_setxattr(struct inode *, const char *, const void *, size_t, -+ int); -+extern int jfs_setxattr(struct dentry *, const char *, const void *, size_t, -+ int); - extern ssize_t __jfs_getxattr(struct inode *, const char *, void *, size_t); - extern ssize_t jfs_getxattr(struct dentry *, const char *, void *, size_t); - extern ssize_t jfs_listxattr(struct dentry *, char *, size_t); -Index: linux-2.4.24-vanilla/fs/jfs/xattr.c -=================================================================== ---- linux-2.4.24-vanilla.orig/fs/jfs/xattr.c 2004-01-10 17:05:55.000000000 +0300 -+++ linux-2.4.24-vanilla/fs/jfs/xattr.c 2004-01-10 17:20:28.000000000 +0300 -@@ -648,7 +648,7 @@ - } - - static int can_set_xattr(struct inode *inode, const char *name, -- void *value, size_t value_len) -+ const void *value, size_t value_len) - { - if (IS_RDONLY(inode)) - return -EROFS; -@@ -667,7 +667,7 @@ - return permission(inode, MAY_WRITE); - } - --int __jfs_setxattr(struct inode *inode, const char *name, void *value, -+int __jfs_setxattr(struct inode *inode, const char *name, const void *value, - size_t value_len, int flags) - { - struct jfs_ea_list *ealist; -@@ -806,7 +806,7 @@ - return rc; - } - --int jfs_setxattr(struct dentry *dentry, const char *name, void *value, -+int jfs_setxattr(struct dentry *dentry, const char *name, const void *value, - size_t value_len, int flags) - { - if (value == NULL) { /* empty EA, do not remove */ -Index: linux-2.4.24-vanilla/fs/mbcache.c -=================================================================== ---- linux-2.4.24-vanilla.orig/fs/mbcache.c 2003-01-30 13:24:37.000000000 +0300 -+++ linux-2.4.24-vanilla/fs/mbcache.c 2004-01-10 17:20:28.000000000 +0300 -@@ -0,0 +1,648 @@ -+/* -+ * linux/fs/mbcache.c -+ * (C) 2001-2002 Andreas Gruenbacher, -+ */ -+ -+/* -+ * Filesystem Meta Information Block Cache (mbcache) -+ * -+ * The mbcache caches blocks of block devices that need to be located -+ * by their device/block number, as well as by other criteria (such -+ * as the block's contents). -+ * -+ * There can only be one cache entry in a cache per device and block number. -+ * Additional indexes need not be unique in this sense. The number of -+ * additional indexes (=other criteria) can be hardwired at compile time -+ * or specified at cache create time. -+ * -+ * Each cache entry is of fixed size. An entry may be `valid' or `invalid' -+ * in the cache. A valid entry is in the main hash tables of the cache, -+ * and may also be in the lru list. An invalid entry is not in any hashes -+ * or lists. -+ * -+ * A valid cache entry is only in the lru list if no handles refer to it. -+ * Invalid cache entries will be freed when the last handle to the cache -+ * entry is released. Entries that cannot be freed immediately are put -+ * back on the lru list. -+ */ -+ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+ -+#ifdef MB_CACHE_DEBUG -+# define mb_debug(f...) do { \ -+ printk(KERN_DEBUG f); \ -+ printk("\n"); \ -+ } while (0) -+#define mb_assert(c) do { if (!(c)) \ -+ printk(KERN_ERR "assertion " #c " failed\n"); \ -+ } while(0) -+#else -+# define mb_debug(f...) do { } while(0) -+# define mb_assert(c) do { } while(0) -+#endif -+#define mb_error(f...) do { \ -+ printk(KERN_ERR f); \ -+ printk("\n"); \ -+ } while(0) -+ -+MODULE_AUTHOR("Andreas Gruenbacher "); -+MODULE_DESCRIPTION("Meta block cache (for extended attributes)"); -+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0) -+MODULE_LICENSE("GPL"); -+#endif -+ -+EXPORT_SYMBOL(mb_cache_create); -+EXPORT_SYMBOL(mb_cache_shrink); -+EXPORT_SYMBOL(mb_cache_destroy); -+EXPORT_SYMBOL(mb_cache_entry_alloc); -+EXPORT_SYMBOL(mb_cache_entry_insert); -+EXPORT_SYMBOL(mb_cache_entry_release); -+EXPORT_SYMBOL(mb_cache_entry_takeout); -+EXPORT_SYMBOL(mb_cache_entry_free); -+EXPORT_SYMBOL(mb_cache_entry_dup); -+EXPORT_SYMBOL(mb_cache_entry_get); -+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) -+EXPORT_SYMBOL(mb_cache_entry_find_first); -+EXPORT_SYMBOL(mb_cache_entry_find_next); -+#endif -+ -+ -+/* -+ * Global data: list of all mbcache's, lru list, and a spinlock for -+ * accessing cache data structures on SMP machines. The lru list is -+ * global across all mbcaches. -+ */ -+ -+static LIST_HEAD(mb_cache_list); -+static LIST_HEAD(mb_cache_lru_list); -+static spinlock_t mb_cache_spinlock = SPIN_LOCK_UNLOCKED; -+ -+static inline int -+mb_cache_indexes(struct mb_cache *cache) -+{ -+#ifdef MB_CACHE_INDEXES_COUNT -+ return MB_CACHE_INDEXES_COUNT; -+#else -+ return cache->c_indexes_count; -+#endif -+} -+ -+/* -+ * What the mbcache registers as to get shrunk dynamically. -+ */ -+ -+static void -+mb_cache_memory_pressure(int priority, unsigned int gfp_mask); -+ -+static struct cache_definition mb_cache_definition = { -+ "mb_cache", -+ mb_cache_memory_pressure -+}; -+ -+ -+static inline int -+__mb_cache_entry_is_hashed(struct mb_cache_entry *ce) -+{ -+ return !list_empty(&ce->e_block_list); -+} -+ -+ -+static inline void -+__mb_cache_entry_unhash(struct mb_cache_entry *ce) -+{ -+ int n; -+ -+ if (__mb_cache_entry_is_hashed(ce)) { -+ list_del_init(&ce->e_block_list); -+ for (n=0; ne_cache); n++) -+ list_del(&ce->e_indexes[n].o_list); -+ } -+} -+ -+ -+static inline void -+__mb_cache_entry_forget(struct mb_cache_entry *ce, int gfp_mask) -+{ -+ struct mb_cache *cache = ce->e_cache; -+ -+ mb_assert(atomic_read(&ce->e_used) == 0); -+ if (cache->c_op.free && cache->c_op.free(ce, gfp_mask)) { -+ /* free failed -- put back on the lru list -+ for freeing later. */ -+ spin_lock(&mb_cache_spinlock); -+ list_add(&ce->e_lru_list, &mb_cache_lru_list); -+ spin_unlock(&mb_cache_spinlock); -+ } else { -+ kmem_cache_free(cache->c_entry_cache, ce); -+ atomic_dec(&cache->c_entry_count); -+ } -+} -+ -+ -+static inline void -+__mb_cache_entry_release_unlock(struct mb_cache_entry *ce) -+{ -+ if (atomic_dec_and_test(&ce->e_used)) { -+ if (__mb_cache_entry_is_hashed(ce)) -+ list_add_tail(&ce->e_lru_list, &mb_cache_lru_list); -+ else { -+ spin_unlock(&mb_cache_spinlock); -+ __mb_cache_entry_forget(ce, GFP_KERNEL); -+ return; -+ } -+ } -+ spin_unlock(&mb_cache_spinlock); -+} -+ -+ -+/* -+ * mb_cache_memory_pressure() memory pressure callback -+ * -+ * This function is called by the kernel memory management when memory -+ * gets low. -+ * -+ * @priority: Amount by which to shrink the cache (0 = highes priority) -+ * @gfp_mask: (ignored) -+ */ -+static void -+mb_cache_memory_pressure(int priority, unsigned int gfp_mask) -+{ -+ LIST_HEAD(free_list); -+ struct list_head *l, *ltmp; -+ int count = 0; -+ -+ spin_lock(&mb_cache_spinlock); -+ list_for_each(l, &mb_cache_list) { -+ struct mb_cache *cache = -+ list_entry(l, struct mb_cache, c_cache_list); -+ mb_debug("cache %s (%d)", cache->c_name, -+ atomic_read(&cache->c_entry_count)); -+ count += atomic_read(&cache->c_entry_count); -+ } -+ mb_debug("trying to free %d of %d entries", -+ count / (priority ? priority : 1), count); -+ if (priority) -+ count /= priority; -+ while (count-- && !list_empty(&mb_cache_lru_list)) { -+ struct mb_cache_entry *ce = -+ list_entry(mb_cache_lru_list.next, -+ struct mb_cache_entry, e_lru_list); -+ list_del(&ce->e_lru_list); -+ __mb_cache_entry_unhash(ce); -+ list_add_tail(&ce->e_lru_list, &free_list); -+ } -+ spin_unlock(&mb_cache_spinlock); -+ list_for_each_safe(l, ltmp, &free_list) { -+ __mb_cache_entry_forget(list_entry(l, struct mb_cache_entry, -+ e_lru_list), gfp_mask); -+ } -+} -+ -+ -+/* -+ * mb_cache_create() create a new cache -+ * -+ * All entries in one cache are equal size. Cache entries may be from -+ * multiple devices. If this is the first mbcache created, registers -+ * the cache with kernel memory management. Returns NULL if no more -+ * memory was available. -+ * -+ * @name: name of the cache (informal) -+ * @cache_op: contains the callback called when freeing a cache entry -+ * @entry_size: The size of a cache entry, including -+ * struct mb_cache_entry -+ * @indexes_count: number of additional indexes in the cache. Must equal -+ * MB_CACHE_INDEXES_COUNT if the number of indexes is -+ * hardwired. -+ * @bucket_count: number of hash buckets -+ */ -+struct mb_cache * -+mb_cache_create(const char *name, struct mb_cache_op *cache_op, -+ size_t entry_size, int indexes_count, int bucket_count) -+{ -+ int m=0, n; -+ struct mb_cache *cache = NULL; -+ -+ if(entry_size < sizeof(struct mb_cache_entry) + -+ indexes_count * sizeof(struct mb_cache_entry_index)) -+ return NULL; -+ -+ MOD_INC_USE_COUNT; -+ cache = kmalloc(sizeof(struct mb_cache) + -+ indexes_count * sizeof(struct list_head), GFP_KERNEL); -+ if (!cache) -+ goto fail; -+ cache->c_name = name; -+ cache->c_op.free = NULL; -+ if (cache_op) -+ cache->c_op.free = cache_op->free; -+ atomic_set(&cache->c_entry_count, 0); -+ cache->c_bucket_count = bucket_count; -+#ifdef MB_CACHE_INDEXES_COUNT -+ mb_assert(indexes_count == MB_CACHE_INDEXES_COUNT); -+#else -+ cache->c_indexes_count = indexes_count; -+#endif -+ cache->c_block_hash = kmalloc(bucket_count * sizeof(struct list_head), -+ GFP_KERNEL); -+ if (!cache->c_block_hash) -+ goto fail; -+ for (n=0; nc_block_hash[n]); -+ for (m=0; mc_indexes_hash[m] = kmalloc(bucket_count * -+ sizeof(struct list_head), -+ GFP_KERNEL); -+ if (!cache->c_indexes_hash[m]) -+ goto fail; -+ for (n=0; nc_indexes_hash[m][n]); -+ } -+ cache->c_entry_cache = kmem_cache_create(name, entry_size, 0, -+ 0 /*SLAB_POISON | SLAB_RED_ZONE*/, NULL, NULL); -+ if (!cache->c_entry_cache) -+ goto fail; -+ -+ spin_lock(&mb_cache_spinlock); -+ list_add(&cache->c_cache_list, &mb_cache_list); -+ spin_unlock(&mb_cache_spinlock); -+ return cache; -+ -+fail: -+ if (cache) { -+ while (--m >= 0) -+ kfree(cache->c_indexes_hash[m]); -+ if (cache->c_block_hash) -+ kfree(cache->c_block_hash); -+ kfree(cache); -+ } -+ MOD_DEC_USE_COUNT; -+ return NULL; -+} -+ -+ -+/* -+ * mb_cache_shrink() -+ * -+ * Removes all cache entires of a device from the cache. All cache entries -+ * currently in use cannot be freed, and thus remain in the cache. -+ * -+ * @cache: which cache to shrink -+ * @dev: which device's cache entries to shrink -+ */ -+void -+mb_cache_shrink(struct mb_cache *cache, kdev_t dev) -+{ -+ LIST_HEAD(free_list); -+ struct list_head *l, *ltmp; -+ -+ spin_lock(&mb_cache_spinlock); -+ list_for_each_safe(l, ltmp, &mb_cache_lru_list) { -+ struct mb_cache_entry *ce = -+ list_entry(l, struct mb_cache_entry, e_lru_list); -+ if (ce->e_dev == dev) { -+ list_del(&ce->e_lru_list); -+ list_add_tail(&ce->e_lru_list, &free_list); -+ __mb_cache_entry_unhash(ce); -+ } -+ } -+ spin_unlock(&mb_cache_spinlock); -+ list_for_each_safe(l, ltmp, &free_list) { -+ __mb_cache_entry_forget(list_entry(l, struct mb_cache_entry, -+ e_lru_list), GFP_KERNEL); -+ } -+} -+ -+ -+/* -+ * mb_cache_destroy() -+ * -+ * Shrinks the cache to its minimum possible size (hopefully 0 entries), -+ * and then destroys it. If this was the last mbcache, un-registers the -+ * mbcache from kernel memory management. -+ */ -+void -+mb_cache_destroy(struct mb_cache *cache) -+{ -+ LIST_HEAD(free_list); -+ struct list_head *l, *ltmp; -+ int n; -+ -+ spin_lock(&mb_cache_spinlock); -+ list_for_each_safe(l, ltmp, &mb_cache_lru_list) { -+ struct mb_cache_entry *ce = -+ list_entry(l, struct mb_cache_entry, e_lru_list); -+ if (ce->e_cache == cache) { -+ list_del(&ce->e_lru_list); -+ list_add_tail(&ce->e_lru_list, &free_list); -+ __mb_cache_entry_unhash(ce); -+ } -+ } -+ list_del(&cache->c_cache_list); -+ spin_unlock(&mb_cache_spinlock); -+ list_for_each_safe(l, ltmp, &free_list) { -+ __mb_cache_entry_forget(list_entry(l, struct mb_cache_entry, -+ e_lru_list), GFP_KERNEL); -+ } -+ -+ if (atomic_read(&cache->c_entry_count) > 0) { -+ mb_error("cache %s: %d orphaned entries", -+ cache->c_name, -+ atomic_read(&cache->c_entry_count)); -+ } -+ -+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)) -+ /* We don't have kmem_cache_destroy() in 2.2.x */ -+ kmem_cache_shrink(cache->c_entry_cache); -+#else -+ kmem_cache_destroy(cache->c_entry_cache); -+#endif -+ for (n=0; n < mb_cache_indexes(cache); n++) -+ kfree(cache->c_indexes_hash[n]); -+ kfree(cache->c_block_hash); -+ kfree(cache); -+ -+ MOD_DEC_USE_COUNT; -+} -+ -+ -+/* -+ * mb_cache_entry_alloc() -+ * -+ * Allocates a new cache entry. The new entry will not be valid initially, -+ * and thus cannot be looked up yet. It should be filled with data, and -+ * then inserted into the cache using mb_cache_entry_insert(). Returns NULL -+ * if no more memory was available. -+ */ -+struct mb_cache_entry * -+mb_cache_entry_alloc(struct mb_cache *cache) -+{ -+ struct mb_cache_entry *ce; -+ -+ atomic_inc(&cache->c_entry_count); -+ ce = kmem_cache_alloc(cache->c_entry_cache, GFP_KERNEL); -+ if (ce) { -+ INIT_LIST_HEAD(&ce->e_lru_list); -+ INIT_LIST_HEAD(&ce->e_block_list); -+ ce->e_cache = cache; -+ atomic_set(&ce->e_used, 1); -+ } -+ return ce; -+} -+ -+ -+/* -+ * mb_cache_entry_insert() -+ * -+ * Inserts an entry that was allocated using mb_cache_entry_alloc() into -+ * the cache. After this, the cache entry can be looked up, but is not yet -+ * in the lru list as the caller still holds a handle to it. Returns 0 on -+ * success, or -EBUSY if a cache entry for that device + inode exists -+ * already (this may happen after a failed lookup, if another process has -+ * inserted the same cache entry in the meantime). -+ * -+ * @dev: device the cache entry belongs to -+ * @block: block number -+ * @keys: array of additional keys. There must be indexes_count entries -+ * in the array (as specified when creating the cache). -+ */ -+int -+mb_cache_entry_insert(struct mb_cache_entry *ce, kdev_t dev, -+ unsigned long block, unsigned int keys[]) -+{ -+ struct mb_cache *cache = ce->e_cache; -+ unsigned int bucket = (HASHDEV(dev) + block) % cache->c_bucket_count; -+ struct list_head *l; -+ int error = -EBUSY, n; -+ -+ spin_lock(&mb_cache_spinlock); -+ list_for_each(l, &cache->c_block_hash[bucket]) { -+ struct mb_cache_entry *ce = -+ list_entry(l, struct mb_cache_entry, e_block_list); -+ if (ce->e_dev == dev && ce->e_block == block) -+ goto out; -+ } -+ __mb_cache_entry_unhash(ce); -+ ce->e_dev = dev; -+ ce->e_block = block; -+ list_add(&ce->e_block_list, &cache->c_block_hash[bucket]); -+ for (n=0; ne_indexes[n].o_key = keys[n]; -+ bucket = keys[n] % cache->c_bucket_count; -+ list_add(&ce->e_indexes[n].o_list, -+ &cache->c_indexes_hash[n][bucket]); -+ } -+out: -+ spin_unlock(&mb_cache_spinlock); -+ return error; -+} -+ -+ -+/* -+ * mb_cache_entry_release() -+ * -+ * Release a handle to a cache entry. When the last handle to a cache entry -+ * is released it is either freed (if it is invalid) or otherwise inserted -+ * in to the lru list. -+ */ -+void -+mb_cache_entry_release(struct mb_cache_entry *ce) -+{ -+ spin_lock(&mb_cache_spinlock); -+ __mb_cache_entry_release_unlock(ce); -+} -+ -+ -+/* -+ * mb_cache_entry_takeout() -+ * -+ * Take a cache entry out of the cache, making it invalid. The entry can later -+ * be re-inserted using mb_cache_entry_insert(), or released using -+ * mb_cache_entry_release(). -+ */ -+void -+mb_cache_entry_takeout(struct mb_cache_entry *ce) -+{ -+ spin_lock(&mb_cache_spinlock); -+ mb_assert(list_empty(&ce->e_lru_list)); -+ __mb_cache_entry_unhash(ce); -+ spin_unlock(&mb_cache_spinlock); -+} -+ -+ -+/* -+ * mb_cache_entry_free() -+ * -+ * This is equivalent to the sequence mb_cache_entry_takeout() -- -+ * mb_cache_entry_release(). -+ */ -+void -+mb_cache_entry_free(struct mb_cache_entry *ce) -+{ -+ spin_lock(&mb_cache_spinlock); -+ mb_assert(list_empty(&ce->e_lru_list)); -+ __mb_cache_entry_unhash(ce); -+ __mb_cache_entry_release_unlock(ce); -+} -+ -+ -+/* -+ * mb_cache_entry_dup() -+ * -+ * Duplicate a handle to a cache entry (does not duplicate the cache entry -+ * itself). After the call, both the old and the new handle must be released. -+ */ -+struct mb_cache_entry * -+mb_cache_entry_dup(struct mb_cache_entry *ce) -+{ -+ atomic_inc(&ce->e_used); -+ return ce; -+} -+ -+ -+/* -+ * mb_cache_entry_get() -+ * -+ * Get a cache entry by device / block number. (There can only be one entry -+ * in the cache per device and block.) Returns NULL if no such cache entry -+ * exists. -+ */ -+struct mb_cache_entry * -+mb_cache_entry_get(struct mb_cache *cache, kdev_t dev, unsigned long block) -+{ -+ unsigned int bucket = (HASHDEV(dev) + block) % cache->c_bucket_count; -+ struct list_head *l; -+ struct mb_cache_entry *ce; -+ -+ spin_lock(&mb_cache_spinlock); -+ list_for_each(l, &cache->c_block_hash[bucket]) { -+ ce = list_entry(l, struct mb_cache_entry, e_block_list); -+ if (ce->e_dev == dev && ce->e_block == block) { -+ if (!list_empty(&ce->e_lru_list)) -+ list_del_init(&ce->e_lru_list); -+ atomic_inc(&ce->e_used); -+ goto cleanup; -+ } -+ } -+ ce = NULL; -+ -+cleanup: -+ spin_unlock(&mb_cache_spinlock); -+ return ce; -+} -+ -+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) -+ -+static struct mb_cache_entry * -+__mb_cache_entry_find(struct list_head *l, struct list_head *head, -+ int index, kdev_t dev, unsigned int key) -+{ -+ while (l != head) { -+ struct mb_cache_entry *ce = -+ list_entry(l, struct mb_cache_entry, -+ e_indexes[index].o_list); -+ if (ce->e_dev == dev && ce->e_indexes[index].o_key == key) { -+ if (!list_empty(&ce->e_lru_list)) -+ list_del_init(&ce->e_lru_list); -+ atomic_inc(&ce->e_used); -+ return ce; -+ } -+ l = l->next; -+ } -+ return NULL; -+} -+ -+ -+/* -+ * mb_cache_entry_find_first() -+ * -+ * Find the first cache entry on a given device with a certain key in -+ * an additional index. Additonal matches can be found with -+ * mb_cache_entry_find_next(). Returns NULL if no match was found. -+ * -+ * @cache: the cache to search -+ * @index: the number of the additonal index to search (0<=indexc_bucket_count; -+ struct list_head *l; -+ struct mb_cache_entry *ce; -+ -+ mb_assert(index < mb_cache_indexes(cache)); -+ spin_lock(&mb_cache_spinlock); -+ l = cache->c_indexes_hash[index][bucket].next; -+ ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket], -+ index, dev, key); -+ spin_unlock(&mb_cache_spinlock); -+ return ce; -+} -+ -+ -+/* -+ * mb_cache_entry_find_next() -+ * -+ * Find the next cache entry on a given device with a certain key in an -+ * additional index. Returns NULL if no match could be found. The previous -+ * entry is atomatically released, so that mb_cache_entry_find_next() can -+ * be called like this: -+ * -+ * entry = mb_cache_entry_find_first(); -+ * while (entry) { -+ * ... -+ * entry = mb_cache_entry_find_next(entry, ...); -+ * } -+ * -+ * @prev: The previous match -+ * @index: the number of the additonal index to search (0<=indexe_cache; -+ unsigned int bucket = key % cache->c_bucket_count; -+ struct list_head *l; -+ struct mb_cache_entry *ce; -+ -+ mb_assert(index < mb_cache_indexes(cache)); -+ spin_lock(&mb_cache_spinlock); -+ l = prev->e_indexes[index].o_list.next; -+ ce = __mb_cache_entry_find(l, &cache->c_indexes_hash[index][bucket], -+ index, dev, key); -+ __mb_cache_entry_release_unlock(prev); -+ return ce; -+} -+ -+#endif /* !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) */ -+ -+static int __init init_mbcache(void) -+{ -+ register_cache(&mb_cache_definition); -+ return 0; -+} -+ -+static void __exit exit_mbcache(void) -+{ -+ unregister_cache(&mb_cache_definition); -+} -+ -+module_init(init_mbcache) -+module_exit(exit_mbcache) -+ -Index: linux-2.4.24-vanilla/include/asm-arm/unistd.h -=================================================================== ---- linux-2.4.24-vanilla.orig/include/asm-arm/unistd.h 2004-01-10 17:05:06.000000000 +0300 -+++ linux-2.4.24-vanilla/include/asm-arm/unistd.h 2004-01-10 17:20:28.000000000 +0300 -@@ -250,7 +250,6 @@ - #define __NR_security (__NR_SYSCALL_BASE+223) - #define __NR_gettid (__NR_SYSCALL_BASE+224) - #define __NR_readahead (__NR_SYSCALL_BASE+225) --#if 0 /* allocated in 2.5 */ - #define __NR_setxattr (__NR_SYSCALL_BASE+226) - #define __NR_lsetxattr (__NR_SYSCALL_BASE+227) - #define __NR_fsetxattr (__NR_SYSCALL_BASE+228) -@@ -263,7 +262,6 @@ - #define __NR_removexattr (__NR_SYSCALL_BASE+235) - #define __NR_lremovexattr (__NR_SYSCALL_BASE+236) - #define __NR_fremovexattr (__NR_SYSCALL_BASE+237) --#endif - #define __NR_tkill (__NR_SYSCALL_BASE+238) - #if 0 /* allocated in 2.5 */ - #define __NR_sendfile64 (__NR_SYSCALL_BASE+239) -Index: linux-2.4.24-vanilla/include/asm-ppc64/unistd.h -=================================================================== ---- linux-2.4.24-vanilla.orig/include/asm-ppc64/unistd.h 2004-01-10 17:05:59.000000000 +0300 -+++ linux-2.4.24-vanilla/include/asm-ppc64/unistd.h 2004-01-10 17:20:28.000000000 +0300 -@@ -218,6 +218,7 @@ - #define __NR_mincore 206 - #define __NR_gettid 207 - #define __NR_tkill 208 -+#endif - #define __NR_setxattr 209 - #define __NR_lsetxattr 210 - #define __NR_fsetxattr 211 -@@ -230,6 +231,7 @@ - #define __NR_removexattr 218 - #define __NR_lremovexattr 219 - #define __NR_fremovexattr 220 -+#if 0 /* Reserved syscalls */ - #define __NR_futex 221 - #define __NR_sched_setaffinity 222 - #define __NR_sched_getaffinity 223 -Index: linux-2.4.24-vanilla/include/asm-s390/unistd.h -=================================================================== ---- linux-2.4.24-vanilla.orig/include/asm-s390/unistd.h 2004-01-10 17:04:42.000000000 +0300 -+++ linux-2.4.24-vanilla/include/asm-s390/unistd.h 2004-01-10 17:20:28.000000000 +0300 -@@ -213,9 +213,18 @@ - #define __NR_getdents64 220 - #define __NR_fcntl64 221 - #define __NR_readahead 222 --/* -- * Numbers 224-235 are reserved for posix acl -- */ -+#define __NR_setxattr 224 -+#define __NR_lsetxattr 225 -+#define __NR_fsetxattr 226 -+#define __NR_getxattr 227 -+#define __NR_lgetxattr 228 -+#define __NR_fgetxattr 229 -+#define __NR_listxattr 230 -+#define __NR_llistxattr 231 -+#define __NR_flistxattr 232 -+#define __NR_removexattr 233 -+#define __NR_lremovexattr 234 -+#define __NR_fremovexattr 235 - #define __NR_gettid 236 - #define __NR_tkill 237 - -Index: linux-2.4.24-vanilla/include/asm-s390x/unistd.h -=================================================================== ---- linux-2.4.24-vanilla.orig/include/asm-s390x/unistd.h 2004-01-10 17:04:42.000000000 +0300 -+++ linux-2.4.24-vanilla/include/asm-s390x/unistd.h 2004-01-10 17:20:28.000000000 +0300 -@@ -181,9 +181,18 @@ - #define __NR_mincore 218 - #define __NR_madvise 219 - #define __NR_readahead 222 --/* -- * Numbers 224-235 are reserved for posix acl -- */ -+#define __NR_setxattr 224 -+#define __NR_lsetxattr 225 -+#define __NR_fsetxattr 226 -+#define __NR_getxattr 227 -+#define __NR_lgetxattr 228 -+#define __NR_fgetxattr 229 -+#define __NR_listxattr 230 -+#define __NR_llistxattr 231 -+#define __NR_flistxattr 232 -+#define __NR_removexattr 233 -+#define __NR_lremovexattr 234 -+#define __NR_fremovexattr 235 - #define __NR_gettid 236 - #define __NR_tkill 237 - -Index: linux-2.4.24-vanilla/include/linux/cache_def.h -=================================================================== ---- linux-2.4.24-vanilla.orig/include/linux/cache_def.h 2003-01-30 13:24:37.000000000 +0300 -+++ linux-2.4.24-vanilla/include/linux/cache_def.h 2004-01-10 17:20:28.000000000 +0300 -@@ -0,0 +1,15 @@ -+/* -+ * linux/cache_def.h -+ * Handling of caches defined in drivers, filesystems, ... -+ * -+ * Copyright (C) 2002 by Andreas Gruenbacher, -+ */ -+ -+struct cache_definition { -+ const char *name; -+ void (*shrink)(int, unsigned int); -+ struct list_head link; -+}; -+ -+extern void register_cache(struct cache_definition *); -+extern void unregister_cache(struct cache_definition *); -Index: linux-2.4.24-vanilla/include/linux/errno.h -=================================================================== ---- linux-2.4.24-vanilla.orig/include/linux/errno.h 2001-02-10 01:46:13.000000000 +0300 -+++ linux-2.4.24-vanilla/include/linux/errno.h 2004-01-10 17:20:28.000000000 +0300 -@@ -23,4 +23,8 @@ - - #endif - -+/* Defined for extended attributes */ -+#define ENOATTR ENODATA /* No such attribute */ -+#define ENOTSUP EOPNOTSUPP /* Operation not supported */ -+ - #endif -Index: linux-2.4.24-vanilla/include/linux/ext2_fs.h -=================================================================== ---- linux-2.4.24-vanilla.orig/include/linux/ext2_fs.h 2004-01-10 17:04:42.000000000 +0300 -+++ linux-2.4.24-vanilla/include/linux/ext2_fs.h 2004-01-10 17:20:28.000000000 +0300 -@@ -57,8 +57,6 @@ - */ - #define EXT2_BAD_INO 1 /* Bad blocks inode */ - #define EXT2_ROOT_INO 2 /* Root inode */ --#define EXT2_ACL_IDX_INO 3 /* ACL inode */ --#define EXT2_ACL_DATA_INO 4 /* ACL inode */ - #define EXT2_BOOT_LOADER_INO 5 /* Boot loader inode */ - #define EXT2_UNDEL_DIR_INO 6 /* Undelete directory inode */ - -@@ -86,7 +84,6 @@ - #else - # define EXT2_BLOCK_SIZE(s) (EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size) - #endif --#define EXT2_ACLE_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry)) - #define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32)) - #ifdef __KERNEL__ - # define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) -@@ -121,28 +118,6 @@ - #endif - - /* -- * ACL structures -- */ --struct ext2_acl_header /* Header of Access Control Lists */ --{ -- __u32 aclh_size; -- __u32 aclh_file_count; -- __u32 aclh_acle_count; -- __u32 aclh_first_acle; --}; -- --struct ext2_acl_entry /* Access Control List Entry */ --{ -- __u32 acle_size; -- __u16 acle_perms; /* Access permissions */ -- __u16 acle_type; /* Type of entry */ -- __u16 acle_tag; /* User or group identity */ -- __u16 acle_pad1; -- __u32 acle_next; /* Pointer on next entry for the */ -- /* same inode or on next free entry */ --}; -- --/* - * Structure of a blocks group descriptor - */ - struct ext2_group_desc -@@ -314,6 +289,7 @@ - #define EXT2_MOUNT_ERRORS_PANIC 0x0040 /* Panic on errors */ - #define EXT2_MOUNT_MINIX_DF 0x0080 /* Mimics the Minix statfs */ - #define EXT2_MOUNT_NO_UID32 0x0200 /* Disable 32-bit UIDs */ -+#define EXT2_MOUNT_XATTR_USER 0x4000 /* Extended user attributes */ - - #define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt - #define set_opt(o, opt) o |= EXT2_MOUNT_##opt -@@ -397,6 +373,7 @@ - - #ifdef __KERNEL__ - #define EXT2_SB(sb) (&((sb)->u.ext2_sb)) -+#define EXT2_I(inode) (&((inode)->u.ext2_i)) - #else - /* Assume that user mode programs are passing in an ext2fs superblock, not - * a kernel struct super_block. This will allow us to call the feature-test -@@ -466,7 +443,7 @@ - #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 - #define EXT2_FEATURE_INCOMPAT_ANY 0xffffffff - --#define EXT2_FEATURE_COMPAT_SUPP 0 -+#define EXT2_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR - #define EXT2_FEATURE_INCOMPAT_SUPP EXT2_FEATURE_INCOMPAT_FILETYPE - #define EXT2_FEATURE_RO_COMPAT_SUPP (EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER| \ - EXT2_FEATURE_RO_COMPAT_LARGE_FILE| \ -@@ -624,8 +601,10 @@ - - /* namei.c */ - extern struct inode_operations ext2_dir_inode_operations; -+extern struct inode_operations ext2_special_inode_operations; - - /* symlink.c */ -+extern struct inode_operations ext2_symlink_inode_operations; - extern struct inode_operations ext2_fast_symlink_inode_operations; - - #endif /* __KERNEL__ */ -Index: linux-2.4.24-vanilla/include/linux/ext2_xattr.h -=================================================================== ---- linux-2.4.24-vanilla.orig/include/linux/ext2_xattr.h 2003-01-30 13:24:37.000000000 +0300 -+++ linux-2.4.24-vanilla/include/linux/ext2_xattr.h 2004-01-10 17:20:28.000000000 +0300 -@@ -0,0 +1,157 @@ -+/* -+ File: linux/ext2_xattr.h -+ -+ On-disk format of extended attributes for the ext2 filesystem. -+ -+ (C) 2001 Andreas Gruenbacher, -+*/ -+ -+#include -+#include -+#include -+ -+/* Magic value in attribute blocks */ -+#define EXT2_XATTR_MAGIC 0xEA020000 -+ -+/* Maximum number of references to one attribute block */ -+#define EXT2_XATTR_REFCOUNT_MAX 1024 -+ -+/* Name indexes */ -+#define EXT2_XATTR_INDEX_MAX 10 -+#define EXT2_XATTR_INDEX_USER 1 -+#define EXT2_XATTR_INDEX_POSIX_ACL_ACCESS 2 -+#define EXT2_XATTR_INDEX_POSIX_ACL_DEFAULT 3 -+ -+struct ext2_xattr_header { -+ __u32 h_magic; /* magic number for identification */ -+ __u32 h_refcount; /* reference count */ -+ __u32 h_blocks; /* number of disk blocks used */ -+ __u32 h_hash; /* hash value of all attributes */ -+ __u32 h_reserved[4]; /* zero right now */ -+}; -+ -+struct ext2_xattr_entry { -+ __u8 e_name_len; /* length of name */ -+ __u8 e_name_index; /* attribute name index */ -+ __u16 e_value_offs; /* offset in disk block of value */ -+ __u32 e_value_block; /* disk block attribute is stored on (n/i) */ -+ __u32 e_value_size; /* size of attribute value */ -+ __u32 e_hash; /* hash value of name and value */ -+ char e_name[0]; /* attribute name */ -+}; -+ -+#define EXT2_XATTR_PAD_BITS 2 -+#define EXT2_XATTR_PAD (1<e_name_len)) ) -+#define EXT2_XATTR_SIZE(size) \ -+ (((size) + EXT2_XATTR_ROUND) & ~EXT2_XATTR_ROUND) -+ -+#ifdef __KERNEL__ -+ -+# ifdef CONFIG_EXT2_FS_XATTR -+ -+struct ext2_xattr_handler { -+ char *prefix; -+ size_t (*list)(char *list, struct inode *inode, const char *name, -+ int name_len); -+ int (*get)(struct inode *inode, const char *name, void *buffer, -+ size_t size); -+ int (*set)(struct inode *inode, const char *name, const void *buffer, -+ size_t size, int flags); -+}; -+ -+extern int ext2_xattr_register(int, struct ext2_xattr_handler *); -+extern void ext2_xattr_unregister(int, struct ext2_xattr_handler *); -+ -+extern int ext2_setxattr(struct dentry *, const char *, const void *, size_t, int); -+extern ssize_t ext2_getxattr(struct dentry *, const char *, void *, size_t); -+extern ssize_t ext2_listxattr(struct dentry *, char *, size_t); -+extern int ext2_removexattr(struct dentry *, const char *); -+ -+extern int ext2_xattr_get(struct inode *, int, const char *, void *, size_t); -+extern int ext2_xattr_list(struct inode *, char *, size_t); -+extern int ext2_xattr_set(struct inode *, int, const char *, const void *, size_t, int); -+ -+extern void ext2_xattr_delete_inode(struct inode *); -+extern void ext2_xattr_put_super(struct super_block *); -+ -+extern int init_ext2_xattr(void) __init; -+extern void exit_ext2_xattr(void); -+ -+# else /* CONFIG_EXT2_FS_XATTR */ -+# define ext2_setxattr NULL -+# define ext2_getxattr NULL -+# define ext2_listxattr NULL -+# define ext2_removexattr NULL -+ -+static inline int -+ext2_xattr_get(struct inode *inode, int name_index, -+ const char *name, void *buffer, size_t size) -+{ -+ return -ENOTSUP; -+} -+ -+static inline int -+ext2_xattr_list(struct inode *inode, char *buffer, size_t size) -+{ -+ return -ENOTSUP; -+} -+ -+static inline int -+ext2_xattr_set(struct inode *inode, int name_index, const char *name, -+ const void *value, size_t size, int flags) -+{ -+ return -ENOTSUP; -+} -+ -+static inline void -+ext2_xattr_delete_inode(struct inode *inode) -+{ -+} -+ -+static inline void -+ext2_xattr_put_super(struct super_block *sb) -+{ -+} -+ -+static inline int -+init_ext2_xattr(void) -+{ -+ return 0; -+} -+ -+static inline void -+exit_ext2_xattr(void) -+{ -+} -+ -+# endif /* CONFIG_EXT2_FS_XATTR */ -+ -+# ifdef CONFIG_EXT2_FS_XATTR_USER -+ -+extern int init_ext2_xattr_user(void) __init; -+extern void exit_ext2_xattr_user(void); -+ -+# else /* CONFIG_EXT2_FS_XATTR_USER */ -+ -+static inline int -+init_ext2_xattr_user(void) -+{ -+ return 0; -+} -+ -+static inline void -+exit_ext2_xattr_user(void) -+{ -+} -+ -+# endif /* CONFIG_EXT2_FS_XATTR_USER */ -+ -+#endif /* __KERNEL__ */ -+ -Index: linux-2.4.24-vanilla/include/linux/ext3_fs.h -=================================================================== ---- linux-2.4.24-vanilla.orig/include/linux/ext3_fs.h 2004-01-10 17:11:50.000000000 +0300 -+++ linux-2.4.24-vanilla/include/linux/ext3_fs.h 2004-01-10 17:20:28.000000000 +0300 -@@ -63,8 +63,6 @@ - */ - #define EXT3_BAD_INO 1 /* Bad blocks inode */ - #define EXT3_ROOT_INO 2 /* Root inode */ --#define EXT3_ACL_IDX_INO 3 /* ACL inode */ --#define EXT3_ACL_DATA_INO 4 /* ACL inode */ - #define EXT3_BOOT_LOADER_INO 5 /* Boot loader inode */ - #define EXT3_UNDEL_DIR_INO 6 /* Undelete directory inode */ - #define EXT3_RESIZE_INO 7 /* Reserved group descriptors inode */ -@@ -94,7 +92,6 @@ - #else - # define EXT3_BLOCK_SIZE(s) (EXT3_MIN_BLOCK_SIZE << (s)->s_log_block_size) - #endif --#define EXT3_ACLE_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (struct ext3_acl_entry)) - #define EXT3_ADDR_PER_BLOCK(s) (EXT3_BLOCK_SIZE(s) / sizeof (__u32)) - #ifdef __KERNEL__ - # define EXT3_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) -@@ -129,28 +126,6 @@ - #endif - - /* -- * ACL structures -- */ --struct ext3_acl_header /* Header of Access Control Lists */ --{ -- __u32 aclh_size; -- __u32 aclh_file_count; -- __u32 aclh_acle_count; -- __u32 aclh_first_acle; --}; -- --struct ext3_acl_entry /* Access Control List Entry */ --{ -- __u32 acle_size; -- __u16 acle_perms; /* Access permissions */ -- __u16 acle_type; /* Type of entry */ -- __u16 acle_tag; /* User or group identity */ -- __u16 acle_pad1; -- __u32 acle_next; /* Pointer on next entry for the */ -- /* same inode or on next free entry */ --}; -- --/* - * Structure of a blocks group descriptor - */ - struct ext3_group_desc -@@ -344,6 +319,7 @@ - #define EXT3_MOUNT_WRITEBACK_DATA 0x0C00 /* No data ordering */ - #define EXT3_MOUNT_UPDATE_JOURNAL 0x1000 /* Update the journal format */ - #define EXT3_MOUNT_NO_UID32 0x2000 /* Disable 32-bit UIDs */ -+#define EXT3_MOUNT_XATTR_USER 0x4000 /* Extended user attributes */ - - /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ - #ifndef _LINUX_EXT2_FS_H -@@ -521,7 +497,7 @@ - #define EXT3_FEATURE_INCOMPAT_RECOVER 0x0004 /* Needs recovery */ - #define EXT3_FEATURE_INCOMPAT_JOURNAL_DEV 0x0008 /* Journal device */ - --#define EXT3_FEATURE_COMPAT_SUPP 0 -+#define EXT3_FEATURE_COMPAT_SUPP EXT2_FEATURE_COMPAT_EXT_ATTR - #define EXT3_FEATURE_INCOMPAT_SUPP (EXT3_FEATURE_INCOMPAT_FILETYPE| \ - EXT3_FEATURE_INCOMPAT_RECOVER) - #define EXT3_FEATURE_RO_COMPAT_SUPP (EXT3_FEATURE_RO_COMPAT_SPARSE_SUPER| \ -@@ -704,6 +680,7 @@ - extern unsigned long ext3_count_free (struct buffer_head *, unsigned); - - /* inode.c */ -+extern int ext3_forget(handle_t *, int, struct inode *, struct buffer_head *, int); - extern struct buffer_head * ext3_getblk (handle_t *, struct inode *, long, int, int *); - extern struct buffer_head * ext3_bread (handle_t *, struct inode *, int, int, int *); - -@@ -773,8 +750,10 @@ - - /* namei.c */ - extern struct inode_operations ext3_dir_inode_operations; -+extern struct inode_operations ext3_special_inode_operations; - - /* symlink.c */ -+extern struct inode_operations ext3_symlink_inode_operations; - extern struct inode_operations ext3_fast_symlink_inode_operations; - - -Index: linux-2.4.24-vanilla/include/linux/ext3_jbd.h -=================================================================== ---- linux-2.4.24-vanilla.orig/include/linux/ext3_jbd.h 2004-01-10 17:11:50.000000000 +0300 -+++ linux-2.4.24-vanilla/include/linux/ext3_jbd.h 2004-01-10 17:20:28.000000000 +0300 -@@ -30,13 +30,19 @@ - - #define EXT3_SINGLEDATA_TRANS_BLOCKS 8U - -+/* Extended attributes may touch two data buffers, two bitmap buffers, -+ * and two group and summaries. */ -+ -+#define EXT3_XATTR_TRANS_BLOCKS 8 -+ - /* Define the minimum size for a transaction which modifies data. This - * needs to take into account the fact that we may end up modifying two - * quota files too (one for the group, one for the user quota). The - * superblock only gets updated once, of course, so don't bother - * counting that again for the quota updates. */ - --#define EXT3_DATA_TRANS_BLOCKS (3 * EXT3_SINGLEDATA_TRANS_BLOCKS - 2) -+#define EXT3_DATA_TRANS_BLOCKS (3 * EXT3_SINGLEDATA_TRANS_BLOCKS + \ -+ EXT3_XATTR_TRANS_BLOCKS - 2) - - extern int ext3_writepage_trans_blocks(struct inode *inode); - -Index: linux-2.4.24-vanilla/include/linux/ext3_xattr.h -=================================================================== ---- linux-2.4.24-vanilla.orig/include/linux/ext3_xattr.h 2003-01-30 13:24:37.000000000 +0300 -+++ linux-2.4.24-vanilla/include/linux/ext3_xattr.h 2004-01-10 17:20:28.000000000 +0300 -@@ -0,0 +1,157 @@ -+/* -+ File: linux/ext3_xattr.h -+ -+ On-disk format of extended attributes for the ext3 filesystem. -+ -+ (C) 2001 Andreas Gruenbacher, -+*/ -+ -+#include -+#include -+#include -+ -+/* Magic value in attribute blocks */ -+#define EXT3_XATTR_MAGIC 0xEA020000 -+ -+/* Maximum number of references to one attribute block */ -+#define EXT3_XATTR_REFCOUNT_MAX 1024 -+ -+/* Name indexes */ -+#define EXT3_XATTR_INDEX_MAX 10 -+#define EXT3_XATTR_INDEX_USER 1 -+#define EXT3_XATTR_INDEX_POSIX_ACL_ACCESS 2 -+#define EXT3_XATTR_INDEX_POSIX_ACL_DEFAULT 3 -+ -+struct ext3_xattr_header { -+ __u32 h_magic; /* magic number for identification */ -+ __u32 h_refcount; /* reference count */ -+ __u32 h_blocks; /* number of disk blocks used */ -+ __u32 h_hash; /* hash value of all attributes */ -+ __u32 h_reserved[4]; /* zero right now */ -+}; -+ -+struct ext3_xattr_entry { -+ __u8 e_name_len; /* length of name */ -+ __u8 e_name_index; /* attribute name index */ -+ __u16 e_value_offs; /* offset in disk block of value */ -+ __u32 e_value_block; /* disk block attribute is stored on (n/i) */ -+ __u32 e_value_size; /* size of attribute value */ -+ __u32 e_hash; /* hash value of name and value */ -+ char e_name[0]; /* attribute name */ -+}; -+ -+#define EXT3_XATTR_PAD_BITS 2 -+#define EXT3_XATTR_PAD (1<e_name_len)) ) -+#define EXT3_XATTR_SIZE(size) \ -+ (((size) + EXT3_XATTR_ROUND) & ~EXT3_XATTR_ROUND) -+ -+#ifdef __KERNEL__ -+ -+# ifdef CONFIG_EXT3_FS_XATTR -+ -+struct ext3_xattr_handler { -+ char *prefix; -+ size_t (*list)(char *list, struct inode *inode, const char *name, -+ int name_len); -+ int (*get)(struct inode *inode, const char *name, void *buffer, -+ size_t size); -+ int (*set)(struct inode *inode, const char *name, const void *buffer, -+ size_t size, int flags); -+}; -+ -+extern int ext3_xattr_register(int, struct ext3_xattr_handler *); -+extern void ext3_xattr_unregister(int, struct ext3_xattr_handler *); -+ -+extern int ext3_setxattr(struct dentry *, const char *, const void *, size_t, int); -+extern ssize_t ext3_getxattr(struct dentry *, const char *, void *, size_t); -+extern ssize_t ext3_listxattr(struct dentry *, char *, size_t); -+extern int ext3_removexattr(struct dentry *, const char *); -+ -+extern int ext3_xattr_get(struct inode *, int, const char *, void *, size_t); -+extern int ext3_xattr_list(struct inode *, char *, size_t); -+extern int ext3_xattr_set(handle_t *handle, struct inode *, int, const char *, const void *, size_t, int); -+ -+extern void ext3_xattr_delete_inode(handle_t *, struct inode *); -+extern void ext3_xattr_put_super(struct super_block *); -+ -+extern int init_ext3_xattr(void) __init; -+extern void exit_ext3_xattr(void); -+ -+# else /* CONFIG_EXT3_FS_XATTR */ -+# define ext3_setxattr NULL -+# define ext3_getxattr NULL -+# define ext3_listxattr NULL -+# define ext3_removexattr NULL -+ -+static inline int -+ext3_xattr_get(struct inode *inode, int name_index, const char *name, -+ void *buffer, size_t size) -+{ -+ return -ENOTSUP; -+} -+ -+static inline int -+ext3_xattr_list(struct inode *inode, void *buffer, size_t size) -+{ -+ return -ENOTSUP; -+} -+ -+static inline int -+ext3_xattr_set(handle_t *handle, struct inode *inode, int name_index, -+ const char *name, const void *value, size_t size, int flags) -+{ -+ return -ENOTSUP; -+} -+ -+static inline void -+ext3_xattr_delete_inode(handle_t *handle, struct inode *inode) -+{ -+} -+ -+static inline void -+ext3_xattr_put_super(struct super_block *sb) -+{ -+} -+ -+static inline int -+init_ext3_xattr(void) -+{ -+ return 0; -+} -+ -+static inline void -+exit_ext3_xattr(void) -+{ -+} -+ -+# endif /* CONFIG_EXT3_FS_XATTR */ -+ -+# ifdef CONFIG_EXT3_FS_XATTR_USER -+ -+extern int init_ext3_xattr_user(void) __init; -+extern void exit_ext3_xattr_user(void); -+ -+# else /* CONFIG_EXT3_FS_XATTR_USER */ -+ -+static inline int -+init_ext3_xattr_user(void) -+{ -+ return 0; -+} -+ -+static inline void -+exit_ext3_xattr_user(void) -+{ -+} -+ -+#endif /* CONFIG_EXT3_FS_XATTR_USER */ -+ -+#endif /* __KERNEL__ */ -+ -Index: linux-2.4.24-vanilla/include/linux/fs.h -=================================================================== ---- linux-2.4.24-vanilla.orig/include/linux/fs.h 2004-01-10 17:11:45.000000000 +0300 -+++ linux-2.4.24-vanilla/include/linux/fs.h 2004-01-10 17:20:28.000000000 +0300 -@@ -913,7 +913,7 @@ - int (*setattr) (struct dentry *, struct iattr *); - int (*setattr_raw) (struct inode *, struct iattr *); - int (*getattr) (struct dentry *, struct iattr *); -- int (*setxattr) (struct dentry *, const char *, void *, size_t, int); -+ int (*setxattr) (struct dentry *, const char *, const void *, size_t, int); - ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t); - ssize_t (*listxattr) (struct dentry *, char *, size_t); - int (*removexattr) (struct dentry *, const char *); -Index: linux-2.4.24-vanilla/include/linux/mbcache.h -=================================================================== ---- linux-2.4.24-vanilla.orig/include/linux/mbcache.h 2003-01-30 13:24:37.000000000 +0300 -+++ linux-2.4.24-vanilla/include/linux/mbcache.h 2004-01-10 17:20:28.000000000 +0300 -@@ -0,0 +1,69 @@ -+/* -+ File: linux/mbcache.h -+ -+ (C) 2001 by Andreas Gruenbacher, -+*/ -+ -+/* Hardwire the number of additional indexes */ -+#define MB_CACHE_INDEXES_COUNT 1 -+ -+struct mb_cache_entry; -+ -+struct mb_cache_op { -+ int (*free)(struct mb_cache_entry *, int); -+}; -+ -+struct mb_cache { -+ struct list_head c_cache_list; -+ const char *c_name; -+ struct mb_cache_op c_op; -+ atomic_t c_entry_count; -+ int c_bucket_count; -+#ifndef MB_CACHE_INDEXES_COUNT -+ int c_indexes_count; -+#endif -+ kmem_cache_t *c_entry_cache; -+ struct list_head *c_block_hash; -+ struct list_head *c_indexes_hash[0]; -+}; -+ -+struct mb_cache_entry_index { -+ struct list_head o_list; -+ unsigned int o_key; -+}; -+ -+struct mb_cache_entry { -+ struct list_head e_lru_list; -+ struct mb_cache *e_cache; -+ atomic_t e_used; -+ kdev_t e_dev; -+ unsigned long e_block; -+ struct list_head e_block_list; -+ struct mb_cache_entry_index e_indexes[0]; -+}; -+ -+/* Functions on caches */ -+ -+struct mb_cache * mb_cache_create(const char *, struct mb_cache_op *, size_t, -+ int, int); -+void mb_cache_shrink(struct mb_cache *, kdev_t); -+void mb_cache_destroy(struct mb_cache *); -+ -+/* Functions on cache entries */ -+ -+struct mb_cache_entry *mb_cache_entry_alloc(struct mb_cache *); -+int mb_cache_entry_insert(struct mb_cache_entry *, kdev_t, unsigned long, -+ unsigned int[]); -+void mb_cache_entry_rehash(struct mb_cache_entry *, unsigned int[]); -+void mb_cache_entry_release(struct mb_cache_entry *); -+void mb_cache_entry_takeout(struct mb_cache_entry *); -+void mb_cache_entry_free(struct mb_cache_entry *); -+struct mb_cache_entry *mb_cache_entry_dup(struct mb_cache_entry *); -+struct mb_cache_entry *mb_cache_entry_get(struct mb_cache *, kdev_t, -+ unsigned long); -+#if !defined(MB_CACHE_INDEXES_COUNT) || (MB_CACHE_INDEXES_COUNT > 0) -+struct mb_cache_entry *mb_cache_entry_find_first(struct mb_cache *cache, int, -+ kdev_t, unsigned int); -+struct mb_cache_entry *mb_cache_entry_find_next(struct mb_cache_entry *, int, -+ kdev_t, unsigned int); -+#endif -Index: linux-2.4.24-vanilla/kernel/ksyms.c -=================================================================== ---- linux-2.4.24-vanilla.orig/kernel/ksyms.c 2004-01-10 17:11:43.000000000 +0300 -+++ linux-2.4.24-vanilla/kernel/ksyms.c 2004-01-10 17:20:28.000000000 +0300 -@@ -11,6 +11,7 @@ - - #include - #include -+#include - #include - #include - #include -@@ -92,6 +93,7 @@ - EXPORT_SYMBOL(exit_files); - EXPORT_SYMBOL(exit_fs); - EXPORT_SYMBOL(exit_sighand); -+EXPORT_SYMBOL(copy_fs_struct); - - /* internal kernel memory management */ - EXPORT_SYMBOL(_alloc_pages); -@@ -109,6 +111,8 @@ - EXPORT_SYMBOL(kmem_cache_alloc); - EXPORT_SYMBOL(kmem_cache_free); - EXPORT_SYMBOL(kmem_cache_size); -+EXPORT_SYMBOL(register_cache); -+EXPORT_SYMBOL(unregister_cache); - EXPORT_SYMBOL(kmalloc); - EXPORT_SYMBOL(kfree); - EXPORT_SYMBOL(vfree); -Index: linux-2.4.24-vanilla/mm/vmscan.c -=================================================================== ---- linux-2.4.24-vanilla.orig/mm/vmscan.c 2004-01-10 17:06:00.000000000 +0300 -+++ linux-2.4.24-vanilla/mm/vmscan.c 2004-01-10 17:21:00.000000000 +0300 -@@ -18,6 +18,7 @@ - #include - #include - #include -+#include - #include - #include - #include -@@ -34,6 +35,39 @@ - */ - int vm_passes = 60; - -+static DECLARE_MUTEX(other_caches_sem); -+static LIST_HEAD(cache_definitions); -+ -+void register_cache(struct cache_definition *cache) -+{ -+ down(&other_caches_sem); -+ list_add(&cache->link, &cache_definitions); -+ up(&other_caches_sem); -+} -+ -+void unregister_cache(struct cache_definition *cache) -+{ -+ down(&other_caches_sem); -+ list_del(&cache->link); -+ up(&other_caches_sem); -+} -+ -+static void shrink_other_caches(unsigned int priority, int gfp_mask) -+{ -+ struct list_head *p; -+ -+ if (down_trylock(&other_caches_sem)) -+ return; -+ -+ list_for_each_prev(p, &cache_definitions) { -+ struct cache_definition *cache = -+ list_entry(p, struct cache_definition, link); -+ -+ cache->shrink(priority, gfp_mask); -+ } -+ up(&other_caches_sem); -+} -+ - /* - * "vm_cache_scan_ratio" is how much of the inactive LRU queue we will scan - * in one go. A value of 6 for vm_cache_scan_ratio implies that we'll -@@ -523,6 +557,7 @@ - #ifdef CONFIG_QUOTA - shrink_dqcache_memory(vm_vfs_scan_ratio, gfp_mask); - #endif -+ shrink_other_caches(vm_vfs_scan_ratio, gfp_mask); - - if (!*failed_swapout) - *failed_swapout = !swap_out(classzone); -@@ -645,6 +680,7 @@ - #ifdef CONFIG_QUOTA - shrink_dqcache_memory(vm_vfs_scan_ratio, gfp_mask); - #endif -+ shrink_other_caches(vm_vfs_scan_ratio, gfp_mask); - if (!failed_swapout) - failed_swapout = !swap_out(classzone); - } while (--tries); diff --git a/lustre/kernel_patches/patches/listman-2.4.24.patch b/lustre/kernel_patches/patches/listman-2.4.24.patch deleted file mode 100644 index 1e4508b..0000000 --- a/lustre/kernel_patches/patches/listman-2.4.24.patch +++ /dev/null @@ -1,22 +0,0 @@ -Index: linux-2.4.20/include/linux/list.h -=================================================================== ---- linux-2.4.20.orig/include/linux/list.h 2003-10-17 23:56:26.000000000 +0400 -+++ linux-2.4.20/include/linux/list.h 2003-10-22 14:02:22.000000000 +0400 -@@ -227,6 +227,17 @@ - pos = list_entry(pos->member.next, typeof(*pos), member), \ - prefetch(pos->member.next)) - -+/* 2.5 uses hlists for some things, like the d_hash. we'll treat them -+ * as 2.5 and let macros drop back.. */ -+#define hlist_entry list_entry -+#define hlist_head list_head -+#define hlist_node list_head -+#define HLIST_HEAD LIST_HEAD -+#define INIT_HLIST_HEAD INIT_LIST_HEAD -+#define hlist_del_init list_del_init -+#define hlist_add_head list_add -+#define hlist_for_each_safe list_for_each_safe -+ - #endif /* __KERNEL__ || _LVM_H_INCLUDE */ - - #endif diff --git a/lustre/kernel_patches/patches/netconsole-2.4.24.patch b/lustre/kernel_patches/patches/netconsole-2.4.24.patch deleted file mode 100644 index 06efea6..0000000 --- a/lustre/kernel_patches/patches/netconsole-2.4.24.patch +++ /dev/null @@ -1,1676 +0,0 @@ -Index: linux-2.4.24/drivers/net/netconsole.c -=================================================================== ---- linux-2.4.24.orig/drivers/net/netconsole.c 2003-01-30 18:24:37.000000000 +0800 -+++ linux-2.4.24/drivers/net/netconsole.c 2004-06-09 18:53:37.000000000 +0800 -@@ -0,0 +1,1376 @@ -+/* -+ * linux/drivers/net/netconsole.c -+ * -+ * Copyright (C) 2001 Ingo Molnar -+ * Copyright (C) 2002 Red Hat, Inc. -+ * -+ * This file contains the implementation of an IRQ-safe, crash-safe -+ * kernel console implementation that outputs kernel messages to the -+ * network. -+ * -+ * Modification history: -+ * -+ * 2001-09-17 started by Ingo Molnar. -+ * 2002-03-14 simultaneous syslog packet option by Michael K. Johnson -+ * 2003-10-30 Add sysrq command processing by Wangdi -+ * -+ */ -+ -+/**************************************************************** -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2, or (at your option) -+ * any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ * -+ ****************************************************************/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#if CONFIG_X86_LOCAL_APIC -+#include -+#endif -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "netconsole.h" -+ -+static struct net_device *netconsole_dev; -+static u16 source_port, netdump_target_port, netlog_target_port, syslog_target_port; -+static u32 source_ip, netdump_target_ip, netlog_target_ip, syslog_target_ip; -+static unsigned char netdump_daddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff} ; -+static unsigned char netlog_daddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff} ; -+static unsigned char syslog_daddr[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff} ; -+ -+static unsigned int mhz = 500, idle_timeout; -+static unsigned long long mhz_cycles, jiffy_cycles; -+ -+ -+#define MAX_UDP_CHUNK 1460 -+#define MAX_PRINT_CHUNK (MAX_UDP_CHUNK-HEADER_LEN) -+ -+#define DEBUG 0 -+#if DEBUG -+# define Dprintk(x...) printk(KERN_INFO x) -+#else -+# define Dprintk(x...) -+#endif -+/* -+ * We maintain a small pool of fully-sized skbs, -+ * to make sure the message gets out even in -+ * extreme OOM situations. -+ */ -+#define MAX_NETCONSOLE_SKBS 128 -+ -+static spinlock_t netconsole_lock = SPIN_LOCK_UNLOCKED; -+static int nr_netconsole_skbs; -+static struct sk_buff *netconsole_skbs; -+ -+#define MAX_SKB_SIZE \ -+ (MAX_UDP_CHUNK + sizeof(struct udphdr) + \ -+ sizeof(struct iphdr) + sizeof(struct ethhdr)) -+ -+static int new_arp = 0; -+static unsigned char arp_sha[ETH_ALEN], arp_tha[ETH_ALEN]; -+static u32 arp_sip, arp_tip; -+ -+static void send_netconsole_arp(struct net_device *dev); -+ -+static void __refill_netconsole_skbs(void) -+{ -+ struct sk_buff *skb; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&netconsole_lock, flags); -+ while (nr_netconsole_skbs < MAX_NETCONSOLE_SKBS) { -+ skb = alloc_skb(MAX_SKB_SIZE, GFP_ATOMIC); -+ if (!skb) -+ break; -+ if (netconsole_skbs) -+ skb->next = netconsole_skbs; -+ else -+ skb->next = NULL; -+ netconsole_skbs = skb; -+ nr_netconsole_skbs++; -+ } -+ spin_unlock_irqrestore(&netconsole_lock, flags); -+} -+ -+static struct sk_buff * get_netconsole_skb(void) -+{ -+ struct sk_buff *skb; -+ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&netconsole_lock, flags); -+ skb = netconsole_skbs; -+ if (skb) { -+ netconsole_skbs = skb->next; -+ skb->next = NULL; -+ nr_netconsole_skbs--; -+ } -+ spin_unlock_irqrestore(&netconsole_lock, flags); -+ -+ return skb; -+} -+ -+static unsigned long long t0; -+ -+/* -+ * Do cleanups: -+ * - zap completed output skbs. -+ * - send ARPs if requested -+ * - reboot the box if inactive for more than N seconds. -+ */ -+static void zap_completion_queue(void) -+{ -+ unsigned long long t1; -+ int cpu = smp_processor_id(); -+ -+ if (softnet_data[cpu].completion_queue) { -+ struct sk_buff *clist; -+ -+ local_irq_disable(); -+ clist = softnet_data[cpu].completion_queue; -+ softnet_data[cpu].completion_queue = NULL; -+ local_irq_enable(); -+ -+ while (clist != NULL) { -+ struct sk_buff *skb = clist; -+ clist = clist->next; -+ __kfree_skb(skb); -+ } -+ } -+ -+ if (new_arp) { -+ Dprintk("got ARP req - sending reply.\n"); -+ new_arp = 0; -+ send_netconsole_arp(netconsole_dev); -+ } -+ -+ rdtscll(t1); -+ if (idle_timeout) { -+ if (t0) { -+ if (((t1 - t0) >> 20) > mhz_cycles * (unsigned long long)idle_timeout) { -+ t0 = t1; -+ printk("netdump idle timeout - rebooting in 3 seconds.\n"); -+ mdelay(3000); -+ machine_restart(NULL); -+ } -+ } -+ } -+ /* maintain jiffies in a polling fashion, based on rdtsc. */ -+ { -+ static unsigned long long prev_tick; -+ -+ if (t1 - prev_tick >= jiffy_cycles) { -+ prev_tick += jiffy_cycles; -+ jiffies++; -+ } -+ } -+} -+void (*irqfunc)(int, void *, struct pt_regs *); -+ -+static void netdump_poll(struct net_device *dev) -+{ -+ int budget = 1; -+ -+ disable_irq(dev->irq); -+ -+ irqfunc(dev->irq, dev, 0); -+ -+ if(dev->poll && test_bit(__LINK_STATE_RX_SCHED, &dev->state)) -+ dev->poll(dev, &budget); -+ -+ enable_irq(dev->irq); -+ -+} -+ -+static struct sk_buff * alloc_netconsole_skb(struct net_device *dev, int len, int reserve) -+{ -+ int once = 1; -+ int count = 0; -+ struct sk_buff *skb = NULL; -+ -+repeat: -+ zap_completion_queue(); -+ if (nr_netconsole_skbs < MAX_NETCONSOLE_SKBS) -+ __refill_netconsole_skbs(); -+ -+ skb = alloc_skb(len, GFP_ATOMIC); -+ if (!skb) { -+ skb = get_netconsole_skb(); -+ if (!skb) { -+ count++; -+ if (once && (count == 1000000)) { -+ printk("possibly FATAL: out of netconsole skbs!!! will keep retrying.\n"); -+ once = 0; -+ } -+ Dprintk("alloc skb: polling controller ...\n"); -+ netdump_poll(dev); -+ goto repeat; -+ } -+ } -+ -+ atomic_set(&skb->users, 1); -+ skb_reserve(skb, reserve); -+ return skb; -+} -+ -+static void transmit_raw_skb(struct sk_buff *skb, struct net_device *dev) -+{ -+ -+repeat_poll: -+ spin_lock(&dev->xmit_lock); -+ dev->xmit_lock_owner = smp_processor_id(); -+ -+ if (netif_queue_stopped(dev)) { -+ dev->xmit_lock_owner = -1; -+ spin_unlock(&dev->xmit_lock); -+ -+ Dprintk("xmit skb: polling controller ...\n"); -+ netdump_poll(dev); -+ zap_completion_queue(); -+ goto repeat_poll; -+ } -+ -+ dev->hard_start_xmit(skb, dev); -+ -+ dev->xmit_lock_owner = -1; -+ spin_unlock(&dev->xmit_lock); -+} -+ -+static void transmit_netconsole_skb(struct sk_buff *skb, struct net_device *dev, -+ int ip_len, int udp_len, -+ u16 source_port, u16 target_port, u32 source_ip, u32 target_ip, -+ unsigned char * macdaddr) -+{ -+ struct udphdr *udph; -+ struct iphdr *iph; -+ struct ethhdr *eth; -+ -+ udph = (struct udphdr *) skb_push(skb, sizeof(*udph)); -+ udph->source = source_port; -+ udph->dest = target_port; -+ udph->len = htons(udp_len); -+ udph->check = 0; -+ -+ iph = (struct iphdr *)skb_push(skb, sizeof(*iph)); -+ -+ iph->version = 4; -+ iph->ihl = 5; -+ iph->tos = 0; -+ iph->tot_len = htons(ip_len); -+ iph->id = 0; -+ iph->frag_off = 0; -+ iph->ttl = 64; -+ iph->protocol = IPPROTO_UDP; -+ iph->check = 0; -+ iph->saddr = source_ip; -+ iph->daddr = target_ip; -+ iph->check = ip_fast_csum((unsigned char *)iph, iph->ihl); -+ -+ eth = (struct ethhdr *) skb_push(skb, ETH_HLEN); -+ -+ eth->h_proto = htons(ETH_P_IP); -+ memcpy(eth->h_source, dev->dev_addr, dev->addr_len); -+ memcpy(eth->h_dest, macdaddr, dev->addr_len); -+ -+ transmit_raw_skb(skb, dev); -+} -+ -+static void send_netconsole_arp(struct net_device *dev) -+{ -+ int total_len, arp_len, arp_data_len; -+ struct sk_buff *skb; -+ unsigned char *arp; -+ struct arphdr *arph; -+ struct ethhdr *eth; -+ -+ arp_data_len = 2*4 + 2*ETH_ALEN; -+ arp_len = arp_data_len + sizeof(struct arphdr); -+ total_len = arp_len + ETH_HLEN; -+ -+ skb = alloc_netconsole_skb(dev, total_len, total_len - arp_data_len); -+ -+ arp = skb->data; -+ -+ memcpy(arp, dev->dev_addr, ETH_ALEN); -+ arp += ETH_ALEN; -+ -+ memcpy(arp, &source_ip, 4); -+ arp += 4; -+ -+ memcpy(arp, arp_sha, ETH_ALEN); -+ arp += ETH_ALEN; -+ -+ memcpy(arp, &arp_sip, 4); -+ arp += 4; -+ -+ skb->len += 2*4 + 2*ETH_ALEN; -+ -+ arph = (struct arphdr *)skb_push(skb, sizeof(*arph)); -+ -+ arph->ar_hrd = htons(dev->type); -+ arph->ar_pro = __constant_htons(ETH_P_IP); -+ arph->ar_hln = ETH_ALEN; -+ arph->ar_pln = 4; -+ arph->ar_op = __constant_htons(ARPOP_REPLY); -+ -+ eth = (struct ethhdr *) skb_push(skb, ETH_HLEN); -+ -+ eth->h_proto = htons(ETH_P_ARP); -+ memcpy(eth->h_source, dev->dev_addr, dev->addr_len); -+ memcpy(eth->h_dest, arp_sha, dev->addr_len); -+ -+ transmit_raw_skb(skb, dev); -+} -+ -+static void send_netdump_skb(struct net_device *dev, const char *msg, unsigned int msg_len, reply_t *reply) -+{ -+ int total_len, ip_len, udp_len; -+ struct sk_buff *skb; -+ -+ udp_len = msg_len + HEADER_LEN + sizeof(struct udphdr); -+ ip_len = udp_len + sizeof(struct iphdr); -+ total_len = ip_len + ETH_HLEN; -+ -+ skb = alloc_netconsole_skb(dev, total_len, total_len - msg_len - HEADER_LEN); -+ -+ skb->data[0] = NETCONSOLE_VERSION; -+ put_unaligned(htonl(reply->nr), (u32 *) (skb->data + 1)); -+ put_unaligned(htonl(reply->code), (u32 *) (skb->data + 5)); -+ put_unaligned(htonl(reply->info), (u32 *) (skb->data + 9)); -+ -+ memcpy(skb->data + HEADER_LEN, msg, msg_len); -+ skb->len += msg_len + HEADER_LEN; -+ -+ transmit_netconsole_skb(skb, dev, ip_len, udp_len, -+ source_port, netdump_target_port, source_ip, netdump_target_ip, netdump_daddr); -+} -+ -+#define SYSLOG_HEADER_LEN 4 -+ -+static void send_netlog_skb(struct net_device *dev, const char *msg, unsigned int msg_len, reply_t *reply) -+{ -+ int total_len, ip_len, udp_len; -+ struct sk_buff *skb; -+ -+ udp_len = msg_len + HEADER_LEN + sizeof(struct udphdr); -+ ip_len = udp_len + sizeof(struct iphdr); -+ total_len = ip_len + ETH_HLEN; -+ -+ skb = alloc_netconsole_skb(dev, total_len, total_len - msg_len - HEADER_LEN); -+ -+ skb->data[0] = NETCONSOLE_VERSION; -+ put_unaligned(htonl(reply->nr), (u32 *) (skb->data + 1)); -+ put_unaligned(htonl(reply->code), (u32 *) (skb->data + 5)); -+ put_unaligned(htonl(reply->info), (u32 *) (skb->data + 9)); -+ -+ memcpy(skb->data + HEADER_LEN, msg, msg_len); -+ skb->len += msg_len + HEADER_LEN; -+ -+ transmit_netconsole_skb(skb, dev, ip_len, udp_len, -+ source_port, netlog_target_port, source_ip, netlog_target_ip, netlog_daddr); -+} -+ -+#define SYSLOG_HEADER_LEN 4 -+ -+static void send_syslog_skb(struct net_device *dev, const char *msg, unsigned int msg_len, int pri) -+{ -+ int total_len, ip_len, udp_len; -+ struct sk_buff *skb; -+ -+ udp_len = msg_len + SYSLOG_HEADER_LEN + sizeof(struct udphdr); -+ ip_len = udp_len + sizeof(struct iphdr); -+ total_len = ip_len + ETH_HLEN; -+ -+ skb = alloc_netconsole_skb(dev, total_len, total_len - msg_len - SYSLOG_HEADER_LEN); -+ -+ skb->data[0] = '<'; -+ skb->data[1] = pri + '0'; -+ skb->data[2]= '>'; -+ skb->data[3]= ' '; -+ -+ memcpy(skb->data + SYSLOG_HEADER_LEN, msg, msg_len); -+ skb->len += msg_len + SYSLOG_HEADER_LEN; -+ -+ transmit_netconsole_skb(skb, dev, ip_len, udp_len, source_port, -+ syslog_target_port, source_ip, syslog_target_ip, syslog_daddr); -+} -+ -+#define MAX_SYSLOG_CHARS 1000 -+ -+static spinlock_t syslog_lock = SPIN_LOCK_UNLOCKED; -+static int syslog_chars; -+static unsigned char syslog_line [MAX_SYSLOG_CHARS + 10]; -+ -+/* -+ * We feed kernel messages char by char, and send the UDP packet -+ * one linefeed. We buffer all characters received. -+ */ -+static inline void feed_syslog_char(struct net_device *dev, const unsigned char c) -+{ -+ if (syslog_chars == MAX_SYSLOG_CHARS) -+ syslog_chars--; -+ syslog_line[syslog_chars] = c; -+ syslog_chars++; -+ if (c == '\n') { -+ send_syslog_skb(dev, syslog_line, syslog_chars, 5); -+ syslog_chars = 0; -+ } -+} -+ -+static spinlock_t sequence_lock = SPIN_LOCK_UNLOCKED; -+static unsigned int log_offset; -+ -+static int thread_stopped = 0; -+/*Interrupt function for netdump */ -+static int sysrq_mode = 0; -+static int stop_sysrq_thread = 0; -+#define Set_Sysrq_mode() (sysrq_mode = 1) -+#define Clear_Sysrq_mode() (sysrq_mode = 0) -+static char send_cache[MAX_PRINT_CHUNK]; -+static unsigned int send_cache_pos = 0; -+wait_queue_head_t sysrq_thread_queue; -+wait_queue_head_t sysrq_thread_waiter_queue; -+ -+#define SEND_MSG_BUFFER(buf, len) \ -+do \ -+{ \ -+ reply_t reply; \ -+ unsigned int flags; \ -+ __save_flags(flags); \ -+ __cli(); \ -+ reply.code = REPLY_LOG; \ -+ reply.nr = 0; \ -+ reply.info = 0; \ -+ spin_lock(&sequence_lock); \ -+ send_netlog_skb(dev, buf, len, &reply); \ -+ spin_unlock(&sequence_lock); \ -+ __restore_flags(flags); \ -+}while(0); -+ -+void netconsole_do_sysrq(req_t *req) -+{ -+ struct pt_regs regs; -+ struct net_device *dev = netconsole_dev; -+ -+ if (!dev) -+ return; -+ Set_Sysrq_mode(); -+ get_current_regs(®s); -+ handle_sysrq((int)req->from, ®s, NULL, NULL); -+ Dprintk("Do the command netconsole\n"); -+ if (send_cache_pos != 0){ -+ SEND_MSG_BUFFER(send_cache, send_cache_pos); -+ memset(send_cache, 0, MAX_PRINT_CHUNK); -+ send_cache_pos = 0; -+ } -+ -+ Clear_Sysrq_mode(); -+} -+static void write_netconsole_msg(struct console *con, const char *msg0, unsigned int msg_len) -+{ -+ int len, left, i; -+ struct net_device *dev; -+ const char *msg = msg0; -+ reply_t reply; -+ -+ dev = netconsole_dev; -+ if (!dev || netdump_mode) -+ return; -+ if (sysrq_mode){ -+ unsigned long total_len = send_cache_pos + msg_len; -+ unsigned long left_len = msg_len; -+ while (total_len >= MAX_PRINT_CHUNK){ -+ unsigned long send_len = MAX_PRINT_CHUNK - send_cache_pos; -+ memcpy(send_cache + send_cache_pos, msg, send_len); -+ SEND_MSG_BUFFER(send_cache, MAX_PRINT_CHUNK); -+ send_cache_pos = 0; -+ total_len -= MAX_PRINT_CHUNK; -+ left_len -= send_len; -+ } -+ if (left_len > 0){ -+ memcpy(send_cache + send_cache_pos, msg + (msg_len -left_len), left_len); -+ send_cache_pos += left_len; -+ } -+ return; -+ }else if (netif_running(dev)) { -+ unsigned long flags; -+ -+ __save_flags(flags); -+ __cli(); -+ left = msg_len; -+ if (netlog_target_ip) { -+ while (left) { -+ if (left > MAX_PRINT_CHUNK) -+ len = MAX_PRINT_CHUNK; -+ else -+ len = left; -+ reply.code = REPLY_LOG; -+ reply.nr = 0; -+ spin_lock(&sequence_lock); -+ reply.info = log_offset; -+ log_offset += len; -+ spin_unlock(&sequence_lock); -+ send_netlog_skb(dev, msg, len, &reply); -+ msg += len; -+ left -= len; -+ } -+ } -+ if (syslog_target_ip) { -+ spin_lock(&syslog_lock); -+ for (i = 0; i < msg_len; i++) -+ feed_syslog_char(dev, msg0[i]); -+ spin_unlock(&syslog_lock); -+ } -+ -+ __restore_flags(flags); -+ } -+} -+ -+static unsigned short udp_check(struct udphdr *uh, int len, unsigned long saddr, unsigned long daddr, unsigned long base) -+{ -+ return(csum_tcpudp_magic(saddr, daddr, len, IPPROTO_UDP, base)); -+} -+ -+static int udp_checksum_init(struct sk_buff *skb, struct udphdr *uh, -+ unsigned short ulen, u32 saddr, u32 daddr) -+{ -+ if (uh->check == 0) { -+ skb->ip_summed = CHECKSUM_UNNECESSARY; -+ } else if (skb->ip_summed == CHECKSUM_HW) { -+ skb->ip_summed = CHECKSUM_UNNECESSARY; -+ if (!udp_check(uh, ulen, saddr, daddr, skb->csum)) -+ return 0; -+ skb->ip_summed = CHECKSUM_NONE; -+ } -+ if (skb->ip_summed != CHECKSUM_UNNECESSARY) -+ skb->csum = csum_tcpudp_nofold(saddr, daddr, ulen, IPPROTO_UDP, -+0); -+ /* Probably, we should checksum udp header (it should be in cache -+ * in any case) and data in tiny packets (< rx copybreak). -+ */ -+ return 0; -+} -+ -+static __inline__ int __udp_checksum_complete(struct sk_buff *skb) -+{ -+ return (unsigned short)csum_fold(skb_checksum(skb, 0, skb->len, skb->csum)); -+} -+ -+static __inline__ int udp_checksum_complete(struct sk_buff *skb) -+{ -+ return skb->ip_summed != CHECKSUM_UNNECESSARY && -+ __udp_checksum_complete(skb); -+} -+ -+/* -+ * NOTE: security depends on the trusted path between the netconsole -+ * server and netconsole client, since none of the packets are -+ * encrypted. The random magic number protects the protocol -+ * against spoofing. -+ */ -+static u64 netconsole_magic; -+static u32 magic1, magic2; -+ -+static spinlock_t req_lock = SPIN_LOCK_UNLOCKED; -+static int nr_req = 0; -+static LIST_HEAD(request_list); -+ -+static void add_new_req(req_t *req) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&req_lock, flags); -+ list_add_tail(&req->list, &request_list); -+ nr_req++; -+ Dprintk("pending requests: %d.\n", nr_req); -+ spin_unlock_irqrestore(&req_lock, flags); -+ -+ rdtscll(t0); -+} -+ -+static req_t *get_new_req(void) -+{ -+ req_t *req = NULL; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&req_lock, flags); -+ if (nr_req) { -+ req = list_entry(request_list.next, req_t, list); -+ list_del(&req->list); -+ nr_req--; -+ } -+ spin_unlock_irqrestore(&req_lock, flags); -+ -+ return req; -+} -+ -+static req_t *alloc_req(void) -+{ -+ req_t *req; -+ -+ req = (req_t *) kmalloc(sizeof(*req), GFP_ATOMIC); -+ return req; -+} -+ -+static int netconsole_rx_hook(struct sk_buff *skb) -+{ -+ int proto; -+ struct iphdr *iph; -+ struct udphdr *uh; -+ __u32 len, saddr, daddr, ulen; -+ req_t *__req; -+ req_t *req; -+ struct net_device *dev; -+ -+#if DEBUG -+ { -+ static int packet_count; -+ Dprintk(" %d\r", ++packet_count); -+ } -+#endif -+ dev = skb->dev; -+ if (dev->type != ARPHRD_ETHER) -+ goto out; -+ proto = ntohs(skb->mac.ethernet->h_proto); -+ Dprintk("rx got skb %p (len: %d, users: %d), dev %s, h_proto: %04x.\n", skb, skb->len, atomic_read(&skb->users), dev->name, proto); -+ #define D(x) skb->mac.ethernet->h_dest[x] -+ Dprintk("... h_dest: %02X:%02X:%02X:%02X:%02X:%02X.\n", D(0), D(1), D(2), D(3), D(4), D(5)); -+ #undef D -+ #define D(x) skb->mac.ethernet->h_source[x] -+ Dprintk("... h_source: %02X:%02X:%02X:%02X:%02X:%02X.\n", D(0), D(1), D(2), D(3), D(4), D(5)); -+ #undef D -+ if (skb->pkt_type == PACKET_OTHERHOST) -+ goto out; -+ if (skb_shared(skb)) -+ goto out; -+ if (proto == ETH_P_ARP) { -+ struct arphdr *arp; -+ unsigned char *arp_ptr; -+ -+ Dprintk("got arp skb.\n"); -+ arp = (struct arphdr *)skb->data; -+ if (!pskb_may_pull(skb, sizeof(struct arphdr) + 2*4 + 2*ETH_ALEN)) -+ goto out; -+ if (htons(dev->type) != arp->ar_hrd) -+ goto out; -+ if (arp->ar_pro != __constant_htons(ETH_P_IP)) -+ goto out; -+ if (arp->ar_hln != ETH_ALEN) -+ goto out; -+ if (arp->ar_pln != 4) -+ goto out; -+ if (arp->ar_op != __constant_htons(ARPOP_REQUEST)) -+ goto out; -+ /* -+ * ARP header looks ok so far, extract fields: -+ */ -+ arp_ptr = (unsigned char *)(arp + 1); -+ -+ memcpy(arp_sha, arp_ptr, ETH_ALEN); -+ arp_ptr += ETH_ALEN; -+ -+ memcpy(&arp_sip, arp_ptr, 4); -+ arp_ptr += 4; -+ -+ memcpy(arp_tha, arp_ptr, ETH_ALEN); -+ arp_ptr += ETH_ALEN; -+ -+ memcpy(&arp_tip, arp_ptr, 4); -+ -+ #define D(x) arp_sha[x] -+ Dprintk("... arp_sha: %02X:%02X:%02X:%02X:%02X:%02X.\n", D(0), D(1), D(2), D(3), D(4), D(5)); -+ #undef D -+ #define D(x) ((unsigned char *)&arp_sip)[x] -+ Dprintk("... arp_sip: %d.%d.%d.%d.\n", D(0), D(1), D(2), D(3)); -+ #undef D -+ #define D(x) arp_tha[x] -+ Dprintk("... arp_tha: %02X:%02X:%02X:%02X:%02X:%02X.\n", D(0), D(1), D(2), D(3), D(4), D(5)); -+ #undef D -+ #define D(x) ((unsigned char *)&arp_tip)[x] -+ Dprintk("... arp_tip: %d.%d.%d.%d.\n", D(0), D(1), D(2), D(3)); -+ #undef D -+ #define D(x) ((unsigned char *)&source_ip)[x] -+ Dprintk("... (source_ip): %d.%d.%d.%d.\n", D(0), D(1), D(2), D(3)); -+ #undef D -+ -+ if (LOOPBACK(arp_tip) || MULTICAST(arp_tip)) -+ goto out; -+ -+ if (arp_tip != source_ip) -+ goto out; -+ new_arp = 1; -+ goto out; -+ } -+ if (proto != ETH_P_IP) -+ goto out; -+ /* -+ * IP header correctness testing: -+ */ -+ iph = (struct iphdr *)skb->data; -+ if (!pskb_may_pull(skb, sizeof(struct iphdr))) -+ goto out; -+ Dprintk("... IP ihl*4: %d, version: %d.\n", iph->ihl*4, iph->version); -+ if (iph->ihl < 5 || iph->version != 4) -+ goto out; -+ if (!pskb_may_pull(skb, iph->ihl*4)) -+ goto out; -+ if (ip_fast_csum((u8 *)iph, iph->ihl) != 0) -+ goto out; -+ len = ntohs(iph->tot_len); -+ Dprintk("... IP len: %d.\n", len); -+ if (skb->len < len || len < iph->ihl*4) -+ goto out; -+ saddr = iph->saddr; -+ daddr = iph->daddr; -+ Dprintk("... IP src: %08x, dst: %08x.\n", saddr, daddr); -+ Dprintk("... IP protocol: %d.\n", iph->protocol); -+ if (iph->protocol != IPPROTO_UDP) -+ goto out; -+ Dprintk("... netdump src: %08x, dst: %08x.\n", source_ip, netlog_target_ip); -+ if (source_ip != daddr) -+ goto out; -+ if (netlog_target_ip != saddr) -+ goto out; -+ len -= iph->ihl*4; -+ uh = (struct udphdr *)(((char *)iph) + iph->ihl*4); -+ ulen = ntohs(uh->len); -+ Dprintk("... UDP len: %d (left %d).\n", ulen, len); -+ -+#define MIN_COMM_SIZE (sizeof(*uh) + NETDUMP_REQ_SIZE) -+ if (ulen != len || ulen < MIN_COMM_SIZE) { -+ Dprintk("... UDP, hm, len not ok.\n"); -+ goto out; -+ } -+ if (udp_checksum_init(skb, uh, ulen, saddr, daddr) < 0) { -+ Dprintk("... UDP, hm, checksum init not ok.\n"); -+ goto out; -+ } -+ if (udp_checksum_complete(skb)) { -+ Dprintk("... UDP, hm, checksum complete not ok.\n"); -+ goto out; -+ } -+ Dprintk("... UDP packet OK!\n"); -+ Dprintk("... UDP src port: %d, dst port: %d.\n", uh->source, uh->dest); -+ if (source_port != uh->source) -+ goto out; -+ if (netlog_target_port != uh->dest) -+ goto out; -+ __req = (req_t *)(uh + 1); -+ Dprintk("... UDP netdump packet OK!\n"); -+ -+ req = alloc_req(); -+ if (!req) { -+ printk("no more RAM to allocate request - dropping it.\n"); -+ goto out; -+ } -+ -+ req->magic = ntohl(__req->magic); -+ req->command = ntohl(__req->command); -+ req->from = ntohl(__req->from); -+ req->to = ntohl(__req->to); -+ req->nr = ntohl(__req->nr); -+ -+ Dprintk("... netdump magic: %08Lx.\n", req->magic); -+ Dprintk("... netdump command: %08x.\n", req->command); -+ Dprintk("... netdump from: %08x.\n", req->from); -+ Dprintk("... netdump to: %08x.\n", req->to); -+ -+ if (netdump_mode) -+ add_new_req(req); -+ else if (req->command == COMM_SYSRQ){ -+ add_new_req(req); -+ wake_up(&sysrq_thread_queue); -+ return NET_RX_DROP; -+ } -+out: -+ if (!netdump_mode) -+ return NET_RX_SUCCESS; -+ return NET_RX_DROP; -+} -+ -+#define INVALID_PAGE "page is not valid!\n" -+ -+static void send_netdump_mem (struct net_device *dev, req_t *req) -+{ -+ int i; -+ char *kaddr; -+ char str[1024]; -+ struct page *page; -+ unsigned long nr = req->from; -+ int nr_chunks = PAGE_SIZE/1024; -+ reply_t reply; -+ -+ return ; -+ -+ reply.nr = req->nr; -+ reply.info = 0; -+ if (req->from >= max_mapnr) { -+ sprintf(str, "page %08lx is bigger than max page # %08lx!\n", nr, max_mapnr); -+ reply.code = REPLY_ERROR; -+ send_netdump_skb(dev, str, strlen(str), &reply); -+ return; -+ } -+ page = mem_map + nr; -+ if (PageReserved(page)) -+ page = ZERO_PAGE(0); -+ -+// kaddr = (char *)kmap_atomic(page, KM_NETDUMP); -+ -+ for (i = 0; i < nr_chunks; i++) { -+ unsigned int offset = i*1024; -+ reply.code = REPLY_MEM; -+ reply.info = offset; -+ send_netdump_skb(dev, kaddr + offset, 1024, &reply); -+ } -+ -+// kunmap_atomic(kaddr, KM_NETDUMP); -+} -+ -+ -+/* -+ * This function waits for the client to acknowledge the receipt -+ * of the netdump startup reply, with the possibility of packets -+ * getting lost. We resend the startup packet if no ACK is received, -+ * after a 1 second delay. -+ * -+ * (The client can test the success of the handshake via the HELLO -+ * command, and send ACKs until we enter netdump mode.) -+ */ -+static void netdump_startup_handshake(struct net_device *dev) -+{ -+ char tmp[200]; -+ reply_t reply; -+ req_t *req = NULL; -+ int i; -+ -+ netdump_mode = 1; -+ -+repeat: -+ sprintf(tmp, "NETDUMP start, waiting for start-ACK.\n"); -+ reply.code = REPLY_START_NETDUMP; -+ reply.nr = 0; -+ reply.info = 0; -+ send_netdump_skb(dev, tmp, strlen(tmp), &reply); -+ -+ for (i = 0; i < 10000; i++) { -+ // wait 1 sec. -+ udelay(100); -+ Dprintk("handshake: polling controller ...\n"); -+ netdump_poll(dev); -+ zap_completion_queue(); -+ req = get_new_req(); -+ if (req) -+ break; -+ } -+ if (!req) -+ goto repeat; -+ if (req->command != COMM_START_NETDUMP_ACK) { -+ kfree(req); -+ goto repeat; -+ } -+ kfree(req); -+ -+ printk("NETDUMP START!\n"); -+} -+ -+#if 0 -+ -+static inline void print_status (req_t *req) -+{ -+ static int count = 0; -+ -+ switch (++count & 3) { -+ case 0: printk("/\r"); break; -+ case 1: printk("|\r"); break; -+ case 2: printk("\\\r"); break; -+ case 3: printk("-\r"); break; -+ } -+} -+ -+#else -+ -+static inline void print_status (req_t *req) -+{ -+ static int count = 0; -+ static int prev_jiffies = 0; -+ -+ if (jiffies/HZ != prev_jiffies/HZ) { -+ prev_jiffies = jiffies; -+ count++; -+ switch (count & 3) { -+ case 0: printk("%d(%ld)/\r", nr_req, jiffies); break; -+ case 1: printk("%d(%ld)|\r", nr_req, jiffies); break; -+ case 2: printk("%d(%ld)\\\r", nr_req, jiffies); break; -+ case 3: printk("%d(%ld)-\r", nr_req, jiffies); break; -+ } -+ } -+} -+ -+#endif -+ -+#define CLI 1 -+ -+#if CONFIG_SMP -+static void freeze_cpu (void * dummy) -+{ -+ printk("CPU#%d is frozen.\n", smp_processor_id()); -+#if CLI -+ for (;;) __cli(); -+#else -+ for (;;) __sti(); -+#endif -+} -+#endif -+ -+static void netconsole_netdump (struct pt_regs *regs) -+{ -+ reply_t reply; -+ char tmp[200]; -+ unsigned long flags; -+ struct net_device *dev = netconsole_dev; -+ unsigned long esp; -+ unsigned short ss; -+ struct pt_regs myregs; -+ req_t *req; -+ -+ __save_flags(flags); -+ __cli(); -+#if CONFIG_X86_LOCAL_APIC -+ //nmi_watchdog = 0; -+#endif -+#if CONFIG_SMP -+ smp_call_function(freeze_cpu, NULL, 1, 0); -+#endif -+ mdelay(1000); -+ /* -+ * Just in case we are crashing within the networking code -+ * ... attempt to fix up. -+ */ -+ spin_lock_init(&dev->xmit_lock); -+ -+ esp = (unsigned long) ((char *)regs + sizeof (struct pt_regs)); -+ ss = __KERNEL_DS; -+ if (regs->xcs & 3) { -+ esp = regs->esp; -+ ss = regs->xss & 0xffff; -+ } -+ myregs = *regs; -+ myregs.esp = esp; -+ myregs.xss = (myregs.xss & 0xffff0000) | ss; -+ -+ rdtscll(t0); -+ -+ printk("< netdump activated - performing handshake with the client. >\n"); -+ netdump_startup_handshake(dev); -+ -+ printk("< handshake completed - listening for dump requests. >\n"); -+ -+ while (netdump_mode) { -+ __cli(); -+ Dprintk("main netdump loop: polling controller ...\n"); -+ netdump_poll(dev); -+ zap_completion_queue(); -+#if !CLI -+ __sti(); -+#endif -+ req = get_new_req(); -+ if (!req) -+ continue; -+ Dprintk("got new req, command %d.\n", req->command); -+ print_status(req); -+ switch (req->command) { -+ case COMM_NONE: -+ Dprintk("got NO command.\n"); -+ break; -+ -+ case COMM_SEND_MEM: -+ Dprintk("got MEM command.\n"); -+ // send ->from ->to. -+ send_netdump_mem(dev, req); -+ break; -+ -+ case COMM_EXIT: -+ Dprintk("got EXIT command.\n"); -+ netdump_mode = 0; -+ break; -+ -+ case COMM_REBOOT: -+ Dprintk("got REBOOT command.\n"); -+ printk("netdump: rebooting in 3 seconds.\n"); -+ mdelay(3000); -+ machine_restart(NULL); -+ break; -+ -+ case COMM_HELLO: -+ sprintf(tmp, "Hello, this is netdump version 0.%02d\n", NETCONSOLE_VERSION); -+ reply.code = REPLY_HELLO; -+ reply.nr = req->nr; -+ reply.info = NETCONSOLE_VERSION; -+ send_netdump_skb(dev, tmp, strlen(tmp), &reply); -+ break; -+ -+ case COMM_GET_PAGE_SIZE: -+ sprintf(tmp, "PAGE_SIZE: %ld\n", PAGE_SIZE); -+ reply.code = REPLY_PAGE_SIZE; -+ reply.nr = req->nr; -+ reply.info = PAGE_SIZE; -+ send_netdump_skb(dev, tmp, strlen(tmp), &reply); -+ break; -+ -+ case COMM_GET_REGS: -+ { -+ char *tmp2 = tmp; -+ elf_gregset_t elf_regs; -+ -+ reply.code = REPLY_REGS; -+ reply.nr = req->nr; -+ reply.info = max_mapnr; -+ tmp2 = tmp + sprintf(tmp, "Sending register info.\n"); -+ ELF_CORE_COPY_REGS(elf_regs, regs); -+ memcpy(tmp2, &elf_regs, sizeof(elf_regs)); -+ send_netdump_skb(dev, tmp, strlen(tmp) + sizeof(elf_regs), &reply); -+ break; -+ } -+ -+ case COMM_GET_NR_PAGES: -+ reply.code = REPLY_NR_PAGES; -+ reply.nr = req->nr; -+ reply.info = max_mapnr; -+ sprintf(tmp, "Number of pages: %ld\n", max_mapnr); -+ send_netdump_skb(dev, tmp, strlen(tmp), &reply); -+ break; -+ -+ case COMM_SHOW_STATE: -+ netdump_mode = 0; -+ //if (regs) -+ //show_regs(regs); -+ //show_state(); -+ //show_mem(); -+ netdump_mode = 1; -+ reply.code = REPLY_SHOW_STATE; -+ reply.nr = req->nr; -+ reply.info = 0; -+ send_netdump_skb(dev, tmp, strlen(tmp), &reply); -+ break; -+ -+ default: -+ reply.code = REPLY_ERROR; -+ reply.nr = req->nr; -+ reply.info = req->command; -+ Dprintk("got UNKNOWN command!\n"); -+ sprintf(tmp, "Got unknown command code %d!\n", req->command); -+ send_netdump_skb(dev, tmp, strlen(tmp), &reply); -+ break; -+ } -+ kfree(req); -+ req = NULL; -+ } -+ sprintf(tmp, "NETDUMP end.\n"); -+ reply.code = REPLY_END_NETDUMP; -+ reply.nr = 0; -+ reply.info = 0; -+ send_netdump_skb(dev, tmp, strlen(tmp), &reply); -+ printk("NETDUMP END!\n"); -+ __restore_flags(flags); -+} -+static int netconsole_sysrq_schedule(void *arg) -+{ -+ struct task_struct *tsk = current; -+ -+ sprintf(tsk->comm, "sysrq_schedule"); -+ sigfillset(&tsk->blocked); -+ -+ /* main loop */ -+ thread_stopped = 0; -+ for (;;) { -+ wait_event_interruptible(sysrq_thread_queue, -+ !list_empty(&request_list) || stop_sysrq_thread); -+ while (!list_empty(&request_list)) { -+ req_t *req = get_new_req(); -+ Dprintk("get new req %d from req_list\n", (int)req->command); -+ if (req->command == COMM_SYSRQ) -+ netconsole_do_sysrq(req); -+ } -+ if (stop_sysrq_thread) -+ break; -+ wake_up(&sysrq_thread_waiter_queue); -+ } -+ thread_stopped = 1; -+ wake_up(&sysrq_thread_waiter_queue); -+ return 0; -+} -+ -+ -+static char *dev; -+static int netdump_target_eth_byte0 = 255; -+static int netdump_target_eth_byte1 = 255; -+static int netdump_target_eth_byte2 = 255; -+static int netdump_target_eth_byte3 = 255; -+static int netdump_target_eth_byte4 = 255; -+static int netdump_target_eth_byte5 = 255; -+ -+static int netlog_target_eth_byte0 = 255; -+static int netlog_target_eth_byte1 = 255; -+static int netlog_target_eth_byte2 = 255; -+static int netlog_target_eth_byte3 = 255; -+static int netlog_target_eth_byte4 = 255; -+static int netlog_target_eth_byte5 = 255; -+ -+static int syslog_target_eth_byte0 = 255; -+static int syslog_target_eth_byte1 = 255; -+static int syslog_target_eth_byte2 = 255; -+static int syslog_target_eth_byte3 = 255; -+static int syslog_target_eth_byte4 = 255; -+static int syslog_target_eth_byte5 = 255; -+ -+MODULE_PARM(netdump_target_ip, "i"); -+MODULE_PARM_DESC(netdump_target_ip, -+ "remote netdump IP address as a native (not network) endian integer"); -+MODULE_PARM(netlog_target_ip, "i"); -+MODULE_PARM_DESC(netlog_target_ip, -+ "remote netlog IP address as a native (not network) endian integer"); -+MODULE_PARM(syslog_target_ip, "i"); -+MODULE_PARM_DESC(syslog_target_ip, -+ "remote syslog IP address as a native (not network) endian integer"); -+ -+MODULE_PARM(source_port, "h"); -+MODULE_PARM_DESC(source_port, -+ "local port from which to send netdump packets"); -+ -+MODULE_PARM(netdump_target_port, "h"); -+MODULE_PARM_DESC(netdump_target_port, -+ "remote port to which to send netdump packets"); -+MODULE_PARM(netlog_target_port, "h"); -+MODULE_PARM_DESC(netlog_target_port, -+ "remote port to which to send netlog packets"); -+MODULE_PARM(syslog_target_port, "h"); -+MODULE_PARM_DESC(syslog_target_port, -+ "remote port to which to send syslog packets"); -+ -+#define ETH_BYTE(name,nr) \ -+ MODULE_PARM(name##_target_eth_byte##nr, "i"); \ -+ MODULE_PARM_DESC(name##_target_eth_byte##nr, \ -+ "byte "#nr" of the netdump server MAC address") -+ -+#define ETH_BYTES(name) \ -+ ETH_BYTE(name, 0); ETH_BYTE(name, 1); ETH_BYTE(name, 2); \ -+ ETH_BYTE(name, 3); ETH_BYTE(name, 4); ETH_BYTE(name, 5); -+ -+ETH_BYTES(netdump); -+ETH_BYTES(netlog); -+ETH_BYTES(syslog); -+ -+MODULE_PARM(magic1, "i"); -+MODULE_PARM_DESC(magic1, -+ "lower 32 bits of magic cookie shared between client and server"); -+MODULE_PARM(magic2, "i"); -+MODULE_PARM_DESC(magic2, -+ "upper 32 bits of magic cookie shared between client and server"); -+MODULE_PARM(dev, "s"); -+MODULE_PARM_DESC(dev, -+ "name of the device from which to send netdump and syslog packets"); -+MODULE_PARM(mhz, "i"); -+MODULE_PARM_DESC(mhz, -+ "one second wall clock time takes this many million CPU cycles"); -+MODULE_PARM(idle_timeout, "i"); -+MODULE_PARM_DESC(idle_timeout, -+ "reboot system after this many idle seconds"); -+ -+static struct console netconsole = -+ { flags: CON_ENABLED, write: write_netconsole_msg }; -+static int init_netconsole(void) -+{ -+ struct net_device *ndev = NULL; -+ struct in_device *in_dev; -+ struct irqaction *action; -+ int rc = 0; -+ -+ printk(KERN_INFO "netlog: using network device <%s>\n", dev); -+ // this will be valid once the device goes up. -+ if (dev) -+ ndev = dev_get_by_name(dev); -+ if (!ndev) { -+ printk(KERN_ERR "netlog: network device %s does not exist, aborting.\n", dev); -+ return -1; -+ } -+ in_dev = in_dev_get(ndev); -+ if (!in_dev) { -+ printk(KERN_ERR "netlog: network device %s is not an IP protocol device, aborting.\n", dev); -+ return -1; -+ } -+ -+ if (!magic1 || !magic2) { -+ printk(KERN_ERR "netlog: magic cookie (magic1,magic2) not specified.\n"); -+ return -1; -+ } -+ netconsole_magic = magic1 + (((u64)magic2)<<32); -+ -+ source_ip = ntohl(in_dev->ifa_list->ifa_local); -+ if (!source_ip) { -+ printk(KERN_ERR "netlog: network device %s has no local address, aborting.\n", dev); -+ return -1; -+ } -+#define IP(x) ((unsigned char *)&source_ip)[x] -+ printk(KERN_INFO "netlog: using source IP %u.%u.%u.%u\n", -+ IP(3), IP(2), IP(1), IP(0)); -+#undef IP -+ source_ip = htonl(source_ip); -+ if (!source_port) { -+ printk(KERN_ERR "netlog: source_port parameter not specified, aborting.\n"); -+ return -1; -+ } -+ printk(KERN_INFO "netlog: using source UDP port: %u\n", source_port); -+ source_port = htons(source_port); -+ -+ if (!netdump_target_ip && !netlog_target_ip && !syslog_target_ip) { -+ printk(KERN_ERR "netlog: target_ip parameter not specified, aborting.\n"); -+ return -1; -+#define IP(x) ((unsigned char *)&netdump_target_ip)[x] -+ printk(KERN_INFO "netlog: using netdump target IP %u.%u.%u.%u\n", -+ IP(3), IP(2), IP(1), IP(0)); -+#undef IP -+ netdump_target_ip = htonl(netdump_target_ip); -+ } -+ if (netlog_target_ip) { -+#define IP(x) ((unsigned char *)&netlog_target_ip)[x] -+ printk(KERN_INFO "netlog: using netlog target IP %u.%u.%u.%u\n", -+ IP(3), IP(2), IP(1), IP(0)); -+#undef IP -+ netlog_target_ip = htonl(netlog_target_ip); -+ } -+ if (syslog_target_ip) { -+ if (!syslog_target_port) -+ syslog_target_port = 514; -+#define IP(x) ((unsigned char *)&syslog_target_ip)[x] -+ printk("netlog: using syslog target IP %u.%u.%u.%u, port: %d\n", IP(3), IP(2), IP(1), IP(0), syslog_target_port); -+#undef IP -+ syslog_target_ip = htonl(syslog_target_ip); -+ syslog_target_port = htons(syslog_target_port); -+ } -+ if (!netdump_target_port && !netlog_target_port && !syslog_target_port) { -+ printk(KERN_ERR "netlog: target_port parameter not specified, aborting.\n"); -+ return -1; -+ } -+ if (netdump_target_port) { -+ printk(KERN_INFO "netlog: using target UDP port: %u\n", netdump_target_port); -+ netdump_target_port = htons(netdump_target_port); -+ } -+ if (netlog_target_port) { -+ printk(KERN_INFO "netlog: using target UDP port: %u\n", netlog_target_port); -+ netlog_target_port = htons(netlog_target_port); -+ } -+ -+ netdump_daddr[0] = netdump_target_eth_byte0; -+ netdump_daddr[1] = netdump_target_eth_byte1; -+ netdump_daddr[2] = netdump_target_eth_byte2; -+ netdump_daddr[3] = netdump_target_eth_byte3; -+ netdump_daddr[4] = netdump_target_eth_byte4; -+ netdump_daddr[5] = netdump_target_eth_byte5; -+ -+ if ((netdump_daddr[0] & netdump_daddr[1] & netdump_daddr[2] & netdump_daddr[3] & netdump_daddr[4] & netdump_daddr[5]) == 255) -+ printk(KERN_INFO "netlog: using broadcast ethernet frames to send netdump packets.\n"); -+ else -+ printk(KERN_INFO "netlog: using netdump target ethernet address %02x:%02x:%02x:%02x:%02x:%02x.\n", -+ netdump_daddr[0], netdump_daddr[1], netdump_daddr[2], netdump_daddr[3], netdump_daddr[4], netdump_daddr[5]); -+ -+ netlog_daddr[0] = netlog_target_eth_byte0; -+ netlog_daddr[1] = netlog_target_eth_byte1; -+ netlog_daddr[2] = netlog_target_eth_byte2; -+ netlog_daddr[3] = netlog_target_eth_byte3; -+ netlog_daddr[4] = netlog_target_eth_byte4; -+ netlog_daddr[5] = netlog_target_eth_byte5; -+ -+ if ((netlog_daddr[0] & netlog_daddr[1] & netlog_daddr[2] & netlog_daddr[3] & netlog_daddr[4] & netlog_daddr[5]) == 255) -+ printk(KERN_INFO "netlog: using broadcast ethernet frames to send netdump packets.\n"); -+ else -+ printk(KERN_INFO "netlog: using netdump target ethernet address %02x:%02x:%02x:%02x:%02x:%02x.\n", -+ netlog_daddr[0], netlog_daddr[1], netlog_daddr[2], netlog_daddr[3], netlog_daddr[4], netlog_daddr[5]); -+ syslog_daddr[0] = syslog_target_eth_byte0; -+ syslog_daddr[1] = syslog_target_eth_byte1; -+ syslog_daddr[2] = syslog_target_eth_byte2; -+ syslog_daddr[3] = syslog_target_eth_byte3; -+ syslog_daddr[4] = syslog_target_eth_byte4; -+ syslog_daddr[5] = syslog_target_eth_byte5; -+ -+ if ((syslog_daddr[0] & syslog_daddr[1] & syslog_daddr[2] & syslog_daddr[3] & syslog_daddr[4] & syslog_daddr[5]) == 255) -+ printk(KERN_INFO "netlog: using broadcast ethernet frames to send syslog packets.\n"); -+ else -+ printk(KERN_INFO "netlog: using syslog target ethernet address %02x:%02x:%02x:%02x:%02x:%02x.\n", -+ syslog_daddr[0], syslog_daddr[1], syslog_daddr[2], syslog_daddr[3], syslog_daddr[4], syslog_daddr[5]); -+ -+ mhz_cycles = (unsigned long long)mhz * 1000000ULL; -+ jiffy_cycles = (unsigned long long)mhz * (1000000/HZ); -+ -+ ndev->rx_hook = netconsole_rx_hook; -+ netdump_func = netconsole_netdump; -+ netconsole_dev = ndev; -+ /* find irq function of the ndev*/ -+ action=find_irq_action(ndev->irq, ndev); -+ if (!action) { -+ printk(KERN_ERR "couldn't find irq handler for <%s>", dev); -+ return -1; -+ } -+ irqfunc = action->handler; -+ -+ stop_sysrq_thread = 0; -+ INIT_LIST_HEAD(&request_list); -+ init_waitqueue_head(&sysrq_thread_queue); -+ init_waitqueue_head(&sysrq_thread_waiter_queue); -+ if ((rc = kernel_thread(netconsole_sysrq_schedule, NULL, 0)) < 0 ){ -+ printk(KERN_ERR "Can not start netconsole sysrq thread: rc %d\n", rc); -+ return -1; -+ } -+ -+#define STARTUP_MSG "[...network console startup...]\n" -+ write_netconsole_msg(NULL, STARTUP_MSG, strlen(STARTUP_MSG)); -+ -+ register_console(&netconsole); -+ printk(KERN_INFO "netlog: network logging started up successfully!\n"); -+ return 0; -+} -+ -+static void cleanup_netconsole(void) -+{ -+ stop_sysrq_thread = 1; -+ -+ wake_up(&sysrq_thread_queue); -+ wait_event(sysrq_thread_waiter_queue, thread_stopped); -+ printk(KERN_INFO"netlog: network logging shut down.\n"); -+ unregister_console(&netconsole); -+ -+#define SHUTDOWN_MSG "[...network console shutdown...]\n" -+ write_netconsole_msg(NULL, SHUTDOWN_MSG, strlen(SHUTDOWN_MSG)); -+ netconsole_dev->rx_hook = NULL; -+ netconsole_dev = NULL; -+} -+ -+module_init(init_netconsole); -+module_exit(cleanup_netconsole); -+ -+MODULE_LICENSE("GPL"); -+ -Index: linux-2.4.24/drivers/net/netconsole.h -=================================================================== ---- linux-2.4.24.orig/drivers/net/netconsole.h 2003-01-30 18:24:37.000000000 +0800 -+++ linux-2.4.24/drivers/net/netconsole.h 2004-06-09 14:14:54.000000000 +0800 -@@ -0,0 +1,102 @@ -+/* -+ * linux/drivers/net/netconsole.h -+ * -+ * Copyright (C) 2001 Ingo Molnar -+ * -+ * This file contains the implementation of an IRQ-safe, crash-safe -+ * kernel console implementation that outputs kernel messages to the -+ * network. -+ * -+ * Modification history: -+ * -+ * 2001-09-17 started by Ingo Molnar. -+ */ -+ -+/**************************************************************** -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2, or (at your option) -+ * any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -+ * -+ ****************************************************************/ -+ -+#define NETCONSOLE_VERSION 0x03 -+ -+enum netdump_commands { -+ COMM_NONE = 0, -+ COMM_SEND_MEM = 1, -+ COMM_EXIT = 2, -+ COMM_REBOOT = 3, -+ COMM_HELLO = 4, -+ COMM_GET_NR_PAGES = 5, -+ COMM_GET_PAGE_SIZE = 6, -+ COMM_START_NETDUMP_ACK = 7, -+ COMM_GET_REGS = 8, -+ COMM_SHOW_STATE = 9, -+ COMM_START_WRITE_NETDUMP_ACK = 10, -+ COMM_SYSRQ = 11, -+}; -+ -+#define NETDUMP_REQ_SIZE (8+4*4) -+ -+typedef struct netdump_req_s { -+ u64 magic; -+ u32 nr; -+ u32 command; -+ u32 from; -+ u32 to; -+ struct list_head list; -+} req_t; -+ -+enum netdump_replies { -+ REPLY_NONE = 0, -+ REPLY_ERROR = 1, -+ REPLY_LOG = 2, -+ REPLY_MEM = 3, -+ REPLY_RESERVED = 4, -+ REPLY_HELLO = 5, -+ REPLY_NR_PAGES = 6, -+ REPLY_PAGE_SIZE = 7, -+ REPLY_START_NETDUMP = 8, -+ REPLY_END_NETDUMP = 9, -+ REPLY_REGS = 10, -+ REPLY_MAGIC = 11, -+ REPLY_SHOW_STATE = 12, -+ REPLY_SYSRQ = 13, -+}; -+ -+typedef struct netdump_reply_s { -+ u32 nr; -+ u32 code; -+ u32 info; -+} reply_t; -+ -+#define HEADER_LEN (1 + sizeof(reply_t)) -+/* for netconsole */ -+static inline void get_current_regs(struct pt_regs *regs) -+{ -+ __asm__ __volatile__("movl %%ebx,%0" : "=m"(regs->ebx)); -+ __asm__ __volatile__("movl %%ecx,%0" : "=m"(regs->ecx)); -+ __asm__ __volatile__("movl %%edx,%0" : "=m"(regs->edx)); -+ __asm__ __volatile__("movl %%esi,%0" : "=m"(regs->esi)); -+ __asm__ __volatile__("movl %%edi,%0" : "=m"(regs->edi)); -+ __asm__ __volatile__("movl %%ebp,%0" : "=m"(regs->ebp)); -+ __asm__ __volatile__("movl %%eax,%0" : "=m"(regs->eax)); -+ __asm__ __volatile__("movl %%esp,%0" : "=m"(regs->esp)); -+ __asm__ __volatile__("movw %%ss, %%ax;" :"=a"(regs->xss)); -+ __asm__ __volatile__("movw %%cs, %%ax;" :"=a"(regs->xcs)); -+ __asm__ __volatile__("movw %%ds, %%ax;" :"=a"(regs->xds)); -+ __asm__ __volatile__("movw %%es, %%ax;" :"=a"(regs->xes)); -+ __asm__ __volatile__("pushfl; popl %0" :"=m"(regs->eflags)); -+ regs->eip = (unsigned long)current_text_addr(); -+} -+ -Index: linux-2.4.24/drivers/net/Makefile -=================================================================== ---- linux-2.4.24.orig/drivers/net/Makefile 2003-11-29 02:26:20.000000000 +0800 -+++ linux-2.4.24/drivers/net/Makefile 2004-06-09 14:16:14.000000000 +0800 -@@ -250,6 +250,8 @@ - obj-y += ../acorn/net/acorn-net.o - endif - -+obj-$(CONFIG_NETCONSOLE) += netconsole.o -+ - # - # HIPPI adapters - # -Index: linux-2.4.24/drivers/net/Config.in -=================================================================== ---- linux-2.4.24.orig/drivers/net/Config.in 2003-11-29 02:26:20.000000000 +0800 -+++ linux-2.4.24/drivers/net/Config.in 2004-06-09 14:17:33.000000000 +0800 -@@ -294,7 +294,7 @@ - fi - dep_tristate ' SysKonnect FDDI PCI support' CONFIG_SKFP $CONFIG_PCI - fi -- -+tristate 'Network logging support' CONFIG_NETCONSOLE - if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then - if [ "$CONFIG_INET" = "y" ]; then - bool 'HIPPI driver support (EXPERIMENTAL)' CONFIG_HIPPI -Index: linux-2.4.24/arch/i386/kernel/traps.c -=================================================================== ---- linux-2.4.24.orig/arch/i386/kernel/traps.c 2004-06-09 14:10:04.000000000 +0800 -+++ linux-2.4.24/arch/i386/kernel/traps.c 2004-06-09 14:29:00.000000000 +0800 -@@ -279,6 +279,8 @@ - bug: - printk("Kernel BUG\n"); - } -+void (*netdump_func) (struct pt_regs *regs) = NULL; -+int netdump_mode = 0; - - spinlock_t die_lock = SPIN_LOCK_UNLOCKED; - -@@ -290,6 +292,8 @@ - handle_BUG(regs); - printk("%s: %04lx\n", str, err & 0xffff); - show_registers(regs); -+ if (netdump_func) -+ netdump_func(regs); - bust_spinlocks(0); - spin_unlock_irq(&die_lock); - do_exit(SIGSEGV); -@@ -1039,5 +1043,7 @@ - return -ENOSYS; - } - -+EXPORT_SYMBOL_GPL(netdump_func); -+EXPORT_SYMBOL_GPL(netdump_mode); - EXPORT_SYMBOL_GPL(is_kernel_text_address); - EXPORT_SYMBOL_GPL(lookup_symbol); -Index: linux-2.4.24/arch/i386/kernel/irq.c -=================================================================== ---- linux-2.4.24.orig/arch/i386/kernel/irq.c 2004-06-09 14:09:59.000000000 +0800 -+++ linux-2.4.24/arch/i386/kernel/irq.c 2004-06-09 14:53:34.000000000 +0800 -@@ -1048,6 +1048,21 @@ - return 0; - } - -+struct irqaction *find_irq_action(unsigned int irq, void *dev_id) -+{ -+ struct irqaction *a, *r=0; -+ -+ spin_lock_irq(&irq_desc[irq].lock); -+ for(a=irq_desc[irq].action; a; a=a->next) { -+ if(a->dev_id == dev_id) { -+ r=a; -+ break; -+ } -+ } -+ spin_unlock_irq(&irq_desc[irq].lock); -+ return r; -+} -+ - static struct proc_dir_entry * root_irq_dir; - static struct proc_dir_entry * irq_dir [NR_IRQS]; - -Index: linux-2.4.24/arch/i386/kernel/i386_ksyms.c -=================================================================== ---- linux-2.4.24.orig/arch/i386/kernel/i386_ksyms.c 2003-11-29 02:26:19.000000000 +0800 -+++ linux-2.4.24/arch/i386/kernel/i386_ksyms.c 2004-06-09 14:55:11.000000000 +0800 -@@ -66,6 +66,7 @@ - EXPORT_SYMBOL(iounmap); - EXPORT_SYMBOL(enable_irq); - EXPORT_SYMBOL(disable_irq); -+EXPORT_SYMBOL(find_irq_action); - EXPORT_SYMBOL(disable_irq_nosync); - EXPORT_SYMBOL(probe_irq_mask); - EXPORT_SYMBOL(kernel_thread); -Index: linux-2.4.24/arch/x86_64/kernel/traps.c -=================================================================== ---- linux-2.4.24.orig/arch/x86_64/kernel/traps.c 2003-11-29 02:26:19.000000000 +0800 -+++ linux-2.4.24/arch/x86_64/kernel/traps.c 2004-06-09 14:30:02.000000000 +0800 -@@ -80,7 +80,7 @@ - extern char iret_address[]; - - struct notifier_block *die_chain; -- -+void (*netdump_func) (struct pt_regs *regs) = NULL; - int kstack_depth_to_print = 12; - - #ifdef CONFIG_KALLSYMS -Index: linux-2.4.24/arch/x86_64/kernel/x8664_ksyms.c -=================================================================== ---- linux-2.4.24.orig/arch/x86_64/kernel/x8664_ksyms.c 2003-11-29 02:26:19.000000000 +0800 -+++ linux-2.4.24/arch/x86_64/kernel/x8664_ksyms.c 2004-06-09 14:32:14.000000000 +0800 -@@ -40,7 +40,7 @@ - extern struct drive_info_struct drive_info; - EXPORT_SYMBOL(drive_info); - #endif -- -+int netdump_mode = 0; - /* platform dependent support */ - EXPORT_SYMBOL(boot_cpu_data); - EXPORT_SYMBOL(dump_fpu); -@@ -226,6 +226,9 @@ - extern void int_ret_from_sys_call(void); - EXPORT_SYMBOL_NOVERS(int_ret_from_sys_call); - -+EXPORT_SYMBOL_GPL(netdump_func); -+EXPORT_SYMBOL_GPL(netdump_mode); -+ - EXPORT_SYMBOL(touch_nmi_watchdog); - - EXPORT_SYMBOL(do_fork); -Index: linux-2.4.24/include/linux/netdevice.h -=================================================================== ---- linux-2.4.24.orig/include/linux/netdevice.h 2004-06-09 14:20:33.000000000 +0800 -+++ linux-2.4.24/include/linux/netdevice.h 2004-06-09 18:40:24.000000000 +0800 -@@ -435,6 +435,7 @@ - unsigned char *haddr); - int (*neigh_setup)(struct net_device *dev, struct neigh_parms *); - int (*accept_fastpath)(struct net_device *, struct dst_entry*); -+ int (*rx_hook)(struct sk_buff *skb); - - /* open/release and usage marking */ - struct module *owner; -Index: linux-2.4.24/include/linux/kernel.h -=================================================================== ---- linux-2.4.24.orig/include/linux/kernel.h 2004-06-09 14:20:33.000000000 +0800 -+++ linux-2.4.24/include/linux/kernel.h 2004-06-09 18:39:18.000000000 +0800 -@@ -105,6 +105,9 @@ - extern void bust_spinlocks(int yes); - extern int oops_in_progress; /* If set, an oops, panic(), BUG() or die() is in progress */ - -+extern void (*netdump_func) (struct pt_regs *regs); -+extern int netdump_mode; -+ - extern int tainted; - extern const char *print_tainted(void); - -Index: linux-2.4.24/include/asm-i386/irq.h -=================================================================== ---- linux-2.4.24.orig/include/asm-i386/irq.h 2004-06-09 14:20:33.000000000 +0800 -+++ linux-2.4.24/include/asm-i386/irq.h 2004-06-09 14:54:04.000000000 +0800 -@@ -38,7 +38,7 @@ - extern void disable_irq_nosync(unsigned int); - extern void enable_irq(unsigned int); - extern void release_x86_irqs(struct task_struct *); -- -+extern struct irqaction *find_irq_action(unsigned int irq, void *dev_id); - #ifdef CONFIG_X86_LOCAL_APIC - #define ARCH_HAS_NMI_WATCHDOG /* See include/linux/nmi.h */ - #endif -Index: linux-2.4.24/net/core/dev.c -=================================================================== ---- linux-2.4.24.orig/net/core/dev.c 2003-11-29 02:26:21.000000000 +0800 -+++ linux-2.4.24/net/core/dev.c 2004-06-09 14:50:03.000000000 +0800 -@@ -1287,7 +1287,13 @@ - queue = &softnet_data[this_cpu]; - - local_irq_save(flags); -- -+ if (unlikely(skb->dev->rx_hook != NULL)) { -+ int ret; -+ -+ ret = skb->dev->rx_hook(skb); -+ if (ret == NET_RX_DROP) -+ goto drop; -+ } - netdev_rx_stat[this_cpu].total++; - if (queue->input_pkt_queue.qlen <= netdev_max_backlog) { - if (queue->input_pkt_queue.qlen) { diff --git a/lustre/kernel_patches/patches/nfs_export_kernel-2.4.24.patch b/lustre/kernel_patches/patches/nfs_export_kernel-2.4.24.patch deleted file mode 100644 index 0aaea3c..0000000 --- a/lustre/kernel_patches/patches/nfs_export_kernel-2.4.24.patch +++ /dev/null @@ -1,746 +0,0 @@ -Index: lum/fs/Makefile -=================================================================== ---- lum.orig/fs/Makefile 2004-06-07 17:25:22.000000000 -0400 -+++ lum/fs/Makefile 2004-06-07 17:25:22.000000000 -0400 -@@ -7,7 +7,8 @@ - - O_TARGET := fs.o - --export-objs := filesystems.o open.o dcache.o buffer.o dquot.o inode.o -+export-objs := filesystems.o open.o dcache.o buffer.o dquot.o inode.o \ -+ namei.o file_table.o - mod-subdirs := nls - - obj-y := open.o read_write.o devices.o file_table.o buffer.o \ -Index: lum/fs/file_table.c -=================================================================== ---- lum.orig/fs/file_table.c 2002-11-28 18:53:15.000000000 -0500 -+++ lum/fs/file_table.c 2004-06-07 17:25:22.000000000 -0400 -@@ -82,7 +82,8 @@ - * and call the open function (if any). The caller must verify that - * inode->i_fop is not NULL. - */ --int init_private_file(struct file *filp, struct dentry *dentry, int mode) -+int init_private_file_it(struct file *filp, struct dentry *dentry, int mode, -+ struct lookup_intent *it) - { - memset(filp, 0, sizeof(*filp)); - filp->f_mode = mode; -@@ -90,12 +91,20 @@ - filp->f_dentry = dentry; - filp->f_uid = current->fsuid; - filp->f_gid = current->fsgid; -+ if (it) -+ filp->f_it = it; - filp->f_op = dentry->d_inode->i_fop; - if (filp->f_op->open) - return filp->f_op->open(dentry->d_inode, filp); - else - return 0; - } -+EXPORT_SYMBOL(init_private_file_it); -+ -+int init_private_file(struct file *filp, struct dentry *dentry, int mode) -+{ -+ return init_private_file_it(filp, dentry, mode, NULL); -+} - - void fput(struct file * file) - { -Index: lum/fs/inode.c -=================================================================== ---- lum.orig/fs/inode.c 2004-06-07 17:25:22.000000000 -0400 -+++ lum/fs/inode.c 2004-06-07 17:25:22.000000000 -0400 -@@ -1045,9 +1045,10 @@ - } - - --struct inode *iget4(struct super_block *sb, unsigned long ino, find_inode_t find_actor, void *opaque) -+static inline struct inode *ifind(struct super_block *sb, unsigned long ino, -+ struct list_head *head, -+ find_inode_t find_actor, void *opaque) - { -- struct list_head * head = inode_hashtable + hash(sb,ino); - struct inode * inode; - - spin_lock(&inode_lock); -@@ -1060,6 +1061,24 @@ - } - spin_unlock(&inode_lock); - -+ return NULL; -+} -+ -+struct inode *ilookup4(struct super_block *sb, unsigned long ino, -+ find_inode_t find_actor, void *opaque) -+{ -+ struct list_head * head = inode_hashtable + hash(sb,ino); -+ return ifind(sb, ino, head, find_actor, opaque); -+} -+ -+struct inode *iget4(struct super_block *sb, unsigned long ino, -+ find_inode_t find_actor, void *opaque) -+{ -+ struct list_head * head = inode_hashtable + hash(sb,ino); -+ struct inode *inode = ifind(sb, ino, head, find_actor, opaque); -+ if (inode) -+ return inode; -+ - /* - * get_new_inode() will do the right thing, re-trying the search - * in case it had to block at any point. -Index: lum/fs/namei.c -=================================================================== ---- lum.orig/fs/namei.c 2004-06-07 17:24:47.000000000 -0400 -+++ lum/fs/namei.c 2004-06-07 18:08:28.000000000 -0400 -@@ -22,6 +22,7 @@ - #include - #include - #include -+#include - - #include - #include -@@ -100,6 +101,7 @@ - it->it_op_release(it); - - } -+EXPORT_SYMBOL(intent_release); - - /* In order to reduce some races, while at the same time doing additional - * checking and hopefully speeding things up, we copy filenames to the -@@ -907,7 +909,8 @@ - - - /* SMP-safe */ --struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) -+struct dentry * lookup_one_len_it(const char * name, struct dentry * base, -+ int len, struct lookup_intent *it) - { - unsigned long hash; - struct qstr this; -@@ -927,11 +930,16 @@ - } - this.hash = end_name_hash(hash); - -- return lookup_hash_it(&this, base, NULL, NULL); -+ return lookup_hash_it(&this, base, NULL, it); - access: - return ERR_PTR(-EACCES); - } - -+struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) -+{ -+ return lookup_one_len_it(name, base, len, NULL); -+} -+ - /* - * namei() - * -Index: lum/fs/nfsd/export.c -=================================================================== ---- lum.orig/fs/nfsd/export.c 2003-11-28 13:26:21.000000000 -0500 -+++ lum/fs/nfsd/export.c 2004-06-07 17:25:22.000000000 -0400 -@@ -223,6 +223,11 @@ - inode = nd.dentry->d_inode; - dev = inode->i_dev; - ino = inode->i_ino; -+ if ((inode->i_sb->s_type->fs_flags & FS_NFSEXP_FSID) && -+ !(nxp->ex_flags & NFSEXP_FSID)) { -+ nxp->ex_dev = inode->i_sb->s_dev; -+ nxp->ex_flags |= NFSEXP_FSID; -+ } - err = -EINVAL; - - exp = exp_get(clp, dev, ino); -Index: lum/fs/nfsd/nfsfh.c -=================================================================== ---- lum.orig/fs/nfsd/nfsfh.c 2003-11-28 13:26:21.000000000 -0500 -+++ lum/fs/nfsd/nfsfh.c 2004-06-07 17:51:58.000000000 -0400 -@@ -36,6 +36,15 @@ - int sequence; /* sequence counter */ - }; - -+static struct dentry *lookup_it(struct inode *inode, struct dentry * dentry) -+{ -+ if (inode->i_op->lookup_it) -+ return inode->i_op->lookup_it(inode, dentry, NULL, NULL, 0); -+ else -+ return inode->i_op->lookup(inode, dentry); -+ -+} -+ - /* - * A rather strange filldir function to capture - * the name matching the specified inode number. -@@ -75,6 +84,8 @@ - int error; - struct file file; - struct nfsd_getdents_callback buffer; -+ struct lookup_intent it; -+ struct file *filp = NULL; - - error = -ENOTDIR; - if (!dir || !S_ISDIR(dir->i_mode)) -@@ -85,9 +96,37 @@ - /* - * Open the directory ... - */ -- error = init_private_file(&file, dentry, FMODE_READ); -- if (error) -+ if (dentry->d_op && dentry->d_op->d_revalidate_it) { -+ if ((dentry->d_flags & DCACHE_NFSD_DISCONNECTED) && -+ (dentry->d_parent == dentry) ) { -+ it.it_op_release = NULL; -+ /* -+ * XXX Temporary Hack: Simulating init_private_file without -+ * f_op->open for disconnected dentry Since we don't have actual -+ * dentry->d_name to revalidate in revalidate_it() -+ */ -+ filp = &file; -+ memset(filp, 0, sizeof(*filp)); -+ filp->f_mode = FMODE_READ; -+ atomic_set(&filp->f_count, 1); -+ filp->f_dentry = dentry; -+ filp->f_uid = current->fsuid; -+ filp->f_gid = current->fsgid; -+ filp->f_op = dentry->d_inode->i_fop; -+ error = 0; -+ } else { -+ intent_init(&it, IT_OPEN, 0); -+ error = revalidate_it(dentry, &it); -+ if (error) -+ goto out; -+ error = init_private_file_it(&file, dentry, FMODE_READ, &it); -+ } -+ } else { -+ error = init_private_file_it(&file, dentry, FMODE_READ, NULL); -+ } -+ if (error) - goto out; -+ - error = -EINVAL; - if (!file.f_op->readdir) - goto out_close; -@@ -113,9 +152,13 @@ - } - - out_close: -- if (file.f_op->release) -+ if (file.f_op->release && !filp) - file.f_op->release(dir, &file); - out: -+ if (dentry->d_op && -+ dentry->d_op->d_revalidate_it && -+ it.it_op_release && !filp) -+ intent_release(&it); - return error; - } - -@@ -274,7 +317,7 @@ - * it is well connected. But nobody returns different dentrys do they? - */ - down(&child->d_inode->i_sem); -- pdentry = child->d_inode->i_op->lookup(child->d_inode, tdentry); -+ pdentry = lookup_it(child->d_inode, tdentry); - up(&child->d_inode->i_sem); - d_drop(tdentry); /* we never want ".." hashed */ - if (!pdentry && tdentry->d_inode == NULL) { -@@ -307,6 +350,8 @@ - pdentry->d_flags |= DCACHE_NFSD_DISCONNECTED; - pdentry->d_op = child->d_op; - } -+ if (child->d_op && child->d_op->d_revalidate_it) -+ pdentry->d_op = child->d_op; - } - if (pdentry == NULL) - pdentry = ERR_PTR(-ENOMEM); -@@ -464,6 +509,8 @@ - struct dentry *pdentry; - struct inode *parent; - -+ if (result->d_op && result->d_op->d_revalidate_it) -+ dentry->d_op = result->d_op; - pdentry = nfsd_findparent(dentry); - err = PTR_ERR(pdentry); - if (IS_ERR(pdentry)) -@@ -670,6 +717,11 @@ - - inode = dentry->d_inode; - -+ /* cache coherency for non-device filesystems */ -+ if (inode->i_op && inode->i_op->revalidate_it) { -+ inode->i_op->revalidate_it(dentry, NULL); -+ } -+ - /* Type check. The correct error return for type mismatches - * does not seem to be generally agreed upon. SunOS seems to - * use EISDIR if file isn't S_IFREG; a comment in the NFSv3 -@@ -903,8 +955,9 @@ - dentry->d_parent->d_name.name, dentry->d_name.name); - goto out; - out_uptodate: -- printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n", -- dentry->d_parent->d_name.name, dentry->d_name.name); -+ if(!dentry->d_parent->d_inode->i_op->mkdir_raw) -+ printk(KERN_ERR "fh_update: %s/%s already up-to-date!\n", -+ dentry->d_parent->d_name.name, dentry->d_name.name); - goto out; - } - -Index: lum/fs/nfsd/vfs.c -=================================================================== ---- lum.orig/fs/nfsd/vfs.c 2003-11-28 13:26:21.000000000 -0500 -+++ lum/fs/nfsd/vfs.c 2004-06-07 17:25:22.000000000 -0400 -@@ -77,6 +77,128 @@ - static struct raparms * raparml; - static struct raparms * raparm_cache; - -+static int link_raw(struct dentry *dold, struct dentry *ddir, -+ struct dentry *dnew) -+{ -+ int err; -+ -+ struct nameidata old_nd = { .dentry = dold }; -+ struct nameidata nd = { .dentry = ddir, .last = dnew->d_name }; -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ err = op->link_raw(&old_nd, &nd); -+ d_instantiate(dnew, dold->d_inode); -+ if(dold->d_inode->i_op && dold->d_inode->i_op->revalidate_it) -+ dold->d_inode->i_op->revalidate_it(dnew, NULL); -+ -+ return err; -+} -+ -+static int unlink_raw(struct dentry *dentry, char *fname, int flen, -+ struct dentry *rdentry) -+{ -+ int err; -+ struct qstr last = { .name = fname, .len = flen }; -+ struct nameidata nd = { .dentry = dentry, .last = last }; -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ err = op->unlink_raw(&nd); -+ if (!err) -+ d_delete(rdentry); -+ -+ return err; -+} -+ -+static int rmdir_raw(struct dentry *dentry, char *fname, int flen, -+ struct dentry *rdentry) -+{ -+ int err; -+ struct qstr last = { .name = fname, .len = flen }; -+ struct nameidata nd = { .dentry = dentry, .last = last }; -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ err = op->rmdir_raw(&nd); -+ if(!err) { -+ rdentry->d_inode->i_flags |= S_DEAD; -+ d_delete(rdentry); -+ } -+ -+ return err; -+} -+ -+static int symlink_raw(struct dentry *dentry, char *fname, int flen, -+ char *path) -+{ -+ int err; -+ struct qstr last = { .name = fname, .len = flen }; -+ struct nameidata nd = { .dentry = dentry, .last = last }; -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ err = op->symlink_raw(&nd, path); -+ -+ return err; -+} -+ -+static int mkdir_raw(struct dentry *dentry, char *fname, int flen, int mode) -+{ -+ int err; -+ struct qstr last = { .name = fname, .len = flen }; -+ struct nameidata nd = { .dentry = dentry, .last = last }; -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ err = op->mkdir_raw(&nd, mode); -+ -+ return err; -+} -+ -+static int mknod_raw(struct dentry *dentry, char *fname, int flen, int mode, -+ dev_t dev) -+{ -+ int err; -+ struct qstr last = { .name = fname, .len = flen }; -+ struct nameidata nd = { .dentry = dentry, .last = last }; -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ err = op->mknod_raw(&nd, mode, dev); -+ -+ return err; -+} -+ -+static int rename_raw(struct dentry *fdentry, struct dentry *tdentry, -+ struct dentry *odentry, struct dentry *ndentry) -+{ -+ int err; -+ -+ struct nameidata old_nd = { .dentry = fdentry, .last = odentry->d_name}; -+ struct nameidata new_nd = { .dentry = tdentry, .last = ndentry->d_name}; -+ struct inode_operations *op = old_nd.dentry->d_inode->i_op; -+ err = op->rename_raw(&old_nd, &new_nd); -+ d_move(odentry, ndentry); -+ -+ return err; -+} -+ -+static int setattr_raw(struct inode *inode, struct iattr *iap) -+{ -+ int err; -+ -+ iap->ia_valid |= ATTR_RAW; -+ err = inode->i_op->setattr_raw(inode, iap); -+ -+ return err; -+} -+ -+int revalidate_it(struct dentry *dentry, struct lookup_intent *it) -+{ -+ int err = 0; -+ -+ if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) { -+ if (!dentry->d_op->d_revalidate_it(dentry, 0, NULL, it) && -+ !d_invalidate(dentry)) { -+ dput(dentry); -+ err = -EINVAL; -+ dentry = NULL; -+ return err; -+ } -+ } -+ -+ return err; -+} -+ - /* - * Look up one component of a pathname. - * N.B. After this call _both_ fhp and resfh need an fh_put -@@ -302,7 +424,10 @@ - } - err = nfserr_notsync; - if (!check_guard || guardtime == inode->i_ctime) { -- err = notify_change(dentry, iap); -+ if ( dentry->d_inode->i_op && dentry->d_inode->i_op->setattr_raw) -+ err = setattr_raw(dentry->d_inode, iap); -+ else -+ err = notify_change(dentry, iap); - err = nfserrno(err); - } - if (size_change) { -@@ -429,6 +554,7 @@ - { - struct dentry *dentry; - struct inode *inode; -+ struct lookup_intent it; - int err; - - /* If we get here, then the client has already done an "open", and (hopefully) -@@ -475,6 +601,14 @@ - filp->f_mode = FMODE_READ; - } - -+ intent_init(&it, IT_OPEN, (filp->f_flags & ~O_ACCMODE) | filp->f_mode); -+ -+ err = revalidate_it(dentry, &it); -+ if (err) -+ goto out_nfserr; -+ -+ filp->f_it = ⁢ -+ - err = 0; - if (filp->f_op && filp->f_op->open) { - err = filp->f_op->open(inode, filp); -@@ -489,7 +623,11 @@ - atomic_dec(&filp->f_count); - } - } -+ - out_nfserr: -+ if (it.it_op_release) -+ intent_release(&it); -+ - if (err) - err = nfserrno(err); - out: -@@ -820,7 +958,7 @@ - { - struct dentry *dentry, *dchild; - struct inode *dirp; -- int err; -+ int err, error = -EOPNOTSUPP; - - err = nfserr_perm; - if (!flen) -@@ -836,20 +974,44 @@ - dentry = fhp->fh_dentry; - dirp = dentry->d_inode; - -+ switch (type) { -+ case S_IFDIR: -+ if (dirp->i_op->mkdir_raw) -+ error = mkdir_raw(dentry, fname, flen, iap->ia_mode); -+ break; -+ case S_IFCHR: -+ case S_IFBLK: -+ case S_IFIFO: -+ case S_IFSOCK: -+ case S_IFREG: -+ if (dirp->i_op->mknod_raw) { -+ if (type == S_IFREG) -+ rdev = 0; -+ error = mknod_raw(dentry, fname, flen, iap->ia_mode, rdev); -+ } -+ break; -+ default: -+ printk("nfsd: bad file type %o in nfsd_create\n", type); -+ } -+ - err = nfserr_notdir; -- if(!dirp->i_op || !dirp->i_op->lookup) -+ if(!dirp->i_op || !(dirp->i_op->lookup || dirp->i_op->lookup_it)) - goto out; - /* - * Check whether the response file handle has been verified yet. - * If it has, the parent directory should already be locked. - */ -- if (!resfhp->fh_dentry) { -- /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create */ -- fh_lock(fhp); -+ if (!resfhp->fh_dentry || dirp->i_op->lookup_it) { -+ /* called from nfsd_proc_mkdir, or possibly nfsd3_proc_create -+ and nfsd_proc_create in case of lustre -+ */ -+ if (!resfhp->fh_dentry) -+ fh_lock(fhp); - dchild = lookup_one_len(fname, dentry, flen); - err = PTR_ERR(dchild); - if (IS_ERR(dchild)) - goto out_nfserr; -+ resfhp->fh_dentry = NULL; - err = fh_compose(resfhp, fhp->fh_export, dchild, fhp); - if (err) - goto out; -@@ -870,10 +1032,12 @@ - * Make sure the child dentry is still negative ... - */ - err = nfserr_exist; -- if (dchild->d_inode) { -- dprintk("nfsd_create: dentry %s/%s not negative!\n", -- dentry->d_name.name, dchild->d_name.name); -- goto out; -+ if ( error == -EOPNOTSUPP) { -+ if (dchild->d_inode) { -+ dprintk("nfsd_create: dentry %s/%s not negative!\n", -+ dentry->d_name.name, dchild->d_name.name); -+ goto out; -+ } - } - - if (!(iap->ia_valid & ATTR_MODE)) -@@ -886,16 +1050,19 @@ - err = nfserr_perm; - switch (type) { - case S_IFREG: -- err = vfs_create(dirp, dchild, iap->ia_mode); -+ if (error == -EOPNOTSUPP) -+ err = vfs_create(dirp, dchild, iap->ia_mode); - break; - case S_IFDIR: -- err = vfs_mkdir(dirp, dchild, iap->ia_mode); -+ if (error == -EOPNOTSUPP) -+ err = vfs_mkdir(dirp, dchild, iap->ia_mode); - break; - case S_IFCHR: - case S_IFBLK: - case S_IFIFO: - case S_IFSOCK: -- err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev); -+ if (error == -EOPNOTSUPP) -+ err = vfs_mknod(dirp, dchild, iap->ia_mode, rdev); - break; - default: - printk("nfsd: bad file type %o in nfsd_create\n", type); -@@ -964,7 +1131,13 @@ - /* Get all the sanity checks out of the way before - * we lock the parent. */ - err = nfserr_notdir; -- if(!dirp->i_op || !dirp->i_op->lookup) -+ if (dirp->i_op->mknod_raw) { -+ err = mknod_raw(dentry, fname, flen, iap->ia_mode, 0); -+ if (err && err != -EOPNOTSUPP) -+ goto out; -+ } -+ -+ if(!dirp->i_op || !(dirp->i_op->lookup || dirp->i_op->lookup_it)) - goto out; - fh_lock(fhp); - -@@ -1015,6 +1188,8 @@ - case NFS3_CREATE_GUARDED: - err = nfserr_exist; - } -+ if(dirp->i_op->mknod_raw) -+ err = 0; - goto out; - } - -@@ -1121,7 +1296,7 @@ - struct iattr *iap) - { - struct dentry *dentry, *dnew; -- int err, cerr; -+ int err, cerr, error = -EOPNOTSUPP; - - err = nfserr_noent; - if (!flen || !plen) -@@ -1135,12 +1310,18 @@ - goto out; - fh_lock(fhp); - dentry = fhp->fh_dentry; -+ -+ if (dentry->d_inode->i_op->symlink_raw) -+ error = symlink_raw(dentry, fname, flen, path); -+ - dnew = lookup_one_len(fname, dentry, flen); - err = PTR_ERR(dnew); - if (IS_ERR(dnew)) - goto out_nfserr; - -- err = vfs_symlink(dentry->d_inode, dnew, path); -+ err = error; -+ if (err == -EOPNOTSUPP || !dentry->d_inode->i_op->symlink_raw) -+ err = vfs_symlink(dentry->d_inode, dnew, path); - if (!err) { - if (EX_ISSYNC(fhp->fh_export)) - nfsd_sync_dir(dentry); -@@ -1150,7 +1331,10 @@ - iap->ia_valid |= ATTR_CTIME; - iap->ia_mode = (iap->ia_mode&S_IALLUGO) - | S_IFLNK; -- err = notify_change(dnew, iap); -+ if (dnew->d_inode->i_op && dnew->d_inode->i_op->setattr_raw) -+ err = setattr_raw(dnew->d_inode, iap); -+ else -+ err = notify_change(dnew, iap); - if (err) - err = nfserrno(err); - else if (EX_ISSYNC(fhp->fh_export)) -@@ -1210,7 +1394,10 @@ - dold = tfhp->fh_dentry; - dest = dold->d_inode; - -- err = vfs_link(dold, dirp, dnew); -+ if (dirp->i_op->link_raw) -+ err = link_raw(dold, ddir, dnew); -+ else -+ err = vfs_link(dold, dirp, dnew); - if (!err) { - if (EX_ISSYNC(ffhp->fh_export)) { - nfsd_sync_dir(ddir); -@@ -1295,7 +1482,10 @@ - err = nfserr_perm; - } else - #endif -- err = vfs_rename(fdir, odentry, tdir, ndentry); -+ if(fdir->i_op->rename_raw) -+ err = rename_raw(fdentry, tdentry, odentry, ndentry); -+ else -+ err = vfs_rename(fdir, odentry, tdir, ndentry); - if (!err && EX_ISSYNC(tfhp->fh_export)) { - nfsd_sync_dir(tdentry); - nfsd_sync_dir(fdentry); -@@ -1316,7 +1506,7 @@ - fill_post_wcc(tfhp); - double_up(&tdir->i_sem, &fdir->i_sem); - ffhp->fh_locked = tfhp->fh_locked = 0; -- -+ - out: - return err; - } -@@ -1362,9 +1552,15 @@ - err = nfserr_perm; - } else - #endif -- err = vfs_unlink(dirp, rdentry); -+ if (dirp->i_op->unlink_raw) -+ err = unlink_raw(dentry, fname, flen, rdentry); -+ else -+ err = vfs_unlink(dirp, rdentry); - } else { /* It's RMDIR */ -- err = vfs_rmdir(dirp, rdentry); -+ if (dirp->i_op->rmdir_raw) -+ err = rmdir_raw(dentry, fname, flen, rdentry); -+ else -+ err = vfs_rmdir(dirp, rdentry); - } - - dput(rdentry); -Index: lum/include/linux/fs.h -=================================================================== ---- lum.orig/include/linux/fs.h 2004-06-07 17:25:22.000000000 -0400 -+++ lum/include/linux/fs.h 2004-06-07 17:25:22.000000000 -0400 -@@ -93,6 +93,9 @@ - #define FS_SINGLE 8 /* Filesystem that can have only one superblock */ - #define FS_NOMOUNT 16 /* Never mount from userland */ - #define FS_LITTER 32 /* Keeps the tree in dcache */ -+#define FS_NFSEXP_FSID 64 /* Use file system specific fsid for -+ * exporting non device filesystems. -+ */ - #define FS_ODD_RENAME 32768 /* Temporary stuff; will go away as soon - * as nfs_rename() will be cleaned up - */ -@@ -1122,6 +1125,9 @@ - struct nameidata *nd, struct lookup_intent *it); - extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, - int flags, struct lookup_intent *it); -+extern int revalidate_it(struct dentry *dentry, struct lookup_intent *it); -+extern int init_private_file_it(struct file *, struct dentry *dentry, int mode, -+ struct lookup_intent *it); - extern int filp_close(struct file *, fl_owner_t id); - extern char * getname(const char *); - -@@ -1419,6 +1425,8 @@ - extern int follow_down(struct vfsmount **, struct dentry **); - extern int follow_up(struct vfsmount **, struct dentry **); - extern struct dentry * lookup_one_len(const char *, struct dentry *, int); -+extern struct dentry * lookup_one_len_it(const char *, struct dentry *, int, -+ struct lookup_intent *); - extern struct dentry * lookup_hash(struct qstr *, struct dentry *, struct nameidata *); - #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd) - #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd) -@@ -1434,6 +1442,8 @@ - - typedef int (*find_inode_t)(struct inode *, unsigned long, void *); - extern struct inode * iget4(struct super_block *, unsigned long, find_inode_t, void *); -+extern struct inode * ilookup4(struct super_block *, unsigned long, -+ find_inode_t, void *); - static inline struct inode *iget(struct super_block *sb, unsigned long ino) - { - return iget4(sb, ino, NULL, NULL); -Index: lum/kernel/ksyms.c -=================================================================== ---- lum.orig/kernel/ksyms.c 2004-06-07 17:25:22.000000000 -0400 -+++ lum/kernel/ksyms.c 2004-06-07 17:25:22.000000000 -0400 -@@ -150,6 +150,7 @@ - EXPORT_SYMBOL(iunique); - EXPORT_SYMBOL(ilookup); - EXPORT_SYMBOL(iget4); -+EXPORT_SYMBOL(ilookup4); - EXPORT_SYMBOL(iput); - EXPORT_SYMBOL(inode_init_once); - EXPORT_SYMBOL(force_delete); -@@ -161,6 +162,7 @@ - EXPORT_SYMBOL(path_release); - EXPORT_SYMBOL(__user_walk); - EXPORT_SYMBOL(lookup_one_len); -+EXPORT_SYMBOL(lookup_one_len_it); - EXPORT_SYMBOL(lookup_hash); - EXPORT_SYMBOL(sys_close); - EXPORT_SYMBOL(dcache_lock); diff --git a/lustre/kernel_patches/patches/procfs-ndynamic-2.4.24.patch b/lustre/kernel_patches/patches/procfs-ndynamic-2.4.24.patch deleted file mode 100644 index bff6c7e..0000000 --- a/lustre/kernel_patches/patches/procfs-ndynamic-2.4.24.patch +++ /dev/null @@ -1,13 +0,0 @@ -Index: linux-2.4.18-chaos/include/linux/proc_fs.h -=================================================================== ---- linux-2.4.18-chaos.orig/include/linux/proc_fs.h 2003-07-28 17:52:18.000000000 +0400 -+++ linux-2.4.18-chaos/include/linux/proc_fs.h 2004-01-12 20:12:38.000000000 +0300 -@@ -25,7 +25,7 @@ - /* Finally, the dynamically allocatable proc entries are reserved: */ - - #define PROC_DYNAMIC_FIRST 4096 --#define PROC_NDYNAMIC 4096 -+#define PROC_NDYNAMIC 16384 - - #define PROC_SUPER_MAGIC 0x9fa0 - diff --git a/lustre/kernel_patches/patches/tcp-zero-copy-2.4.24.patch b/lustre/kernel_patches/patches/tcp-zero-copy-2.4.24.patch deleted file mode 100644 index edcb7c7..0000000 --- a/lustre/kernel_patches/patches/tcp-zero-copy-2.4.24.patch +++ /dev/null @@ -1,467 +0,0 @@ - include/linux/skbuff.h | 30 +++++ - include/net/tcp.h | 5 - net/core/skbuff.c | 25 ++++ - net/ipv4/tcp.c | 252 ++++++++++++++++++++++++++++++++++++++++++++++++- - net/netsyms.c | 2 - 5 files changed, 311 insertions(+), 3 deletions(-) - -Index: linux-2.4.22-vanilla/include/linux/skbuff.h -=================================================================== ---- linux-2.4.22-vanilla.orig/include/linux/skbuff.h 2003-11-03 23:22:13.000000000 +0300 -+++ linux-2.4.22-vanilla/include/linux/skbuff.h 2003-12-02 23:56:35.000000000 +0300 -@@ -116,6 +116,30 @@ - __u16 size; - }; - -+/* Support for callback when skb data has been released */ -+typedef struct zccd /* Zero Copy Callback Descriptor */ -+{ /* (embed as first member of custom struct) */ -+ atomic_t zccd_count; /* reference count */ -+ void (*zccd_destructor)(struct zccd *); /* callback when refcount reaches zero */ -+} zccd_t; -+ -+static inline void zccd_init (zccd_t *d, void (*callback)(zccd_t *)) -+{ -+ atomic_set (&d->zccd_count, 1); -+ d->zccd_destructor = callback; -+} -+ -+static inline void zccd_get (zccd_t *d) /* take a reference */ -+{ -+ atomic_inc (&d->zccd_count); -+} -+ -+static inline void zccd_put (zccd_t *d) /* release a reference */ -+{ -+ if (atomic_dec_and_test (&d->zccd_count)) -+ (d->zccd_destructor)(d); -+} -+ - /* This data is invariant across clones and lives at - * the end of the header data, ie. at skb->end. - */ -@@ -123,6 +147,12 @@ - atomic_t dataref; - unsigned int nr_frags; - struct sk_buff *frag_list; -+ zccd_t *zccd; /* zero copy descriptor */ -+ zccd_t *zccd2; /* 2nd zero copy descriptor */ -+ /* NB we expect zero-copy data to be at least 1 packet, so -+ * having 2 zccds means we don't unneccessarily split the packet -+ * where consecutive zero-copy sends abutt. -+ */ - skb_frag_t frags[MAX_SKB_FRAGS]; - }; - -Index: linux-2.4.22-vanilla/include/net/tcp.h -=================================================================== ---- linux-2.4.22-vanilla.orig/include/net/tcp.h 2003-11-03 23:22:13.000000000 +0300 -+++ linux-2.4.22-vanilla/include/net/tcp.h 2003-12-02 23:58:10.000000000 +0300 -@@ -643,6 +643,8 @@ - - extern int tcp_sendmsg(struct sock *sk, struct msghdr *msg, int size); - extern ssize_t tcp_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags); -+extern ssize_t tcp_sendpage_zccd(struct socket *sock, struct page *page, int offset, size_t size, -+ int flags, zccd_t *zccd); - - extern int tcp_ioctl(struct sock *sk, - int cmd, -@@ -737,6 +739,9 @@ - struct msghdr *msg, - int len, int nonblock, - int flags, int *addr_len); -+extern int tcp_recvpackets(struct sock *sk, -+ struct sk_buff_head *packets, -+ int len, int nonblock); - - extern int tcp_listen_start(struct sock *sk); - -Index: linux-2.4.22-vanilla/net/core/skbuff.c -=================================================================== ---- linux-2.4.22-vanilla.orig/net/core/skbuff.c 2003-11-03 23:22:13.000000000 +0300 -+++ linux-2.4.22-vanilla/net/core/skbuff.c 2003-12-02 23:56:15.000000000 +0300 -@@ -208,6 +208,8 @@ - atomic_set(&(skb_shinfo(skb)->dataref), 1); - skb_shinfo(skb)->nr_frags = 0; - skb_shinfo(skb)->frag_list = NULL; -+ skb_shinfo(skb)->zccd = NULL; /* skbuffs kick off with NO user zero copy descriptors */ -+ skb_shinfo(skb)->zccd2 = NULL; - return skb; - - nodata: -@@ -277,6 +279,10 @@ - { - if (!skb->cloned || - atomic_dec_and_test(&(skb_shinfo(skb)->dataref))) { -+ if (skb_shinfo(skb)->zccd != NULL) /* zero copy callback descriptor? */ -+ zccd_put (skb_shinfo(skb)->zccd); /* release hold */ -+ if (skb_shinfo(skb)->zccd2 != NULL) /* 2nd zero copy callback descriptor? */ -+ zccd_put (skb_shinfo(skb)->zccd2); /* release hold */ - if (skb_shinfo(skb)->nr_frags) { - int i; - for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) -@@ -535,6 +541,8 @@ - atomic_set(&(skb_shinfo(skb)->dataref), 1); - skb_shinfo(skb)->nr_frags = 0; - skb_shinfo(skb)->frag_list = NULL; -+ skb_shinfo(skb)->zccd = NULL; /* copied data => no user zero copy descriptor */ -+ skb_shinfo(skb)->zccd2 = NULL; - - /* We are no longer a clone, even if we were. */ - skb->cloned = 0; -@@ -581,6 +589,14 @@ - n->data_len = skb->data_len; - n->len = skb->len; - -+ if (skb_shinfo(skb)->zccd != NULL) /* user zero copy descriptor? */ -+ zccd_get (skb_shinfo(skb)->zccd); /* 1 more ref (pages are shared) */ -+ skb_shinfo(n)->zccd = skb_shinfo(skb)->zccd; -+ -+ if (skb_shinfo(skb)->zccd2 != NULL) /* 2nd user zero copy descriptor? */ -+ zccd_get (skb_shinfo(skb)->zccd2); /* 1 more ref (pages are shared) */ -+ skb_shinfo(n)->zccd2 = skb_shinfo(skb)->zccd2; -+ - if (skb_shinfo(skb)->nr_frags) { - int i; - -@@ -623,6 +639,8 @@ - u8 *data; - int size = nhead + (skb->end - skb->head) + ntail; - long off; -+ zccd_t *zccd = skb_shinfo(skb)->zccd; /* stash user zero copy descriptor */ -+ zccd_t *zccd2 = skb_shinfo(skb)->zccd2; /* stash 2nd user zero copy descriptor */ - - if (skb_shared(skb)) - BUG(); -@@ -644,6 +662,11 @@ - if (skb_shinfo(skb)->frag_list) - skb_clone_fraglist(skb); - -+ if (zccd != NULL) /* user zero copy descriptor? */ -+ zccd_get (zccd); /* extra ref (pages are shared) */ -+ if (zccd2 != NULL) /* 2nd user zero copy descriptor? */ -+ zccd_get (zccd2); /* extra ref (pages are shared) */ -+ - skb_release_data(skb); - - off = (data+nhead) - skb->head; -@@ -658,6 +681,8 @@ - skb->nh.raw += off; - skb->cloned = 0; - atomic_set(&skb_shinfo(skb)->dataref, 1); -+ skb_shinfo(skb)->zccd = zccd; -+ skb_shinfo(skb)->zccd2 = zccd2; - return 0; - - nodata: -Index: linux-2.4.22-vanilla/net/ipv4/tcp.c -=================================================================== ---- linux-2.4.22-vanilla.orig/net/ipv4/tcp.c 2003-11-03 23:22:13.000000000 +0300 -+++ linux-2.4.22-vanilla/net/ipv4/tcp.c 2003-12-02 23:56:15.000000000 +0300 -@@ -747,7 +747,7 @@ - goto out; - } - --ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, size_t psize, int flags); -+ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, size_t psize, int flags, zccd_t *zccd); - - static inline int - can_coalesce(struct sk_buff *skb, int i, struct page *page, int off) -@@ -826,7 +826,8 @@ - return err; - } - --ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, size_t psize, int flags) -+/* Extra parameter: user zero copy descriptor (or NULL if not doing that) */ -+ssize_t do_tcp_sendpages(struct sock *sk, struct page **pages, int poffset, size_t psize, int flags, zccd_t *zccd) - { - struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); - int mss_now; -@@ -874,6 +875,17 @@ - copy = size; - - i = skb_shinfo(skb)->nr_frags; -+ -+ if (zccd != NULL && /* this is a zcc I/O */ -+ skb_shinfo(skb)->zccd != NULL && /* skb is part of a zcc I/O */ -+ skb_shinfo(skb)->zccd2 != NULL && -+ skb_shinfo(skb)->zccd != zccd && /* not the same one */ -+ skb_shinfo(skb)->zccd2 != zccd) -+ { -+ tcp_mark_push (tp, skb); -+ goto new_segment; -+ } -+ - if (can_coalesce(skb, i, page, offset)) { - skb_shinfo(skb)->frags[i-1].size += copy; - } else if (i < MAX_SKB_FRAGS) { -@@ -884,6 +896,20 @@ - goto new_segment; - } - -+ if (zccd != NULL && /* this is a zcc I/O */ -+ skb_shinfo(skb)->zccd != zccd && /* not already referencing this zccd */ -+ skb_shinfo(skb)->zccd2 != zccd) -+ { -+ zccd_get (zccd); /* bump ref count */ -+ -+ BUG_TRAP (skb_shinfo(skb)->zccd2 == NULL); -+ -+ if (skb_shinfo(skb)->zccd == NULL) /* reference this zccd */ -+ skb_shinfo(skb)->zccd = zccd; -+ else -+ skb_shinfo(skb)->zccd2 = zccd; -+ } -+ - skb->len += copy; - skb->data_len += copy; - skb->ip_summed = CHECKSUM_HW; -@@ -947,7 +973,31 @@ - - lock_sock(sk); - TCP_CHECK_TIMER(sk); -- res = do_tcp_sendpages(sk, &page, offset, size, flags); -+ res = do_tcp_sendpages(sk, &page, offset, size, flags, NULL); -+ TCP_CHECK_TIMER(sk); -+ release_sock(sk); -+ return res; -+} -+ -+ssize_t tcp_sendpage_zccd(struct socket *sock, struct page *page, int offset, size_t size, -+ int flags, zccd_t *zccd) -+{ -+ ssize_t res; -+ struct sock *sk = sock->sk; -+ -+#define TCP_ZC_CSUM_FLAGS (NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM) -+ -+ if (!(sk->route_caps & NETIF_F_SG) || /* caller shouldn't waste her time */ -+ !(sk->route_caps & TCP_ZC_CSUM_FLAGS)) /* on double mapping */ -+ BUG (); -+ -+#undef TCP_ZC_CSUM_FLAGS -+ -+ lock_sock(sk); -+ TCP_CHECK_TIMER(sk); -+ -+ res = do_tcp_sendpages(sk, &page, offset, size, flags, zccd); -+ - TCP_CHECK_TIMER(sk); - release_sock(sk); - return res; -@@ -1771,6 +1821,202 @@ - goto out; - } - -+int tcp_recvpackets (struct sock *sk, struct sk_buff_head *packets, -+ int len, int nonblock) -+{ -+ struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp); -+ int copied; -+ long timeo; -+ -+ BUG_TRAP (len > 0); -+ /*BUG_TRAP ((flags & (MSG_OOB | MSG_PEEK | MSG_TRUNC)) == 0);*/ -+ -+ lock_sock(sk); -+ -+ TCP_CHECK_TIMER(sk); -+ -+ copied = -ENOTCONN; -+ if (sk->state == TCP_LISTEN) -+ goto out; -+ -+ copied = 0; -+ timeo = sock_rcvtimeo(sk, nonblock); -+ -+ do { -+ struct sk_buff * skb; -+ u32 offset; -+ unsigned long used; -+ int exhausted; -+ int eaten; -+ -+ /* Are we at urgent data? Stop if we have read anything. */ -+ if (copied && tp->urg_data && tp->urg_seq == tp->copied_seq) -+ break; -+ -+ /* We need to check signals first, to get correct SIGURG -+ * handling. FIXME: Need to check this doesnt impact 1003.1g -+ * and move it down to the bottom of the loop -+ */ -+ if (signal_pending(current)) { -+ if (copied) -+ break; -+ copied = timeo ? sock_intr_errno(timeo) : -EAGAIN; -+ break; -+ } -+ -+ /* Next get a buffer. */ -+ -+ skb = skb_peek(&sk->receive_queue); -+ -+ if (skb == NULL) /* nothing ready */ -+ { -+ if (copied) { -+ if (sk->err || -+ sk->state == TCP_CLOSE || -+ (sk->shutdown & RCV_SHUTDOWN) || -+ !timeo || -+ (0)) -+ break; -+ } else { -+ if (sk->done) -+ break; -+ -+ if (sk->err) { -+ copied = sock_error(sk); -+ break; -+ } -+ -+ if (sk->shutdown & RCV_SHUTDOWN) -+ break; -+ -+ if (sk->state == TCP_CLOSE) { -+ if (!sk->done) { -+ /* This occurs when user tries to read -+ * from never connected socket. -+ */ -+ copied = -ENOTCONN; -+ break; -+ } -+ break; -+ } -+ -+ if (!timeo) { -+ copied = -EAGAIN; -+ break; -+ } -+ } -+ -+ cleanup_rbuf(sk, copied); -+ timeo = tcp_data_wait(sk, timeo); -+ continue; -+ } -+ -+ BUG_TRAP (atomic_read (&skb->users) == 1); -+ -+ exhausted = eaten = 0; -+ -+ offset = tp->copied_seq - TCP_SKB_CB(skb)->seq; -+ if (skb->h.th->syn) -+ offset--; -+ -+ used = skb->len - offset; -+ -+ if (tp->urg_data) { -+ u32 urg_offset = tp->urg_seq - tp->copied_seq; -+ if (urg_offset < used) { -+ if (!urg_offset) { /* at urgent date */ -+ if (!sk->urginline) { -+ tp->copied_seq++; /* discard the single byte of urgent data */ -+ offset++; -+ used--; -+ } -+ } else /* truncate read */ -+ used = urg_offset; -+ } -+ } -+ -+ BUG_TRAP (used >= 0); -+ if (len < used) -+ used = len; -+ -+ if (used == 0) -+ exhausted = 1; -+ else -+ { -+ if (skb_is_nonlinear (skb)) -+ { -+ int rc = skb_linearize (skb, GFP_KERNEL); -+ -+ printk ("tcp_recvpackets(): linearising: %d\n", rc); -+ -+ if (rc) -+ { -+ if (!copied) -+ copied = rc; -+ break; -+ } -+ } -+ -+ if ((offset + used) == skb->len) /* consuming the whole packet */ -+ { -+ __skb_unlink (skb, &sk->receive_queue); -+ dst_release (skb->dst); -+ skb_orphan (skb); -+ __skb_pull (skb, offset); -+ __skb_queue_tail (packets, skb); -+ exhausted = eaten = 1; -+ } -+ else /* consuming only part of the packet */ -+ { -+ struct sk_buff *skb2 = skb_clone (skb, GFP_KERNEL); -+ -+ if (skb2 == NULL) -+ { -+ if (!copied) -+ copied = -ENOMEM; -+ break; -+ } -+ -+ dst_release (skb2->dst); -+ __skb_pull (skb2, offset); -+ __skb_trim (skb2, used); -+ __skb_queue_tail (packets, skb2); -+ } -+ -+ tp->copied_seq += used; -+ copied += used; -+ len -= used; -+ } -+ -+ if (tp->urg_data && after(tp->copied_seq,tp->urg_seq)) { -+ tp->urg_data = 0; -+ tcp_fast_path_check(sk, tp); -+ } -+ -+ if (!exhausted) -+ continue; -+ -+ if (skb->h.th->fin) -+ { -+ tp->copied_seq++; -+ if (!eaten) -+ tcp_eat_skb (sk, skb); -+ break; -+ } -+ -+ if (!eaten) -+ tcp_eat_skb (sk, skb); -+ -+ } while (len > 0); -+ -+ out: -+ /* Clean up data we have read: This will do ACK frames. */ -+ cleanup_rbuf(sk, copied); -+ TCP_CHECK_TIMER(sk); -+ release_sock(sk); -+ return copied; -+} -+ - /* - * State processing on a close. This implements the state shift for - * sending our FIN frame. Note that we only send a FIN for some -Index: linux-2.4.22-vanilla/net/netsyms.c -=================================================================== ---- linux-2.4.22-vanilla.orig/net/netsyms.c 2003-11-03 23:22:13.000000000 +0300 -+++ linux-2.4.22-vanilla/net/netsyms.c 2003-12-04 20:42:50.000000000 +0300 -@@ -417,6 +417,8 @@ - - #endif - -+EXPORT_SYMBOL(tcp_sendpage_zccd); -+EXPORT_SYMBOL(tcp_recvpackets); - EXPORT_SYMBOL(tcp_read_sock); - - EXPORT_SYMBOL(netlink_set_err); diff --git a/lustre/kernel_patches/patches/uml-2.4.24-do_mmap_pgoff-fix.patch b/lustre/kernel_patches/patches/uml-2.4.24-do_mmap_pgoff-fix.patch deleted file mode 100644 index a44071e..0000000 --- a/lustre/kernel_patches/patches/uml-2.4.24-do_mmap_pgoff-fix.patch +++ /dev/null @@ -1,42 +0,0 @@ ---- linux-2.4.20-vanilla/arch/i386/kernel/sys_i386.c~uml-2.4.20-do_mmap_pgoff-fix 2001-03-19 23:35:09.000000000 +0300 -+++ linux-2.4.20-vanilla-alexey/arch/i386/kernel/sys_i386.c 2003-09-15 10:26:19.000000000 +0400 -@@ -56,7 +56,7 @@ static inline long do_mmap2( - } - - down_write(¤t->mm->mmap_sem); -- error = do_mmap_pgoff(file, addr, len, prot, flags, pgoff); -+ error = do_mmap_pgoff(current->mm, file, addr, len, prot, flags, pgoff); - up_write(¤t->mm->mmap_sem); - - if (file) ---- linux-2.4.24-vanilla/arch/x86_64/kernel/sys_x86_64.c 2004-10-15 12:19:54.919366416 -0400 -+++ linux-2.4.24-vanilla-x86_64/arch/x86_64/kernel/sys_x86_64.c 2003-11-28 13:26:19.000000000 -0500 -@@ -56,7 +56,7 @@ - } - - down_write(¤t->mm->mmap_sem); -- error = do_mmap_pgoff(file, addr, len, prot, flags, off >> PAGE_SHIFT); -+ error = do_mmap_pgoff(current->mm, file, addr, len, prot, flags, off >> PAGE_SHIFT); - up_write(¤t->mm->mmap_sem); - - if (file) ---- linux-2.4.24-vanilla/arch/x86_64/ia32/sys_ia32.c 2003-11-28 13:26:19.000000000 -0500 -+++ linux-2.4.24-vanilla-x86_64/arch/x86_64/ia32/sys_ia32.c 2004-10-15 12:36:52.114075768 -0400 -@@ -335,7 +335,7 @@ - - mm = current->mm; - down_write(&mm->mmap_sem); -- retval = do_mmap_pgoff(file, a.addr, a.len, a.prot, a.flags, a.offset>>PAGE_SHIFT); -+ retval = do_mmap_pgoff(current->mm, file, a.addr, a.len, a.prot, a.flags, a.offset>>PAGE_SHIFT); - if (file) - fput(file); - -@@ -2111,7 +2111,7 @@ - prot |= PROT_EXEC; - - down_write(&mm->mmap_sem); -- error = do_mmap_pgoff(file, addr, len, prot, flags|MAP_32BIT, pgoff); -+ error = do_mmap_pgoff(current->mm, file, addr, len, prot, flags|MAP_32BIT, pgoff); - up_write(&mm->mmap_sem); - - if (file) diff --git a/lustre/kernel_patches/patches/uml-export-end_iomem-2.4.24.patch b/lustre/kernel_patches/patches/uml-export-end_iomem-2.4.24.patch deleted file mode 100644 index ab8a84b..0000000 --- a/lustre/kernel_patches/patches/uml-export-end_iomem-2.4.24.patch +++ /dev/null @@ -1,12 +0,0 @@ -Index: linux-2.4.24-vanilla/arch/um/kernel/ksyms.c -=================================================================== ---- linux-2.4.24-vanilla.orig/arch/um/kernel/ksyms.c 2004-01-10 17:47:10.000000000 +0300 -+++ linux-2.4.24-vanilla/arch/um/kernel/ksyms.c 2004-01-10 18:22:30.000000000 +0300 -@@ -34,6 +34,7 @@ - EXPORT_SYMBOL(host_task_size); - EXPORT_SYMBOL(arch_validate); - EXPORT_SYMBOL(get_kmem_end); -+EXPORT_SYMBOL(end_iomem); - - EXPORT_SYMBOL(high_physmem); - EXPORT_SYMBOL(empty_zero_page); diff --git a/lustre/kernel_patches/patches/uml-patch-2.4.24-1.patch b/lustre/kernel_patches/patches/uml-patch-2.4.24-1.patch deleted file mode 100644 index ade809d..0000000 --- a/lustre/kernel_patches/patches/uml-patch-2.4.24-1.patch +++ /dev/null @@ -1,41971 +0,0 @@ -diff -Naur -X ../exclude-files orig/arch/um/common.ld.in um/arch/um/common.ld.in ---- orig/arch/um/common.ld.in 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/common.ld.in 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,53 @@ -+ .kstrtab : { *(.kstrtab) } -+ -+ . = ALIGN(16); /* Exception table */ -+ __start___ex_table = .; -+ __ex_table : { *(__ex_table) } -+ __stop___ex_table = .; -+ -+ __start___ksymtab = .; /* Kernel symbol table */ -+ __ksymtab : { *(__ksymtab) } -+ __stop___ksymtab = .; -+ -+ .unprotected : { *(.unprotected) } -+ . = ALIGN(4096); -+ PROVIDE (_unprotected_end = .); -+ -+ . = ALIGN(4096); -+ __uml_setup_start = .; -+ .uml.setup.init : { *(.uml.setup.init) } -+ __uml_setup_end = .; -+ __uml_help_start = .; -+ .uml.help.init : { *(.uml.help.init) } -+ __uml_help_end = .; -+ __uml_postsetup_start = .; -+ .uml.postsetup.init : { *(.uml.postsetup.init) } -+ __uml_postsetup_end = .; -+ __setup_start = .; -+ .setup.init : { *(.setup.init) } -+ __setup_end = .; -+ __initcall_start = .; -+ .initcall.init : { *(.initcall.init) } -+ __initcall_end = .; -+ __uml_initcall_start = .; -+ .uml.initcall.init : { *(.uml.initcall.init) } -+ __uml_initcall_end = .; -+ __init_end = .; -+ __exitcall_begin = .; -+ .exitcall : { *(.exitcall.exit) } -+ __exitcall_end = .; -+ __uml_exitcall_begin = .; -+ .uml.exitcall : { *(.uml.exitcall.exit) } -+ __uml_exitcall_end = .; -+ -+ __preinit_array_start = .; -+ .preinit_array : { *(.preinit_array) } -+ __preinit_array_end = .; -+ __init_array_start = .; -+ .init_array : { *(.init_array) } -+ __init_array_end = .; -+ __fini_array_start = .; -+ .fini_array : { *(.fini_array) } -+ __fini_array_end = .; -+ -+ .data.init : { *(.data.init) } -diff -Naur -X ../exclude-files orig/arch/um/config_block.in um/arch/um/config_block.in ---- orig/arch/um/config_block.in 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/config_block.in 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,22 @@ -+mainmenu_option next_comment -+comment 'Block Devices' -+ -+bool 'Virtual block device' CONFIG_BLK_DEV_UBD -+dep_bool ' Always do synchronous disk IO for UBD' CONFIG_BLK_DEV_UBD_SYNC $CONFIG_BLK_DEV_UBD -+bool 'COW device' CONFIG_COW -+ -+if [ "$CONFIG_BLK_DEV_UBD" = "y" -o "$CONFIG_COW" = "y" ] ; then -+ define_bool CONFIG_COW_COMMON y -+fi -+ -+tristate 'Loopback device support' CONFIG_BLK_DEV_LOOP -+dep_tristate 'Network block device support' CONFIG_BLK_DEV_NBD $CONFIG_NET -+tristate 'RAM disk support' CONFIG_BLK_DEV_RAM -+if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then -+ int ' Default RAM disk size' CONFIG_BLK_DEV_RAM_SIZE 4096 -+fi -+dep_bool ' Initial RAM disk (initrd) support' CONFIG_BLK_DEV_INITRD $CONFIG_BLK_DEV_RAM -+ -+tristate 'Example IO memory driver' CONFIG_MMAPPER -+ -+endmenu -diff -Naur -X ../exclude-files orig/arch/um/config_char.in um/arch/um/config_char.in ---- orig/arch/um/config_char.in 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/config_char.in 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,37 @@ -+mainmenu_option next_comment -+comment 'Character Devices' -+ -+define_bool CONFIG_STDIO_CONSOLE y -+ -+bool 'Virtual serial line' CONFIG_SSL -+ -+bool 'file descriptor channel support' CONFIG_FD_CHAN -+bool 'null channel support' CONFIG_NULL_CHAN -+bool 'port channel support' CONFIG_PORT_CHAN -+bool 'pty channel support' CONFIG_PTY_CHAN -+bool 'tty channel support' CONFIG_TTY_CHAN -+bool 'xterm channel support' CONFIG_XTERM_CHAN -+string 'Default main console channel initialization' CONFIG_CON_ZERO_CHAN \ -+ "fd:0,fd:1" -+string 'Default console channel initialization' CONFIG_CON_CHAN "xterm" -+string 'Default serial line channel initialization' CONFIG_SSL_CHAN "pty" -+ -+ -+bool 'Unix98 PTY support' CONFIG_UNIX98_PTYS -+if [ "$CONFIG_UNIX98_PTYS" = "y" ]; then -+ int 'Maximum number of Unix98 PTYs in use (0-2048)' CONFIG_UNIX98_PTY_COUNT 256 -+fi -+ -+bool 'Watchdog Timer Support' CONFIG_WATCHDOG -+dep_bool ' Disable watchdog shutdown on close' CONFIG_WATCHDOG_NOWAYOUT \ -+ $CONFIG_WATCHDOG -+dep_tristate ' Software Watchdog' CONFIG_SOFT_WATCHDOG $CONFIG_WATCHDOG -+dep_tristate ' UML watchdog' CONFIG_UML_WATCHDOG $CONFIG_WATCHDOG -+ -+tristate 'Sound support' CONFIG_UML_SOUND -+define_tristate CONFIG_SOUND $CONFIG_UML_SOUND -+define_tristate CONFIG_HOSTAUDIO $CONFIG_UML_SOUND -+ -+bool 'Enable tty logging' CONFIG_TTY_LOG -+ -+endmenu -diff -Naur -X ../exclude-files orig/arch/um/config.in um/arch/um/config.in ---- orig/arch/um/config.in 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/config.in 2003-12-14 11:34:02.000000000 -0500 -@@ -0,0 +1,105 @@ -+define_bool CONFIG_USERMODE y -+ -+mainmenu_name "Linux/Usermode Kernel Configuration" -+ -+define_bool CONFIG_ISA n -+define_bool CONFIG_SBUS n -+define_bool CONFIG_PCI n -+ -+define_bool CONFIG_UID16 y -+ -+define_bool CONFIG_RWSEM_XCHGADD_ALGORITHM y -+ -+mainmenu_option next_comment -+comment 'Code maturity level options' -+bool 'Prompt for development and/or incomplete code/drivers' CONFIG_EXPERIMENTAL -+endmenu -+ -+mainmenu_option next_comment -+comment 'General Setup' -+ -+bool 'Separate kernel address space support' CONFIG_MODE_SKAS -+ -+# This is to ensure that at least one of the modes is enabled. When neither -+# is present in defconfig, they default to N, which is bad. -+if [ "$CONFIG_MODE_SKAS" != "y" ]; then -+ define_bool CONFIG_MODE_TT y -+fi -+ -+bool 'Tracing thread support' CONFIG_MODE_TT -+if [ "$CONFIG_MODE_TT" != "y" ]; then -+ bool 'Statically linked binary when CONFIG_MODE_TT is disabled' CONFIG_STATIC_LINK -+fi -+bool 'Networking support' CONFIG_NET -+bool 'System V IPC' CONFIG_SYSVIPC -+bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT -+bool 'Sysctl support' CONFIG_SYSCTL -+tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT -+tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF -+tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC -+tristate 'Host filesystem' CONFIG_HOSTFS -+tristate 'Honeypot proc filesystem' CONFIG_HPPFS -+bool 'Management console' CONFIG_MCONSOLE -+dep_bool 'Magic SysRq key' CONFIG_MAGIC_SYSRQ $CONFIG_MCONSOLE -+bool '2G/2G host address space split' CONFIG_HOST_2G_2G -+bool 'Symmetric multi-processing support' CONFIG_UML_SMP -+define_bool CONFIG_SMP $CONFIG_UML_SMP -+int 'Nesting level' CONFIG_NEST_LEVEL 0 -+int 'Kernel address space size (in .5G units)' CONFIG_KERNEL_HALF_GIGS 1 -+bool 'Highmem support' CONFIG_HIGHMEM -+bool '/proc/mm' CONFIG_PROC_MM -+int 'Kernel stack size order' CONFIG_KERNEL_STACK_ORDER 2 -+bool 'Real-time Clock' CONFIG_UML_REAL_TIME_CLOCK -+endmenu -+ -+mainmenu_option next_comment -+comment 'Loadable module support' -+bool 'Enable loadable module support' CONFIG_MODULES -+if [ "$CONFIG_MODULES" = "y" ]; then -+# MODVERSIONS does not yet work in this architecture -+# bool ' Set version information on all module symbols' CONFIG_MODVERSIONS -+ bool ' Kernel module loader' CONFIG_KMOD -+fi -+endmenu -+ -+source arch/um/config_char.in -+ -+source arch/um/config_block.in -+ -+define_bool CONFIG_NETDEVICES $CONFIG_NET -+ -+if [ "$CONFIG_NET" = "y" ]; then -+ source arch/um/config_net.in -+ source net/Config.in -+fi -+ -+source fs/Config.in -+ -+mainmenu_option next_comment -+comment 'SCSI support' -+ -+tristate 'SCSI support' CONFIG_SCSI -+ -+if [ "$CONFIG_SCSI" != "n" ]; then -+ source arch/um/config_scsi.in -+fi -+endmenu -+ -+source drivers/md/Config.in -+ -+source drivers/mtd/Config.in -+ -+source lib/Config.in -+ -+mainmenu_option next_comment -+comment 'Kernel hacking' -+bool 'Debug memory allocations' CONFIG_DEBUG_SLAB -+bool 'Enable kernel debugging symbols' CONFIG_DEBUGSYM -+if [ "$CONFIG_XTERM_CHAN" = "y" ]; then -+ dep_bool 'Enable ptrace proxy' CONFIG_PT_PROXY $CONFIG_DEBUGSYM -+else -+ define_bool CONFIG_PT_PROXY n -+fi -+dep_bool 'Enable gprof support' CONFIG_GPROF $CONFIG_DEBUGSYM -+dep_bool 'Enable gcov support' CONFIG_GCOV $CONFIG_DEBUGSYM -+endmenu -diff -Naur -X ../exclude-files orig/arch/um/config_net.in um/arch/um/config_net.in ---- orig/arch/um/config_net.in 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/config_net.in 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,47 @@ -+mainmenu_option next_comment -+comment 'Network Devices' -+ -+# UML virtual driver -+bool 'Virtual network device' CONFIG_UML_NET -+ -+dep_bool ' Ethertap transport' CONFIG_UML_NET_ETHERTAP $CONFIG_UML_NET -+dep_bool ' TUN/TAP transport' CONFIG_UML_NET_TUNTAP $CONFIG_UML_NET -+dep_bool ' SLIP transport' CONFIG_UML_NET_SLIP $CONFIG_UML_NET -+dep_bool ' SLiRP transport' CONFIG_UML_NET_SLIRP $CONFIG_UML_NET -+dep_bool ' Daemon transport' CONFIG_UML_NET_DAEMON $CONFIG_UML_NET -+dep_bool ' Multicast transport' CONFIG_UML_NET_MCAST $CONFIG_UML_NET -+dep_bool ' pcap transport' CONFIG_UML_NET_PCAP $CONFIG_UML_NET -+ -+# Below are hardware-independent drivers mirrored from -+# drivers/net/Config.in. It would be nice if Linux -+# had HW independent drivers separated from the other -+# but it does not. Until then each non-ISA/PCI arch -+# needs to provide it's own menu of network drivers -+ -+tristate 'Dummy net driver support' CONFIG_DUMMY -+tristate 'Bonding driver support' CONFIG_BONDING -+tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER -+tristate 'Universal TUN/TAP device driver support' CONFIG_TUN -+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then -+ if [ "$CONFIG_NETLINK" = "y" ]; then -+ tristate 'Ethertap network tap (OBSOLETE)' CONFIG_ETHERTAP -+ fi -+fi -+ -+tristate 'PPP (point-to-point protocol) support' CONFIG_PPP -+if [ ! "$CONFIG_PPP" = "n" ]; then -+ dep_bool ' PPP multilink support (EXPERIMENTAL)' CONFIG_PPP_MULTILINK $CONFIG_EXPERIMENTAL -+ dep_bool ' PPP filtering' CONFIG_PPP_FILTER $CONFIG_FILTER -+ dep_tristate ' PPP support for async serial ports' CONFIG_PPP_ASYNC $CONFIG_PPP -+ dep_tristate ' PPP support for sync tty ports' CONFIG_PPP_SYNC_TTY $CONFIG_PPP -+ dep_tristate ' PPP Deflate compression' CONFIG_PPP_DEFLATE $CONFIG_PPP -+ dep_tristate ' PPP BSD-Compress compression' CONFIG_PPP_BSDCOMP $CONFIG_PPP -+ dep_tristate ' PPP over Ethernet (EXPERIMENTAL)' CONFIG_PPPOE $CONFIG_PPP $CONFIG_EXPERIMENTAL -+fi -+ -+tristate 'SLIP (serial line) support' CONFIG_SLIP -+dep_bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED $CONFIG_SLIP -+dep_bool ' Keepalive and linefill' CONFIG_SLIP_SMART $CONFIG_SLIP -+dep_bool ' Six bit SLIP encapsulation' CONFIG_SLIP_MODE_SLIP6 $CONFIG_SLIP -+ -+endmenu -diff -Naur -X ../exclude-files orig/arch/um/config.release um/arch/um/config.release ---- orig/arch/um/config.release 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/config.release 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,302 @@ -+# -+# Automatically generated make config: don't edit -+# -+CONFIG_USERMODE=y -+# CONFIG_ISA is not set -+# CONFIG_SBUS is not set -+# CONFIG_PCI is not set -+CONFIG_UID16=y -+CONFIG_RWSEM_XCHGADD_ALGORITHM=y -+ -+# -+# Code maturity level options -+# -+CONFIG_EXPERIMENTAL=y -+ -+# -+# General Setup -+# -+CONFIG_NET=y -+CONFIG_SYSVIPC=y -+CONFIG_BSD_PROCESS_ACCT=y -+CONFIG_SYSCTL=y -+CONFIG_BINFMT_AOUT=y -+CONFIG_BINFMT_ELF=y -+CONFIG_BINFMT_MISC=y -+CONFIG_HOSTFS=y -+# CONFIG_HPPFS is not set -+CONFIG_MCONSOLE=y -+CONFIG_MAGIC_SYSRQ=y -+# CONFIG_HOST_2G_2G is not set -+# CONFIG_UML_SMP is not set -+# CONFIG_SMP is not set -+CONFIG_NEST_LEVEL=0 -+CONFIG_KERNEL_HALF_GIGS=1 -+ -+# -+# Loadable module support -+# -+CONFIG_MODULES=y -+CONFIG_KMOD=y -+ -+# -+# Character Devices -+# -+CONFIG_STDIO_CONSOLE=y -+CONFIG_SSL=y -+CONFIG_FD_CHAN=y -+# CONFIG_NULL_CHAN is not set -+CONFIG_PORT_CHAN=y -+CONFIG_PTY_CHAN=y -+CONFIG_TTY_CHAN=y -+CONFIG_XTERM_CHAN=y -+CONFIG_CON_ZERO_CHAN="fd:0,fd:1" -+CONFIG_CON_CHAN="xterm" -+CONFIG_SSL_CHAN="pty" -+CONFIG_UNIX98_PTYS=y -+CONFIG_UNIX98_PTY_COUNT=256 -+# CONFIG_WATCHDOG is not set -+CONFIG_UML_SOUND=y -+CONFIG_SOUND=y -+CONFIG_HOSTAUDIO=y -+# CONFIG_TTY_LOG is not set -+ -+# -+# Block Devices -+# -+CONFIG_BLK_DEV_UBD=y -+# CONFIG_BLK_DEV_UBD_SYNC is not set -+CONFIG_BLK_DEV_LOOP=y -+CONFIG_BLK_DEV_NBD=y -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_SIZE=4096 -+CONFIG_BLK_DEV_INITRD=y -+# CONFIG_MMAPPER is not set -+CONFIG_NETDEVICES=y -+ -+# -+# Network Devices -+# -+CONFIG_UML_NET=y -+CONFIG_UML_NET_ETHERTAP=y -+CONFIG_UML_NET_TUNTAP=y -+CONFIG_UML_NET_SLIP=y -+CONFIG_UML_NET_DAEMON=y -+CONFIG_UML_NET_MCAST=y -+CONFIG_DUMMY=y -+CONFIG_BONDING=m -+CONFIG_EQUALIZER=m -+CONFIG_TUN=y -+CONFIG_PPP=m -+CONFIG_PPP_MULTILINK=y -+# CONFIG_PPP_ASYNC is not set -+CONFIG_PPP_SYNC_TTY=m -+CONFIG_PPP_DEFLATE=m -+CONFIG_PPP_BSDCOMP=m -+CONFIG_PPPOE=m -+CONFIG_SLIP=m -+ -+# -+# Networking options -+# -+CONFIG_PACKET=y -+CONFIG_PACKET_MMAP=y -+# CONFIG_NETLINK_DEV is not set -+# CONFIG_NETFILTER is not set -+# CONFIG_FILTER is not set -+CONFIG_UNIX=y -+CONFIG_INET=y -+# CONFIG_IP_MULTICAST is not set -+# CONFIG_IP_ADVANCED_ROUTER is not set -+# CONFIG_IP_PNP is not set -+# CONFIG_NET_IPIP is not set -+# CONFIG_NET_IPGRE is not set -+# CONFIG_ARPD is not set -+# CONFIG_INET_ECN is not set -+# CONFIG_SYN_COOKIES is not set -+# CONFIG_IPV6 is not set -+# CONFIG_KHTTPD is not set -+# CONFIG_ATM is not set -+# CONFIG_VLAN_8021Q is not set -+ -+# -+# -+# -+# CONFIG_IPX is not set -+# CONFIG_ATALK is not set -+ -+# -+# Appletalk devices -+# -+# CONFIG_DECNET is not set -+# CONFIG_BRIDGE is not set -+# CONFIG_X25 is not set -+# CONFIG_LAPB is not set -+# CONFIG_LLC is not set -+# CONFIG_NET_DIVERT is not set -+# CONFIG_ECONET is not set -+# CONFIG_WAN_ROUTER is not set -+# CONFIG_NET_FASTROUTE is not set -+# CONFIG_NET_HW_FLOWCONTROL is not set -+ -+# -+# QoS and/or fair queueing -+# -+# CONFIG_NET_SCHED is not set -+ -+# -+# Network testing -+# -+# CONFIG_NET_PKTGEN is not set -+ -+# -+# File systems -+# -+CONFIG_QUOTA=y -+CONFIG_AUTOFS_FS=m -+CONFIG_AUTOFS4_FS=m -+CONFIG_REISERFS_FS=m -+# CONFIG_REISERFS_CHECK is not set -+# CONFIG_REISERFS_PROC_INFO is not set -+CONFIG_ADFS_FS=m -+# CONFIG_ADFS_FS_RW is not set -+CONFIG_AFFS_FS=m -+CONFIG_HFS_FS=m -+CONFIG_BFS_FS=m -+CONFIG_EXT3_FS=y -+CONFIG_JBD=y -+# CONFIG_JBD_DEBUG is not set -+CONFIG_FAT_FS=y -+CONFIG_MSDOS_FS=y -+CONFIG_UMSDOS_FS=y -+CONFIG_VFAT_FS=y -+CONFIG_EFS_FS=m -+CONFIG_CRAMFS=m -+CONFIG_TMPFS=y -+CONFIG_RAMFS=y -+CONFIG_ISO9660_FS=y -+# CONFIG_JOLIET is not set -+# CONFIG_ZISOFS is not set -+CONFIG_MINIX_FS=m -+CONFIG_VXFS_FS=m -+# CONFIG_NTFS_FS is not set -+CONFIG_HPFS_FS=m -+CONFIG_PROC_FS=y -+CONFIG_DEVFS_FS=y -+CONFIG_DEVFS_MOUNT=y -+# CONFIG_DEVFS_DEBUG is not set -+CONFIG_DEVPTS_FS=y -+CONFIG_QNX4FS_FS=m -+# CONFIG_QNX4FS_RW is not set -+CONFIG_ROMFS_FS=m -+CONFIG_EXT2_FS=y -+CONFIG_SYSV_FS=m -+CONFIG_UDF_FS=m -+# CONFIG_UDF_RW is not set -+CONFIG_UFS_FS=m -+# CONFIG_UFS_FS_WRITE is not set -+ -+# -+# Network File Systems -+# -+# CONFIG_CODA_FS is not set -+# CONFIG_INTERMEZZO_FS is not set -+CONFIG_NFS_FS=y -+CONFIG_NFS_V3=y -+CONFIG_NFSD=y -+CONFIG_NFSD_V3=y -+CONFIG_SUNRPC=y -+CONFIG_LOCKD=y -+CONFIG_LOCKD_V4=y -+# CONFIG_SMB_FS is not set -+# CONFIG_NCP_FS is not set -+# CONFIG_ZISOFS_FS is not set -+CONFIG_ZLIB_FS_INFLATE=m -+ -+# -+# Partition Types -+# -+# CONFIG_PARTITION_ADVANCED is not set -+CONFIG_MSDOS_PARTITION=y -+# CONFIG_SMB_NLS is not set -+CONFIG_NLS=y -+ -+# -+# Native Language Support -+# -+CONFIG_NLS_DEFAULT="iso8859-1" -+# CONFIG_NLS_CODEPAGE_437 is not set -+# CONFIG_NLS_CODEPAGE_737 is not set -+# CONFIG_NLS_CODEPAGE_775 is not set -+# CONFIG_NLS_CODEPAGE_850 is not set -+# CONFIG_NLS_CODEPAGE_852 is not set -+# CONFIG_NLS_CODEPAGE_855 is not set -+# CONFIG_NLS_CODEPAGE_857 is not set -+# CONFIG_NLS_CODEPAGE_860 is not set -+# CONFIG_NLS_CODEPAGE_861 is not set -+# CONFIG_NLS_CODEPAGE_862 is not set -+# CONFIG_NLS_CODEPAGE_863 is not set -+# CONFIG_NLS_CODEPAGE_864 is not set -+# CONFIG_NLS_CODEPAGE_865 is not set -+# CONFIG_NLS_CODEPAGE_866 is not set -+# CONFIG_NLS_CODEPAGE_869 is not set -+# CONFIG_NLS_CODEPAGE_936 is not set -+# CONFIG_NLS_CODEPAGE_950 is not set -+# CONFIG_NLS_CODEPAGE_932 is not set -+# CONFIG_NLS_CODEPAGE_949 is not set -+# CONFIG_NLS_CODEPAGE_874 is not set -+# CONFIG_NLS_ISO8859_8 is not set -+# CONFIG_NLS_CODEPAGE_1250 is not set -+# CONFIG_NLS_CODEPAGE_1251 is not set -+# CONFIG_NLS_ISO8859_1 is not set -+# CONFIG_NLS_ISO8859_2 is not set -+# CONFIG_NLS_ISO8859_3 is not set -+# CONFIG_NLS_ISO8859_4 is not set -+# CONFIG_NLS_ISO8859_5 is not set -+# CONFIG_NLS_ISO8859_6 is not set -+# CONFIG_NLS_ISO8859_7 is not set -+# CONFIG_NLS_ISO8859_9 is not set -+# CONFIG_NLS_ISO8859_13 is not set -+# CONFIG_NLS_ISO8859_14 is not set -+# CONFIG_NLS_ISO8859_15 is not set -+# CONFIG_NLS_KOI8_R is not set -+# CONFIG_NLS_KOI8_U is not set -+# CONFIG_NLS_UTF8 is not set -+ -+# -+# SCSI support -+# -+CONFIG_SCSI=y -+ -+# -+# SCSI support type (disk, tape, CD-ROM) -+# -+# CONFIG_BLK_DEV_SD is not set -+# CONFIG_CHR_DEV_ST is not set -+# CONFIG_BLK_DEV_SR is not set -+# CONFIG_CHR_DEV_SG is not set -+ -+# -+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -+# -+# CONFIG_SCSI_DEBUG_QUEUES is not set -+# CONFIG_SCSI_MULTI_LUN is not set -+# CONFIG_SCSI_CONSTANTS is not set -+# CONFIG_SCSI_LOGGING is not set -+CONFIG_SCSI_DEBUG=m -+ -+# -+# Multi-device support (RAID and LVM) -+# -+# CONFIG_MD is not set -+ -+# -+# Memory Technology Devices (MTD) -+# -+# CONFIG_MTD is not set -+ -+# -+# Kernel hacking -+# -+# CONFIG_DEBUG_SLAB is not set -+# CONFIG_DEBUGSYM is not set -diff -Naur -X ../exclude-files orig/arch/um/config_scsi.in um/arch/um/config_scsi.in ---- orig/arch/um/config_scsi.in 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/config_scsi.in 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,30 @@ -+comment 'SCSI support type (disk, tape, CD-ROM)' -+ -+dep_tristate ' SCSI disk support' CONFIG_BLK_DEV_SD $CONFIG_SCSI -+ -+if [ "$CONFIG_BLK_DEV_SD" != "n" ]; then -+ int 'Maximum number of SCSI disks that can be loaded as modules' CONFIG_SD_EXTRA_DEVS 40 -+fi -+ -+dep_tristate ' SCSI tape support' CONFIG_CHR_DEV_ST $CONFIG_SCSI -+ -+dep_tristate ' SCSI CD-ROM support' CONFIG_BLK_DEV_SR $CONFIG_SCSI -+ -+if [ "$CONFIG_BLK_DEV_SR" != "n" ]; then -+ bool ' Enable vendor-specific extensions (for SCSI CDROM)' CONFIG_BLK_DEV_SR_VENDOR -+ int 'Maximum number of CDROM devices that can be loaded as modules' CONFIG_SR_EXTRA_DEVS 2 -+fi -+dep_tristate ' SCSI generic support' CONFIG_CHR_DEV_SG $CONFIG_SCSI -+ -+comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs' -+ -+#if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then -+ bool ' Enable extra checks in new queueing code' CONFIG_SCSI_DEBUG_QUEUES -+#fi -+ -+bool ' Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN -+ -+bool ' Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS -+bool ' SCSI logging facility' CONFIG_SCSI_LOGGING -+ -+dep_tristate 'SCSI debugging host simulator (EXPERIMENTAL)' CONFIG_SCSI_DEBUG $CONFIG_SCSI -diff -Naur -X ../exclude-files orig/arch/um/defconfig um/arch/um/defconfig ---- orig/arch/um/defconfig 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/defconfig 2003-12-17 02:15:39.000000000 -0500 -@@ -0,0 +1,423 @@ -+# -+# Automatically generated make config: don't edit -+# -+CONFIG_USERMODE=y -+# CONFIG_ISA is not set -+# CONFIG_SBUS is not set -+# CONFIG_PCI is not set -+CONFIG_UID16=y -+CONFIG_RWSEM_XCHGADD_ALGORITHM=y -+ -+# -+# Code maturity level options -+# -+CONFIG_EXPERIMENTAL=y -+ -+# -+# General Setup -+# -+CONFIG_MODE_SKAS=y -+CONFIG_MODE_TT=y -+CONFIG_NET=y -+CONFIG_SYSVIPC=y -+CONFIG_BSD_PROCESS_ACCT=y -+CONFIG_SYSCTL=y -+CONFIG_BINFMT_AOUT=y -+CONFIG_BINFMT_ELF=y -+CONFIG_BINFMT_MISC=y -+CONFIG_HOSTFS=y -+CONFIG_HPPFS=y -+CONFIG_MCONSOLE=y -+CONFIG_MAGIC_SYSRQ=y -+# CONFIG_HOST_2G_2G is not set -+# CONFIG_UML_SMP is not set -+# CONFIG_SMP is not set -+CONFIG_NEST_LEVEL=0 -+CONFIG_KERNEL_HALF_GIGS=1 -+# CONFIG_HIGHMEM is not set -+CONFIG_PROC_MM=y -+CONFIG_KERNEL_STACK_ORDER=2 -+CONFIG_UML_REAL_TIME_CLOCK=y -+ -+# -+# Loadable module support -+# -+CONFIG_MODULES=y -+# CONFIG_KMOD is not set -+ -+# -+# Character Devices -+# -+CONFIG_STDIO_CONSOLE=y -+CONFIG_SSL=y -+CONFIG_FD_CHAN=y -+CONFIG_NULL_CHAN=y -+CONFIG_PORT_CHAN=y -+CONFIG_PTY_CHAN=y -+CONFIG_TTY_CHAN=y -+CONFIG_XTERM_CHAN=y -+CONFIG_CON_ZERO_CHAN="fd:0,fd:1" -+CONFIG_CON_CHAN="xterm" -+CONFIG_SSL_CHAN="pty" -+CONFIG_UNIX98_PTYS=y -+CONFIG_UNIX98_PTY_COUNT=256 -+# CONFIG_WATCHDOG is not set -+# CONFIG_WATCHDOG_NOWAYOUT is not set -+# CONFIG_SOFT_WATCHDOG is not set -+# CONFIG_UML_WATCHDOG is not set -+CONFIG_UML_SOUND=y -+CONFIG_SOUND=y -+CONFIG_HOSTAUDIO=y -+# CONFIG_TTY_LOG is not set -+ -+# -+# Block Devices -+# -+CONFIG_BLK_DEV_UBD=y -+# CONFIG_BLK_DEV_UBD_SYNC is not set -+# CONFIG_COW is not set -+CONFIG_COW_COMMON=y -+CONFIG_BLK_DEV_LOOP=y -+CONFIG_BLK_DEV_NBD=y -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_SIZE=4096 -+CONFIG_BLK_DEV_INITRD=y -+# CONFIG_MMAPPER is not set -+CONFIG_NETDEVICES=y -+ -+# -+# Network Devices -+# -+CONFIG_UML_NET=y -+CONFIG_UML_NET_ETHERTAP=y -+CONFIG_UML_NET_TUNTAP=y -+CONFIG_UML_NET_SLIP=y -+CONFIG_UML_NET_SLIRP=y -+CONFIG_UML_NET_DAEMON=y -+CONFIG_UML_NET_MCAST=y -+# CONFIG_UML_NET_PCAP is not set -+CONFIG_DUMMY=y -+# CONFIG_BONDING is not set -+# CONFIG_EQUALIZER is not set -+CONFIG_TUN=y -+CONFIG_PPP=y -+# CONFIG_PPP_MULTILINK is not set -+# CONFIG_PPP_FILTER is not set -+# CONFIG_PPP_ASYNC is not set -+# CONFIG_PPP_SYNC_TTY is not set -+# CONFIG_PPP_DEFLATE is not set -+# CONFIG_PPP_BSDCOMP is not set -+# CONFIG_PPPOE is not set -+CONFIG_SLIP=y -+# CONFIG_SLIP_COMPRESSED is not set -+# CONFIG_SLIP_SMART is not set -+# CONFIG_SLIP_MODE_SLIP6 is not set -+ -+# -+# Networking options -+# -+CONFIG_PACKET=y -+CONFIG_PACKET_MMAP=y -+# CONFIG_NETLINK_DEV is not set -+# CONFIG_NETFILTER is not set -+# CONFIG_FILTER is not set -+CONFIG_UNIX=y -+CONFIG_INET=y -+# CONFIG_IP_MULTICAST is not set -+# CONFIG_IP_ADVANCED_ROUTER is not set -+# CONFIG_IP_PNP is not set -+# CONFIG_NET_IPIP is not set -+# CONFIG_NET_IPGRE is not set -+# CONFIG_ARPD is not set -+# CONFIG_INET_ECN is not set -+# CONFIG_SYN_COOKIES is not set -+# CONFIG_IPV6 is not set -+# CONFIG_KHTTPD is not set -+ -+# -+# SCTP Configuration (EXPERIMENTAL) -+# -+CONFIG_IPV6_SCTP__=y -+# CONFIG_IP_SCTP is not set -+# CONFIG_ATM is not set -+# CONFIG_VLAN_8021Q is not set -+ -+# -+# -+# -+# CONFIG_IPX is not set -+# CONFIG_ATALK is not set -+ -+# -+# Appletalk devices -+# -+# CONFIG_DEV_APPLETALK is not set -+# CONFIG_DECNET is not set -+# CONFIG_BRIDGE is not set -+# CONFIG_X25 is not set -+# CONFIG_LAPB is not set -+# CONFIG_LLC is not set -+# CONFIG_NET_DIVERT is not set -+# CONFIG_ECONET is not set -+# CONFIG_WAN_ROUTER is not set -+# CONFIG_NET_FASTROUTE is not set -+# CONFIG_NET_HW_FLOWCONTROL is not set -+ -+# -+# QoS and/or fair queueing -+# -+# CONFIG_NET_SCHED is not set -+ -+# -+# Network testing -+# -+# CONFIG_NET_PKTGEN is not set -+ -+# -+# File systems -+# -+CONFIG_QUOTA=y -+# CONFIG_QFMT_V2 is not set -+CONFIG_AUTOFS_FS=y -+CONFIG_AUTOFS4_FS=y -+CONFIG_REISERFS_FS=y -+# CONFIG_REISERFS_CHECK is not set -+# CONFIG_REISERFS_PROC_INFO is not set -+# CONFIG_ADFS_FS is not set -+# CONFIG_ADFS_FS_RW is not set -+# CONFIG_AFFS_FS is not set -+# CONFIG_HFS_FS is not set -+# CONFIG_HFSPLUS_FS is not set -+# CONFIG_BEFS_FS is not set -+# CONFIG_BEFS_DEBUG is not set -+# CONFIG_BFS_FS is not set -+# CONFIG_EXT3_FS is not set -+# CONFIG_JBD is not set -+# CONFIG_JBD_DEBUG is not set -+CONFIG_FAT_FS=y -+CONFIG_MSDOS_FS=y -+CONFIG_UMSDOS_FS=y -+CONFIG_VFAT_FS=y -+# CONFIG_EFS_FS is not set -+CONFIG_JFFS_FS=y -+CONFIG_JFFS_FS_VERBOSE=0 -+CONFIG_JFFS_PROC_FS=y -+CONFIG_JFFS2_FS=y -+CONFIG_JFFS2_FS_DEBUG=0 -+# CONFIG_CRAMFS is not set -+# CONFIG_TMPFS is not set -+CONFIG_RAMFS=y -+CONFIG_ISO9660_FS=y -+# CONFIG_JOLIET is not set -+# CONFIG_ZISOFS is not set -+# CONFIG_JFS_FS is not set -+# CONFIG_JFS_DEBUG is not set -+# CONFIG_JFS_STATISTICS is not set -+CONFIG_MINIX_FS=y -+# CONFIG_VXFS_FS is not set -+# CONFIG_NTFS_FS is not set -+# CONFIG_NTFS_RW is not set -+# CONFIG_HPFS_FS is not set -+CONFIG_PROC_FS=y -+CONFIG_DEVFS_FS=y -+CONFIG_DEVFS_MOUNT=y -+# CONFIG_DEVFS_DEBUG is not set -+CONFIG_DEVPTS_FS=y -+# CONFIG_QNX4FS_FS is not set -+# CONFIG_QNX4FS_RW is not set -+# CONFIG_ROMFS_FS is not set -+CONFIG_EXT2_FS=y -+# CONFIG_SYSV_FS is not set -+# CONFIG_UDF_FS is not set -+# CONFIG_UDF_RW is not set -+# CONFIG_UFS_FS is not set -+# CONFIG_UFS_FS_WRITE is not set -+ -+# -+# Network File Systems -+# -+# CONFIG_CODA_FS is not set -+# CONFIG_INTERMEZZO_FS is not set -+# CONFIG_NFS_FS is not set -+# CONFIG_NFS_V3 is not set -+# CONFIG_NFS_DIRECTIO is not set -+# CONFIG_ROOT_NFS is not set -+# CONFIG_NFSD is not set -+# CONFIG_NFSD_V3 is not set -+# CONFIG_NFSD_TCP is not set -+# CONFIG_SUNRPC is not set -+# CONFIG_LOCKD is not set -+# CONFIG_SMB_FS is not set -+# CONFIG_NCP_FS is not set -+# CONFIG_NCPFS_PACKET_SIGNING is not set -+# CONFIG_NCPFS_IOCTL_LOCKING is not set -+# CONFIG_NCPFS_STRONG is not set -+# CONFIG_NCPFS_NFS_NS is not set -+# CONFIG_NCPFS_OS2_NS is not set -+# CONFIG_NCPFS_SMALLDOS is not set -+# CONFIG_NCPFS_NLS is not set -+# CONFIG_NCPFS_EXTRAS is not set -+# CONFIG_ZISOFS_FS is not set -+ -+# -+# Partition Types -+# -+# CONFIG_PARTITION_ADVANCED is not set -+CONFIG_MSDOS_PARTITION=y -+# CONFIG_SMB_NLS is not set -+CONFIG_NLS=y -+ -+# -+# Native Language Support -+# -+CONFIG_NLS_DEFAULT="iso8859-1" -+# CONFIG_NLS_CODEPAGE_437 is not set -+# CONFIG_NLS_CODEPAGE_737 is not set -+# CONFIG_NLS_CODEPAGE_775 is not set -+# CONFIG_NLS_CODEPAGE_850 is not set -+# CONFIG_NLS_CODEPAGE_852 is not set -+# CONFIG_NLS_CODEPAGE_855 is not set -+# CONFIG_NLS_CODEPAGE_857 is not set -+# CONFIG_NLS_CODEPAGE_860 is not set -+# CONFIG_NLS_CODEPAGE_861 is not set -+# CONFIG_NLS_CODEPAGE_862 is not set -+# CONFIG_NLS_CODEPAGE_863 is not set -+# CONFIG_NLS_CODEPAGE_864 is not set -+# CONFIG_NLS_CODEPAGE_865 is not set -+# CONFIG_NLS_CODEPAGE_866 is not set -+# CONFIG_NLS_CODEPAGE_869 is not set -+# CONFIG_NLS_CODEPAGE_936 is not set -+# CONFIG_NLS_CODEPAGE_950 is not set -+# CONFIG_NLS_CODEPAGE_932 is not set -+# CONFIG_NLS_CODEPAGE_949 is not set -+# CONFIG_NLS_CODEPAGE_874 is not set -+# CONFIG_NLS_ISO8859_8 is not set -+# CONFIG_NLS_CODEPAGE_1250 is not set -+# CONFIG_NLS_CODEPAGE_1251 is not set -+# CONFIG_NLS_ISO8859_1 is not set -+# CONFIG_NLS_ISO8859_2 is not set -+# CONFIG_NLS_ISO8859_3 is not set -+# CONFIG_NLS_ISO8859_4 is not set -+# CONFIG_NLS_ISO8859_5 is not set -+# CONFIG_NLS_ISO8859_6 is not set -+# CONFIG_NLS_ISO8859_7 is not set -+# CONFIG_NLS_ISO8859_9 is not set -+# CONFIG_NLS_ISO8859_13 is not set -+# CONFIG_NLS_ISO8859_14 is not set -+# CONFIG_NLS_ISO8859_15 is not set -+# CONFIG_NLS_KOI8_R is not set -+# CONFIG_NLS_KOI8_U is not set -+# CONFIG_NLS_UTF8 is not set -+ -+# -+# SCSI support -+# -+CONFIG_SCSI=y -+ -+# -+# SCSI support type (disk, tape, CD-ROM) -+# -+# CONFIG_BLK_DEV_SD is not set -+# CONFIG_CHR_DEV_ST is not set -+# CONFIG_BLK_DEV_SR is not set -+# CONFIG_CHR_DEV_SG is not set -+ -+# -+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs -+# -+# CONFIG_SCSI_DEBUG_QUEUES is not set -+# CONFIG_SCSI_MULTI_LUN is not set -+# CONFIG_SCSI_CONSTANTS is not set -+# CONFIG_SCSI_LOGGING is not set -+CONFIG_SCSI_DEBUG=y -+ -+# -+# Multi-device support (RAID and LVM) -+# -+# CONFIG_MD is not set -+# CONFIG_BLK_DEV_MD is not set -+# CONFIG_MD_LINEAR is not set -+# CONFIG_MD_RAID0 is not set -+# CONFIG_MD_RAID1 is not set -+# CONFIG_MD_RAID5 is not set -+# CONFIG_MD_MULTIPATH is not set -+# CONFIG_BLK_DEV_LVM is not set -+ -+# -+# Memory Technology Devices (MTD) -+# -+CONFIG_MTD=y -+# CONFIG_MTD_DEBUG is not set -+# CONFIG_MTD_PARTITIONS is not set -+# CONFIG_MTD_CONCAT is not set -+# CONFIG_MTD_REDBOOT_PARTS is not set -+# CONFIG_MTD_CMDLINE_PARTS is not set -+ -+# -+# User Modules And Translation Layers -+# -+CONFIG_MTD_CHAR=y -+CONFIG_MTD_BLOCK=y -+# CONFIG_FTL is not set -+# CONFIG_NFTL is not set -+ -+# -+# RAM/ROM/Flash chip drivers -+# -+# CONFIG_MTD_CFI is not set -+# CONFIG_MTD_JEDECPROBE is not set -+# CONFIG_MTD_GEN_PROBE is not set -+# CONFIG_MTD_CFI_INTELEXT is not set -+# CONFIG_MTD_CFI_AMDSTD is not set -+# CONFIG_MTD_CFI_STAA is not set -+# CONFIG_MTD_RAM is not set -+# CONFIG_MTD_ROM is not set -+# CONFIG_MTD_ABSENT is not set -+# CONFIG_MTD_OBSOLETE_CHIPS is not set -+# CONFIG_MTD_AMDSTD is not set -+# CONFIG_MTD_SHARP is not set -+# CONFIG_MTD_JEDEC is not set -+ -+# -+# Mapping drivers for chip access -+# -+# CONFIG_MTD_PHYSMAP is not set -+# CONFIG_MTD_PCI is not set -+# CONFIG_MTD_PCMCIA is not set -+ -+# -+# Self-contained MTD device drivers -+# -+# CONFIG_MTD_PMC551 is not set -+# CONFIG_MTD_SLRAM is not set -+# CONFIG_MTD_MTDRAM is not set -+CONFIG_MTD_BLKMTD=y -+ -+# -+# Disk-On-Chip Device Drivers -+# -+# CONFIG_MTD_DOC1000 is not set -+# CONFIG_MTD_DOC2000 is not set -+# CONFIG_MTD_DOC2001 is not set -+# CONFIG_MTD_DOCPROBE is not set -+ -+# -+# NAND Flash Device Drivers -+# -+# CONFIG_MTD_NAND is not set -+ -+# -+# Library routines -+# -+# CONFIG_CRC32 is not set -+CONFIG_ZLIB_INFLATE=y -+CONFIG_ZLIB_DEFLATE=y -+ -+# -+# Kernel hacking -+# -+# CONFIG_DEBUG_SLAB is not set -+CONFIG_DEBUGSYM=y -+CONFIG_PT_PROXY=y -+# CONFIG_GPROF is not set -+# CONFIG_GCOV is not set -diff -Naur -X ../exclude-files orig/arch/um/drivers/chan_kern.c um/arch/um/drivers/chan_kern.c ---- orig/arch/um/drivers/chan_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/chan_kern.c 2003-11-07 07:25:34.000000000 -0500 -@@ -0,0 +1,519 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "chan_kern.h" -+#include "user_util.h" -+#include "kern.h" -+#include "irq_user.h" -+#include "sigio.h" -+#include "line.h" -+ -+static void *not_configged_init(char *str, int device, struct chan_opts *opts) -+{ -+ printk(KERN_ERR "Using a channel type which is configured out of " -+ "UML\n"); -+ return(NULL); -+} -+ -+static int not_configged_open(int input, int output, int primary, void *data, -+ char **dev_out) -+{ -+ printk(KERN_ERR "Using a channel type which is configured out of " -+ "UML\n"); -+ return(-ENODEV); -+} -+ -+static void not_configged_close(int fd, void *data) -+{ -+ printk(KERN_ERR "Using a channel type which is configured out of " -+ "UML\n"); -+} -+ -+static int not_configged_read(int fd, char *c_out, void *data) -+{ -+ printk(KERN_ERR "Using a channel type which is configured out of " -+ "UML\n"); -+ return(-EIO); -+} -+ -+static int not_configged_write(int fd, const char *buf, int len, void *data) -+{ -+ printk(KERN_ERR "Using a channel type which is configured out of " -+ "UML\n"); -+ return(-EIO); -+} -+ -+static int not_configged_console_write(int fd, const char *buf, int len, -+ void *data) -+{ -+ printk(KERN_ERR "Using a channel type which is configured out of " -+ "UML\n"); -+ return(-EIO); -+} -+ -+static int not_configged_window_size(int fd, void *data, unsigned short *rows, -+ unsigned short *cols) -+{ -+ printk(KERN_ERR "Using a channel type which is configured out of " -+ "UML\n"); -+ return(-ENODEV); -+} -+ -+static void not_configged_free(void *data) -+{ -+ printk(KERN_ERR "Using a channel type which is configured out of " -+ "UML\n"); -+} -+ -+static struct chan_ops not_configged_ops = { -+ .init = not_configged_init, -+ .open = not_configged_open, -+ .close = not_configged_close, -+ .read = not_configged_read, -+ .write = not_configged_write, -+ .console_write = not_configged_console_write, -+ .window_size = not_configged_window_size, -+ .free = not_configged_free, -+ .winch = 0, -+}; -+ -+static void tty_receive_char(struct tty_struct *tty, char ch) -+{ -+ if(tty == NULL) return; -+ -+ if(I_IXON(tty) && !I_IXOFF(tty) && !tty->raw) { -+ if(ch == STOP_CHAR(tty)){ -+ stop_tty(tty); -+ return; -+ } -+ else if(ch == START_CHAR(tty)){ -+ start_tty(tty); -+ return; -+ } -+ } -+ -+ if((tty->flip.flag_buf_ptr == NULL) || -+ (tty->flip.char_buf_ptr == NULL)) -+ return; -+ tty_insert_flip_char(tty, ch, TTY_NORMAL); -+} -+ -+static int open_one_chan(struct chan *chan, int input, int output, int primary) -+{ -+ int fd; -+ -+ if(chan->opened) return(0); -+ if(chan->ops->open == NULL) fd = 0; -+ else fd = (*chan->ops->open)(input, output, primary, chan->data, -+ &chan->dev); -+ if(fd < 0) return(fd); -+ chan->fd = fd; -+ -+ chan->opened = 1; -+ return(0); -+} -+ -+int open_chan(struct list_head *chans) -+{ -+ struct list_head *ele; -+ struct chan *chan; -+ int ret, err = 0; -+ -+ list_for_each(ele, chans){ -+ chan = list_entry(ele, struct chan, list); -+ ret = open_one_chan(chan, chan->input, chan->output, -+ chan->primary); -+ if(chan->primary) err = ret; -+ } -+ return(err); -+} -+ -+void chan_enable_winch(struct list_head *chans, void *line) -+{ -+ struct list_head *ele; -+ struct chan *chan; -+ -+ list_for_each(ele, chans){ -+ chan = list_entry(ele, struct chan, list); -+ if(chan->primary && chan->output && chan->ops->winch){ -+ register_winch(chan->fd, line); -+ return; -+ } -+ } -+} -+ -+void enable_chan(struct list_head *chans, void *data) -+{ -+ struct list_head *ele; -+ struct chan *chan; -+ -+ list_for_each(ele, chans){ -+ chan = list_entry(ele, struct chan, list); -+ if(!chan->opened) continue; -+ -+ line_setup_irq(chan->fd, chan->input, chan->output, data); -+ } -+} -+ -+void close_chan(struct list_head *chans) -+{ -+ struct list_head *ele; -+ struct chan *chan; -+ -+ /* Close in reverse order as open in case more than one of them -+ * refers to the same device and they save and restore that device's -+ * state. Then, the first one opened will have the original state, -+ * so it must be the last closed. -+ */ -+ for(ele = chans->prev; ele != chans; ele = ele->prev){ -+ chan = list_entry(ele, struct chan, list); -+ if(!chan->opened) continue; -+ if(chan->ops->close != NULL) -+ (*chan->ops->close)(chan->fd, chan->data); -+ chan->opened = 0; -+ chan->fd = -1; -+ } -+} -+ -+int write_chan(struct list_head *chans, const char *buf, int len, -+ int write_irq) -+{ -+ struct list_head *ele; -+ struct chan *chan; -+ int n, ret = 0; -+ -+ list_for_each(ele, chans){ -+ chan = list_entry(ele, struct chan, list); -+ if(!chan->output || (chan->ops->write == NULL)) continue; -+ n = chan->ops->write(chan->fd, buf, len, chan->data); -+ if(chan->primary){ -+ ret = n; -+ if((ret == -EAGAIN) || ((ret >= 0) && (ret < len))){ -+ reactivate_fd(chan->fd, write_irq); -+ if(ret == -EAGAIN) ret = 0; -+ } -+ } -+ } -+ return(ret); -+} -+ -+int console_write_chan(struct list_head *chans, const char *buf, int len) -+{ -+ struct list_head *ele; -+ struct chan *chan; -+ int n, ret = 0; -+ -+ list_for_each(ele, chans){ -+ chan = list_entry(ele, struct chan, list); -+ if(!chan->output || (chan->ops->console_write == NULL)) -+ continue; -+ n = chan->ops->console_write(chan->fd, buf, len, chan->data); -+ if(chan->primary) ret = n; -+ } -+ return(ret); -+} -+ -+int chan_window_size(struct list_head *chans, unsigned short *rows_out, -+ unsigned short *cols_out) -+{ -+ struct list_head *ele; -+ struct chan *chan; -+ -+ list_for_each(ele, chans){ -+ chan = list_entry(ele, struct chan, list); -+ if(chan->primary){ -+ if(chan->ops->window_size == NULL) return(0); -+ return(chan->ops->window_size(chan->fd, chan->data, -+ rows_out, cols_out)); -+ } -+ } -+ return(0); -+} -+ -+void free_one_chan(struct chan *chan) -+{ -+ list_del(&chan->list); -+ if(chan->ops->free != NULL) -+ (*chan->ops->free)(chan->data); -+ free_irq_by_fd(chan->fd); -+ if(chan->primary && chan->output) ignore_sigio_fd(chan->fd); -+ kfree(chan); -+} -+ -+void free_chan(struct list_head *chans) -+{ -+ struct list_head *ele, *next; -+ struct chan *chan; -+ -+ list_for_each_safe(ele, next, chans){ -+ chan = list_entry(ele, struct chan, list); -+ free_one_chan(chan); -+ } -+} -+ -+static int one_chan_config_string(struct chan *chan, char *str, int size, -+ char **error_out) -+{ -+ int n = 0; -+ -+ if(chan == NULL){ -+ CONFIG_CHUNK(str, size, n, "none", 1); -+ return(n); -+ } -+ -+ CONFIG_CHUNK(str, size, n, chan->ops->type, 0); -+ -+ if(chan->dev == NULL){ -+ CONFIG_CHUNK(str, size, n, "", 1); -+ return(n); -+ } -+ -+ CONFIG_CHUNK(str, size, n, ":", 0); -+ CONFIG_CHUNK(str, size, n, chan->dev, 0); -+ -+ return(n); -+} -+ -+static int chan_pair_config_string(struct chan *in, struct chan *out, -+ char *str, int size, char **error_out) -+{ -+ int n; -+ -+ n = one_chan_config_string(in, str, size, error_out); -+ str += n; -+ size -= n; -+ -+ if(in == out){ -+ CONFIG_CHUNK(str, size, n, "", 1); -+ return(n); -+ } -+ -+ CONFIG_CHUNK(str, size, n, ",", 1); -+ n = one_chan_config_string(out, str, size, error_out); -+ str += n; -+ size -= n; -+ CONFIG_CHUNK(str, size, n, "", 1); -+ -+ return(n); -+} -+ -+int chan_config_string(struct list_head *chans, char *str, int size, -+ char **error_out) -+{ -+ struct list_head *ele; -+ struct chan *chan, *in = NULL, *out = NULL; -+ -+ list_for_each(ele, chans){ -+ chan = list_entry(ele, struct chan, list); -+ if(!chan->primary) -+ continue; -+ if(chan->input) -+ in = chan; -+ if(chan->output) -+ out = chan; -+ } -+ -+ return(chan_pair_config_string(in, out, str, size, error_out)); -+} -+ -+struct chan_type { -+ char *key; -+ struct chan_ops *ops; -+}; -+ -+struct chan_type chan_table[] = { -+#ifdef CONFIG_FD_CHAN -+ { "fd", &fd_ops }, -+#else -+ { "fd", ¬_configged_ops }, -+#endif -+ -+#ifdef CONFIG_NULL_CHAN -+ { "null", &null_ops }, -+#else -+ { "null", ¬_configged_ops }, -+#endif -+ -+#ifdef CONFIG_PORT_CHAN -+ { "port", &port_ops }, -+#else -+ { "port", ¬_configged_ops }, -+#endif -+ -+#ifdef CONFIG_PTY_CHAN -+ { "pty", &pty_ops }, -+ { "pts", &pts_ops }, -+#else -+ { "pty", ¬_configged_ops }, -+ { "pts", ¬_configged_ops }, -+#endif -+ -+#ifdef CONFIG_TTY_CHAN -+ { "tty", &tty_ops }, -+#else -+ { "tty", ¬_configged_ops }, -+#endif -+ -+#ifdef CONFIG_XTERM_CHAN -+ { "xterm", &xterm_ops }, -+#else -+ { "xterm", ¬_configged_ops }, -+#endif -+}; -+ -+static struct chan *parse_chan(char *str, int pri, int device, -+ struct chan_opts *opts) -+{ -+ struct chan_type *entry; -+ struct chan_ops *ops; -+ struct chan *chan; -+ void *data; -+ int i; -+ -+ ops = NULL; -+ data = NULL; -+ for(i = 0; i < sizeof(chan_table)/sizeof(chan_table[0]); i++){ -+ entry = &chan_table[i]; -+ if(!strncmp(str, entry->key, strlen(entry->key))){ -+ ops = entry->ops; -+ str += strlen(entry->key); -+ break; -+ } -+ } -+ if(ops == NULL){ -+ printk(KERN_ERR "parse_chan couldn't parse \"%s\"\n", -+ str); -+ return(NULL); -+ } -+ if(ops->init == NULL) return(NULL); -+ data = (*ops->init)(str, device, opts); -+ if(data == NULL) return(NULL); -+ -+ chan = kmalloc(sizeof(*chan), GFP_KERNEL); -+ if(chan == NULL) return(NULL); -+ *chan = ((struct chan) { .list = LIST_HEAD_INIT(chan->list), -+ .primary = 1, -+ .input = 0, -+ .output = 0, -+ .opened = 0, -+ .fd = -1, -+ .pri = pri, -+ .ops = ops, -+ .data = data }); -+ return(chan); -+} -+ -+int parse_chan_pair(char *str, struct list_head *chans, int pri, int device, -+ struct chan_opts *opts) -+{ -+ struct chan *new, *chan; -+ char *in, *out; -+ -+ if(!list_empty(chans)){ -+ chan = list_entry(chans->next, struct chan, list); -+ if(chan->pri >= pri) return(0); -+ free_chan(chans); -+ INIT_LIST_HEAD(chans); -+ } -+ -+ out = strchr(str, ','); -+ if(out != NULL){ -+ in = str; -+ *out = '\0'; -+ out++; -+ new = parse_chan(in, pri, device, opts); -+ if(new == NULL) return(-1); -+ new->input = 1; -+ list_add(&new->list, chans); -+ -+ new = parse_chan(out, pri, device, opts); -+ if(new == NULL) return(-1); -+ list_add(&new->list, chans); -+ new->output = 1; -+ } -+ else { -+ new = parse_chan(str, pri, device, opts); -+ if(new == NULL) return(-1); -+ list_add(&new->list, chans); -+ new->input = 1; -+ new->output = 1; -+ } -+ return(0); -+} -+ -+int chan_out_fd(struct list_head *chans) -+{ -+ struct list_head *ele; -+ struct chan *chan; -+ -+ list_for_each(ele, chans){ -+ chan = list_entry(ele, struct chan, list); -+ if(chan->primary && chan->output) -+ return(chan->fd); -+ } -+ return(-1); -+} -+ -+void chan_interrupt(struct list_head *chans, struct tq_struct *task, -+ struct tty_struct *tty, int irq, void *dev) -+{ -+ struct list_head *ele, *next; -+ struct chan *chan; -+ int err; -+ char c; -+ -+ list_for_each_safe(ele, next, chans){ -+ chan = list_entry(ele, struct chan, list); -+ if(!chan->input || (chan->ops->read == NULL)) continue; -+ do { -+ if((tty != NULL) && -+ (tty->flip.count >= TTY_FLIPBUF_SIZE)){ -+ queue_task(task, &tq_timer); -+ goto out; -+ } -+ err = chan->ops->read(chan->fd, &c, chan->data); -+ if(err > 0) -+ tty_receive_char(tty, c); -+ } while(err > 0); -+ -+ if(err == 0) reactivate_fd(chan->fd, irq); -+ if(err == -EIO){ -+ if(chan->primary){ -+ if(tty != NULL) -+ tty_hangup(tty); -+ line_disable(dev, irq); -+ close_chan(chans); -+ free_chan(chans); -+ return; -+ } -+ else { -+ if(chan->ops->close != NULL) -+ chan->ops->close(chan->fd, chan->data); -+ free_one_chan(chan); -+ } -+ } -+ } -+ out: -+ if(tty) tty_flip_buffer_push(tty); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/chan_user.c um/arch/um/drivers/chan_user.c ---- orig/arch/um/drivers/chan_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/chan_user.c 2003-11-07 07:23:45.000000000 -0500 -@@ -0,0 +1,217 @@ -+/* -+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) -+ * Licensed under the GPL -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "kern_util.h" -+#include "user_util.h" -+#include "chan_user.h" -+#include "user.h" -+#include "helper.h" -+#include "os.h" -+#include "choose-mode.h" -+#include "mode.h" -+ -+void generic_close(int fd, void *unused) -+{ -+ os_close_file(fd); -+} -+ -+int generic_read(int fd, char *c_out, void *unused) -+{ -+ int n; -+ -+ n = os_read_file(fd, c_out, sizeof(*c_out)); -+ -+ if(n == -EAGAIN) -+ return(0); -+ else if(n == 0) -+ return(-EIO); -+ return(n); -+} -+ -+/* XXX Trivial wrapper around os_write_file */ -+ -+int generic_write(int fd, const char *buf, int n, void *unused) -+{ -+ return(os_write_file(fd, buf, n)); -+} -+ -+int generic_console_write(int fd, const char *buf, int n, void *unused) -+{ -+ struct termios save, new; -+ int err; -+ -+ if(isatty(fd)){ -+ tcgetattr(fd, &save); -+ new = save; -+ new.c_oflag |= OPOST; -+ tcsetattr(fd, TCSAFLUSH, &new); -+ } -+ err = generic_write(fd, buf, n, NULL); -+ if(isatty(fd)) tcsetattr(fd, TCSAFLUSH, &save); -+ return(err); -+} -+ -+int generic_window_size(int fd, void *unused, unsigned short *rows_out, -+ unsigned short *cols_out) -+{ -+ int rows, cols; -+ int ret; -+ -+ ret = os_window_size(fd, &rows, &cols); -+ if(ret < 0) -+ return(ret); -+ -+ ret = ((*rows_out != rows) || (*cols_out != cols)); -+ -+ *rows_out = rows; -+ *cols_out = cols; -+ -+ return(ret); -+} -+ -+void generic_free(void *data) -+{ -+ kfree(data); -+} -+ -+static void winch_handler(int sig) -+{ -+} -+ -+struct winch_data { -+ int pty_fd; -+ int pipe_fd; -+ int close_me; -+}; -+ -+static int winch_thread(void *arg) -+{ -+ struct winch_data *data = arg; -+ sigset_t sigs; -+ int pty_fd, pipe_fd; -+ int count, err; -+ char c = 1; -+ -+ os_close_file(data->close_me); -+ pty_fd = data->pty_fd; -+ pipe_fd = data->pipe_fd; -+ count = os_write_file(pipe_fd, &c, sizeof(c)); -+ if(count != sizeof(c)) -+ printk("winch_thread : failed to write synchronization " -+ "byte, err = %d\n", -count); -+ -+ signal(SIGWINCH, winch_handler); -+ sigfillset(&sigs); -+ sigdelset(&sigs, SIGWINCH); -+ if(sigprocmask(SIG_SETMASK, &sigs, NULL) < 0){ -+ printk("winch_thread : sigprocmask failed, errno = %d\n", -+ errno); -+ exit(1); -+ } -+ -+ if(setsid() < 0){ -+ printk("winch_thread : setsid failed, errno = %d\n", errno); -+ exit(1); -+ } -+ -+ err = os_new_tty_pgrp(pty_fd, os_getpid()); -+ if(err < 0){ -+ printk("winch_thread : new_tty_pgrp failed, err = %d\n", -err); -+ exit(1); -+ } -+ -+ count = os_read_file(pipe_fd, &c, sizeof(c)); -+ if(count != sizeof(c)) -+ printk("winch_thread : failed to read synchronization byte, " -+ "err = %d\n", -count); -+ -+ while(1){ -+ pause(); -+ -+ count = os_write_file(pipe_fd, &c, sizeof(c)); -+ if(count != sizeof(c)) -+ printk("winch_thread : write failed, err = %d\n", -+ -count); -+ } -+} -+ -+static int winch_tramp(int fd, void *device_data, int *fd_out) -+{ -+ struct winch_data data; -+ unsigned long stack; -+ int fds[2], pid, n, err; -+ char c; -+ -+ err = os_pipe(fds, 1, 1); -+ if(err < 0){ -+ printk("winch_tramp : os_pipe failed, err = %d\n", -err); -+ return(err); -+ } -+ -+ data = ((struct winch_data) { .pty_fd = fd, -+ .pipe_fd = fds[1], -+ .close_me = fds[0] } ); -+ pid = run_helper_thread(winch_thread, &data, 0, &stack, 0); -+ if(pid < 0){ -+ printk("fork of winch_thread failed - errno = %d\n", errno); -+ return(pid); -+ } -+ -+ os_close_file(fds[1]); -+ *fd_out = fds[0]; -+ n = os_read_file(fds[0], &c, sizeof(c)); -+ if(n != sizeof(c)){ -+ printk("winch_tramp : failed to read synchronization byte\n"); -+ printk("read failed, err = %d\n", -n); -+ printk("fd %d will not support SIGWINCH\n", fd); -+ *fd_out = -1; -+ } -+ return(pid); -+} -+ -+void register_winch(int fd, void *device_data) -+{ -+ int pid, thread, thread_fd; -+ int count; -+ char c = 1; -+ -+ if(!isatty(fd)) -+ return; -+ -+ pid = tcgetpgrp(fd); -+ if(!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd, -+ device_data) && (pid == -1)){ -+ thread = winch_tramp(fd, device_data, &thread_fd); -+ if(fd != -1){ -+ register_winch_irq(thread_fd, fd, thread, device_data); -+ -+ count = os_write_file(thread_fd, &c, sizeof(c)); -+ if(count != sizeof(c)) -+ printk("register_winch : failed to write " -+ "synchronization byte, err = %d\n", -+ -count); -+ } -+ } -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/cow.h um/arch/um/drivers/cow.h ---- orig/arch/um/drivers/cow.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/cow.h 2004-01-16 03:45:20.000000000 -0500 -@@ -0,0 +1,41 @@ -+#ifndef __COW_H__ -+#define __COW_H__ -+ -+#include -+ -+#if __BYTE_ORDER == __BIG_ENDIAN -+# define ntohll(x) (x) -+# define htonll(x) (x) -+#elif __BYTE_ORDER == __LITTLE_ENDIAN -+# define ntohll(x) bswap_64(x) -+# define htonll(x) bswap_64(x) -+#else -+#error "__BYTE_ORDER not defined" -+#endif -+ -+extern int init_cow_file(int fd, char *cow_file, char *backing_file, -+ int sectorsize, int alignment, int *bitmap_offset_out, -+ unsigned long *bitmap_len_out, int *data_offset_out); -+ -+extern int file_reader(__u64 offset, char *buf, int len, void *arg); -+extern int read_cow_header(int (*reader)(__u64, char *, int, void *), -+ void *arg, __u32 *version_out, -+ char **backing_file_out, time_t *mtime_out, -+ __u64 *size_out, int *sectorsize_out, -+ __u32 *align_out, int *bitmap_offset_out); -+ -+extern int write_cow_header(char *cow_file, int fd, char *backing_file, -+ int sectorsize, int alignment, long long *size); -+ -+extern void cow_sizes(int version, __u64 size, int sectorsize, int align, -+ int bitmap_offset, unsigned long *bitmap_len_out, -+ int *data_offset_out); -+ -+#endif -+ -+/* -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/cow_kern.c um/arch/um/drivers/cow_kern.c ---- orig/arch/um/drivers/cow_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/cow_kern.c 2004-01-10 05:55:04.000000000 -0500 -@@ -0,0 +1,630 @@ -+#define COW_MAJOR 60 -+#define MAJOR_NR COW_MAJOR -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "2_5compat.h" -+#include "cow.h" -+#include "ubd_user.h" -+ -+#define COW_SHIFT 4 -+ -+struct cow { -+ int count; -+ char *cow_path; -+ dev_t cow_dev; -+ struct block_device *cow_bdev; -+ char *backing_path; -+ dev_t backing_dev; -+ struct block_device *backing_bdev; -+ int sectorsize; -+ unsigned long *bitmap; -+ unsigned long bitmap_len; -+ int bitmap_offset; -+ int data_offset; -+ devfs_handle_t devfs; -+ struct semaphore sem; -+ struct semaphore io_sem; -+ atomic_t working; -+ spinlock_t io_lock; -+ struct buffer_head *bh; -+ struct buffer_head *bhtail; -+ void *end_io; -+}; -+ -+#define DEFAULT_COW { \ -+ .count = 0, \ -+ .cow_path = NULL, \ -+ .cow_dev = 0, \ -+ .backing_path = NULL, \ -+ .backing_dev = 0, \ -+ .bitmap = NULL, \ -+ .bitmap_len = 0, \ -+ .bitmap_offset = 0, \ -+ .data_offset = 0, \ -+ .devfs = NULL, \ -+ .working = ATOMIC_INIT(0), \ -+ .io_lock = SPIN_LOCK_UNLOCKED, \ -+} -+ -+#define MAX_DEV (8) -+#define MAX_MINOR (MAX_DEV << COW_SHIFT) -+ -+struct cow cow_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_COW }; -+ -+/* Not modified by this driver */ -+static int blk_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = BLOCK_SIZE }; -+static int hardsect_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 512 }; -+ -+/* Protected by cow_lock */ -+static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 }; -+ -+static struct hd_struct cow_part[MAX_MINOR] = -+ { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } }; -+ -+/* Protected by io_request_lock */ -+static request_queue_t *cow_queue; -+ -+static int cow_open(struct inode *inode, struct file *filp); -+static int cow_release(struct inode * inode, struct file * file); -+static int cow_ioctl(struct inode * inode, struct file * file, -+ unsigned int cmd, unsigned long arg); -+static int cow_revalidate(kdev_t rdev); -+ -+static struct block_device_operations cow_blops = { -+ .open = cow_open, -+ .release = cow_release, -+ .ioctl = cow_ioctl, -+ .revalidate = cow_revalidate, -+}; -+ -+/* Initialized in an initcall, and unchanged thereafter */ -+devfs_handle_t cow_dir_handle; -+ -+#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \ -+{ \ -+ .major = maj, \ -+ .major_name = name, \ -+ .minor_shift = shift, \ -+ .max_p = 1 << shift, \ -+ .part = parts, \ -+ .sizes = bsizes, \ -+ .nr_real = max, \ -+ .real_devices = NULL, \ -+ .next = NULL, \ -+ .fops = blops, \ -+ .de_arr = NULL, \ -+ .flags = 0 \ -+} -+ -+static spinlock_t cow_lock = SPIN_LOCK_UNLOCKED; -+ -+static struct gendisk cow_gendisk = INIT_GENDISK(MAJOR_NR, "cow", cow_part, -+ COW_SHIFT, sizes, MAX_DEV, -+ &cow_blops); -+ -+static int cow_add(int n) -+{ -+ struct cow *dev = &cow_dev[n]; -+ char name[sizeof("nnnnnn\0")]; -+ int err = -ENODEV; -+ -+ if(dev->cow_path == NULL) -+ goto out; -+ -+ sprintf(name, "%d", n); -+ dev->devfs = devfs_register(cow_dir_handle, name, DEVFS_FL_REMOVABLE, -+ MAJOR_NR, n << COW_SHIFT, S_IFBLK | -+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, -+ &cow_blops, NULL); -+ -+ init_MUTEX_LOCKED(&dev->sem); -+ init_MUTEX(&dev->io_sem); -+ -+ return(0); -+ -+ out: -+ return(err); -+} -+ -+/* -+ * Add buffer_head to back of pending list -+ */ -+static void cow_add_bh(struct cow *cow, struct buffer_head *bh) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&cow->io_lock, flags); -+ if(cow->bhtail != NULL){ -+ cow->bhtail->b_reqnext = bh; -+ cow->bhtail = bh; -+ } -+ else { -+ cow->bh = bh; -+ cow->bhtail = bh; -+ } -+ spin_unlock_irqrestore(&cow->io_lock, flags); -+} -+ -+/* -+ * Grab first pending buffer -+ */ -+static struct buffer_head *cow_get_bh(struct cow *cow) -+{ -+ struct buffer_head *bh; -+ -+ spin_lock_irq(&cow->io_lock); -+ bh = cow->bh; -+ if(bh != NULL){ -+ if(bh == cow->bhtail) -+ cow->bhtail = NULL; -+ cow->bh = bh->b_reqnext; -+ bh->b_reqnext = NULL; -+ } -+ spin_unlock_irq(&cow->io_lock); -+ -+ return(bh); -+} -+ -+static void cow_handle_bh(struct cow *cow, struct buffer_head *bh, -+ struct buffer_head **cow_bh, int ncow_bh) -+{ -+ int i; -+ -+ if(ncow_bh > 0) -+ ll_rw_block(WRITE, ncow_bh, cow_bh); -+ -+ for(i = 0; i < ncow_bh ; i++){ -+ wait_on_buffer(cow_bh[i]); -+ brelse(cow_bh[i]); -+ } -+ -+ ll_rw_block(WRITE, 1, &bh); -+ brelse(bh); -+} -+ -+static struct buffer_head *cow_new_bh(struct cow *dev, int sector) -+{ -+ struct buffer_head *bh; -+ -+ sector = (dev->bitmap_offset + sector / 8) / dev->sectorsize; -+ bh = getblk(dev->cow_dev, sector, dev->sectorsize); -+ memcpy(bh->b_data, dev->bitmap + sector / (8 * sizeof(dev->bitmap[0])), -+ dev->sectorsize); -+ return(bh); -+} -+ -+/* Copied from loop.c, needed to avoid deadlocking in make_request. */ -+ -+static int cow_thread(void *data) -+{ -+ struct cow *dev = data; -+ struct buffer_head *bh; -+ -+ daemonize(); -+ exit_files(current); -+ -+ sprintf(current->comm, "cow%d", dev - cow_dev); -+ -+ spin_lock_irq(¤t->sigmask_lock); -+ sigfillset(¤t->blocked); -+ flush_signals(current); -+ spin_unlock_irq(¤t->sigmask_lock); -+ -+ atomic_inc(&dev->working); -+ -+ current->policy = SCHED_OTHER; -+ current->nice = -20; -+ -+ current->flags |= PF_NOIO; -+ -+ /* -+ * up sem, we are running -+ */ -+ up(&dev->sem); -+ -+ for(;;){ -+ int start, len, nbh, i, update_bitmap = 0; -+ struct buffer_head *cow_bh[2]; -+ -+ down_interruptible(&dev->io_sem); -+ /* -+ * could be upped because of tear-down, not because of -+ * pending work -+ */ -+ if(!atomic_read(&dev->working)) -+ break; -+ -+ bh = cow_get_bh(dev); -+ if(bh == NULL){ -+ printk(KERN_ERR "cow: missing bh\n"); -+ continue; -+ } -+ -+ start = bh->b_blocknr * bh->b_size / dev->sectorsize; -+ len = bh->b_size / dev->sectorsize; -+ for(i = 0; i < len ; i++){ -+ if(ubd_test_bit(start + i, -+ (unsigned char *) dev->bitmap)) -+ continue; -+ -+ update_bitmap = 1; -+ ubd_set_bit(start + i, (unsigned char *) dev->bitmap); -+ } -+ -+ cow_bh[0] = NULL; -+ cow_bh[1] = NULL; -+ nbh = 0; -+ if(update_bitmap){ -+ cow_bh[0] = cow_new_bh(dev, start); -+ nbh++; -+ if(start / dev->sectorsize != -+ (start + len) / dev->sectorsize){ -+ cow_bh[1] = cow_new_bh(dev, start + len); -+ nbh++; -+ } -+ } -+ -+ bh->b_dev = dev->cow_dev; -+ bh->b_blocknr += dev->data_offset / dev->sectorsize; -+ -+ cow_handle_bh(dev, bh, cow_bh, nbh); -+ -+ /* -+ * upped both for pending work and tear-down, lo_pending -+ * will hit zero then -+ */ -+ if(atomic_dec_and_test(&dev->working)) -+ break; -+ } -+ -+ up(&dev->sem); -+ return(0); -+} -+ -+static int cow_make_request(request_queue_t *q, int rw, struct buffer_head *bh) -+{ -+ struct cow *dev; -+ int n, minor; -+ -+ minor = MINOR(bh->b_rdev); -+ n = minor >> COW_SHIFT; -+ dev = &cow_dev[n]; -+ -+ dev->end_io = NULL; -+ if(ubd_test_bit(bh->b_rsector, (unsigned char *) dev->bitmap)){ -+ bh->b_rdev = dev->cow_dev; -+ bh->b_rsector += dev->data_offset / dev->sectorsize; -+ } -+ else if(rw == WRITE){ -+ bh->b_dev = dev->cow_dev; -+ bh->b_blocknr += dev->data_offset / dev->sectorsize; -+ -+ cow_add_bh(dev, bh); -+ up(&dev->io_sem); -+ return(0); -+ } -+ else { -+ bh->b_rdev = dev->backing_dev; -+ } -+ -+ return(1); -+} -+ -+int cow_init(void) -+{ -+ int i; -+ -+ cow_dir_handle = devfs_mk_dir (NULL, "cow", NULL); -+ if (devfs_register_blkdev(MAJOR_NR, "cow", &cow_blops)) { -+ printk(KERN_ERR "cow: unable to get major %d\n", MAJOR_NR); -+ return -1; -+ } -+ read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read-ahead */ -+ blksize_size[MAJOR_NR] = blk_sizes; -+ blk_size[MAJOR_NR] = sizes; -+ INIT_HARDSECT(hardsect_size, MAJOR_NR, hardsect_sizes); -+ -+ cow_queue = BLK_DEFAULT_QUEUE(MAJOR_NR); -+ blk_init_queue(cow_queue, NULL); -+ INIT_ELV(cow_queue, &cow_queue->elevator); -+ blk_queue_make_request(cow_queue, cow_make_request); -+ -+ add_gendisk(&cow_gendisk); -+ -+ for(i=0;i 0){ -+ n = (left > blocksize) ? blocksize : left; -+ -+ bh = bread(dev, block, (n < 512) ? 512 : n); -+ if(bh == NULL) -+ return(-EIO); -+ -+ n -= offset; -+ memcpy(&buf[cur], bh->b_data + offset, n); -+ block++; -+ left -= n; -+ cur += n; -+ offset = 0; -+ brelse(bh); -+ } -+ -+ return(count); -+} -+ -+static int cow_open(struct inode *inode, struct file *filp) -+{ -+ int (*dev_ioctl)(struct inode *, struct file *, unsigned int, -+ unsigned long); -+ mm_segment_t fs; -+ struct cow *dev; -+ __u64 size; -+ __u32 version, align; -+ time_t mtime; -+ char *backing_file; -+ int n, offset, err = 0; -+ -+ n = DEVICE_NR(inode->i_rdev); -+ if(n >= MAX_DEV) -+ return(-ENODEV); -+ dev = &cow_dev[n]; -+ offset = n << COW_SHIFT; -+ -+ spin_lock(&cow_lock); -+ -+ if(dev->count == 0){ -+ dev->cow_dev = name_to_kdev_t(dev->cow_path); -+ if(dev->cow_dev == 0){ -+ printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") " -+ "failed\n", dev->cow_path); -+ err = -ENODEV; -+ } -+ -+ dev->backing_dev = name_to_kdev_t(dev->backing_path); -+ if(dev->backing_dev == 0){ -+ printk(KERN_ERR "cow_open - name_to_kdev_t(\"%s\") " -+ "failed\n", dev->backing_path); -+ err = -ENODEV; -+ } -+ -+ if(err) -+ goto out; -+ -+ dev->cow_bdev = bdget(dev->cow_dev); -+ if(dev->cow_bdev == NULL){ -+ printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", -+ dev->cow_path); -+ err = -ENOMEM; -+ } -+ dev->backing_bdev = bdget(dev->backing_dev); -+ if(dev->backing_bdev == NULL){ -+ printk(KERN_ERR "cow_open - bdget(\"%s\") failed\n", -+ dev->backing_path); -+ err = -ENOMEM; -+ } -+ -+ if(err) -+ goto out; -+ -+ err = blkdev_get(dev->cow_bdev, FMODE_READ|FMODE_WRITE, 0, -+ BDEV_RAW); -+ if(err){ -+ printk("cow_open - blkdev_get of COW device failed, " -+ "error = %d\n", err); -+ goto out; -+ } -+ -+ err = blkdev_get(dev->backing_bdev, FMODE_READ, 0, BDEV_RAW); -+ if(err){ -+ printk("cow_open - blkdev_get of backing device " -+ "failed, error = %d\n", err); -+ goto out; -+ } -+ -+ err = read_cow_header(reader, &dev->cow_dev, &version, -+ &backing_file, &mtime, &size, -+ &dev->sectorsize, &align, -+ &dev->bitmap_offset); -+ if(err){ -+ printk(KERN_ERR "cow_open - read_cow_header failed, " -+ "err = %d\n", err); -+ goto out; -+ } -+ -+ cow_sizes(version, size, dev->sectorsize, align, -+ dev->bitmap_offset, &dev->bitmap_len, -+ &dev->data_offset); -+ dev->bitmap = (void *) vmalloc(dev->bitmap_len); -+ if(dev->bitmap == NULL){ -+ err = -ENOMEM; -+ printk(KERN_ERR "Failed to vmalloc COW bitmap\n"); -+ goto out; -+ } -+ flush_tlb_kernel_vm(); -+ -+ err = reader(dev->bitmap_offset, (char *) dev->bitmap, -+ dev->bitmap_len, &dev->cow_dev); -+ if(err < 0){ -+ printk(KERN_ERR "Failed to read COW bitmap\n"); -+ vfree(dev->bitmap); -+ goto out; -+ } -+ -+ dev_ioctl = dev->backing_bdev->bd_op->ioctl; -+ fs = get_fs(); -+ set_fs(KERNEL_DS); -+ err = (*dev_ioctl)(inode, filp, BLKGETSIZE, -+ (unsigned long) &sizes[offset]); -+ set_fs(fs); -+ if(err){ -+ printk(KERN_ERR "cow_open - BLKGETSIZE failed, " -+ "error = %d\n", err); -+ goto out; -+ } -+ -+ kernel_thread(cow_thread, dev, -+ CLONE_FS | CLONE_FILES | CLONE_SIGHAND); -+ down(&dev->sem); -+ } -+ dev->count++; -+ out: -+ spin_unlock(&cow_lock); -+ return(err); -+} -+ -+static int cow_release(struct inode * inode, struct file * file) -+{ -+ struct cow *dev; -+ int n, err; -+ -+ n = DEVICE_NR(inode->i_rdev); -+ if(n >= MAX_DEV) -+ return(-ENODEV); -+ dev = &cow_dev[n]; -+ -+ spin_lock(&cow_lock); -+ -+ if(--dev->count > 0) -+ goto out; -+ -+ err = blkdev_put(dev->cow_bdev, BDEV_RAW); -+ if(err) -+ printk("cow_release - blkdev_put of cow device failed, " -+ "error = %d\n", err); -+ bdput(dev->cow_bdev); -+ dev->cow_bdev = 0; -+ -+ err = blkdev_put(dev->backing_bdev, BDEV_RAW); -+ if(err) -+ printk("cow_release - blkdev_put of backing device failed, " -+ "error = %d\n", err); -+ bdput(dev->backing_bdev); -+ dev->backing_bdev = 0; -+ -+ out: -+ spin_unlock(&cow_lock); -+ return(0); -+} -+ -+static int cow_ioctl(struct inode * inode, struct file * file, -+ unsigned int cmd, unsigned long arg) -+{ -+ struct cow *dev; -+ int (*dev_ioctl)(struct inode *, struct file *, unsigned int, -+ unsigned long); -+ int n; -+ -+ n = DEVICE_NR(inode->i_rdev); -+ if(n >= MAX_DEV) -+ return(-ENODEV); -+ dev = &cow_dev[n]; -+ -+ dev_ioctl = dev->backing_bdev->bd_op->ioctl; -+ return((*dev_ioctl)(inode, file, cmd, arg)); -+} -+ -+static int cow_revalidate(kdev_t rdev) -+{ -+ printk(KERN_ERR "Need to implement cow_revalidate\n"); -+ return(0); -+} -+ -+static int parse_unit(char **ptr) -+{ -+ char *str = *ptr, *end; -+ int n = -1; -+ -+ if(isdigit(*str)) { -+ n = simple_strtoul(str, &end, 0); -+ if(end == str) -+ return(-1); -+ *ptr = end; -+ } -+ else if (('a' <= *str) && (*str <= 'h')) { -+ n = *str - 'a'; -+ str++; -+ *ptr = str; -+ } -+ return(n); -+} -+ -+static int cow_setup(char *str) -+{ -+ struct cow *dev; -+ char *cow_name, *backing_name; -+ int unit; -+ -+ unit = parse_unit(&str); -+ if(unit < 0){ -+ printk(KERN_ERR "cow_setup - Couldn't parse unit number\n"); -+ return(1); -+ } -+ -+ if(*str != '='){ -+ printk(KERN_ERR "cow_setup - Missing '=' after unit " -+ "number\n"); -+ return(1); -+ } -+ str++; -+ -+ cow_name = str; -+ backing_name = strchr(str, ','); -+ if(backing_name == NULL){ -+ printk(KERN_ERR "cow_setup - missing backing device name\n"); -+ return(0); -+ } -+ *backing_name = '\0'; -+ backing_name++; -+ -+ spin_lock(&cow_lock); -+ -+ dev = &cow_dev[unit]; -+ dev->cow_path = cow_name; -+ dev->backing_path = backing_name; -+ -+ spin_unlock(&cow_lock); -+ return(0); -+} -+ -+__setup("cow", cow_setup); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/cow_sys.h um/arch/um/drivers/cow_sys.h ---- orig/arch/um/drivers/cow_sys.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/cow_sys.h 2003-12-17 10:53:03.000000000 -0500 -@@ -0,0 +1,48 @@ -+#ifndef __COW_SYS_H__ -+#define __COW_SYS_H__ -+ -+#include "kern_util.h" -+#include "user_util.h" -+#include "os.h" -+#include "user.h" -+ -+static inline void *cow_malloc(int size) -+{ -+ return(um_kmalloc(size)); -+} -+ -+static inline void cow_free(void *ptr) -+{ -+ kfree(ptr); -+} -+ -+#define cow_printf printk -+ -+static inline char *cow_strdup(char *str) -+{ -+ return(uml_strdup(str)); -+} -+ -+static inline int cow_seek_file(int fd, __u64 offset) -+{ -+ return(os_seek_file(fd, offset)); -+} -+ -+static inline int cow_file_size(char *file, __u64 *size_out) -+{ -+ return(os_file_size(file, size_out)); -+} -+ -+static inline int cow_write_file(int fd, char *buf, int size) -+{ -+ return(os_write_file(fd, buf, size)); -+} -+ -+#endif -+ -+/* -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/cow_user.c um/arch/um/drivers/cow_user.c ---- orig/arch/um/drivers/cow_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/cow_user.c 2004-01-10 05:56:22.000000000 -0500 -@@ -0,0 +1,375 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "os.h" -+ -+#include "cow.h" -+#include "cow_sys.h" -+ -+#define PATH_LEN_V1 256 -+ -+struct cow_header_v1 { -+ int magic; -+ int version; -+ char backing_file[PATH_LEN_V1]; -+ time_t mtime; -+ __u64 size; -+ int sectorsize; -+}; -+ -+#define PATH_LEN_V2 MAXPATHLEN -+ -+struct cow_header_v2 { -+ unsigned long magic; -+ unsigned long version; -+ char backing_file[PATH_LEN_V2]; -+ time_t mtime; -+ __u64 size; -+ int sectorsize; -+}; -+ -+/* Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in -+ * case other systems have different values for MAXPATHLEN -+ */ -+#define PATH_LEN_V3 4096 -+ -+/* Changes from V2 - -+ * PATH_LEN_V3 as described above -+ * Explicitly specify field bit lengths for systems with different -+ * lengths for the usual C types. Not sure whether char or -+ * time_t should be changed, this can be changed later without -+ * breaking compatibility -+ * Add alignment field so that different alignments can be used for the -+ * bitmap and data -+ * Add cow_format field to allow for the possibility of different ways -+ * of specifying the COW blocks. For now, the only value is 0, -+ * for the traditional COW bitmap. -+ * Move the backing_file field to the end of the header. This allows -+ * for the possibility of expanding it into the padding required -+ * by the bitmap alignment. -+ * The bitmap and data portions of the file will be aligned as specified -+ * by the alignment field. This is to allow COW files to be -+ * put on devices with restrictions on access alignments, such as -+ * /dev/raw, with a 512 byte alignment restriction. This also -+ * allows the data to be more aligned more strictly than on -+ * sector boundaries. This is needed for ubd-mmap, which needs -+ * the data to be page aligned. -+ * Fixed (finally!) the rounding bug -+ */ -+ -+struct cow_header_v3 { -+ __u32 magic; -+ __u32 version; -+ time_t mtime; -+ __u64 size; -+ __u32 sectorsize; -+ __u32 alignment; -+ __u32 cow_format; -+ char backing_file[PATH_LEN_V3]; -+}; -+ -+/* COW format definitions - for now, we have only the usual COW bitmap */ -+#define COW_BITMAP 0 -+ -+union cow_header { -+ struct cow_header_v1 v1; -+ struct cow_header_v2 v2; -+ struct cow_header_v3 v3; -+}; -+ -+#define COW_MAGIC 0x4f4f4f4d /* MOOO */ -+#define COW_VERSION 3 -+ -+#define DIV_ROUND(x, len) (((x) + (len) - 1) / (len)) -+#define ROUND_UP(x, align) DIV_ROUND(x, align) * (align) -+ -+void cow_sizes(int version, __u64 size, int sectorsize, int align, -+ int bitmap_offset, unsigned long *bitmap_len_out, -+ int *data_offset_out) -+{ -+ if(version < 3){ -+ *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize); -+ -+ *data_offset_out = bitmap_offset + *bitmap_len_out; -+ *data_offset_out = (*data_offset_out + sectorsize - 1) / -+ sectorsize; -+ *data_offset_out *= sectorsize; -+ } -+ else { -+ *bitmap_len_out = DIV_ROUND(size, sectorsize); -+ *bitmap_len_out = DIV_ROUND(*bitmap_len_out, 8); -+ -+ *data_offset_out = bitmap_offset + *bitmap_len_out; -+ *data_offset_out = ROUND_UP(*data_offset_out, align); -+ } -+} -+ -+static int absolutize(char *to, int size, char *from) -+{ -+ char save_cwd[256], *slash; -+ int remaining; -+ -+ if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) { -+ cow_printf("absolutize : unable to get cwd - errno = %d\n", -+ errno); -+ return(-1); -+ } -+ slash = strrchr(from, '/'); -+ if(slash != NULL){ -+ *slash = '\0'; -+ if(chdir(from)){ -+ *slash = '/'; -+ cow_printf("absolutize : Can't cd to '%s' - " -+ "errno = %d\n", from, errno); -+ return(-1); -+ } -+ *slash = '/'; -+ if(getcwd(to, size) == NULL){ -+ cow_printf("absolutize : unable to get cwd of '%s' - " -+ "errno = %d\n", from, errno); -+ return(-1); -+ } -+ remaining = size - strlen(to); -+ if(strlen(slash) + 1 > remaining){ -+ cow_printf("absolutize : unable to fit '%s' into %d " -+ "chars\n", from, size); -+ return(-1); -+ } -+ strcat(to, slash); -+ } -+ else { -+ if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){ -+ cow_printf("absolutize : unable to fit '%s' into %d " -+ "chars\n", from, size); -+ return(-1); -+ } -+ strcpy(to, save_cwd); -+ strcat(to, "/"); -+ strcat(to, from); -+ } -+ chdir(save_cwd); -+ return(0); -+} -+ -+int write_cow_header(char *cow_file, int fd, char *backing_file, -+ int sectorsize, int alignment, long long *size) -+{ -+ struct cow_header_v3 *header; -+ unsigned long modtime; -+ int err; -+ -+ err = cow_seek_file(fd, 0); -+ if(err < 0){ -+ cow_printf("write_cow_header - lseek failed, err = %d\n", -err); -+ goto out; -+ } -+ -+ err = -ENOMEM; -+ header = cow_malloc(sizeof(*header)); -+ if(header == NULL){ -+ cow_printf("Failed to allocate COW V3 header\n"); -+ goto out; -+ } -+ header->magic = htonl(COW_MAGIC); -+ header->version = htonl(COW_VERSION); -+ -+ err = -EINVAL; -+ if(strlen(backing_file) > sizeof(header->backing_file) - 1){ -+ cow_printf("Backing file name \"%s\" is too long - names are " -+ "limited to %d characters\n", backing_file, -+ sizeof(header->backing_file) - 1); -+ goto out_free; -+ } -+ -+ if(absolutize(header->backing_file, sizeof(header->backing_file), -+ backing_file)) -+ goto out_free; -+ -+ err = os_file_modtime(header->backing_file, &modtime); -+ if(err < 0){ -+ cow_printf("Backing file '%s' mtime request failed, " -+ "err = %d\n", header->backing_file, -err); -+ goto out_free; -+ } -+ -+ err = cow_file_size(header->backing_file, size); -+ if(err < 0){ -+ cow_printf("Couldn't get size of backing file '%s', " -+ "err = %d\n", header->backing_file, -err); -+ goto out_free; -+ } -+ -+ header->mtime = htonl(modtime); -+ header->size = htonll(*size); -+ header->sectorsize = htonl(sectorsize); -+ header->alignment = htonl(alignment); -+ header->cow_format = COW_BITMAP; -+ -+ err = os_write_file(fd, header, sizeof(*header)); -+ if(err != sizeof(*header)){ -+ cow_printf("Write of header to new COW file '%s' failed, " -+ "err = %d\n", cow_file, -err); -+ goto out_free; -+ } -+ err = 0; -+ out_free: -+ cow_free(header); -+ out: -+ return(err); -+} -+ -+int file_reader(__u64 offset, char *buf, int len, void *arg) -+{ -+ int fd = *((int *) arg); -+ -+ return(pread(fd, buf, len, offset)); -+} -+ -+/* XXX Need to sanity-check the values read from the header */ -+ -+int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, -+ __u32 *version_out, char **backing_file_out, -+ time_t *mtime_out, __u64 *size_out, -+ int *sectorsize_out, __u32 *align_out, -+ int *bitmap_offset_out) -+{ -+ union cow_header *header; -+ char *file; -+ int err, n; -+ unsigned long version, magic; -+ -+ header = cow_malloc(sizeof(*header)); -+ if(header == NULL){ -+ cow_printf("read_cow_header - Failed to allocate header\n"); -+ return(-ENOMEM); -+ } -+ err = -EINVAL; -+ n = (*reader)(0, (char *) header, sizeof(*header), arg); -+ if(n < offsetof(typeof(header->v1), backing_file)){ -+ cow_printf("read_cow_header - short header\n"); -+ goto out; -+ } -+ -+ magic = header->v1.magic; -+ if(magic == COW_MAGIC) { -+ version = header->v1.version; -+ } -+ else if(magic == ntohl(COW_MAGIC)){ -+ version = ntohl(header->v1.version); -+ } -+ /* No error printed because the non-COW case comes through here */ -+ else goto out; -+ -+ *version_out = version; -+ -+ if(version == 1){ -+ if(n < sizeof(header->v1)){ -+ cow_printf("read_cow_header - failed to read V1 " -+ "header\n"); -+ goto out; -+ } -+ *mtime_out = header->v1.mtime; -+ *size_out = header->v1.size; -+ *sectorsize_out = header->v1.sectorsize; -+ *bitmap_offset_out = sizeof(header->v1); -+ *align_out = *sectorsize_out; -+ file = header->v1.backing_file; -+ } -+ else if(version == 2){ -+ if(n < sizeof(header->v2)){ -+ cow_printf("read_cow_header - failed to read V2 " -+ "header\n"); -+ goto out; -+ } -+ *mtime_out = ntohl(header->v2.mtime); -+ *size_out = ntohll(header->v2.size); -+ *sectorsize_out = ntohl(header->v2.sectorsize); -+ *bitmap_offset_out = sizeof(header->v2); -+ *align_out = *sectorsize_out; -+ file = header->v2.backing_file; -+ } -+ else if(version == 3){ -+ if(n < sizeof(header->v3)){ -+ cow_printf("read_cow_header - failed to read V2 " -+ "header\n"); -+ goto out; -+ } -+ *mtime_out = ntohl(header->v3.mtime); -+ *size_out = ntohll(header->v3.size); -+ *sectorsize_out = ntohl(header->v3.sectorsize); -+ *align_out = ntohl(header->v3.alignment); -+ *bitmap_offset_out = ROUND_UP(sizeof(header->v3), *align_out); -+ file = header->v3.backing_file; -+ } -+ else { -+ cow_printf("read_cow_header - invalid COW version\n"); -+ goto out; -+ } -+ err = -ENOMEM; -+ *backing_file_out = cow_strdup(file); -+ if(*backing_file_out == NULL){ -+ cow_printf("read_cow_header - failed to allocate backing " -+ "file\n"); -+ goto out; -+ } -+ err = 0; -+ out: -+ cow_free(header); -+ return(err); -+} -+ -+int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize, -+ int alignment, int *bitmap_offset_out, -+ unsigned long *bitmap_len_out, int *data_offset_out) -+{ -+ __u64 size, offset; -+ char zero = 0; -+ int err; -+ -+ err = write_cow_header(cow_file, fd, backing_file, sectorsize, -+ alignment, &size); -+ if(err) -+ goto out; -+ -+ *bitmap_offset_out = ROUND_UP(sizeof(struct cow_header_v3), alignment); -+ cow_sizes(COW_VERSION, size, sectorsize, alignment, *bitmap_offset_out, -+ bitmap_len_out, data_offset_out); -+ -+ offset = *data_offset_out + size - sizeof(zero); -+ err = cow_seek_file(fd, offset); -+ if(err < 0){ -+ cow_printf("cow bitmap lseek failed : err = %d\n", -err); -+ goto out; -+ } -+ -+ /* does not really matter how much we write it is just to set EOF -+ * this also sets the entire COW bitmap -+ * to zero without having to allocate it -+ */ -+ err = cow_write_file(fd, &zero, sizeof(zero)); -+ if(err != sizeof(zero)){ -+ cow_printf("Write of bitmap to new COW file '%s' failed, " -+ "err = %d\n", cow_file, -err); -+ err = -EINVAL; -+ goto out; -+ } -+ -+ return(0); -+ -+ out: -+ return(err); -+} -+ -+/* -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/daemon.h um/arch/um/drivers/daemon.h ---- orig/arch/um/drivers/daemon.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/daemon.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,35 @@ -+/* -+ * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "net_user.h" -+ -+#define SWITCH_VERSION 3 -+ -+struct daemon_data { -+ char *sock_type; -+ char *ctl_sock; -+ void *ctl_addr; -+ void *data_addr; -+ void *local_addr; -+ int fd; -+ int control; -+ void *dev; -+}; -+ -+extern struct net_user_info daemon_user_info; -+ -+extern int daemon_user_write(int fd, void *buf, int len, -+ struct daemon_data *pri); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/daemon_kern.c um/arch/um/drivers/daemon_kern.c ---- orig/arch/um/drivers/daemon_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/daemon_kern.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,113 @@ -+/* -+ * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and -+ * James Leu (jleu@mindspring.net). -+ * Copyright (C) 2001 by various other people who didn't put their name here. -+ * Licensed under the GPL. -+ */ -+ -+#include "linux/kernel.h" -+#include "linux/init.h" -+#include "linux/netdevice.h" -+#include "linux/etherdevice.h" -+#include "net_kern.h" -+#include "net_user.h" -+#include "daemon.h" -+ -+struct daemon_init { -+ char *sock_type; -+ char *ctl_sock; -+}; -+ -+void daemon_init(struct net_device *dev, void *data) -+{ -+ struct uml_net_private *pri; -+ struct daemon_data *dpri; -+ struct daemon_init *init = data; -+ -+ init_etherdev(dev, 0); -+ pri = dev->priv; -+ dpri = (struct daemon_data *) pri->user; -+ *dpri = ((struct daemon_data) -+ { .sock_type = init->sock_type, -+ .ctl_sock = init->ctl_sock, -+ .ctl_addr = NULL, -+ .data_addr = NULL, -+ .local_addr = NULL, -+ .fd = -1, -+ .control = -1, -+ .dev = dev }); -+ -+ printk("daemon backend (uml_switch version %d) - %s:%s", -+ SWITCH_VERSION, dpri->sock_type, dpri->ctl_sock); -+ printk("\n"); -+} -+ -+static int daemon_read(int fd, struct sk_buff **skb, -+ struct uml_net_private *lp) -+{ -+ *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); -+ if(*skb == NULL) return(-ENOMEM); -+ return(net_recvfrom(fd, (*skb)->mac.raw, -+ (*skb)->dev->mtu + ETH_HEADER_OTHER)); -+} -+ -+static int daemon_write(int fd, struct sk_buff **skb, -+ struct uml_net_private *lp) -+{ -+ return(daemon_user_write(fd, (*skb)->data, (*skb)->len, -+ (struct daemon_data *) &lp->user)); -+} -+ -+static struct net_kern_info daemon_kern_info = { -+ .init = daemon_init, -+ .protocol = eth_protocol, -+ .read = daemon_read, -+ .write = daemon_write, -+}; -+ -+int daemon_setup(char *str, char **mac_out, void *data) -+{ -+ struct daemon_init *init = data; -+ char *remain; -+ -+ *init = ((struct daemon_init) -+ { .sock_type = "unix", -+ .ctl_sock = "/tmp/uml.ctl" }); -+ -+ remain = split_if_spec(str, mac_out, &init->sock_type, &init->ctl_sock, -+ NULL); -+ if(remain != NULL) -+ printk(KERN_WARNING "daemon_setup : Ignoring data socket " -+ "specification\n"); -+ -+ return(1); -+} -+ -+static struct transport daemon_transport = { -+ .list = LIST_HEAD_INIT(daemon_transport.list), -+ .name = "daemon", -+ .setup = daemon_setup, -+ .user = &daemon_user_info, -+ .kern = &daemon_kern_info, -+ .private_size = sizeof(struct daemon_data), -+ .setup_size = sizeof(struct daemon_init), -+}; -+ -+static int register_daemon(void) -+{ -+ register_transport(&daemon_transport); -+ return(1); -+} -+ -+__initcall(register_daemon); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/daemon_user.c um/arch/um/drivers/daemon_user.c ---- orig/arch/um/drivers/daemon_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/daemon_user.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,197 @@ -+/* -+ * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and -+ * James Leu (jleu@mindspring.net). -+ * Copyright (C) 2001 by various other people who didn't put their name here. -+ * Licensed under the GPL. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "net_user.h" -+#include "daemon.h" -+#include "kern_util.h" -+#include "user_util.h" -+#include "user.h" -+#include "os.h" -+ -+#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) -+ -+enum request_type { REQ_NEW_CONTROL }; -+ -+#define SWITCH_MAGIC 0xfeedface -+ -+struct request_v3 { -+ uint32_t magic; -+ uint32_t version; -+ enum request_type type; -+ struct sockaddr_un sock; -+}; -+ -+static struct sockaddr_un *new_addr(void *name, int len) -+{ -+ struct sockaddr_un *sun; -+ -+ sun = um_kmalloc(sizeof(struct sockaddr_un)); -+ if(sun == NULL){ -+ printk("new_addr: allocation of sockaddr_un failed\n"); -+ return(NULL); -+ } -+ sun->sun_family = AF_UNIX; -+ memcpy(sun->sun_path, name, len); -+ return(sun); -+} -+ -+static int connect_to_switch(struct daemon_data *pri) -+{ -+ struct sockaddr_un *ctl_addr = pri->ctl_addr; -+ struct sockaddr_un *local_addr = pri->local_addr; -+ struct sockaddr_un *sun; -+ struct request_v3 req; -+ int fd, n, err; -+ -+ pri->control = socket(AF_UNIX, SOCK_STREAM, 0); -+ if(pri->control < 0){ -+ printk("daemon_open : control socket failed, errno = %d\n", -+ errno); -+ return(-errno); -+ } -+ -+ if(connect(pri->control, (struct sockaddr *) ctl_addr, -+ sizeof(*ctl_addr)) < 0){ -+ printk("daemon_open : control connect failed, errno = %d\n", -+ errno); -+ err = -errno; -+ goto out; -+ } -+ -+ fd = socket(AF_UNIX, SOCK_DGRAM, 0); -+ if(fd < 0){ -+ printk("daemon_open : data socket failed, errno = %d\n", -+ errno); -+ err = -errno; -+ goto out; -+ } -+ if(bind(fd, (struct sockaddr *) local_addr, sizeof(*local_addr)) < 0){ -+ printk("daemon_open : data bind failed, errno = %d\n", -+ errno); -+ err = -errno; -+ goto out_close; -+ } -+ -+ sun = um_kmalloc(sizeof(struct sockaddr_un)); -+ if(sun == NULL){ -+ printk("new_addr: allocation of sockaddr_un failed\n"); -+ err = -ENOMEM; -+ goto out_close; -+ } -+ -+ req.magic = SWITCH_MAGIC; -+ req.version = SWITCH_VERSION; -+ req.type = REQ_NEW_CONTROL; -+ req.sock = *local_addr; -+ n = os_write_file(pri->control, &req, sizeof(req)); -+ if(n != sizeof(req)){ -+ printk("daemon_open : control setup request failed, err = %d\n", -+ -n); -+ err = -ENOTCONN; -+ goto out; -+ } -+ -+ n = os_read_file(pri->control, sun, sizeof(*sun)); -+ if(n != sizeof(*sun)){ -+ printk("daemon_open : read of data socket failed, err = %d\n", -+ -n); -+ err = -ENOTCONN; -+ goto out_close; -+ } -+ -+ pri->data_addr = sun; -+ return(fd); -+ -+ out_close: -+ os_close_file(fd); -+ out: -+ os_close_file(pri->control); -+ return(err); -+} -+ -+static void daemon_user_init(void *data, void *dev) -+{ -+ struct daemon_data *pri = data; -+ struct timeval tv; -+ struct { -+ char zero; -+ int pid; -+ int usecs; -+ } name; -+ -+ if(!strcmp(pri->sock_type, "unix")) -+ pri->ctl_addr = new_addr(pri->ctl_sock, -+ strlen(pri->ctl_sock) + 1); -+ name.zero = 0; -+ name.pid = os_getpid(); -+ gettimeofday(&tv, NULL); -+ name.usecs = tv.tv_usec; -+ pri->local_addr = new_addr(&name, sizeof(name)); -+ pri->dev = dev; -+ pri->fd = connect_to_switch(pri); -+ if(pri->fd < 0){ -+ kfree(pri->local_addr); -+ pri->local_addr = NULL; -+ } -+} -+ -+static int daemon_open(void *data) -+{ -+ struct daemon_data *pri = data; -+ return(pri->fd); -+} -+ -+static void daemon_remove(void *data) -+{ -+ struct daemon_data *pri = data; -+ -+ os_close_file(pri->fd); -+ os_close_file(pri->control); -+ if(pri->data_addr != NULL) kfree(pri->data_addr); -+ if(pri->ctl_addr != NULL) kfree(pri->ctl_addr); -+ if(pri->local_addr != NULL) kfree(pri->local_addr); -+} -+ -+int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri) -+{ -+ struct sockaddr_un *data_addr = pri->data_addr; -+ -+ return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr))); -+} -+ -+static int daemon_set_mtu(int mtu, void *data) -+{ -+ return(mtu); -+} -+ -+struct net_user_info daemon_user_info = { -+ .init = daemon_user_init, -+ .open = daemon_open, -+ .close = NULL, -+ .remove = daemon_remove, -+ .set_mtu = daemon_set_mtu, -+ .add_address = NULL, -+ .delete_address = NULL, -+ .max_packet = MAX_PACKET - ETH_HEADER_OTHER -+}; -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/fd.c um/arch/um/drivers/fd.c ---- orig/arch/um/drivers/fd.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/fd.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,97 @@ -+/* -+ * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include -+#include -+#include -+#include -+#include "user.h" -+#include "user_util.h" -+#include "chan_user.h" -+ -+struct fd_chan { -+ int fd; -+ int raw; -+ struct termios tt; -+ char str[sizeof("1234567890\0")]; -+}; -+ -+void *fd_init(char *str, int device, struct chan_opts *opts) -+{ -+ struct fd_chan *data; -+ char *end; -+ int n; -+ -+ if(*str != ':'){ -+ printk("fd_init : channel type 'fd' must specify a file " -+ "descriptor\n"); -+ return(NULL); -+ } -+ str++; -+ n = strtoul(str, &end, 0); -+ if((*end != '\0') || (end == str)){ -+ printk("fd_init : couldn't parse file descriptor '%s'\n", str); -+ return(NULL); -+ } -+ data = um_kmalloc(sizeof(*data)); -+ if(data == NULL) return(NULL); -+ *data = ((struct fd_chan) { .fd = n, -+ .raw = opts->raw }); -+ return(data); -+} -+ -+int fd_open(int input, int output, int primary, void *d, char **dev_out) -+{ -+ struct fd_chan *data = d; -+ -+ if(data->raw && isatty(data->fd)){ -+ tcgetattr(data->fd, &data->tt); -+ raw(data->fd, 0); -+ } -+ sprintf(data->str, "%d", data->fd); -+ *dev_out = data->str; -+ return(data->fd); -+} -+ -+void fd_close(int fd, void *d) -+{ -+ struct fd_chan *data = d; -+ -+ if(data->raw && isatty(fd)){ -+ tcsetattr(fd, TCSAFLUSH, &data->tt); -+ data->raw = 0; -+ } -+} -+ -+int fd_console_write(int fd, const char *buf, int n, void *d) -+{ -+ struct fd_chan *data = d; -+ -+ return(generic_console_write(fd, buf, n, &data->tt)); -+} -+ -+struct chan_ops fd_ops = { -+ .type = "fd", -+ .init = fd_init, -+ .open = fd_open, -+ .close = fd_close, -+ .read = generic_read, -+ .write = generic_write, -+ .console_write = fd_console_write, -+ .window_size = generic_window_size, -+ .free = generic_free, -+ .winch = 1, -+}; -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/harddog_kern.c um/arch/um/drivers/harddog_kern.c ---- orig/arch/um/drivers/harddog_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/harddog_kern.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,194 @@ -+/* UML hardware watchdog, shamelessly stolen from: -+ * -+ * SoftDog 0.05: A Software Watchdog Device -+ * -+ * (c) Copyright 1996 Alan Cox , All Rights Reserved. -+ * http://www.redhat.com -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ * -+ * Neither Alan Cox nor CymruNet Ltd. admit liability nor provide -+ * warranty for any of this software. This material is provided -+ * "AS-IS" and at no charge. -+ * -+ * (c) Copyright 1995 Alan Cox -+ * -+ * Software only watchdog driver. Unlike its big brother the WDT501P -+ * driver this won't always recover a failed machine. -+ * -+ * 03/96: Angelo Haritsis : -+ * Modularised. -+ * Added soft_margin; use upon insmod to change the timer delay. -+ * NB: uses same minor as wdt (WATCHDOG_MINOR); we could use separate -+ * minors. -+ * -+ * 19980911 Alan Cox -+ * Made SMP safe for 2.3.x -+ * -+ * 20011127 Joel Becker (jlbec@evilplan.org> -+ * Added soft_noboot; Allows testing the softdog trigger without -+ * requiring a recompile. -+ * Added WDIOC_GETTIMEOUT and WDIOC_SETTIMOUT. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "helper.h" -+#include "mconsole.h" -+ -+MODULE_LICENSE("GPL"); -+ -+/* Locked by the BKL in harddog_open and harddog_release */ -+static int timer_alive; -+static int harddog_in_fd = -1; -+static int harddog_out_fd = -1; -+ -+/* -+ * Allow only one person to hold it open -+ */ -+ -+extern int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock); -+ -+static int harddog_open(struct inode *inode, struct file *file) -+{ -+ int err; -+ char *sock = NULL; -+ -+ lock_kernel(); -+ if(timer_alive) -+ return -EBUSY; -+#ifdef CONFIG_HARDDOG_NOWAYOUT -+ MOD_INC_USE_COUNT; -+#endif -+ -+#ifdef CONFIG_MCONSOLE -+ sock = mconsole_notify_socket(); -+#endif -+ err = start_watchdog(&harddog_in_fd, &harddog_out_fd, sock); -+ if(err) return(err); -+ -+ timer_alive = 1; -+ unlock_kernel(); -+ return 0; -+} -+ -+extern void stop_watchdog(int in_fd, int out_fd); -+ -+static int harddog_release(struct inode *inode, struct file *file) -+{ -+ /* -+ * Shut off the timer. -+ */ -+ lock_kernel(); -+ -+ stop_watchdog(harddog_in_fd, harddog_out_fd); -+ harddog_in_fd = -1; -+ harddog_out_fd = -1; -+ -+ timer_alive=0; -+ unlock_kernel(); -+ return 0; -+} -+ -+extern int ping_watchdog(int fd); -+ -+static ssize_t harddog_write(struct file *file, const char *data, size_t len, -+ loff_t *ppos) -+{ -+ /* Can't seek (pwrite) on this device */ -+ if (ppos != &file->f_pos) -+ return -ESPIPE; -+ -+ /* -+ * Refresh the timer. -+ */ -+ if(len) -+ return(ping_watchdog(harddog_out_fd)); -+ return 0; -+} -+ -+static int harddog_ioctl(struct inode *inode, struct file *file, -+ unsigned int cmd, unsigned long arg) -+{ -+ static struct watchdog_info ident = { -+ WDIOF_SETTIMEOUT, -+ 0, -+ "UML Hardware Watchdog" -+ }; -+ switch (cmd) { -+ default: -+ return -ENOTTY; -+ case WDIOC_GETSUPPORT: -+ if(copy_to_user((struct harddog_info *)arg, &ident, -+ sizeof(ident))) -+ return -EFAULT; -+ return 0; -+ case WDIOC_GETSTATUS: -+ case WDIOC_GETBOOTSTATUS: -+ return put_user(0,(int *)arg); -+ case WDIOC_KEEPALIVE: -+ return(ping_watchdog(harddog_out_fd)); -+ } -+} -+ -+static struct file_operations harddog_fops = { -+ .owner = THIS_MODULE, -+ .write = harddog_write, -+ .ioctl = harddog_ioctl, -+ .open = harddog_open, -+ .release = harddog_release, -+}; -+ -+static struct miscdevice harddog_miscdev = { -+ .minor = WATCHDOG_MINOR, -+ .name = "watchdog", -+ .fops = &harddog_fops, -+}; -+ -+static char banner[] __initdata = KERN_INFO "UML Watchdog Timer\n"; -+ -+static int __init harddog_init(void) -+{ -+ int ret; -+ -+ ret = misc_register(&harddog_miscdev); -+ -+ if (ret) -+ return ret; -+ -+ printk(banner); -+ -+ return(0); -+} -+ -+static void __exit harddog_exit(void) -+{ -+ misc_deregister(&harddog_miscdev); -+} -+ -+module_init(harddog_init); -+module_exit(harddog_exit); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/harddog_user.c um/arch/um/drivers/harddog_user.c ---- orig/arch/um/drivers/harddog_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/harddog_user.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,143 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include -+#include -+#include -+#include "user_util.h" -+#include "user.h" -+#include "helper.h" -+#include "mconsole.h" -+#include "os.h" -+#include "choose-mode.h" -+#include "mode.h" -+ -+struct dog_data { -+ int stdin; -+ int stdout; -+ int close_me[2]; -+}; -+ -+static void pre_exec(void *d) -+{ -+ struct dog_data *data = d; -+ -+ dup2(data->stdin, 0); -+ dup2(data->stdout, 1); -+ dup2(data->stdout, 2); -+ os_close_file(data->stdin); -+ os_close_file(data->stdout); -+ os_close_file(data->close_me[0]); -+ os_close_file(data->close_me[1]); -+} -+ -+int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock) -+{ -+ struct dog_data data; -+ int in_fds[2], out_fds[2], pid, n, err; -+ char pid_buf[sizeof("nnnnn\0")], c; -+ char *pid_args[] = { "/usr/bin/uml_watchdog", "-pid", pid_buf, NULL }; -+ char *mconsole_args[] = { "/usr/bin/uml_watchdog", "-mconsole", NULL, -+ NULL }; -+ char **args = NULL; -+ -+ err = os_pipe(in_fds, 1, 0); -+ if(err < 0){ -+ printk("harddog_open - os_pipe failed, err = %d\n", -err); -+ goto out; -+ } -+ -+ err = os_pipe(out_fds, 1, 0); -+ if(err < 0){ -+ printk("harddog_open - os_pipe failed, err = %d\n", -err); -+ goto out_close_in; -+ } -+ -+ data.stdin = out_fds[0]; -+ data.stdout = in_fds[1]; -+ data.close_me[0] = out_fds[1]; -+ data.close_me[1] = in_fds[0]; -+ -+ if(sock != NULL){ -+ mconsole_args[2] = sock; -+ args = mconsole_args; -+ } -+ else { -+ /* XXX The os_getpid() is not SMP correct */ -+ sprintf(pid_buf, "%d", CHOOSE_MODE(tracing_pid, os_getpid())); -+ args = pid_args; -+ } -+ -+ pid = run_helper(pre_exec, &data, args, NULL); -+ -+ os_close_file(out_fds[0]); -+ os_close_file(in_fds[1]); -+ -+ if(pid < 0){ -+ err = -pid; -+ printk("harddog_open - run_helper failed, errno = %d\n", -err); -+ goto out_close_out; -+ } -+ -+ n = os_read_file(in_fds[0], &c, sizeof(c)); -+ if(n == 0){ -+ printk("harddog_open - EOF on watchdog pipe\n"); -+ helper_wait(pid); -+ err = -EIO; -+ goto out_close_out; -+ } -+ else if(n < 0){ -+ printk("harddog_open - read of watchdog pipe failed, " -+ "err = %d\n", -n); -+ helper_wait(pid); -+ err = n; -+ goto out_close_out; -+ } -+ *in_fd_ret = in_fds[0]; -+ *out_fd_ret = out_fds[1]; -+ return(0); -+ -+ out_close_in: -+ os_close_file(in_fds[0]); -+ os_close_file(in_fds[1]); -+ out_close_out: -+ os_close_file(out_fds[0]); -+ os_close_file(out_fds[1]); -+ out: -+ return(err); -+} -+ -+void stop_watchdog(int in_fd, int out_fd) -+{ -+ os_close_file(in_fd); -+ os_close_file(out_fd); -+} -+ -+int ping_watchdog(int fd) -+{ -+ int n; -+ char c = '\n'; -+ -+ n = os_write_file(fd, &c, sizeof(c)); -+ if(n != sizeof(c)){ -+ printk("ping_watchdog - write failed, err = %d\n", -n); -+ if(n < 0) -+ return(n); -+ return(-EIO); -+ } -+ return 1; -+ -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/hostaudio_kern.c um/arch/um/drivers/hostaudio_kern.c ---- orig/arch/um/drivers/hostaudio_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/hostaudio_kern.c 2004-02-12 05:46:22.000000000 -0500 -@@ -0,0 +1,352 @@ -+/* -+ * Copyright (C) 2002 Steve Schmidtke -+ * Licensed under the GPL -+ */ -+ -+#include "linux/config.h" -+#include "linux/module.h" -+#include "linux/init.h" -+#include "linux/slab.h" -+#include "linux/fs.h" -+#include "linux/sound.h" -+#include "linux/soundcard.h" -+#include "asm/uaccess.h" -+#include "kern_util.h" -+#include "init.h" -+#include "os.h" -+ -+struct hostaudio_state { -+ int fd; -+}; -+ -+struct hostmixer_state { -+ int fd; -+}; -+ -+#define HOSTAUDIO_DEV_DSP "/dev/sound/dsp" -+#define HOSTAUDIO_DEV_MIXER "/dev/sound/mixer" -+ -+/* Only changed from linux_main at boot time */ -+char *dsp = HOSTAUDIO_DEV_DSP; -+char *mixer = HOSTAUDIO_DEV_MIXER; -+ -+#define DSP_HELP \ -+" This is used to specify the host dsp device to the hostaudio driver.\n" \ -+" The default is \"" HOSTAUDIO_DEV_DSP "\".\n\n" -+ -+#define MIXER_HELP \ -+" This is used to specify the host mixer device to the hostaudio driver.\n" \ -+" The default is \"" HOSTAUDIO_DEV_MIXER "\".\n\n" -+ -+#ifndef MODULE -+static int set_dsp(char *name, int *add) -+{ -+ dsp = name; -+ return(0); -+} -+ -+__uml_setup("dsp=", set_dsp, "dsp=\n" DSP_HELP); -+ -+static int set_mixer(char *name, int *add) -+{ -+ mixer = name; -+ return(0); -+} -+ -+__uml_setup("mixer=", set_mixer, "mixer=\n" MIXER_HELP); -+ -+#else /*MODULE*/ -+ -+MODULE_PARM(dsp, "s"); -+MODULE_PARM_DESC(dsp, DSP_HELP); -+ -+MODULE_PARM(mixer, "s"); -+MODULE_PARM_DESC(mixer, MIXER_HELP); -+ -+#endif -+ -+/* /dev/dsp file operations */ -+ -+static ssize_t hostaudio_read(struct file *file, char *buffer, size_t count, -+ loff_t *ppos) -+{ -+ struct hostaudio_state *state = file->private_data; -+ void *kbuf; -+ int err; -+ -+#ifdef DEBUG -+ printk("hostaudio: read called, count = %d\n", count); -+#endif -+ -+ kbuf = kmalloc(count, GFP_KERNEL); -+ if(kbuf == NULL) -+ return(-ENOMEM); -+ -+ err = os_read_file(state->fd, kbuf, count); -+ if(err < 0) -+ goto out; -+ -+ if(copy_to_user(buffer, kbuf, err)) -+ err = -EFAULT; -+ -+ out: -+ kfree(kbuf); -+ return(err); -+} -+ -+static ssize_t hostaudio_write(struct file *file, const char *buffer, -+ size_t count, loff_t *ppos) -+{ -+ struct hostaudio_state *state = file->private_data; -+ void *kbuf; -+ int err; -+ -+#ifdef DEBUG -+ printk("hostaudio: write called, count = %d\n", count); -+#endif -+ -+ kbuf = kmalloc(count, GFP_KERNEL); -+ if(kbuf == NULL) -+ return(-ENOMEM); -+ -+ err = -EFAULT; -+ if(copy_from_user(kbuf, buffer, count)) -+ goto out; -+ -+ err = os_write_file(state->fd, kbuf, count); -+ if(err < 0) -+ goto out; -+ *ppos += err; -+ -+ out: -+ kfree(kbuf); -+ return(err); -+} -+ -+static unsigned int hostaudio_poll(struct file *file, -+ struct poll_table_struct *wait) -+{ -+ unsigned int mask = 0; -+ -+#ifdef DEBUG -+ printk("hostaudio: poll called (unimplemented)\n"); -+#endif -+ -+ return(mask); -+} -+ -+static int hostaudio_ioctl(struct inode *inode, struct file *file, -+ unsigned int cmd, unsigned long arg) -+{ -+ struct hostaudio_state *state = file->private_data; -+ unsigned long data = 0; -+ int err; -+ -+#ifdef DEBUG -+ printk("hostaudio: ioctl called, cmd = %u\n", cmd); -+#endif -+ switch(cmd){ -+ case SNDCTL_DSP_SPEED: -+ case SNDCTL_DSP_STEREO: -+ case SNDCTL_DSP_GETBLKSIZE: -+ case SNDCTL_DSP_CHANNELS: -+ case SNDCTL_DSP_SUBDIVIDE: -+ case SNDCTL_DSP_SETFRAGMENT: -+ if(get_user(data, (int *) arg)) -+ return(-EFAULT); -+ break; -+ default: -+ break; -+ } -+ -+ err = os_ioctl_generic(state->fd, cmd, (unsigned long) &data); -+ -+ switch(cmd){ -+ case SNDCTL_DSP_SPEED: -+ case SNDCTL_DSP_STEREO: -+ case SNDCTL_DSP_GETBLKSIZE: -+ case SNDCTL_DSP_CHANNELS: -+ case SNDCTL_DSP_SUBDIVIDE: -+ case SNDCTL_DSP_SETFRAGMENT: -+ if(put_user(data, (int *) arg)) -+ return(-EFAULT); -+ break; -+ default: -+ break; -+ } -+ -+ return(err); -+} -+ -+static int hostaudio_open(struct inode *inode, struct file *file) -+{ -+ struct hostaudio_state *state; -+ int r = 0, w = 0; -+ int ret; -+ -+#ifdef DEBUG -+ printk("hostaudio: open called (host: %s)\n", dsp); -+#endif -+ -+ state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL); -+ if(state == NULL) -+ return(-ENOMEM); -+ -+ if(file->f_mode & FMODE_READ) r = 1; -+ if(file->f_mode & FMODE_WRITE) w = 1; -+ -+ ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0); -+ if(ret < 0){ -+ kfree(state); -+ return(ret); -+ } -+ -+ state->fd = ret; -+ file->private_data = state; -+ return(0); -+} -+ -+static int hostaudio_release(struct inode *inode, struct file *file) -+{ -+ struct hostaudio_state *state = file->private_data; -+ -+#ifdef DEBUG -+ printk("hostaudio: release called\n"); -+#endif -+ -+ os_close_file(state->fd); -+ kfree(state); -+ -+ return(0); -+} -+ -+/* /dev/mixer file operations */ -+ -+static int hostmixer_ioctl_mixdev(struct inode *inode, struct file *file, -+ unsigned int cmd, unsigned long arg) -+{ -+ struct hostmixer_state *state = file->private_data; -+ -+#ifdef DEBUG -+ printk("hostmixer: ioctl called\n"); -+#endif -+ -+ return(os_ioctl_generic(state->fd, cmd, arg)); -+} -+ -+static int hostmixer_open_mixdev(struct inode *inode, struct file *file) -+{ -+ struct hostmixer_state *state; -+ int r = 0, w = 0; -+ int ret; -+ -+#ifdef DEBUG -+ printk("hostmixer: open called (host: %s)\n", mixer); -+#endif -+ -+ state = kmalloc(sizeof(struct hostmixer_state), GFP_KERNEL); -+ if(state == NULL) return(-ENOMEM); -+ -+ if(file->f_mode & FMODE_READ) r = 1; -+ if(file->f_mode & FMODE_WRITE) w = 1; -+ -+ ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0); -+ -+ if(ret < 0){ -+ printk("hostaudio_open_mixdev failed to open '%s', err = %d\n", -+ dsp, -ret); -+ kfree(state); -+ return(ret); -+ } -+ -+ file->private_data = state; -+ return(0); -+} -+ -+static int hostmixer_release(struct inode *inode, struct file *file) -+{ -+ struct hostmixer_state *state = file->private_data; -+ -+#ifdef DEBUG -+ printk("hostmixer: release called\n"); -+#endif -+ -+ os_close_file(state->fd); -+ kfree(state); -+ -+ return(0); -+} -+ -+ -+/* kernel module operations */ -+ -+static struct file_operations hostaudio_fops = { -+ .owner = THIS_MODULE, -+ .llseek = no_llseek, -+ .read = hostaudio_read, -+ .write = hostaudio_write, -+ .poll = hostaudio_poll, -+ .ioctl = hostaudio_ioctl, -+ .mmap = NULL, -+ .open = hostaudio_open, -+ .release = hostaudio_release, -+}; -+ -+static struct file_operations hostmixer_fops = { -+ .owner = THIS_MODULE, -+ .llseek = no_llseek, -+ .ioctl = hostmixer_ioctl_mixdev, -+ .open = hostmixer_open_mixdev, -+ .release = hostmixer_release, -+}; -+ -+struct { -+ int dev_audio; -+ int dev_mixer; -+} module_data; -+ -+MODULE_AUTHOR("Steve Schmidtke"); -+MODULE_DESCRIPTION("UML Audio Relay"); -+MODULE_LICENSE("GPL"); -+ -+static int __init hostaudio_init_module(void) -+{ -+ printk(KERN_INFO "UML Audio Relay (host dsp = %s, host mixer = %s)\n", -+ dsp, mixer); -+ -+ module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1); -+ if(module_data.dev_audio < 0){ -+ printk(KERN_ERR "hostaudio: couldn't register DSP device!\n"); -+ return -ENODEV; -+ } -+ -+ module_data.dev_mixer = register_sound_mixer(&hostmixer_fops, -1); -+ if(module_data.dev_mixer < 0){ -+ printk(KERN_ERR "hostmixer: couldn't register mixer " -+ "device!\n"); -+ unregister_sound_dsp(module_data.dev_audio); -+ return -ENODEV; -+ } -+ -+ return 0; -+} -+ -+static void __exit hostaudio_cleanup_module (void) -+{ -+ unregister_sound_mixer(module_data.dev_mixer); -+ unregister_sound_dsp(module_data.dev_audio); -+} -+ -+module_init(hostaudio_init_module); -+module_exit(hostaudio_cleanup_module); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/line.c um/arch/um/drivers/line.c ---- orig/arch/um/drivers/line.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/line.c 2003-11-07 03:03:57.000000000 -0500 -@@ -0,0 +1,610 @@ -+/* -+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/sched.h" -+#include "linux/slab.h" -+#include "linux/list.h" -+#include "linux/devfs_fs_kernel.h" -+#include "asm/irq.h" -+#include "asm/uaccess.h" -+#include "chan_kern.h" -+#include "irq_user.h" -+#include "line.h" -+#include "kern.h" -+#include "user_util.h" -+#include "kern_util.h" -+#include "os.h" -+#include "irq_kern.h" -+ -+#define LINE_BUFSIZE 4096 -+ -+static void line_interrupt(int irq, void *data, struct pt_regs *unused) -+{ -+ struct line *dev = data; -+ -+ if(dev->count > 0) -+ chan_interrupt(&dev->chan_list, &dev->task, dev->tty, irq, -+ dev); -+} -+ -+static void line_timer_cb(void *arg) -+{ -+ struct line *dev = arg; -+ -+ line_interrupt(dev->driver->read_irq, dev, NULL); -+} -+ -+static int write_room(struct line *dev) -+{ -+ int n; -+ -+ if(dev->buffer == NULL) return(LINE_BUFSIZE - 1); -+ -+ n = dev->head - dev->tail; -+ if(n <= 0) n = LINE_BUFSIZE + n; -+ return(n - 1); -+} -+ -+static int buffer_data(struct line *line, const char *buf, int len) -+{ -+ int end, room; -+ -+ if(line->buffer == NULL){ -+ line->buffer = kmalloc(LINE_BUFSIZE, GFP_ATOMIC); -+ if(line->buffer == NULL){ -+ printk("buffer_data - atomic allocation failed\n"); -+ return(0); -+ } -+ line->head = line->buffer; -+ line->tail = line->buffer; -+ } -+ -+ room = write_room(line); -+ len = (len > room) ? room : len; -+ -+ end = line->buffer + LINE_BUFSIZE - line->tail; -+ if(len < end){ -+ memcpy(line->tail, buf, len); -+ line->tail += len; -+ } -+ else { -+ memcpy(line->tail, buf, end); -+ buf += end; -+ len -= end; -+ memcpy(line->buffer, buf, len); -+ line->tail = line->buffer + len; -+ } -+ -+ return(len); -+} -+ -+static int flush_buffer(struct line *line) -+{ -+ int n, count; -+ -+ if((line->buffer == NULL) || (line->head == line->tail)) return(1); -+ -+ if(line->tail < line->head){ -+ count = line->buffer + LINE_BUFSIZE - line->head; -+ n = write_chan(&line->chan_list, line->head, count, -+ line->driver->write_irq); -+ if(n < 0) return(n); -+ if(n == count) line->head = line->buffer; -+ else { -+ line->head += n; -+ return(0); -+ } -+ } -+ -+ count = line->tail - line->head; -+ n = write_chan(&line->chan_list, line->head, count, -+ line->driver->write_irq); -+ if(n < 0) return(n); -+ -+ line->head += n; -+ return(line->head == line->tail); -+} -+ -+int line_write(struct line *lines, struct tty_struct *tty, int from_user, -+ const char *buf, int len) -+{ -+ struct line *line; -+ char *new; -+ unsigned long flags; -+ int n, err, i, ret = 0; -+ -+ if(tty->stopped) return 0; -+ -+ if(from_user){ -+ new = kmalloc(len, GFP_KERNEL); -+ if(new == NULL) -+ return(0); -+ n = copy_from_user(new, buf, len); -+ buf = new; -+ if(n == len){ -+ len = -EFAULT; -+ goto out_free; -+ } -+ -+ len -= n; -+ } -+ -+ i = minor(tty->device) - tty->driver.minor_start; -+ line = &lines[i]; -+ -+ down(&line->sem); -+ if(line->head != line->tail){ -+ local_irq_save(flags); -+ ret += buffer_data(line, buf, len); -+ err = flush_buffer(line); -+ local_irq_restore(flags); -+ if(err <= 0) -+ goto out_up; -+ } -+ else { -+ n = write_chan(&line->chan_list, buf, len, -+ line->driver->write_irq); -+ if(n < 0){ -+ ret = n; -+ goto out_up; -+ } -+ -+ len -= n; -+ ret += n; -+ if(len > 0) -+ ret += buffer_data(line, buf + n, len); -+ } -+ out_up: -+ up(&line->sem); -+ -+ out_free: -+ if(from_user) -+ kfree(buf); -+ return(ret); -+} -+ -+static void line_write_interrupt(int irq, void *data, struct pt_regs *unused) -+{ -+ struct line *dev = data; -+ struct tty_struct *tty = dev->tty; -+ int err; -+ -+ err = flush_buffer(dev); -+ if(err == 0) return; -+ else if(err < 0){ -+ dev->head = dev->buffer; -+ dev->tail = dev->buffer; -+ } -+ -+ if(tty == NULL) return; -+ -+ if(test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && -+ (tty->ldisc.write_wakeup != NULL)) -+ (tty->ldisc.write_wakeup)(tty); -+ -+ /* BLOCKING mode -+ * In blocking mode, everything sleeps on tty->write_wait. -+ * Sleeping in the console driver would break non-blocking -+ * writes. -+ */ -+ -+ if (waitqueue_active(&tty->write_wait)) -+ wake_up_interruptible(&tty->write_wait); -+ -+} -+ -+int line_setup_irq(int fd, int input, int output, void *data) -+{ -+ struct line *line = data; -+ struct line_driver *driver = line->driver; -+ int err = 0, flags = SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM; -+ -+ if(input) err = um_request_irq(driver->read_irq, fd, IRQ_READ, -+ line_interrupt, flags, -+ driver->read_irq_name, line); -+ if(err) return(err); -+ if(output) err = um_request_irq(driver->write_irq, fd, IRQ_WRITE, -+ line_write_interrupt, flags, -+ driver->write_irq_name, line); -+ line->have_irq = 1; -+ return(err); -+} -+ -+void line_disable(struct line *line, int current_irq) -+{ -+ if(!line->have_irq) return; -+ -+ if(line->driver->read_irq == current_irq) -+ free_irq_later(line->driver->read_irq, line); -+ else -+ free_irq(line->driver->read_irq, line); -+ -+ if(line->driver->write_irq == current_irq) -+ free_irq_later(line->driver->write_irq, line); -+ else -+ free_irq(line->driver->write_irq, line); -+ -+ line->have_irq = 0; -+} -+ -+int line_open(struct line *lines, struct tty_struct *tty, -+ struct chan_opts *opts) -+{ -+ struct line *line; -+ int n, err = 0; -+ -+ if(tty == NULL) n = 0; -+ else n = minor(tty->device) - tty->driver.minor_start; -+ line = &lines[n]; -+ -+ down(&line->sem); -+ if(line->count == 0){ -+ if(!line->valid){ -+ err = -ENODEV; -+ goto out; -+ } -+ if(list_empty(&line->chan_list)){ -+ err = parse_chan_pair(line->init_str, &line->chan_list, -+ line->init_pri, n, opts); -+ if(err) goto out; -+ err = open_chan(&line->chan_list); -+ if(err) goto out; -+ } -+ enable_chan(&line->chan_list, line); -+ INIT_TQUEUE(&line->task, line_timer_cb, line); -+ } -+ -+ if(!line->sigio){ -+ chan_enable_winch(&line->chan_list, line); -+ line->sigio = 1; -+ } -+ -+ /* This is outside the if because the initial console is opened -+ * with tty == NULL -+ */ -+ line->tty = tty; -+ -+ if(tty != NULL){ -+ tty->driver_data = line; -+ chan_window_size(&line->chan_list, &tty->winsize.ws_row, -+ &tty->winsize.ws_col); -+ } -+ -+ line->count++; -+ out: -+ up(&line->sem); -+ return(err); -+} -+ -+void line_close(struct line *lines, struct tty_struct *tty) -+{ -+ struct line *line; -+ int n; -+ -+ if(tty == NULL) n = 0; -+ else n = minor(tty->device) - tty->driver.minor_start; -+ line = &lines[n]; -+ -+ down(&line->sem); -+ line->count--; -+ -+ /* I don't like this, but I can't think of anything better. What's -+ * going on is that the tty is in the process of being closed for -+ * the last time. Its count hasn't been dropped yet, so it's still -+ * at 1. This may happen when line->count != 0 because of the initial -+ * console open (without a tty) bumping it up to 1. -+ */ -+ if((line->tty != NULL) && (line->tty->count == 1)) -+ line->tty = NULL; -+ if(line->count == 0) -+ line_disable(line, -1); -+ up(&line->sem); -+} -+ -+void close_lines(struct line *lines, int nlines) -+{ -+ int i; -+ -+ for(i = 0; i < nlines; i++) -+ close_chan(&lines[i].chan_list); -+} -+ -+int line_setup(struct line *lines, int num, char *init, int all_allowed) -+{ -+ int i, n; -+ char *end; -+ -+ if(*init == '=') n = -1; -+ else { -+ n = simple_strtoul(init, &end, 0); -+ if(*end != '='){ -+ printk(KERN_ERR "line_setup failed to parse \"%s\"\n", -+ init); -+ return(0); -+ } -+ init = end; -+ } -+ init++; -+ if((n >= 0) && (n >= num)){ -+ printk("line_setup - %d out of range ((0 ... %d) allowed)\n", -+ n, num); -+ return(0); -+ } -+ else if(n >= 0){ -+ if(lines[n].count > 0){ -+ printk("line_setup - device %d is open\n", n); -+ return(0); -+ } -+ if(lines[n].init_pri <= INIT_ONE){ -+ lines[n].init_pri = INIT_ONE; -+ if(!strcmp(init, "none")) lines[n].valid = 0; -+ else { -+ lines[n].init_str = init; -+ lines[n].valid = 1; -+ } -+ } -+ } -+ else if(!all_allowed){ -+ printk("line_setup - can't configure all devices from " -+ "mconsole\n"); -+ return(0); -+ } -+ else { -+ for(i = 0; i < num; i++){ -+ if(lines[i].init_pri <= INIT_ALL){ -+ lines[i].init_pri = INIT_ALL; -+ if(!strcmp(init, "none")) lines[i].valid = 0; -+ else { -+ lines[i].init_str = init; -+ lines[i].valid = 1; -+ } -+ } -+ } -+ } -+ return(1); -+} -+ -+int line_config(struct line *lines, int num, char *str) -+{ -+ char *new = uml_strdup(str); -+ -+ if(new == NULL){ -+ printk("line_config - uml_strdup failed\n"); -+ return(-ENOMEM); -+ } -+ return(!line_setup(lines, num, new, 0)); -+} -+ -+int line_get_config(char *name, struct line *lines, int num, char *str, -+ int size, char **error_out) -+{ -+ struct line *line; -+ char *end; -+ int dev, n = 0; -+ -+ dev = simple_strtoul(name, &end, 0); -+ if((*end != '\0') || (end == name)){ -+ *error_out = "line_get_config failed to parse device number"; -+ return(0); -+ } -+ -+ if((dev < 0) || (dev >= num)){ -+ *error_out = "device number of of range"; -+ return(0); -+ } -+ -+ line = &lines[dev]; -+ -+ down(&line->sem); -+ if(!line->valid) -+ CONFIG_CHUNK(str, size, n, "none", 1); -+ else if(line->count == 0) -+ CONFIG_CHUNK(str, size, n, line->init_str, 1); -+ else n = chan_config_string(&line->chan_list, str, size, error_out); -+ up(&line->sem); -+ -+ return(n); -+} -+ -+int line_remove(struct line *lines, int num, char *str) -+{ -+ char config[sizeof("conxxxx=none\0")]; -+ -+ sprintf(config, "%s=none", str); -+ return(!line_setup(lines, num, config, 0)); -+} -+ -+static int line_write_room(struct tty_struct *tty) -+{ -+ struct line *dev = tty->driver_data; -+ -+ return(write_room(dev)); -+} -+ -+void line_register_devfs(struct lines *set, struct line_driver *line_driver, -+ struct tty_driver *driver, struct line *lines, -+ int nlines) -+{ -+ int err, i, n; -+ char *from, *to; -+ -+ driver->driver_name = line_driver->name; -+ driver->name = line_driver->devfs_name; -+ driver->major = line_driver->major; -+ driver->minor_start = line_driver->minor_start; -+ driver->type = line_driver->type; -+ driver->subtype = line_driver->subtype; -+ driver->magic = TTY_DRIVER_MAGIC; -+ driver->flags = TTY_DRIVER_REAL_RAW; -+ -+ n = set->num; -+ driver->num = n; -+ driver->table = kmalloc(n * sizeof(driver->table[0]), GFP_KERNEL); -+ driver->termios = kmalloc(n * sizeof(driver->termios[0]), GFP_KERNEL); -+ driver->termios_locked = kmalloc(n * sizeof(driver->termios_locked[0]), -+ GFP_KERNEL); -+ if((driver->table == NULL) || (driver->termios == NULL) || -+ (driver->termios_locked == NULL)) -+ panic("Failed to allocate driver table"); -+ -+ memset(driver->table, 0, n * sizeof(driver->table[0])); -+ memset(driver->termios, 0, n * sizeof(driver->termios[0])); -+ memset(driver->termios_locked, 0, -+ n * sizeof(driver->termios_locked[0])); -+ -+ driver->write_room = line_write_room; -+ driver->init_termios = tty_std_termios; -+ -+ if (tty_register_driver(driver)) -+ panic("line_register_devfs : Couldn't register driver\n"); -+ -+ from = line_driver->symlink_from; -+ to = line_driver->symlink_to; -+ err = devfs_mk_symlink(NULL, from, 0, to, NULL, NULL); -+ if(err) printk("Symlink creation from /dev/%s to /dev/%s " -+ "returned %d\n", from, to, err); -+ -+ for(i = 0; i < nlines; i++){ -+ if(!lines[i].valid) -+ tty_unregister_devfs(driver, driver->minor_start + i); -+ } -+ -+ mconsole_register_dev(&line_driver->mc); -+} -+ -+void lines_init(struct line *lines, int nlines) -+{ -+ struct line *line; -+ int i; -+ -+ for(i = 0; i < nlines; i++){ -+ line = &lines[i]; -+ INIT_LIST_HEAD(&line->chan_list); -+ sema_init(&line->sem, 1); -+ if(line->init_str != NULL){ -+ line->init_str = uml_strdup(line->init_str); -+ if(line->init_str == NULL) -+ printk("lines_init - uml_strdup returned " -+ "NULL\n"); -+ } -+ } -+} -+ -+struct winch { -+ struct list_head list; -+ int fd; -+ int tty_fd; -+ int pid; -+ struct line *line; -+}; -+ -+void winch_interrupt(int irq, void *data, struct pt_regs *unused) -+{ -+ struct winch *winch = data; -+ struct tty_struct *tty; -+ int err; -+ char c; -+ -+ if(winch->fd != -1){ -+ err = generic_read(winch->fd, &c, NULL); -+ if(err < 0){ -+ if(err != -EAGAIN){ -+ printk("winch_interrupt : read failed, " -+ "errno = %d\n", -err); -+ printk("fd %d is losing SIGWINCH support\n", -+ winch->tty_fd); -+ return; -+ } -+ goto out; -+ } -+ } -+ tty = winch->line->tty; -+ if(tty != NULL){ -+ chan_window_size(&winch->line->chan_list, -+ &tty->winsize.ws_row, -+ &tty->winsize.ws_col); -+ kill_pg(tty->pgrp, SIGWINCH, 1); -+ } -+ out: -+ if(winch->fd != -1) -+ reactivate_fd(winch->fd, WINCH_IRQ); -+} -+ -+DECLARE_MUTEX(winch_handler_sem); -+LIST_HEAD(winch_handlers); -+ -+void register_winch_irq(int fd, int tty_fd, int pid, void *line) -+{ -+ struct winch *winch; -+ -+ down(&winch_handler_sem); -+ winch = kmalloc(sizeof(*winch), GFP_KERNEL); -+ if(winch == NULL){ -+ printk("register_winch_irq - kmalloc failed\n"); -+ goto out; -+ } -+ *winch = ((struct winch) { .list = LIST_HEAD_INIT(winch->list), -+ .fd = fd, -+ .tty_fd = tty_fd, -+ .pid = pid, -+ .line = line }); -+ list_add(&winch->list, &winch_handlers); -+ if(um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, -+ SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, -+ "winch", winch) < 0) -+ printk("register_winch_irq - failed to register IRQ\n"); -+ out: -+ up(&winch_handler_sem); -+} -+ -+static void winch_cleanup(void) -+{ -+ struct list_head *ele; -+ struct winch *winch; -+ -+ list_for_each(ele, &winch_handlers){ -+ winch = list_entry(ele, struct winch, list); -+ if(winch->fd != -1){ -+ deactivate_fd(winch->fd, WINCH_IRQ); -+ os_close_file(winch->fd); -+ } -+ if(winch->pid != -1) -+ os_kill_process(winch->pid, 1); -+ } -+} -+ -+__uml_exitcall(winch_cleanup); -+ -+char *add_xterm_umid(char *base) -+{ -+ char *umid, *title; -+ int len; -+ -+ umid = get_umid(1); -+ if(umid == NULL) return(base); -+ -+ len = strlen(base) + strlen(" ()") + strlen(umid) + 1; -+ title = kmalloc(len, GFP_KERNEL); -+ if(title == NULL){ -+ printk("Failed to allocate buffer for xterm title\n"); -+ return(base); -+ } -+ -+ strncpy(title, base, len); -+ len -= strlen(title); -+ snprintf(&title[strlen(title)], len, " (%s)", umid); -+ return(title); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/Makefile um/arch/um/drivers/Makefile ---- orig/arch/um/drivers/Makefile 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/Makefile 2004-02-12 03:55:08.000000000 -0500 -@@ -0,0 +1,97 @@ -+# -+# Copyright (C) 2000, 2002, 2003 Jeff Dike (jdike@karaya.com) -+# Licensed under the GPL -+# -+ -+O_TARGET := built-in.o -+ -+CHAN_OBJS := chan_kern.o chan_user.o line.o -+ -+list-multi := slip.o slirp.o daemon.o mcast.o mconsole.o net.o ubd.o \ -+ hostaudio.o pcap.o port.o harddog.o -+ -+slip-objs := slip_kern.o slip_user.o -+slirp-objs := slirp_kern.o slirp_user.o -+daemon-objs := daemon_kern.o daemon_user.o -+mcast-objs := mcast_kern.o mcast_user.o -+pcap-objs := pcap_kern.o pcap_user.o -+pcap-libs := -lpcap -L/usr/lib -+net-objs := net_kern.o net_user.o -+mconsole-objs := mconsole_kern.o mconsole_user.o -+hostaudio-objs := hostaudio_kern.o -+ubd-objs := ubd_kern.o ubd_user.o -+port-objs := port_kern.o port_user.o -+harddog-objs := harddog_kern.o harddog_user.o -+ -+export-objs := mconsole_kern.o -+ -+obj-y = -+obj-$(CONFIG_SSL) += ssl.o -+obj-$(CONFIG_UML_NET_SLIP) += slip.o -+obj-$(CONFIG_UML_NET_SLIRP) += slirp.o -+obj-$(CONFIG_UML_NET_DAEMON) += daemon.o -+obj-$(CONFIG_UML_NET_MCAST) += mcast.o -+obj-$(CONFIG_UML_NET_PCAP) += pcap.o -+obj-$(CONFIG_UML_NET) += net.o -+obj-$(CONFIG_MCONSOLE) += mconsole.o -+obj-$(CONFIG_MMAPPER) += mmapper_kern.o -+obj-$(CONFIG_BLK_DEV_UBD) += ubd.o -+obj-$(CONFIG_HOSTAUDIO) += hostaudio.o -+obj-$(CONFIG_FD_CHAN) += fd.o -+obj-$(CONFIG_NULL_CHAN) += null.o -+obj-$(CONFIG_PORT_CHAN) += port.o -+obj-$(CONFIG_PTY_CHAN) += pty.o -+obj-$(CONFIG_TTY_CHAN) += tty.o -+obj-$(CONFIG_XTERM_CHAN) += xterm.o xterm_kern.o -+obj-$(CONFIG_UML_WATCHDOG) += harddog.o -+obj-$(CONFIG_COW) += cow_kern.o -+obj-$(CONFIG_COW_COMMON) += cow_user.o -+ -+CFLAGS_pcap_user.o = -I/usr/include/pcap -+ -+obj-y += stdio_console.o $(CHAN_OBJS) -+ -+USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y) $(obj-m)),$($(f)-objs)) -+ -+USER_OBJS = $(filter %_user.o,$(obj-y) $(obj-m) $(USER_SINGLE_OBJS)) fd.o \ -+ null.o pty.o tty.o xterm.o -+ -+include $(TOPDIR)/Rules.make -+ -+$(USER_OBJS) : %.o: %.c -+ $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $< -+ -+clean: -+ -+modules: -+ -+fastdep: -+ -+dep: -+ -+archmrproper: -+ -+daemon.o : $(daemon-objs) -+ -+slip.o : $(slip-objs) -+ -+slirp.o : $(slirp-objs) -+ -+mcast.o : $(mcast-objs) -+ -+pcap.o : $(pcap-objs) -+ -+mconsole.o : $(mconsole-objs) -+ -+net.o : $(net-objs) -+ -+hostaudio.o : $(hostaudio-objs) -+ -+ubd.o : $(ubd-objs) -+ -+port.o : $(port-objs) -+ -+harddog.o : $(harddog-objs) -+ -+$(list-multi) : # This doesn't work, but should : '%.o : $(%-objs)' -+ $(LD) -r -o $@ $($(patsubst %.o,%,$@)-objs) $($(patsubst %.o,%,$@)-libs) -diff -Naur -X ../exclude-files orig/arch/um/drivers/mcast.h um/arch/um/drivers/mcast.h ---- orig/arch/um/drivers/mcast.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/mcast.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,30 @@ -+/* -+ * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "net_user.h" -+ -+struct mcast_data { -+ char *addr; -+ unsigned short port; -+ void *mcast_addr; -+ int ttl; -+ void *dev; -+}; -+ -+extern struct net_user_info mcast_user_info; -+ -+extern int mcast_user_write(int fd, void *buf, int len, -+ struct mcast_data *pri); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/mcast_kern.c um/arch/um/drivers/mcast_kern.c ---- orig/arch/um/drivers/mcast_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/mcast_kern.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,145 @@ -+/* -+ * user-mode-linux networking multicast transport -+ * Copyright (C) 2001 by Harald Welte -+ * -+ * based on the existing uml-networking code, which is -+ * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and -+ * James Leu (jleu@mindspring.net). -+ * Copyright (C) 2001 by various other people who didn't put their name here. -+ * -+ * Licensed under the GPL. -+ */ -+ -+#include "linux/kernel.h" -+#include "linux/init.h" -+#include "linux/netdevice.h" -+#include "linux/etherdevice.h" -+#include "linux/in.h" -+#include "linux/inet.h" -+#include "net_kern.h" -+#include "net_user.h" -+#include "mcast.h" -+ -+struct mcast_init { -+ char *addr; -+ int port; -+ int ttl; -+}; -+ -+void mcast_init(struct net_device *dev, void *data) -+{ -+ struct uml_net_private *pri; -+ struct mcast_data *dpri; -+ struct mcast_init *init = data; -+ -+ init_etherdev(dev, 0); -+ pri = dev->priv; -+ dpri = (struct mcast_data *) pri->user; -+ *dpri = ((struct mcast_data) -+ { .addr = init->addr, -+ .port = init->port, -+ .ttl = init->ttl, -+ .mcast_addr = NULL, -+ .dev = dev }); -+ printk("mcast backend "); -+ printk("multicast adddress: %s:%u, TTL:%u ", -+ dpri->addr, dpri->port, dpri->ttl); -+ -+ printk("\n"); -+} -+ -+static int mcast_read(int fd, struct sk_buff **skb, struct uml_net_private *lp) -+{ -+ *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); -+ if(*skb == NULL) return(-ENOMEM); -+ return(net_recvfrom(fd, (*skb)->mac.raw, -+ (*skb)->dev->mtu + ETH_HEADER_OTHER)); -+} -+ -+static int mcast_write(int fd, struct sk_buff **skb, -+ struct uml_net_private *lp) -+{ -+ return mcast_user_write(fd, (*skb)->data, (*skb)->len, -+ (struct mcast_data *) &lp->user); -+} -+ -+static struct net_kern_info mcast_kern_info = { -+ .init = mcast_init, -+ .protocol = eth_protocol, -+ .read = mcast_read, -+ .write = mcast_write, -+}; -+ -+int mcast_setup(char *str, char **mac_out, void *data) -+{ -+ struct mcast_init *init = data; -+ char *port_str = NULL, *ttl_str = NULL, *remain; -+ char *last; -+ int n; -+ -+ *init = ((struct mcast_init) -+ { .addr = "239.192.168.1", -+ .port = 1102, -+ .ttl = 1 }); -+ -+ remain = split_if_spec(str, mac_out, &init->addr, &port_str, &ttl_str, -+ NULL); -+ if(remain != NULL){ -+ printk(KERN_ERR "mcast_setup - Extra garbage on " -+ "specification : '%s'\n", remain); -+ return(0); -+ } -+ -+ if(port_str != NULL){ -+ n = simple_strtoul(port_str, &last, 10); -+ if((*last != '\0') || (last == port_str)){ -+ printk(KERN_ERR "mcast_setup - Bad port : '%s'\n", -+ port_str); -+ return(0); -+ } -+ init->port = htons(n); -+ } -+ -+ if(ttl_str != NULL){ -+ init->ttl = simple_strtoul(ttl_str, &last, 10); -+ if((*last != '\0') || (last == ttl_str)){ -+ printk(KERN_ERR "mcast_setup - Bad ttl : '%s'\n", -+ ttl_str); -+ return(0); -+ } -+ } -+ -+ printk(KERN_INFO "Configured mcast device: %s:%u-%u\n", init->addr, -+ init->port, init->ttl); -+ -+ return(1); -+} -+ -+static struct transport mcast_transport = { -+ .list = LIST_HEAD_INIT(mcast_transport.list), -+ .name = "mcast", -+ .setup = mcast_setup, -+ .user = &mcast_user_info, -+ .kern = &mcast_kern_info, -+ .private_size = sizeof(struct mcast_data), -+ .setup_size = sizeof(struct mcast_init), -+}; -+ -+static int register_mcast(void) -+{ -+ register_transport(&mcast_transport); -+ return(1); -+} -+ -+__initcall(register_mcast); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/mcast_user.c um/arch/um/drivers/mcast_user.c ---- orig/arch/um/drivers/mcast_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/mcast_user.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,177 @@ -+/* -+ * user-mode-linux networking multicast transport -+ * Copyright (C) 2001 by Harald Welte -+ * -+ * based on the existing uml-networking code, which is -+ * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and -+ * James Leu (jleu@mindspring.net). -+ * Copyright (C) 2001 by various other people who didn't put their name here. -+ * -+ * Licensed under the GPL. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "net_user.h" -+#include "mcast.h" -+#include "kern_util.h" -+#include "user_util.h" -+#include "user.h" -+#include "os.h" -+ -+#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) -+ -+static struct sockaddr_in *new_addr(char *addr, unsigned short port) -+{ -+ struct sockaddr_in *sin; -+ -+ sin = um_kmalloc(sizeof(struct sockaddr_in)); -+ if(sin == NULL){ -+ printk("new_addr: allocation of sockaddr_in failed\n"); -+ return(NULL); -+ } -+ sin->sin_family = AF_INET; -+ sin->sin_addr.s_addr = in_aton(addr); -+ sin->sin_port = port; -+ return(sin); -+} -+ -+static void mcast_user_init(void *data, void *dev) -+{ -+ struct mcast_data *pri = data; -+ -+ pri->mcast_addr = new_addr(pri->addr, pri->port); -+ pri->dev = dev; -+} -+ -+static int mcast_open(void *data) -+{ -+ struct mcast_data *pri = data; -+ struct sockaddr_in *sin = pri->mcast_addr; -+ struct ip_mreq mreq; -+ int fd, yes = 1; -+ -+ -+ if ((sin->sin_addr.s_addr == 0) || (sin->sin_port == 0)) { -+ fd = -EINVAL; -+ goto out; -+ } -+ -+ fd = socket(AF_INET, SOCK_DGRAM, 0); -+ if (fd < 0){ -+ printk("mcast_open : data socket failed, errno = %d\n", -+ errno); -+ fd = -ENOMEM; -+ goto out; -+ } -+ -+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) { -+ printk("mcast_open: SO_REUSEADDR failed, errno = %d\n", -+ errno); -+ os_close_file(fd); -+ fd = -EINVAL; -+ goto out; -+ } -+ -+ /* set ttl according to config */ -+ if (setsockopt(fd, SOL_IP, IP_MULTICAST_TTL, &pri->ttl, -+ sizeof(pri->ttl)) < 0) { -+ printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n", -+ errno); -+ os_close_file(fd); -+ fd = -EINVAL; -+ goto out; -+ } -+ -+ /* set LOOP, so data does get fed back to local sockets */ -+ if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) { -+ printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n", -+ errno); -+ os_close_file(fd); -+ fd = -EINVAL; -+ goto out; -+ } -+ -+ /* bind socket to mcast address */ -+ if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) { -+ printk("mcast_open : data bind failed, errno = %d\n", errno); -+ os_close_file(fd); -+ fd = -EINVAL; -+ goto out; -+ } -+ -+ /* subscribe to the multicast group */ -+ mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr; -+ mreq.imr_interface.s_addr = 0; -+ if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP, -+ &mreq, sizeof(mreq)) < 0) { -+ printk("mcast_open: IP_ADD_MEMBERSHIP failed, error = %d\n", -+ errno); -+ printk("There appears not to be a multicast-capable network " -+ "interface on the host.\n"); -+ printk("eth0 should be configured in order to use the " -+ "multicast transport.\n"); -+ os_close_file(fd); -+ fd = -EINVAL; -+ } -+ -+ out: -+ return(fd); -+} -+ -+static void mcast_close(int fd, void *data) -+{ -+ struct ip_mreq mreq; -+ struct mcast_data *pri = data; -+ struct sockaddr_in *sin = pri->mcast_addr; -+ -+ mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr; -+ mreq.imr_interface.s_addr = 0; -+ if (setsockopt(fd, SOL_IP, IP_DROP_MEMBERSHIP, -+ &mreq, sizeof(mreq)) < 0) { -+ printk("mcast_open: IP_DROP_MEMBERSHIP failed, error = %d\n", -+ errno); -+ } -+ -+ os_close_file(fd); -+} -+ -+int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri) -+{ -+ struct sockaddr_in *data_addr = pri->mcast_addr; -+ -+ return(net_sendto(fd, buf, len, data_addr, sizeof(*data_addr))); -+} -+ -+static int mcast_set_mtu(int mtu, void *data) -+{ -+ return(mtu); -+} -+ -+struct net_user_info mcast_user_info = { -+ .init = mcast_user_init, -+ .open = mcast_open, -+ .close = mcast_close, -+ .remove = NULL, -+ .set_mtu = mcast_set_mtu, -+ .add_address = NULL, -+ .delete_address = NULL, -+ .max_packet = MAX_PACKET - ETH_HEADER_OTHER -+}; -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/mconsole_kern.c um/arch/um/drivers/mconsole_kern.c ---- orig/arch/um/drivers/mconsole_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/mconsole_kern.c 2004-02-12 03:09:12.000000000 -0500 -@@ -0,0 +1,560 @@ -+/* -+ * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) -+ * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/kernel.h" -+#include "linux/slab.h" -+#include "linux/init.h" -+#include "linux/notifier.h" -+#include "linux/reboot.h" -+#include "linux/utsname.h" -+#include "linux/ctype.h" -+#include "linux/interrupt.h" -+#include "linux/sysrq.h" -+#include "linux/tqueue.h" -+#include "linux/module.h" -+#include "linux/file.h" -+#include "linux/fs.h" -+#include "linux/proc_fs.h" -+#include "asm/irq.h" -+#include "asm/uaccess.h" -+#include "user_util.h" -+#include "kern_util.h" -+#include "kern.h" -+#include "mconsole.h" -+#include "mconsole_kern.h" -+#include "irq_user.h" -+#include "init.h" -+#include "os.h" -+#include "umid.h" -+#include "irq_kern.h" -+ -+static int do_unlink_socket(struct notifier_block *notifier, -+ unsigned long what, void *data) -+{ -+ return(mconsole_unlink_socket()); -+} -+ -+ -+static struct notifier_block reboot_notifier = { -+ .notifier_call = do_unlink_socket, -+ .priority = 0, -+}; -+ -+/* Safe without explicit locking for now. Tasklets provide their own -+ * locking, and the interrupt handler is safe because it can't interrupt -+ * itself and it can only happen on CPU 0. -+ */ -+ -+LIST_HEAD(mc_requests); -+ -+void mc_task_proc(void *unused) -+{ -+ struct mconsole_entry *req; -+ unsigned long flags; -+ int done; -+ -+ do { -+ save_flags(flags); -+ req = list_entry(mc_requests.next, struct mconsole_entry, -+ list); -+ list_del(&req->list); -+ done = list_empty(&mc_requests); -+ restore_flags(flags); -+ req->request.cmd->handler(&req->request); -+ kfree(req); -+ } while(!done); -+} -+ -+struct tq_struct mconsole_task = { -+ .routine = mc_task_proc, -+ .data = NULL -+}; -+ -+void mconsole_interrupt(int irq, void *dev_id, struct pt_regs *regs) -+{ -+ int fd; -+ struct mconsole_entry *new; -+ struct mc_request req; -+ -+ fd = (int) dev_id; -+ while (mconsole_get_request(fd, &req)){ -+ if(req.cmd->context == MCONSOLE_INTR) -+ (*req.cmd->handler)(&req); -+ else { -+ new = kmalloc(sizeof(*new), GFP_ATOMIC); -+ if(new == NULL) -+ mconsole_reply(&req, "Out of memory", 1, 0); -+ else { -+ new->request = req; -+ list_add(&new->list, &mc_requests); -+ } -+ } -+ } -+ if(!list_empty(&mc_requests)) schedule_task(&mconsole_task); -+ reactivate_fd(fd, MCONSOLE_IRQ); -+} -+ -+void mconsole_version(struct mc_request *req) -+{ -+ char version[256]; -+ -+ sprintf(version, "%s %s %s %s %s", system_utsname.sysname, -+ system_utsname.nodename, system_utsname.release, -+ system_utsname.version, system_utsname.machine); -+ mconsole_reply(req, version, 0, 0); -+} -+ -+void mconsole_log(struct mc_request *req) -+{ -+ int len; -+ char *ptr = req->request.data; -+ -+ ptr += strlen("log "); -+ -+ len = req->len - (ptr - req->request.data); -+ printk("%.*s", len, ptr); -+ mconsole_reply(req, "", 0, 0); -+} -+ -+void mconsole_proc(struct mc_request *req) -+{ -+ struct nameidata nd; -+ struct file_system_type *proc; -+ struct super_block *super; -+ struct file *file; -+ int n, err; -+ char *ptr = req->request.data, *buf; -+ -+ ptr += strlen("proc"); -+ while(isspace(*ptr)) ptr++; -+ -+ proc = get_fs_type("proc"); -+ if(proc == NULL){ -+ mconsole_reply(req, "procfs not registered", 1, 0); -+ goto out; -+ } -+ -+ super = get_anon_super(proc, NULL, NULL); -+ if(super == NULL){ -+ mconsole_reply(req, "Failed to get procfs superblock", 1, 0); -+ goto out_put; -+ } -+ -+ if(super->s_root == NULL){ -+ super = (*proc->read_super)(super, NULL, 0); -+ if(super == NULL){ -+ mconsole_reply(req, "Failed to read superblock", 1, 0); -+ goto out_put; -+ } -+ } -+ up_write(&super->s_umount); -+ -+ nd.dentry = super->s_root; -+ nd.mnt = NULL; -+ nd.flags = O_RDONLY + 1; -+ nd.last_type = LAST_ROOT; -+ -+ err = link_path_walk(ptr, &nd); -+ if(err){ -+ mconsole_reply(req, "Failed to look up file", 1, 0); -+ goto out_kill; -+ } -+ -+ file = dentry_open(nd.dentry, nd.mnt, O_RDONLY); -+ if(IS_ERR(file)){ -+ mconsole_reply(req, "Failed to open file", 1, 0); -+ goto out_kill; -+ } -+ -+ buf = kmalloc(PAGE_SIZE, GFP_KERNEL); -+ if(buf == NULL){ -+ mconsole_reply(req, "Failed to allocate buffer", 1, 0); -+ goto out_fput; -+ } -+ -+ if((file->f_op != NULL) && (file->f_op->read != NULL)){ -+ do { -+ n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1, -+ &file->f_pos); -+ if(n >= 0){ -+ buf[n] = '\0'; -+ mconsole_reply(req, buf, 0, (n > 0)); -+ } -+ else { -+ mconsole_reply(req, "Read of file failed", -+ 1, 0); -+ goto out_free; -+ } -+ } while(n > 0); -+ } -+ else mconsole_reply(req, "", 0, 0); -+ -+ out_free: -+ kfree(buf); -+ out_fput: -+ fput(file); -+ out_kill: -+ kill_super(super); -+ out_put: -+ /* put_filesystem(proc); */ -+ out: ; -+} -+ -+#define UML_MCONSOLE_HELPTEXT \ -+"Commands: \n\ -+ version - Get kernel version \n\ -+ help - Print this message \n\ -+ halt - Halt UML \n\ -+ reboot - Reboot UML \n\ -+ config = - Add a new device to UML; \n\ -+ same syntax as command line \n\ -+ config - Query the configuration of a device \n\ -+ remove - Remove a device from UML \n\ -+ sysrq - Performs the SysRq action controlled by the letter \n\ -+ cad - invoke the Ctl-Alt-Del handler \n\ -+ stop - pause the UML; it will do nothing until it receives a 'go' \n\ -+ go - continue the UML after a 'stop' \n\ -+ log - make UML enter into the kernel log\n\ -+ proc - returns the contents of the UML's /proc/\n\ -+" -+ -+void mconsole_help(struct mc_request *req) -+{ -+ mconsole_reply(req, UML_MCONSOLE_HELPTEXT, 0, 0); -+} -+ -+void mconsole_halt(struct mc_request *req) -+{ -+ mconsole_reply(req, "", 0, 0); -+ machine_halt(); -+} -+ -+void mconsole_reboot(struct mc_request *req) -+{ -+ mconsole_reply(req, "", 0, 0); -+ machine_restart(NULL); -+} -+ -+extern void ctrl_alt_del(void); -+ -+void mconsole_cad(struct mc_request *req) -+{ -+ mconsole_reply(req, "", 0, 0); -+ ctrl_alt_del(); -+} -+ -+void mconsole_go(struct mc_request *req) -+{ -+ mconsole_reply(req, "Not stopped", 1, 0); -+} -+ -+void mconsole_stop(struct mc_request *req) -+{ -+ deactivate_fd(req->originating_fd, MCONSOLE_IRQ); -+ os_set_fd_block(req->originating_fd, 1); -+ mconsole_reply(req, "", 0, 0); -+ while(mconsole_get_request(req->originating_fd, req)){ -+ if(req->cmd->handler == mconsole_go) break; -+ (*req->cmd->handler)(req); -+ } -+ os_set_fd_block(req->originating_fd, 0); -+ reactivate_fd(req->originating_fd, MCONSOLE_IRQ); -+ mconsole_reply(req, "", 0, 0); -+} -+ -+/* This list is populated by __initcall routines. */ -+ -+LIST_HEAD(mconsole_devices); -+ -+void mconsole_register_dev(struct mc_device *new) -+{ -+ list_add(&new->list, &mconsole_devices); -+} -+ -+static struct mc_device *mconsole_find_dev(char *name) -+{ -+ struct list_head *ele; -+ struct mc_device *dev; -+ -+ list_for_each(ele, &mconsole_devices){ -+ dev = list_entry(ele, struct mc_device, list); -+ if(!strncmp(name, dev->name, strlen(dev->name))) -+ return(dev); -+ } -+ return(NULL); -+} -+ -+#define CONFIG_BUF_SIZE 64 -+ -+static void mconsole_get_config(int (*get_config)(char *, char *, int, -+ char **), -+ struct mc_request *req, char *name) -+{ -+ char default_buf[CONFIG_BUF_SIZE], *error, *buf; -+ int n, size; -+ -+ if(get_config == NULL){ -+ mconsole_reply(req, "No get_config routine defined", 1, 0); -+ return; -+ } -+ -+ error = NULL; -+ size = sizeof(default_buf)/sizeof(default_buf[0]); -+ buf = default_buf; -+ -+ while(1){ -+ n = (*get_config)(name, buf, size, &error); -+ if(error != NULL){ -+ mconsole_reply(req, error, 1, 0); -+ goto out; -+ } -+ -+ if(n <= size){ -+ mconsole_reply(req, buf, 0, 0); -+ goto out; -+ } -+ -+ if(buf != default_buf) -+ kfree(buf); -+ -+ size = n; -+ buf = kmalloc(size, GFP_KERNEL); -+ if(buf == NULL){ -+ mconsole_reply(req, "Failed to allocate buffer", 1, 0); -+ return; -+ } -+ } -+ out: -+ if(buf != default_buf) -+ kfree(buf); -+ -+} -+ -+void mconsole_config(struct mc_request *req) -+{ -+ struct mc_device *dev; -+ char *ptr = req->request.data, *name; -+ int err; -+ -+ ptr += strlen("config"); -+ while(isspace(*ptr)) ptr++; -+ dev = mconsole_find_dev(ptr); -+ if(dev == NULL){ -+ mconsole_reply(req, "Bad configuration option", 1, 0); -+ return; -+ } -+ -+ name = &ptr[strlen(dev->name)]; -+ ptr = name; -+ while((*ptr != '=') && (*ptr != '\0')) -+ ptr++; -+ -+ if(*ptr == '='){ -+ err = (*dev->config)(name); -+ mconsole_reply(req, "", err, 0); -+ } -+ else mconsole_get_config(dev->get_config, req, name); -+} -+ -+void mconsole_remove(struct mc_request *req) -+{ -+ struct mc_device *dev; -+ char *ptr = req->request.data; -+ int err; -+ -+ ptr += strlen("remove"); -+ while(isspace(*ptr)) ptr++; -+ dev = mconsole_find_dev(ptr); -+ if(dev == NULL){ -+ mconsole_reply(req, "Bad remove option", 1, 0); -+ return; -+ } -+ err = (*dev->remove)(&ptr[strlen(dev->name)]); -+ mconsole_reply(req, "", err, 0); -+} -+ -+#ifdef CONFIG_MAGIC_SYSRQ -+void mconsole_sysrq(struct mc_request *req) -+{ -+ char *ptr = req->request.data; -+ -+ ptr += strlen("sysrq"); -+ while(isspace(*ptr)) ptr++; -+ -+ mconsole_reply(req, "", 0, 0); -+ handle_sysrq(*ptr, ¤t->thread.regs, NULL, NULL); -+} -+#else -+void mconsole_sysrq(struct mc_request *req) -+{ -+ mconsole_reply(req, "Sysrq not compiled in", 1, 0); -+} -+#endif -+ -+/* Changed by mconsole_setup, which is __setup, and called before SMP is -+ * active. -+ */ -+static char *notify_socket = NULL; -+ -+int mconsole_init(void) -+{ -+ int err, sock; -+ char file[256]; -+ -+ if(umid_file_name("mconsole", file, sizeof(file))) return(-1); -+ snprintf(mconsole_socket_name, sizeof(file), "%s", file); -+ -+ sock = os_create_unix_socket(file, sizeof(file), 1); -+ if (sock < 0){ -+ printk("Failed to initialize management console\n"); -+ return(1); -+ } -+ -+ register_reboot_notifier(&reboot_notifier); -+ -+ err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt, -+ SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, -+ "mconsole", (void *)sock); -+ if (err){ -+ printk("Failed to get IRQ for management console\n"); -+ return(1); -+ } -+ -+ if(notify_socket != NULL){ -+ notify_socket = uml_strdup(notify_socket); -+ if(notify_socket != NULL) -+ mconsole_notify(notify_socket, MCONSOLE_SOCKET, -+ mconsole_socket_name, -+ strlen(mconsole_socket_name) + 1); -+ else printk(KERN_ERR "mconsole_setup failed to strdup " -+ "string\n"); -+ } -+ -+ printk("mconsole (version %d) initialized on %s\n", -+ MCONSOLE_VERSION, mconsole_socket_name); -+ return(0); -+} -+ -+__initcall(mconsole_init); -+ -+static int write_proc_mconsole(struct file *file, const char *buffer, -+ unsigned long count, void *data) -+{ -+ char *buf; -+ -+ buf = kmalloc(count + 1, GFP_KERNEL); -+ if(buf == NULL) -+ return(-ENOMEM); -+ -+ if(copy_from_user(buf, buffer, count)){ -+ count = -EFAULT; -+ goto out; -+ } -+ -+ buf[count] = '\0'; -+ -+ mconsole_notify(notify_socket, MCONSOLE_USER_NOTIFY, buf, count); -+ out: -+ kfree(buf); -+ return(count); -+} -+ -+static int create_proc_mconsole(void) -+{ -+ struct proc_dir_entry *ent; -+ -+ if(notify_socket == NULL) return(0); -+ -+ ent = create_proc_entry("mconsole", S_IFREG | 0200, NULL); -+ if(ent == NULL){ -+ printk("create_proc_mconsole : create_proc_entry failed\n"); -+ return(0); -+ } -+ -+ ent->read_proc = NULL; -+ ent->write_proc = write_proc_mconsole; -+ return(0); -+} -+ -+static spinlock_t notify_spinlock = SPIN_LOCK_UNLOCKED; -+ -+void lock_notify(void) -+{ -+ spin_lock(¬ify_spinlock); -+} -+ -+void unlock_notify(void) -+{ -+ spin_unlock(¬ify_spinlock); -+} -+ -+__initcall(create_proc_mconsole); -+ -+#define NOTIFY "=notify:" -+ -+static int mconsole_setup(char *str) -+{ -+ if(!strncmp(str, NOTIFY, strlen(NOTIFY))){ -+ str += strlen(NOTIFY); -+ notify_socket = str; -+ } -+ else printk(KERN_ERR "mconsole_setup : Unknown option - '%s'\n", str); -+ return(1); -+} -+ -+__setup("mconsole", mconsole_setup); -+ -+__uml_help(mconsole_setup, -+"mconsole=notify:\n" -+" Requests that the mconsole driver send a message to the named Unix\n" -+" socket containing the name of the mconsole socket. This also serves\n" -+" to notify outside processes when UML has booted far enough to respond\n" -+" to mconsole requests.\n\n" -+); -+ -+static int notify_panic(struct notifier_block *self, unsigned long unused1, -+ void *ptr) -+{ -+ char *message = ptr; -+ -+ if(notify_socket == NULL) return(0); -+ -+ mconsole_notify(notify_socket, MCONSOLE_PANIC, message, -+ strlen(message) + 1); -+ return(0); -+} -+ -+static struct notifier_block panic_exit_notifier = { -+ .notifier_call = notify_panic, -+ .next = NULL, -+ .priority = 1 -+}; -+ -+static int add_notifier(void) -+{ -+ notifier_chain_register(&panic_notifier_list, &panic_exit_notifier); -+ return(0); -+} -+ -+__initcall(add_notifier); -+ -+char *mconsole_notify_socket(void) -+{ -+ return(notify_socket); -+} -+ -+EXPORT_SYMBOL(mconsole_notify_socket); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/mconsole_user.c um/arch/um/drivers/mconsole_user.c ---- orig/arch/um/drivers/mconsole_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/mconsole_user.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,215 @@ -+/* -+ * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) -+ * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com) -+ * Licensed under the GPL -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "user.h" -+#include "mconsole.h" -+#include "umid.h" -+ -+static struct mconsole_command commands[] = { -+ { "version", mconsole_version, MCONSOLE_INTR }, -+ { "halt", mconsole_halt, MCONSOLE_PROC }, -+ { "reboot", mconsole_reboot, MCONSOLE_PROC }, -+ { "config", mconsole_config, MCONSOLE_PROC }, -+ { "remove", mconsole_remove, MCONSOLE_PROC }, -+ { "sysrq", mconsole_sysrq, MCONSOLE_INTR }, -+ { "help", mconsole_help, MCONSOLE_INTR }, -+ { "cad", mconsole_cad, MCONSOLE_INTR }, -+ { "stop", mconsole_stop, MCONSOLE_PROC }, -+ { "go", mconsole_go, MCONSOLE_INTR }, -+ { "log", mconsole_log, MCONSOLE_INTR }, -+ { "proc", mconsole_proc, MCONSOLE_PROC }, -+}; -+ -+/* Initialized in mconsole_init, which is an initcall */ -+char mconsole_socket_name[256]; -+ -+int mconsole_reply_v0(struct mc_request *req, char *reply) -+{ -+ struct iovec iov; -+ struct msghdr msg; -+ -+ iov.iov_base = reply; -+ iov.iov_len = strlen(reply); -+ -+ msg.msg_name = &(req->origin); -+ msg.msg_namelen = req->originlen; -+ msg.msg_iov = &iov; -+ msg.msg_iovlen = 1; -+ msg.msg_control = NULL; -+ msg.msg_controllen = 0; -+ msg.msg_flags = 0; -+ -+ return sendmsg(req->originating_fd, &msg, 0); -+} -+ -+static struct mconsole_command *mconsole_parse(struct mc_request *req) -+{ -+ struct mconsole_command *cmd; -+ int i; -+ -+ for(i=0;irequest.data, cmd->command, -+ strlen(cmd->command))){ -+ return(cmd); -+ } -+ } -+ return(NULL); -+} -+ -+#define MIN(a,b) ((a)<(b) ? (a):(b)) -+ -+#define STRINGX(x) #x -+#define STRING(x) STRINGX(x) -+ -+int mconsole_get_request(int fd, struct mc_request *req) -+{ -+ int len; -+ -+ req->originlen = sizeof(req->origin); -+ req->len = recvfrom(fd, &req->request, sizeof(req->request), 0, -+ (struct sockaddr *) req->origin, &req->originlen); -+ if (req->len < 0) -+ return 0; -+ -+ req->originating_fd = fd; -+ -+ if(req->request.magic != MCONSOLE_MAGIC){ -+ /* Unversioned request */ -+ len = MIN(sizeof(req->request.data) - 1, -+ strlen((char *) &req->request)); -+ memmove(req->request.data, &req->request, len); -+ req->request.data[len] = '\0'; -+ -+ req->request.magic = MCONSOLE_MAGIC; -+ req->request.version = 0; -+ req->request.len = len; -+ -+ mconsole_reply_v0(req, "ERR Version 0 mconsole clients are " -+ "not supported by this driver"); -+ return(0); -+ } -+ -+ if(req->request.len >= MCONSOLE_MAX_DATA){ -+ mconsole_reply(req, "Request too large", 1, 0); -+ return(0); -+ } -+ if(req->request.version != MCONSOLE_VERSION){ -+ mconsole_reply(req, "This driver only supports version " -+ STRING(MCONSOLE_VERSION) " clients", 1, 0); -+ } -+ -+ req->request.data[req->request.len] = '\0'; -+ req->cmd = mconsole_parse(req); -+ if(req->cmd == NULL){ -+ mconsole_reply(req, "Unknown command", 1, 0); -+ return(0); -+ } -+ -+ return(1); -+} -+ -+int mconsole_reply(struct mc_request *req, char *str, int err, int more) -+{ -+ struct mconsole_reply reply; -+ int total, len, n; -+ -+ total = strlen(str); -+ do { -+ reply.err = err; -+ -+ /* err can only be true on the first packet */ -+ err = 0; -+ -+ len = MIN(total, MCONSOLE_MAX_DATA - 1); -+ -+ if(len == total) reply.more = more; -+ else reply.more = 1; -+ -+ memcpy(reply.data, str, len); -+ reply.data[len] = '\0'; -+ total -= len; -+ str += len; -+ reply.len = len + 1; -+ -+ len = sizeof(reply) + reply.len - sizeof(reply.data); -+ -+ n = sendto(req->originating_fd, &reply, len, 0, -+ (struct sockaddr *) req->origin, req->originlen); -+ -+ if(n < 0) return(-errno); -+ } while(total > 0); -+ return(0); -+} -+ -+int mconsole_unlink_socket(void) -+{ -+ unlink(mconsole_socket_name); -+ return 0; -+} -+ -+static int notify_sock = -1; -+ -+int mconsole_notify(char *sock_name, int type, const void *data, int len) -+{ -+ struct sockaddr_un target; -+ struct mconsole_notify packet; -+ int n, err = 0; -+ -+ lock_notify(); -+ if(notify_sock < 0){ -+ notify_sock = socket(PF_UNIX, SOCK_DGRAM, 0); -+ if(notify_sock < 0){ -+ printk("mconsole_notify - socket failed, errno = %d\n", -+ errno); -+ err = -errno; -+ } -+ } -+ unlock_notify(); -+ -+ if(err) -+ return(err); -+ -+ target.sun_family = AF_UNIX; -+ strcpy(target.sun_path, sock_name); -+ -+ packet.magic = MCONSOLE_MAGIC; -+ packet.version = MCONSOLE_VERSION; -+ packet.type = type; -+ len = (len > sizeof(packet.data)) ? sizeof(packet.data) : len; -+ packet.len = len; -+ memcpy(packet.data, data, len); -+ -+ err = 0; -+ len = sizeof(packet) + packet.len - sizeof(packet.data); -+ n = sendto(notify_sock, &packet, len, 0, (struct sockaddr *) &target, -+ sizeof(target)); -+ if(n < 0){ -+ printk("mconsole_notify - sendto failed, errno = %d\n", errno); -+ err = -errno; -+ } -+ return(err); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/mmapper_kern.c um/arch/um/drivers/mmapper_kern.c ---- orig/arch/um/drivers/mmapper_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/mmapper_kern.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,151 @@ -+/* -+ * arch/um/drivers/mmapper_kern.c -+ * -+ * BRIEF MODULE DESCRIPTION -+ * -+ * Copyright (C) 2000 RidgeRun, Inc. -+ * Author: RidgeRun, Inc. -+ * Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com -+ * -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "mem_user.h" -+#include "user_util.h" -+ -+/* These are set in mmapper_init, which is called at boot time */ -+static unsigned long mmapper_size; -+static unsigned long p_buf = 0; -+static char *v_buf = NULL; -+ -+static ssize_t -+mmapper_read(struct file *file, char *buf, size_t count, loff_t *ppos) -+{ -+ if(*ppos > mmapper_size) -+ return -EINVAL; -+ -+ if(count + *ppos > mmapper_size) -+ count = count + *ppos - mmapper_size; -+ -+ if(count < 0) -+ return -EINVAL; -+ -+ copy_to_user(buf,&v_buf[*ppos],count); -+ -+ return count; -+} -+ -+static ssize_t -+mmapper_write(struct file *file, const char *buf, size_t count, loff_t *ppos) -+{ -+ if(*ppos > mmapper_size) -+ return -EINVAL; -+ -+ if(count + *ppos > mmapper_size) -+ count = count + *ppos - mmapper_size; -+ -+ if(count < 0) -+ return -EINVAL; -+ -+ copy_from_user(&v_buf[*ppos],buf,count); -+ -+ return count; -+} -+ -+static int -+mmapper_ioctl(struct inode *inode, struct file *file, unsigned int cmd, -+ unsigned long arg) -+{ -+ return(-ENOIOCTLCMD); -+} -+ -+static int -+mmapper_mmap(struct file *file, struct vm_area_struct * vma) -+{ -+ int ret = -EINVAL; -+ int size; -+ -+ lock_kernel(); -+ if (vma->vm_pgoff != 0) -+ goto out; -+ -+ size = vma->vm_end - vma->vm_start; -+ if(size > mmapper_size) return(-EFAULT); -+ -+ /* XXX A comment above remap_page_range says it should only be -+ * called when the mm semaphore is held -+ */ -+ if (remap_page_range(vma->vm_start, p_buf, size, vma->vm_page_prot)) -+ goto out; -+ ret = 0; -+out: -+ unlock_kernel(); -+ return ret; -+} -+ -+static int -+mmapper_open(struct inode *inode, struct file *file) -+{ -+ return 0; -+} -+ -+static int -+mmapper_release(struct inode *inode, struct file *file) -+{ -+ return 0; -+} -+ -+static struct file_operations mmapper_fops = { -+ .owner = THIS_MODULE, -+ .read = mmapper_read, -+ .write = mmapper_write, -+ .ioctl = mmapper_ioctl, -+ .mmap = mmapper_mmap, -+ .open = mmapper_open, -+ .release = mmapper_release, -+}; -+ -+static int __init mmapper_init(void) -+{ -+ printk(KERN_INFO "Mapper v0.1\n"); -+ -+ v_buf = (char *) find_iomem("mmapper", &mmapper_size); -+ if(mmapper_size == 0){ -+ printk(KERN_ERR "mmapper_init - find_iomem failed\n"); -+ return(0); -+ } -+ -+ p_buf = __pa(v_buf); -+ -+ devfs_register (NULL, "mmapper", DEVFS_FL_DEFAULT, -+ 30, 0, S_IFCHR | S_IRUGO | S_IWUGO, -+ &mmapper_fops, NULL); -+ devfs_mk_symlink(NULL, "mmapper0", DEVFS_FL_DEFAULT, "mmapper", -+ NULL, NULL); -+ return(0); -+} -+ -+static void mmapper_exit(void) -+{ -+} -+ -+module_init(mmapper_init); -+module_exit(mmapper_exit); -+ -+MODULE_AUTHOR("Greg Lonnon "); -+MODULE_DESCRIPTION("DSPLinux simulator mmapper driver"); -+/* -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/net_kern.c um/arch/um/drivers/net_kern.c ---- orig/arch/um/drivers/net_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/net_kern.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,872 @@ -+/* -+ * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and -+ * James Leu (jleu@mindspring.net). -+ * Copyright (C) 2001 by various other people who didn't put their name here. -+ * Licensed under the GPL. -+ */ -+ -+#include "linux/config.h" -+#include "linux/kernel.h" -+#include "linux/netdevice.h" -+#include "linux/rtnetlink.h" -+#include "linux/skbuff.h" -+#include "linux/socket.h" -+#include "linux/spinlock.h" -+#include "linux/module.h" -+#include "linux/init.h" -+#include "linux/etherdevice.h" -+#include "linux/list.h" -+#include "linux/inetdevice.h" -+#include "linux/ctype.h" -+#include "linux/bootmem.h" -+#include "user_util.h" -+#include "kern_util.h" -+#include "net_kern.h" -+#include "net_user.h" -+#include "mconsole_kern.h" -+#include "init.h" -+#include "irq_user.h" -+#include "irq_kern.h" -+ -+static spinlock_t opened_lock = SPIN_LOCK_UNLOCKED; -+LIST_HEAD(opened); -+ -+static int uml_net_rx(struct net_device *dev) -+{ -+ struct uml_net_private *lp = dev->priv; -+ int pkt_len; -+ struct sk_buff *skb; -+ -+ /* If we can't allocate memory, try again next round. */ -+ skb = dev_alloc_skb(dev->mtu); -+ if (skb == NULL) { -+ lp->stats.rx_dropped++; -+ return 0; -+ } -+ -+ skb->dev = dev; -+ skb_put(skb, dev->mtu); -+ skb->mac.raw = skb->data; -+ pkt_len = (*lp->read)(lp->fd, &skb, lp); -+ -+ if (pkt_len > 0) { -+ skb_trim(skb, pkt_len); -+ skb->protocol = (*lp->protocol)(skb); -+ netif_rx(skb); -+ -+ lp->stats.rx_bytes += skb->len; -+ lp->stats.rx_packets++; -+ return pkt_len; -+ } -+ -+ kfree_skb(skb); -+ return pkt_len; -+} -+ -+void uml_net_interrupt(int irq, void *dev_id, struct pt_regs *regs) -+{ -+ struct net_device *dev = dev_id; -+ struct uml_net_private *lp = dev->priv; -+ int err; -+ -+ if(!netif_running(dev)) -+ return; -+ -+ spin_lock(&lp->lock); -+ while((err = uml_net_rx(dev)) > 0) ; -+ if(err < 0) { -+ printk(KERN_ERR -+ "Device '%s' read returned %d, shutting it down\n", -+ dev->name, err); -+ dev_close(dev); -+ goto out; -+ } -+ reactivate_fd(lp->fd, UM_ETH_IRQ); -+ -+ out: -+ spin_unlock(&lp->lock); -+} -+ -+static int uml_net_open(struct net_device *dev) -+{ -+ struct uml_net_private *lp = dev->priv; -+ char addr[sizeof("255.255.255.255\0")]; -+ int err; -+ -+ spin_lock(&lp->lock); -+ -+ if(lp->fd >= 0){ -+ err = -ENXIO; -+ goto out; -+ } -+ -+ if(!lp->have_mac){ -+ dev_ip_addr(dev, addr, &lp->mac[2]); -+ set_ether_mac(dev, lp->mac); -+ } -+ -+ lp->fd = (*lp->open)(&lp->user); -+ if(lp->fd < 0){ -+ err = lp->fd; -+ goto out; -+ } -+ -+ err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt, -+ SA_INTERRUPT | SA_SHIRQ, dev->name, dev); -+ if(err != 0){ -+ printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err); -+ if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user); -+ lp->fd = -1; -+ err = -ENETUNREACH; -+ } -+ -+ lp->tl.data = (unsigned long) &lp->user; -+ netif_start_queue(dev); -+ -+ spin_lock(&opened_lock); -+ list_add(&lp->list, &opened); -+ spin_unlock(&opened_lock); -+ MOD_INC_USE_COUNT; -+ out: -+ spin_unlock(&lp->lock); -+ return(err); -+} -+ -+static int uml_net_close(struct net_device *dev) -+{ -+ struct uml_net_private *lp = dev->priv; -+ -+ netif_stop_queue(dev); -+ spin_lock(&lp->lock); -+ -+ free_irq(dev->irq, dev); -+ if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user); -+ lp->fd = -1; -+ spin_lock(&opened_lock); -+ list_del(&lp->list); -+ spin_unlock(&opened_lock); -+ -+ MOD_DEC_USE_COUNT; -+ spin_unlock(&lp->lock); -+ return 0; -+} -+ -+static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev) -+{ -+ struct uml_net_private *lp = dev->priv; -+ unsigned long flags; -+ int len; -+ -+ netif_stop_queue(dev); -+ -+ spin_lock_irqsave(&lp->lock, flags); -+ -+ len = (*lp->write)(lp->fd, &skb, lp); -+ -+ if(len == skb->len) { -+ lp->stats.tx_packets++; -+ lp->stats.tx_bytes += skb->len; -+ dev->trans_start = jiffies; -+ netif_start_queue(dev); -+ -+ /* this is normally done in the interrupt when tx finishes */ -+ netif_wake_queue(dev); -+ } -+ else if(len == 0){ -+ netif_start_queue(dev); -+ lp->stats.tx_dropped++; -+ } -+ else { -+ netif_start_queue(dev); -+ printk(KERN_ERR "uml_net_start_xmit: failed(%d)\n", len); -+ } -+ -+ spin_unlock_irqrestore(&lp->lock, flags); -+ -+ dev_kfree_skb(skb); -+ -+ return 0; -+} -+ -+static struct net_device_stats *uml_net_get_stats(struct net_device *dev) -+{ -+ struct uml_net_private *lp = dev->priv; -+ return &lp->stats; -+} -+ -+static void uml_net_set_multicast_list(struct net_device *dev) -+{ -+ if (dev->flags & IFF_PROMISC) return; -+ else if (dev->mc_count) dev->flags |= IFF_ALLMULTI; -+ else dev->flags &= ~IFF_ALLMULTI; -+} -+ -+static void uml_net_tx_timeout(struct net_device *dev) -+{ -+ dev->trans_start = jiffies; -+ netif_wake_queue(dev); -+} -+ -+static int uml_net_set_mac(struct net_device *dev, void *addr) -+{ -+ struct uml_net_private *lp = dev->priv; -+ struct sockaddr *hwaddr = addr; -+ -+ spin_lock(&lp->lock); -+ memcpy(dev->dev_addr, hwaddr->sa_data, ETH_ALEN); -+ spin_unlock(&lp->lock); -+ -+ return(0); -+} -+ -+static int uml_net_change_mtu(struct net_device *dev, int new_mtu) -+{ -+ struct uml_net_private *lp = dev->priv; -+ int err = 0; -+ -+ spin_lock(&lp->lock); -+ -+ new_mtu = (*lp->set_mtu)(new_mtu, &lp->user); -+ if(new_mtu < 0){ -+ err = new_mtu; -+ goto out; -+ } -+ -+ dev->mtu = new_mtu; -+ -+ out: -+ spin_unlock(&lp->lock); -+ return err; -+} -+ -+static int uml_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) -+{ -+ return(-EINVAL); -+} -+ -+void uml_net_user_timer_expire(unsigned long _conn) -+{ -+#ifdef undef -+ struct connection *conn = (struct connection *)_conn; -+ -+ dprintk(KERN_INFO "uml_net_user_timer_expire [%p]\n", conn); -+ do_connect(conn); -+#endif -+} -+ -+/* -+ * default do nothing hard header packet routines for struct net_device init. -+ * real ethernet transports will overwrite with real routines. -+ */ -+static int uml_net_hard_header(struct sk_buff *skb, struct net_device *dev, -+ unsigned short type, void *daddr, void *saddr, unsigned len) -+{ -+ return(0); /* no change */ -+} -+ -+static int uml_net_rebuild_header(struct sk_buff *skb) -+{ -+ return(0); /* ignore */ -+} -+ -+static int uml_net_header_cache(struct neighbour *neigh, struct hh_cache *hh) -+{ -+ return(-1); /* fail */ -+} -+ -+static void uml_net_header_cache_update(struct hh_cache *hh, -+ struct net_device *dev, unsigned char * haddr) -+{ -+ /* ignore */ -+} -+ -+static int uml_net_header_parse(struct sk_buff *skb, unsigned char *haddr) -+{ -+ return(0); /* nothing */ -+} -+ -+static spinlock_t devices_lock = SPIN_LOCK_UNLOCKED; -+static struct list_head devices = LIST_HEAD_INIT(devices); -+ -+static int eth_configure(int n, void *init, char *mac, -+ struct transport *transport) -+{ -+ struct uml_net *device; -+ struct net_device *dev; -+ struct uml_net_private *lp; -+ int save, err, size; -+ -+ size = transport->private_size + sizeof(struct uml_net_private) + -+ sizeof(((struct uml_net_private *) 0)->user); -+ -+ device = kmalloc(sizeof(*device), GFP_KERNEL); -+ if(device == NULL){ -+ printk(KERN_ERR "eth_configure failed to allocate uml_net\n"); -+ return(1); -+ } -+ -+ *device = ((struct uml_net) { .list = LIST_HEAD_INIT(device->list), -+ .dev = NULL, -+ .index = n, -+ .mac = { [ 0 ... 5 ] = 0 }, -+ .have_mac = 0 }); -+ -+ spin_lock(&devices_lock); -+ list_add(&device->list, &devices); -+ spin_unlock(&devices_lock); -+ -+ if(setup_etheraddr(mac, device->mac)) -+ device->have_mac = 1; -+ -+ printk(KERN_INFO "Netdevice %d ", n); -+ if(device->have_mac) printk("(%02x:%02x:%02x:%02x:%02x:%02x) ", -+ device->mac[0], device->mac[1], -+ device->mac[2], device->mac[3], -+ device->mac[4], device->mac[5]); -+ printk(": "); -+ dev = kmalloc(sizeof(*dev) + size, GFP_KERNEL); -+ if(dev == NULL){ -+ printk(KERN_ERR "eth_configure: failed to allocate device\n"); -+ return(1); -+ } -+ memset(dev, 0, sizeof(*dev) + size); -+ -+ snprintf(dev->name, sizeof(dev->name), "eth%d", n); -+ dev->priv = (void *) &dev[1]; -+ device->dev = dev; -+ -+ dev->hard_header = uml_net_hard_header; -+ dev->rebuild_header = uml_net_rebuild_header; -+ dev->hard_header_cache = uml_net_header_cache; -+ dev->header_cache_update= uml_net_header_cache_update; -+ dev->hard_header_parse = uml_net_header_parse; -+ -+ (*transport->kern->init)(dev, init); -+ -+ dev->mtu = transport->user->max_packet; -+ dev->open = uml_net_open; -+ dev->hard_start_xmit = uml_net_start_xmit; -+ dev->stop = uml_net_close; -+ dev->get_stats = uml_net_get_stats; -+ dev->set_multicast_list = uml_net_set_multicast_list; -+ dev->tx_timeout = uml_net_tx_timeout; -+ dev->set_mac_address = uml_net_set_mac; -+ dev->change_mtu = uml_net_change_mtu; -+ dev->do_ioctl = uml_net_ioctl; -+ dev->watchdog_timeo = (HZ >> 1); -+ dev->irq = UM_ETH_IRQ; -+ -+ rtnl_lock(); -+ err = register_netdevice(dev); -+ rtnl_unlock(); -+ if(err) -+ return(1); -+ lp = dev->priv; -+ -+ /* lp.user is the first four bytes of the transport data, which -+ * has already been initialized. This structure assignment will -+ * overwrite that, so we make sure that .user gets overwritten with -+ * what it already has. -+ */ -+ save = lp->user[0]; -+ *lp = ((struct uml_net_private) -+ { .list = LIST_HEAD_INIT(lp->list), -+ .lock = SPIN_LOCK_UNLOCKED, -+ .dev = dev, -+ .fd = -1, -+ .mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0}, -+ .have_mac = device->have_mac, -+ .protocol = transport->kern->protocol, -+ .open = transport->user->open, -+ .close = transport->user->close, -+ .remove = transport->user->remove, -+ .read = transport->kern->read, -+ .write = transport->kern->write, -+ .add_address = transport->user->add_address, -+ .delete_address = transport->user->delete_address, -+ .set_mtu = transport->user->set_mtu, -+ .user = { save } }); -+ init_timer(&lp->tl); -+ lp->tl.function = uml_net_user_timer_expire; -+ memset(&lp->stats, 0, sizeof(lp->stats)); -+ if(lp->have_mac) memcpy(lp->mac, device->mac, sizeof(lp->mac)); -+ -+ if(transport->user->init) -+ (*transport->user->init)(&lp->user, dev); -+ -+ if(device->have_mac) -+ set_ether_mac(dev, device->mac); -+ return(0); -+} -+ -+static struct uml_net *find_device(int n) -+{ -+ struct uml_net *device; -+ struct list_head *ele; -+ -+ spin_lock(&devices_lock); -+ list_for_each(ele, &devices){ -+ device = list_entry(ele, struct uml_net, list); -+ if(device->index == n) -+ goto out; -+ } -+ device = NULL; -+ out: -+ spin_unlock(&devices_lock); -+ return(device); -+} -+ -+static int eth_parse(char *str, int *index_out, char **str_out) -+{ -+ char *end; -+ int n; -+ -+ n = simple_strtoul(str, &end, 0); -+ if(end == str){ -+ printk(KERN_ERR "eth_setup: Failed to parse '%s'\n", str); -+ return(1); -+ } -+ if(n < 0){ -+ printk(KERN_ERR "eth_setup: device %d is negative\n", n); -+ return(1); -+ } -+ str = end; -+ if(*str != '='){ -+ printk(KERN_ERR -+ "eth_setup: expected '=' after device number\n"); -+ return(1); -+ } -+ str++; -+ if(find_device(n)){ -+ printk(KERN_ERR "eth_setup: Device %d already configured\n", -+ n); -+ return(1); -+ } -+ if(index_out) *index_out = n; -+ *str_out = str; -+ return(0); -+} -+ -+struct eth_init { -+ struct list_head list; -+ char *init; -+ int index; -+}; -+ -+/* Filled in at boot time. Will need locking if the transports become -+ * modular. -+ */ -+struct list_head transports = LIST_HEAD_INIT(transports); -+ -+/* Filled in during early boot */ -+struct list_head eth_cmd_line = LIST_HEAD_INIT(eth_cmd_line); -+ -+static int check_transport(struct transport *transport, char *eth, int n, -+ void **init_out, char **mac_out) -+{ -+ int len; -+ -+ len = strlen(transport->name); -+ if(strncmp(eth, transport->name, len)) -+ return(0); -+ -+ eth += len; -+ if(*eth == ',') -+ eth++; -+ else if(*eth != '\0') -+ return(0); -+ -+ *init_out = kmalloc(transport->setup_size, GFP_KERNEL); -+ if(*init_out == NULL) -+ return(1); -+ -+ if(!transport->setup(eth, mac_out, *init_out)){ -+ kfree(*init_out); -+ *init_out = NULL; -+ } -+ return(1); -+} -+ -+void register_transport(struct transport *new) -+{ -+ struct list_head *ele, *next; -+ struct eth_init *eth; -+ void *init; -+ char *mac = NULL; -+ int match; -+ -+ list_add(&new->list, &transports); -+ -+ list_for_each_safe(ele, next, ð_cmd_line){ -+ eth = list_entry(ele, struct eth_init, list); -+ match = check_transport(new, eth->init, eth->index, &init, -+ &mac); -+ if(!match) -+ continue; -+ else if(init != NULL){ -+ eth_configure(eth->index, init, mac, new); -+ kfree(init); -+ } -+ list_del(ð->list); -+ } -+} -+ -+static int eth_setup_common(char *str, int index) -+{ -+ struct list_head *ele; -+ struct transport *transport; -+ void *init; -+ char *mac = NULL; -+ -+ list_for_each(ele, &transports){ -+ transport = list_entry(ele, struct transport, list); -+ if(!check_transport(transport, str, index, &init, &mac)) -+ continue; -+ if(init != NULL){ -+ eth_configure(index, init, mac, transport); -+ kfree(init); -+ } -+ return(1); -+ } -+ return(0); -+} -+ -+static int eth_setup(char *str) -+{ -+ struct eth_init *new; -+ int n, err; -+ -+ err = eth_parse(str, &n, &str); -+ if(err) return(1); -+ -+ new = alloc_bootmem(sizeof(new)); -+ if(new == NULL){ -+ printk("eth_init : alloc_bootmem failed\n"); -+ return(1); -+ } -+ *new = ((struct eth_init) { .list = LIST_HEAD_INIT(new->list), -+ .index = n, -+ .init = str }); -+ list_add_tail(&new->list, ð_cmd_line); -+ return(1); -+} -+ -+__setup("eth", eth_setup); -+__uml_help(eth_setup, -+"eth[0-9]+=,\n" -+" Configure a network device.\n\n" -+); -+ -+static int eth_init(void) -+{ -+ struct list_head *ele, *next; -+ struct eth_init *eth; -+ -+ list_for_each_safe(ele, next, ð_cmd_line){ -+ eth = list_entry(ele, struct eth_init, list); -+ -+ if(eth_setup_common(eth->init, eth->index)) -+ list_del(ð->list); -+ } -+ -+ return(1); -+} -+ -+__initcall(eth_init); -+ -+static int net_config(char *str) -+{ -+ int n, err; -+ -+ err = eth_parse(str, &n, &str); -+ if(err) return(err); -+ -+ str = uml_strdup(str); -+ if(str == NULL){ -+ printk(KERN_ERR "net_config failed to strdup string\n"); -+ return(-1); -+ } -+ err = !eth_setup_common(str, n); -+ if(err) -+ kfree(str); -+ return(err); -+} -+ -+static int net_remove(char *str) -+{ -+ struct uml_net *device; -+ struct net_device *dev; -+ struct uml_net_private *lp; -+ char *end; -+ int n; -+ -+ n = simple_strtoul(str, &end, 0); -+ if((*end != '\0') || (end == str)) -+ return(-1); -+ -+ device = find_device(n); -+ if(device == NULL) -+ return(0); -+ -+ dev = device->dev; -+ lp = dev->priv; -+ if(lp->fd > 0) return(-1); -+ if(lp->remove != NULL) (*lp->remove)(&lp->user); -+ unregister_netdev(dev); -+ -+ list_del(&device->list); -+ kfree(device); -+ return(0); -+} -+ -+static struct mc_device net_mc = { -+ .name = "eth", -+ .config = net_config, -+ .get_config = NULL, -+ .remove = net_remove, -+}; -+ -+static int uml_inetaddr_event(struct notifier_block *this, unsigned long event, -+ void *ptr) -+{ -+ struct in_ifaddr *ifa = ptr; -+ u32 addr = ifa->ifa_address; -+ u32 netmask = ifa->ifa_mask; -+ struct net_device *dev = ifa->ifa_dev->dev; -+ struct uml_net_private *lp; -+ void (*proc)(unsigned char *, unsigned char *, void *); -+ unsigned char addr_buf[4], netmask_buf[4]; -+ -+ if(dev->open != uml_net_open) return(NOTIFY_DONE); -+ -+ lp = dev->priv; -+ -+ proc = NULL; -+ switch (event){ -+ case NETDEV_UP: -+ proc = lp->add_address; -+ break; -+ case NETDEV_DOWN: -+ proc = lp->delete_address; -+ break; -+ } -+ if(proc != NULL){ -+ addr_buf[0] = addr & 0xff; -+ addr_buf[1] = (addr >> 8) & 0xff; -+ addr_buf[2] = (addr >> 16) & 0xff; -+ addr_buf[3] = addr >> 24; -+ netmask_buf[0] = netmask & 0xff; -+ netmask_buf[1] = (netmask >> 8) & 0xff; -+ netmask_buf[2] = (netmask >> 16) & 0xff; -+ netmask_buf[3] = netmask >> 24; -+ (*proc)(addr_buf, netmask_buf, &lp->user); -+ } -+ return(NOTIFY_DONE); -+} -+ -+struct notifier_block uml_inetaddr_notifier = { -+ .notifier_call = uml_inetaddr_event, -+}; -+ -+static int uml_net_init(void) -+{ -+ struct list_head *ele; -+ struct uml_net_private *lp; -+ struct in_device *ip; -+ struct in_ifaddr *in; -+ -+ mconsole_register_dev(&net_mc); -+ register_inetaddr_notifier(¨_inetaddr_notifier); -+ -+ /* Devices may have been opened already, so the uml_inetaddr_notifier -+ * didn't get a chance to run for them. This fakes it so that -+ * addresses which have already been set up get handled properly. -+ */ -+ list_for_each(ele, &opened){ -+ lp = list_entry(ele, struct uml_net_private, list); -+ ip = lp->dev->ip_ptr; -+ if(ip == NULL) continue; -+ in = ip->ifa_list; -+ while(in != NULL){ -+ uml_inetaddr_event(NULL, NETDEV_UP, in); -+ in = in->ifa_next; -+ } -+ } -+ -+ return(0); -+} -+ -+__initcall(uml_net_init); -+ -+static void close_devices(void) -+{ -+ struct list_head *ele; -+ struct uml_net_private *lp; -+ -+ list_for_each(ele, &opened){ -+ lp = list_entry(ele, struct uml_net_private, list); -+ if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user); -+ if(lp->remove != NULL) (*lp->remove)(&lp->user); -+ } -+} -+ -+__uml_exitcall(close_devices); -+ -+int setup_etheraddr(char *str, unsigned char *addr) -+{ -+ char *end; -+ int i; -+ -+ if(str == NULL) -+ return(0); -+ for(i=0;i<6;i++){ -+ addr[i] = simple_strtoul(str, &end, 16); -+ if((end == str) || -+ ((*end != ':') && (*end != ',') && (*end != '\0'))){ -+ printk(KERN_ERR -+ "setup_etheraddr: failed to parse '%s' " -+ "as an ethernet address\n", str); -+ return(0); -+ } -+ str = end + 1; -+ } -+ if(addr[0] & 1){ -+ printk(KERN_ERR -+ "Attempt to assign a broadcast ethernet address to a " -+ "device disallowed\n"); -+ return(0); -+ } -+ return(1); -+} -+ -+void dev_ip_addr(void *d, char *buf, char *bin_buf) -+{ -+ struct net_device *dev = d; -+ struct in_device *ip = dev->ip_ptr; -+ struct in_ifaddr *in; -+ u32 addr; -+ -+ if((ip == NULL) || ((in = ip->ifa_list) == NULL)){ -+ printk(KERN_WARNING "dev_ip_addr - device not assigned an " -+ "IP address\n"); -+ return; -+ } -+ addr = in->ifa_address; -+ sprintf(buf, "%d.%d.%d.%d", addr & 0xff, (addr >> 8) & 0xff, -+ (addr >> 16) & 0xff, addr >> 24); -+ if(bin_buf){ -+ bin_buf[0] = addr & 0xff; -+ bin_buf[1] = (addr >> 8) & 0xff; -+ bin_buf[2] = (addr >> 16) & 0xff; -+ bin_buf[3] = addr >> 24; -+ } -+} -+ -+void set_ether_mac(void *d, unsigned char *addr) -+{ -+ struct net_device *dev = d; -+ -+ memcpy(dev->dev_addr, addr, ETH_ALEN); -+} -+ -+struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra) -+{ -+ if((skb != NULL) && (skb_tailroom(skb) < extra)){ -+ struct sk_buff *skb2; -+ -+ skb2 = skb_copy_expand(skb, 0, extra, GFP_ATOMIC); -+ dev_kfree_skb(skb); -+ skb = skb2; -+ } -+ if(skb != NULL) skb_put(skb, extra); -+ return(skb); -+} -+ -+void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *, -+ void *), -+ void *arg) -+{ -+ struct net_device *dev = d; -+ struct in_device *ip = dev->ip_ptr; -+ struct in_ifaddr *in; -+ unsigned char address[4], netmask[4]; -+ -+ if(ip == NULL) return; -+ in = ip->ifa_list; -+ while(in != NULL){ -+ address[0] = in->ifa_address & 0xff; -+ address[1] = (in->ifa_address >> 8) & 0xff; -+ address[2] = (in->ifa_address >> 16) & 0xff; -+ address[3] = in->ifa_address >> 24; -+ netmask[0] = in->ifa_mask & 0xff; -+ netmask[1] = (in->ifa_mask >> 8) & 0xff; -+ netmask[2] = (in->ifa_mask >> 16) & 0xff; -+ netmask[3] = in->ifa_mask >> 24; -+ (*cb)(address, netmask, arg); -+ in = in->ifa_next; -+ } -+} -+ -+int dev_netmask(void *d, void *m) -+{ -+ struct net_device *dev = d; -+ struct in_device *ip = dev->ip_ptr; -+ struct in_ifaddr *in; -+ __u32 *mask_out = m; -+ -+ if(ip == NULL) -+ return(1); -+ -+ in = ip->ifa_list; -+ if(in == NULL) -+ return(1); -+ -+ *mask_out = in->ifa_mask; -+ return(0); -+} -+ -+void *get_output_buffer(int *len_out) -+{ -+ void *ret; -+ -+ ret = (void *) __get_free_pages(GFP_KERNEL, 0); -+ if(ret) *len_out = PAGE_SIZE; -+ else *len_out = 0; -+ return(ret); -+} -+ -+void free_output_buffer(void *buffer) -+{ -+ free_pages((unsigned long) buffer, 0); -+} -+ -+int tap_setup_common(char *str, char *type, char **dev_name, char **mac_out, -+ char **gate_addr) -+{ -+ char *remain; -+ -+ remain = split_if_spec(str, dev_name, mac_out, gate_addr, NULL); -+ if(remain != NULL){ -+ printk("tap_setup_common - Extra garbage on specification : " -+ "'%s'\n", remain); -+ return(1); -+ } -+ -+ return(0); -+} -+ -+unsigned short eth_protocol(struct sk_buff *skb) -+{ -+ return(eth_type_trans(skb, skb->dev)); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/net_user.c um/arch/um/drivers/net_user.c ---- orig/arch/um/drivers/net_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/net_user.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,252 @@ -+/* -+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "user.h" -+#include "user_util.h" -+#include "kern_util.h" -+#include "net_user.h" -+#include "helper.h" -+#include "os.h" -+ -+int tap_open_common(void *dev, char *gate_addr) -+{ -+ int tap_addr[4]; -+ -+ if(gate_addr == NULL) return(0); -+ if(sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0], -+ &tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4){ -+ printk("Invalid tap IP address - '%s'\n", gate_addr); -+ return(-EINVAL); -+ } -+ return(0); -+} -+ -+void tap_check_ips(char *gate_addr, char *eth_addr) -+{ -+ int tap_addr[4]; -+ -+ if((gate_addr != NULL) && -+ (sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0], -+ &tap_addr[1], &tap_addr[2], &tap_addr[3]) == 4) && -+ (eth_addr[0] == tap_addr[0]) && -+ (eth_addr[1] == tap_addr[1]) && -+ (eth_addr[2] == tap_addr[2]) && -+ (eth_addr[3] == tap_addr[3])){ -+ printk("The tap IP address and the UML eth IP address" -+ " must be different\n"); -+ } -+} -+ -+void read_output(int fd, char *output, int len) -+{ -+ int remain, n, actual; -+ char c; -+ -+ if(output == NULL){ -+ output = &c; -+ len = sizeof(c); -+ } -+ -+ *output = '\0'; -+ n = os_read_file(fd, &remain, sizeof(remain)); -+ if(n != sizeof(remain)){ -+ printk("read_output - read of length failed, err = %d\n", -n); -+ return; -+ } -+ -+ while(remain != 0){ -+ n = (remain < len) ? remain : len; -+ actual = os_read_file(fd, output, n); -+ if(actual != n){ -+ printk("read_output - read of data failed, " -+ "err = %d\n", -actual); -+ return; -+ } -+ remain -= actual; -+ } -+ return; -+} -+ -+int net_read(int fd, void *buf, int len) -+{ -+ int n; -+ -+ n = os_read_file(fd, buf, len); -+ -+ if(n == -EAGAIN) -+ return(0); -+ else if(n == 0) -+ return(-ENOTCONN); -+ return(n); -+} -+ -+int net_recvfrom(int fd, void *buf, int len) -+{ -+ int n; -+ -+ while(((n = recvfrom(fd, buf, len, 0, NULL, NULL)) < 0) && -+ (errno == EINTR)) ; -+ -+ if(n < 0){ -+ if(errno == EAGAIN) return(0); -+ return(-errno); -+ } -+ else if(n == 0) return(-ENOTCONN); -+ return(n); -+} -+ -+int net_write(int fd, void *buf, int len) -+{ -+ int n; -+ -+ n = os_write_file(fd, buf, len); -+ -+ if(n == -EAGAIN) -+ return(0); -+ else if(n == 0) -+ return(-ENOTCONN); -+ return(n); -+} -+ -+int net_send(int fd, void *buf, int len) -+{ -+ int n; -+ -+ while(((n = send(fd, buf, len, 0)) < 0) && (errno == EINTR)) ; -+ if(n < 0){ -+ if(errno == EAGAIN) return(0); -+ return(-errno); -+ } -+ else if(n == 0) return(-ENOTCONN); -+ return(n); -+} -+ -+int net_sendto(int fd, void *buf, int len, void *to, int sock_len) -+{ -+ int n; -+ -+ while(((n = sendto(fd, buf, len, 0, (struct sockaddr *) to, -+ sock_len)) < 0) && (errno == EINTR)) ; -+ if(n < 0){ -+ if(errno == EAGAIN) return(0); -+ return(-errno); -+ } -+ else if(n == 0) return(-ENOTCONN); -+ return(n); -+} -+ -+struct change_pre_exec_data { -+ int close_me; -+ int stdout; -+}; -+ -+static void change_pre_exec(void *arg) -+{ -+ struct change_pre_exec_data *data = arg; -+ -+ os_close_file(data->close_me); -+ dup2(data->stdout, 1); -+} -+ -+static int change_tramp(char **argv, char *output, int output_len) -+{ -+ int pid, fds[2], err; -+ struct change_pre_exec_data pe_data; -+ -+ err = os_pipe(fds, 1, 0); -+ if(err < 0){ -+ printk("change_tramp - pipe failed, err = %d\n", -err); -+ return(err); -+ } -+ pe_data.close_me = fds[0]; -+ pe_data.stdout = fds[1]; -+ pid = run_helper(change_pre_exec, &pe_data, argv, NULL); -+ -+ os_close_file(fds[1]); -+ read_output(fds[0], output, output_len); -+ waitpid(pid, NULL, 0); -+ return(pid); -+} -+ -+static void change(char *dev, char *what, unsigned char *addr, -+ unsigned char *netmask) -+{ -+ char addr_buf[sizeof("255.255.255.255\0")]; -+ char netmask_buf[sizeof("255.255.255.255\0")]; -+ char version[sizeof("nnnnn\0")]; -+ char *argv[] = { "uml_net", version, what, dev, addr_buf, -+ netmask_buf, NULL }; -+ char *output; -+ int output_len, pid; -+ -+ sprintf(version, "%d", UML_NET_VERSION); -+ sprintf(addr_buf, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]); -+ sprintf(netmask_buf, "%d.%d.%d.%d", netmask[0], netmask[1], -+ netmask[2], netmask[3]); -+ -+ output_len = page_size(); -+ output = um_kmalloc(output_len); -+ if(output == NULL) -+ printk("change : failed to allocate output buffer\n"); -+ -+ pid = change_tramp(argv, output, output_len); -+ if(pid < 0) return; -+ -+ if(output != NULL){ -+ printk("%s", output); -+ kfree(output); -+ } -+} -+ -+void open_addr(unsigned char *addr, unsigned char *netmask, void *arg) -+{ -+ change(arg, "add", addr, netmask); -+} -+ -+void close_addr(unsigned char *addr, unsigned char *netmask, void *arg) -+{ -+ change(arg, "del", addr, netmask); -+} -+ -+char *split_if_spec(char *str, ...) -+{ -+ char **arg, *end; -+ va_list ap; -+ -+ va_start(ap, str); -+ while((arg = va_arg(ap, char **)) != NULL){ -+ if(*str == '\0') -+ return(NULL); -+ end = strchr(str, ','); -+ if(end != str) -+ *arg = str; -+ if(end == NULL) -+ return(NULL); -+ *end++ = '\0'; -+ str = end; -+ } -+ va_end(ap); -+ return(str); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/null.c um/arch/um/drivers/null.c ---- orig/arch/um/drivers/null.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/null.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,55 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include -+#include -+#include "chan_user.h" -+#include "os.h" -+ -+static int null_chan; -+ -+void *null_init(char *str, int device, struct chan_opts *opts) -+{ -+ return(&null_chan); -+} -+ -+int null_open(int input, int output, int primary, void *d, char **dev_out) -+{ -+ *dev_out = NULL; -+ return(os_open_file(DEV_NULL, of_rdwr(OPENFLAGS()), 0)); -+} -+ -+int null_read(int fd, char *c_out, void *unused) -+{ -+ return(-ENODEV); -+} -+ -+void null_free(void *data) -+{ -+} -+ -+struct chan_ops null_ops = { -+ .type = "null", -+ .init = null_init, -+ .open = null_open, -+ .close = generic_close, -+ .read = null_read, -+ .write = generic_write, -+ .console_write = generic_console_write, -+ .window_size = generic_window_size, -+ .free = null_free, -+ .winch = 0, -+}; -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/pcap_kern.c um/arch/um/drivers/pcap_kern.c ---- orig/arch/um/drivers/pcap_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/pcap_kern.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,127 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike -+ * Licensed under the GPL. -+ */ -+ -+#include "linux/init.h" -+#include "linux/netdevice.h" -+#include "linux/etherdevice.h" -+#include "net_kern.h" -+#include "net_user.h" -+#include "pcap_user.h" -+ -+struct pcap_init { -+ char *host_if; -+ int promisc; -+ int optimize; -+ char *filter; -+}; -+ -+void pcap_init(struct net_device *dev, void *data) -+{ -+ struct uml_net_private *pri; -+ struct pcap_data *ppri; -+ struct pcap_init *init = data; -+ -+ init_etherdev(dev, 0); -+ pri = dev->priv; -+ ppri = (struct pcap_data *) pri->user; -+ *ppri = ((struct pcap_data) -+ { .host_if = init->host_if, -+ .promisc = init->promisc, -+ .optimize = init->optimize, -+ .filter = init->filter, -+ .compiled = NULL, -+ .pcap = NULL }); -+} -+ -+static int pcap_read(int fd, struct sk_buff **skb, -+ struct uml_net_private *lp) -+{ -+ *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); -+ if(*skb == NULL) return(-ENOMEM); -+ return(pcap_user_read(fd, (*skb)->mac.raw, -+ (*skb)->dev->mtu + ETH_HEADER_OTHER, -+ (struct pcap_data *) &lp->user)); -+} -+ -+static int pcap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp) -+{ -+ return(-EPERM); -+} -+ -+static struct net_kern_info pcap_kern_info = { -+ .init = pcap_init, -+ .protocol = eth_protocol, -+ .read = pcap_read, -+ .write = pcap_write, -+}; -+ -+int pcap_setup(char *str, char **mac_out, void *data) -+{ -+ struct pcap_init *init = data; -+ char *remain, *host_if = NULL, *options[2] = { NULL, NULL }; -+ int i; -+ -+ *init = ((struct pcap_init) -+ { .host_if = "eth0", -+ .promisc = 1, -+ .optimize = 0, -+ .filter = NULL }); -+ -+ remain = split_if_spec(str, &host_if, &init->filter, -+ &options[0], &options[1], NULL); -+ if(remain != NULL){ -+ printk(KERN_ERR "pcap_setup - Extra garbage on " -+ "specification : '%s'\n", remain); -+ return(0); -+ } -+ -+ if(host_if != NULL) -+ init->host_if = host_if; -+ -+ for(i = 0; i < sizeof(options)/sizeof(options[0]); i++){ -+ if(options[i] == NULL) -+ continue; -+ if(!strcmp(options[i], "promisc")) -+ init->promisc = 1; -+ else if(!strcmp(options[i], "nopromisc")) -+ init->promisc = 0; -+ else if(!strcmp(options[i], "optimize")) -+ init->optimize = 1; -+ else if(!strcmp(options[i], "nooptimize")) -+ init->optimize = 0; -+ else printk("pcap_setup : bad option - '%s'\n", options[i]); -+ } -+ -+ return(1); -+} -+ -+static struct transport pcap_transport = { -+ .list = LIST_HEAD_INIT(pcap_transport.list), -+ .name = "pcap", -+ .setup = pcap_setup, -+ .user = &pcap_user_info, -+ .kern = &pcap_kern_info, -+ .private_size = sizeof(struct pcap_data), -+ .setup_size = sizeof(struct pcap_init), -+}; -+ -+static int register_pcap(void) -+{ -+ register_transport(&pcap_transport); -+ return(1); -+} -+ -+__initcall(register_pcap); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/pcap_user.c um/arch/um/drivers/pcap_user.c ---- orig/arch/um/drivers/pcap_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/pcap_user.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,143 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike -+ * Licensed under the GPL. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "net_user.h" -+#include "pcap_user.h" -+#include "user.h" -+ -+#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) -+ -+#define PCAP_FD(p) (*(int *)(p)) -+ -+static void pcap_user_init(void *data, void *dev) -+{ -+ struct pcap_data *pri = data; -+ pcap_t *p; -+ char errors[PCAP_ERRBUF_SIZE]; -+ -+ p = pcap_open_live(pri->host_if, MAX_PACKET, pri->promisc, 0, errors); -+ if(p == NULL){ -+ printk("pcap_user_init : pcap_open_live failed - '%s'\n", -+ errors); -+ return; -+ } -+ -+ pri->dev = dev; -+ pri->pcap = p; -+} -+ -+static int pcap_open(void *data) -+{ -+ struct pcap_data *pri = data; -+ __u32 netmask; -+ int err; -+ -+ if(pri->pcap == NULL) -+ return(-ENODEV); -+ -+ if(pri->filter != NULL){ -+ err = dev_netmask(pri->dev, &netmask); -+ if(err < 0){ -+ printk("pcap_open : dev_netmask failed\n"); -+ return(-EIO); -+ } -+ -+ pri->compiled = um_kmalloc(sizeof(struct bpf_program)); -+ if(pri->compiled == NULL){ -+ printk("pcap_open : kmalloc failed\n"); -+ return(-ENOMEM); -+ } -+ -+ err = pcap_compile(pri->pcap, -+ (struct bpf_program *) pri->compiled, -+ pri->filter, pri->optimize, netmask); -+ if(err < 0){ -+ printk("pcap_open : pcap_compile failed - '%s'\n", -+ pcap_geterr(pri->pcap)); -+ return(-EIO); -+ } -+ -+ err = pcap_setfilter(pri->pcap, pri->compiled); -+ if(err < 0){ -+ printk("pcap_open : pcap_setfilter failed - '%s'\n", -+ pcap_geterr(pri->pcap)); -+ return(-EIO); -+ } -+ } -+ -+ return(PCAP_FD(pri->pcap)); -+} -+ -+static void pcap_remove(void *data) -+{ -+ struct pcap_data *pri = data; -+ -+ if(pri->compiled != NULL) -+ pcap_freecode(pri->compiled); -+ -+ pcap_close(pri->pcap); -+} -+ -+struct pcap_handler_data { -+ char *buffer; -+ int len; -+}; -+ -+static void handler(u_char *data, const struct pcap_pkthdr *header, -+ const u_char *packet) -+{ -+ int len; -+ -+ struct pcap_handler_data *hdata = (struct pcap_handler_data *) data; -+ -+ len = hdata->len < header->caplen ? hdata->len : header->caplen; -+ memcpy(hdata->buffer, packet, len); -+ hdata->len = len; -+} -+ -+int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri) -+{ -+ struct pcap_handler_data hdata = ((struct pcap_handler_data) -+ { .buffer = buffer, -+ .len = len }); -+ int n; -+ -+ n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata); -+ if(n < 0){ -+ printk("pcap_dispatch failed - %s\n", pcap_geterr(pri->pcap)); -+ return(-EIO); -+ } -+ else if(n == 0) -+ return(0); -+ return(hdata.len); -+} -+ -+struct net_user_info pcap_user_info = { -+ .init = pcap_user_init, -+ .open = pcap_open, -+ .close = NULL, -+ .remove = pcap_remove, -+ .set_mtu = NULL, -+ .add_address = NULL, -+ .delete_address = NULL, -+ .max_packet = MAX_PACKET - ETH_HEADER_OTHER -+}; -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/pcap_user.h um/arch/um/drivers/pcap_user.h ---- orig/arch/um/drivers/pcap_user.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/pcap_user.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,31 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "net_user.h" -+ -+struct pcap_data { -+ char *host_if; -+ int promisc; -+ int optimize; -+ char *filter; -+ void *compiled; -+ void *pcap; -+ void *dev; -+}; -+ -+extern struct net_user_info pcap_user_info; -+ -+extern int pcap_user_read(int fd, void *buf, int len, struct pcap_data *pri); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/port.h um/arch/um/drivers/port.h ---- orig/arch/um/drivers/port.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/port.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,30 @@ -+/* -+ * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __PORT_H__ -+#define __PORT_H__ -+ -+extern void *port_data(int port); -+extern int port_wait(void *data); -+extern void port_kern_close(void *d); -+extern int port_connection(int fd, int *socket_out, int *pid_out); -+extern int port_listen_fd(int port); -+extern void port_read(int fd, void *data); -+extern void port_kern_free(void *d); -+extern int port_rcv_fd(int fd); -+extern void port_remove_dev(void *d); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/port_kern.c um/arch/um/drivers/port_kern.c ---- orig/arch/um/drivers/port_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/port_kern.c 2004-01-10 06:18:49.000000000 -0500 -@@ -0,0 +1,303 @@ -+/* -+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/list.h" -+#include "linux/sched.h" -+#include "linux/slab.h" -+#include "linux/irq.h" -+#include "linux/spinlock.h" -+#include "linux/errno.h" -+#include "asm/semaphore.h" -+#include "asm/errno.h" -+#include "kern_util.h" -+#include "kern.h" -+#include "irq_user.h" -+#include "irq_kern.h" -+#include "port.h" -+#include "init.h" -+#include "os.h" -+ -+struct port_list { -+ struct list_head list; -+ int has_connection; -+ struct semaphore sem; -+ int port; -+ int fd; -+ spinlock_t lock; -+ struct list_head pending; -+ struct list_head connections; -+}; -+ -+struct port_dev { -+ struct port_list *port; -+ int helper_pid; -+ int telnetd_pid; -+}; -+ -+struct connection { -+ struct list_head list; -+ int fd; -+ int helper_pid; -+ int socket[2]; -+ int telnetd_pid; -+ struct port_list *port; -+}; -+ -+static void pipe_interrupt(int irq, void *data, struct pt_regs *regs) -+{ -+ struct connection *conn = data; -+ int fd; -+ -+ fd = os_rcv_fd(conn->socket[0], &conn->helper_pid); -+ if(fd < 0){ -+ if(fd == -EAGAIN) -+ return; -+ -+ printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n", -+ -fd); -+ os_close_file(conn->fd); -+ } -+ -+ list_del(&conn->list); -+ -+ conn->fd = fd; -+ list_add(&conn->list, &conn->port->connections); -+ -+ up(&conn->port->sem); -+} -+ -+static int port_accept(struct port_list *port) -+{ -+ struct connection *conn; -+ int fd, socket[2], pid, ret = 0; -+ -+ fd = port_connection(port->fd, socket, &pid); -+ if(fd < 0){ -+ if(fd != -EAGAIN) -+ printk(KERN_ERR "port_accept : port_connection " -+ "returned %d\n", -fd); -+ goto out; -+ } -+ -+ conn = kmalloc(sizeof(*conn), GFP_ATOMIC); -+ if(conn == NULL){ -+ printk(KERN_ERR "port_accept : failed to allocate " -+ "connection\n"); -+ goto out_close; -+ } -+ *conn = ((struct connection) -+ { .list = LIST_HEAD_INIT(conn->list), -+ .fd = fd, -+ .socket = { socket[0], socket[1] }, -+ .telnetd_pid = pid, -+ .port = port }); -+ -+ if(um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, -+ SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, -+ "telnetd", conn)){ -+ printk(KERN_ERR "port_accept : failed to get IRQ for " -+ "telnetd\n"); -+ goto out_free; -+ } -+ -+ list_add(&conn->list, &port->pending); -+ return(1); -+ -+ out_free: -+ kfree(conn); -+ out_close: -+ os_close_file(fd); -+ if(pid != -1) -+ os_kill_process(pid, 1); -+ out: -+ return(ret); -+} -+ -+DECLARE_MUTEX(ports_sem); -+struct list_head ports = LIST_HEAD_INIT(ports); -+ -+void port_task_proc(void *unused) -+{ -+ struct port_list *port; -+ struct list_head *ele; -+ unsigned long flags; -+ -+ save_flags(flags); -+ list_for_each(ele, &ports){ -+ port = list_entry(ele, struct port_list, list); -+ if(!port->has_connection) -+ continue; -+ reactivate_fd(port->fd, ACCEPT_IRQ); -+ while(port_accept(port)) ; -+ port->has_connection = 0; -+ } -+ restore_flags(flags); -+} -+ -+struct tq_struct port_task = { -+ .routine = port_task_proc, -+ .data = NULL -+}; -+ -+static void port_interrupt(int irq, void *data, struct pt_regs *regs) -+{ -+ struct port_list *port = data; -+ -+ port->has_connection = 1; -+ schedule_task(&port_task); -+} -+ -+void *port_data(int port_num) -+{ -+ struct list_head *ele; -+ struct port_list *port; -+ struct port_dev *dev = NULL; -+ int fd; -+ -+ down(&ports_sem); -+ list_for_each(ele, &ports){ -+ port = list_entry(ele, struct port_list, list); -+ if(port->port == port_num) goto found; -+ } -+ port = kmalloc(sizeof(struct port_list), GFP_KERNEL); -+ if(port == NULL){ -+ printk(KERN_ERR "Allocation of port list failed\n"); -+ goto out; -+ } -+ -+ fd = port_listen_fd(port_num); -+ if(fd < 0){ -+ printk(KERN_ERR "binding to port %d failed, errno = %d\n", -+ port_num, -fd); -+ goto out_free; -+ } -+ if(um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt, -+ SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, "port", -+ port)){ -+ printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num); -+ goto out_close; -+ } -+ -+ *port = ((struct port_list) -+ { .list = LIST_HEAD_INIT(port->list), -+ .has_connection = 0, -+ .sem = __SEMAPHORE_INITIALIZER(port->sem, -+ 0), -+ .lock = SPIN_LOCK_UNLOCKED, -+ .port = port_num, -+ .fd = fd, -+ .pending = LIST_HEAD_INIT(port->pending), -+ .connections = LIST_HEAD_INIT(port->connections) }); -+ list_add(&port->list, &ports); -+ -+ found: -+ dev = kmalloc(sizeof(struct port_dev), GFP_KERNEL); -+ if(dev == NULL){ -+ printk(KERN_ERR "Allocation of port device entry failed\n"); -+ goto out; -+ } -+ -+ *dev = ((struct port_dev) { .port = port, -+ .helper_pid = -1, -+ .telnetd_pid = -1 }); -+ goto out; -+ -+ out_free: -+ kfree(port); -+ out_close: -+ os_close_file(fd); -+ out: -+ up(&ports_sem); -+ return(dev); -+} -+ -+int port_wait(void *data) -+{ -+ struct port_dev *dev = data; -+ struct connection *conn; -+ struct port_list *port = dev->port; -+ int fd; -+ -+ while(1){ -+ if(down_interruptible(&port->sem)) -+ return(-ERESTARTSYS); -+ -+ spin_lock(&port->lock); -+ -+ conn = list_entry(port->connections.next, struct connection, -+ list); -+ list_del(&conn->list); -+ spin_unlock(&port->lock); -+ -+ os_shutdown_socket(conn->socket[0], 1, 1); -+ os_close_file(conn->socket[0]); -+ os_shutdown_socket(conn->socket[1], 1, 1); -+ os_close_file(conn->socket[1]); -+ -+ /* This is done here because freeing an IRQ can't be done -+ * within the IRQ handler. So, pipe_interrupt always ups -+ * the semaphore regardless of whether it got a successful -+ * connection. Then we loop here throwing out failed -+ * connections until a good one is found. -+ */ -+ free_irq(TELNETD_IRQ, conn); -+ -+ if(conn->fd >= 0) break; -+ os_close_file(conn->fd); -+ kfree(conn); -+ } -+ -+ fd = conn->fd; -+ dev->helper_pid = conn->helper_pid; -+ dev->telnetd_pid = conn->telnetd_pid; -+ kfree(conn); -+ -+ return(fd); -+} -+ -+void port_remove_dev(void *d) -+{ -+ struct port_dev *dev = d; -+ -+ if(dev->helper_pid != -1) -+ os_kill_process(dev->helper_pid, 0); -+ if(dev->telnetd_pid != -1) -+ os_kill_process(dev->telnetd_pid, 1); -+ dev->helper_pid = -1; -+ dev->telnetd_pid = -1; -+} -+ -+void port_kern_free(void *d) -+{ -+ struct port_dev *dev = d; -+ -+ port_remove_dev(dev); -+ kfree(dev); -+} -+ -+static void free_port(void) -+{ -+ struct list_head *ele; -+ struct port_list *port; -+ -+ list_for_each(ele, &ports){ -+ port = list_entry(ele, struct port_list, list); -+ free_irq_by_fd(port->fd); -+ os_close_file(port->fd); -+ } -+} -+ -+__uml_exitcall(free_port); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/port_user.c um/arch/um/drivers/port_user.c ---- orig/arch/um/drivers/port_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/port_user.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,213 @@ -+/* -+ * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "user_util.h" -+#include "kern_util.h" -+#include "user.h" -+#include "chan_user.h" -+#include "port.h" -+#include "helper.h" -+#include "os.h" -+ -+struct port_chan { -+ int raw; -+ struct termios tt; -+ void *kernel_data; -+ char dev[sizeof("32768\0")]; -+}; -+ -+void *port_init(char *str, int device, struct chan_opts *opts) -+{ -+ struct port_chan *data; -+ void *kern_data; -+ char *end; -+ int port; -+ -+ if(*str != ':'){ -+ printk("port_init : channel type 'port' must specify a " -+ "port number\n"); -+ return(NULL); -+ } -+ str++; -+ port = strtoul(str, &end, 0); -+ if((*end != '\0') || (end == str)){ -+ printk("port_init : couldn't parse port '%s'\n", str); -+ return(NULL); -+ } -+ -+ kern_data = port_data(port); -+ if(kern_data == NULL) -+ return(NULL); -+ -+ data = um_kmalloc(sizeof(*data)); -+ if(data == NULL) -+ goto err; -+ -+ *data = ((struct port_chan) { .raw = opts->raw, -+ .kernel_data = kern_data }); -+ sprintf(data->dev, "%d", port); -+ -+ return(data); -+ err: -+ port_kern_free(kern_data); -+ return(NULL); -+} -+ -+void port_free(void *d) -+{ -+ struct port_chan *data = d; -+ -+ port_kern_free(data->kernel_data); -+ kfree(data); -+} -+ -+int port_open(int input, int output, int primary, void *d, char **dev_out) -+{ -+ struct port_chan *data = d; -+ int fd; -+ -+ fd = port_wait(data->kernel_data); -+ if((fd >= 0) && data->raw){ -+ tcgetattr(fd, &data->tt); -+ raw(fd, 0); -+ } -+ *dev_out = data->dev; -+ return(fd); -+} -+ -+void port_close(int fd, void *d) -+{ -+ struct port_chan *data = d; -+ -+ port_remove_dev(data->kernel_data); -+ os_close_file(fd); -+} -+ -+int port_console_write(int fd, const char *buf, int n, void *d) -+{ -+ struct port_chan *data = d; -+ -+ return(generic_console_write(fd, buf, n, &data->tt)); -+} -+ -+struct chan_ops port_ops = { -+ .type = "port", -+ .init = port_init, -+ .open = port_open, -+ .close = port_close, -+ .read = generic_read, -+ .write = generic_write, -+ .console_write = port_console_write, -+ .window_size = generic_window_size, -+ .free = port_free, -+ .winch = 1, -+}; -+ -+int port_listen_fd(int port) -+{ -+ struct sockaddr_in addr; -+ int fd, err; -+ -+ fd = socket(PF_INET, SOCK_STREAM, 0); -+ if(fd == -1) -+ return(-errno); -+ -+ addr.sin_family = AF_INET; -+ addr.sin_port = htons(port); -+ addr.sin_addr.s_addr = htonl(INADDR_ANY); -+ if(bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0){ -+ err = -errno; -+ goto out; -+ } -+ -+ if(listen(fd, 1) < 0){ -+ err = -errno; -+ goto out; -+ } -+ -+ err = os_set_fd_block(fd, 0); -+ if(err < 0) -+ goto out; -+ -+ return(fd); -+ out: -+ os_close_file(fd); -+ return(err); -+} -+ -+struct port_pre_exec_data { -+ int sock_fd; -+ int pipe_fd; -+}; -+ -+void port_pre_exec(void *arg) -+{ -+ struct port_pre_exec_data *data = arg; -+ -+ dup2(data->sock_fd, 0); -+ dup2(data->sock_fd, 1); -+ dup2(data->sock_fd, 2); -+ os_close_file(data->sock_fd); -+ dup2(data->pipe_fd, 3); -+ os_shutdown_socket(3, 1, 0); -+ os_close_file(data->pipe_fd); -+} -+ -+int port_connection(int fd, int *socket, int *pid_out) -+{ -+ int new, err; -+ char *argv[] = { "/usr/sbin/in.telnetd", "-L", -+ "/usr/lib/uml/port-helper", NULL }; -+ struct port_pre_exec_data data; -+ -+ new = os_accept_connection(fd); -+ if(new < 0) -+ return(new); -+ -+ err = os_pipe(socket, 0, 0); -+ if(err < 0) -+ goto out_close; -+ -+ data = ((struct port_pre_exec_data) -+ { .sock_fd = new, -+ .pipe_fd = socket[1] }); -+ -+ err = run_helper(port_pre_exec, &data, argv, NULL); -+ if(err < 0) -+ goto out_shutdown; -+ -+ *pid_out = err; -+ return(new); -+ -+ out_shutdown: -+ os_shutdown_socket(socket[0], 1, 1); -+ os_close_file(socket[0]); -+ os_shutdown_socket(socket[1], 1, 1); -+ os_close_file(socket[1]); -+ out_close: -+ os_close_file(new); -+ return(err); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/pty.c um/arch/um/drivers/pty.c ---- orig/arch/um/drivers/pty.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/pty.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,148 @@ -+/* -+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include "chan_user.h" -+#include "user.h" -+#include "user_util.h" -+#include "kern_util.h" -+#include "os.h" -+ -+struct pty_chan { -+ void (*announce)(char *dev_name, int dev); -+ int dev; -+ int raw; -+ struct termios tt; -+ char dev_name[sizeof("/dev/pts/0123456\0")]; -+}; -+ -+void *pty_chan_init(char *str, int device, struct chan_opts *opts) -+{ -+ struct pty_chan *data; -+ -+ data = um_kmalloc(sizeof(*data)); -+ if(data == NULL) return(NULL); -+ *data = ((struct pty_chan) { .announce = opts->announce, -+ .dev = device, -+ .raw = opts->raw }); -+ return(data); -+} -+ -+int pts_open(int input, int output, int primary, void *d, char **dev_out) -+{ -+ struct pty_chan *data = d; -+ char *dev; -+ int fd; -+ -+ fd = get_pty(); -+ if(fd < 0){ -+ printk("open_pts : Failed to open pts\n"); -+ return(-errno); -+ } -+ if(data->raw){ -+ tcgetattr(fd, &data->tt); -+ raw(fd, 0); -+ } -+ -+ dev = ptsname(fd); -+ sprintf(data->dev_name, "%s", dev); -+ *dev_out = data->dev_name; -+ if(data->announce) (*data->announce)(dev, data->dev); -+ return(fd); -+} -+ -+int getmaster(char *line) -+{ -+ char *pty, *bank, *cp; -+ int master, err; -+ -+ pty = &line[strlen("/dev/ptyp")]; -+ for (bank = "pqrs"; *bank; bank++) { -+ line[strlen("/dev/pty")] = *bank; -+ *pty = '0'; -+ if (os_stat_file(line, NULL) < 0) -+ break; -+ for (cp = "0123456789abcdef"; *cp; cp++) { -+ *pty = *cp; -+ master = os_open_file(line, of_rdwr(OPENFLAGS()), 0); -+ if (master >= 0) { -+ char *tp = &line[strlen("/dev/")]; -+ -+ /* verify slave side is usable */ -+ *tp = 't'; -+ err = os_access(line, OS_ACC_RW_OK); -+ *tp = 'p'; -+ if(err == 0) return(master); -+ (void) os_close_file(master); -+ } -+ } -+ } -+ return(-1); -+} -+ -+int pty_open(int input, int output, int primary, void *d, char **dev_out) -+{ -+ struct pty_chan *data = d; -+ int fd; -+ char dev[sizeof("/dev/ptyxx\0")] = "/dev/ptyxx"; -+ -+ fd = getmaster(dev); -+ if(fd < 0) return(-errno); -+ -+ if(data->raw) raw(fd, 0); -+ if(data->announce) (*data->announce)(dev, data->dev); -+ -+ sprintf(data->dev_name, "%s", dev); -+ *dev_out = data->dev_name; -+ return(fd); -+} -+ -+int pty_console_write(int fd, const char *buf, int n, void *d) -+{ -+ struct pty_chan *data = d; -+ -+ return(generic_console_write(fd, buf, n, &data->tt)); -+} -+ -+struct chan_ops pty_ops = { -+ .type = "pty", -+ .init = pty_chan_init, -+ .open = pty_open, -+ .close = generic_close, -+ .read = generic_read, -+ .write = generic_write, -+ .console_write = pty_console_write, -+ .window_size = generic_window_size, -+ .free = generic_free, -+ .winch = 0, -+}; -+ -+struct chan_ops pts_ops = { -+ .type = "pts", -+ .init = pty_chan_init, -+ .open = pts_open, -+ .close = generic_close, -+ .read = generic_read, -+ .write = generic_write, -+ .console_write = pty_console_write, -+ .window_size = generic_window_size, -+ .free = generic_free, -+ .winch = 0, -+}; -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/slip.h um/arch/um/drivers/slip.h ---- orig/arch/um/drivers/slip.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/slip.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,39 @@ -+#ifndef __UM_SLIP_H -+#define __UM_SLIP_H -+ -+#define BUF_SIZE 1500 -+ /* two bytes each for a (pathological) max packet of escaped chars + * -+ * terminating END char + initial END char */ -+#define ENC_BUF_SIZE (2 * BUF_SIZE + 2) -+ -+struct slip_data { -+ void *dev; -+ char name[sizeof("slnnnnn\0")]; -+ char *addr; -+ char *gate_addr; -+ int slave; -+ char ibuf[ENC_BUF_SIZE]; -+ char obuf[ENC_BUF_SIZE]; -+ int more; /* more data: do not read fd until ibuf has been drained */ -+ int pos; -+ int esc; -+}; -+ -+extern struct net_user_info slip_user_info; -+ -+extern int set_umn_addr(int fd, char *addr, char *ptp_addr); -+extern int slip_user_read(int fd, void *buf, int len, struct slip_data *pri); -+extern int slip_user_write(int fd, void *buf, int len, struct slip_data *pri); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/slip_kern.c um/arch/um/drivers/slip_kern.c ---- orig/arch/um/drivers/slip_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/slip_kern.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,109 @@ -+#include "linux/config.h" -+#include "linux/kernel.h" -+#include "linux/stddef.h" -+#include "linux/init.h" -+#include "linux/netdevice.h" -+#include "linux/if_arp.h" -+#include "net_kern.h" -+#include "net_user.h" -+#include "kern.h" -+#include "slip.h" -+ -+struct slip_init { -+ char *gate_addr; -+}; -+ -+void slip_init(struct net_device *dev, void *data) -+{ -+ struct uml_net_private *private; -+ struct slip_data *spri; -+ struct slip_init *init = data; -+ -+ private = dev->priv; -+ spri = (struct slip_data *) private->user; -+ *spri = ((struct slip_data) -+ { .name = { '\0' }, -+ .addr = NULL, -+ .gate_addr = init->gate_addr, -+ .slave = -1, -+ .ibuf = { '\0' }, -+ .obuf = { '\0' }, -+ .pos = 0, -+ .esc = 0, -+ .dev = dev }); -+ -+ dev->init = NULL; -+ dev->hard_header_len = 0; -+ dev->addr_len = 4; -+ dev->type = ARPHRD_ETHER; -+ dev->tx_queue_len = 256; -+ dev->flags = IFF_NOARP; -+ printk("SLIP backend - SLIP IP = %s\n", spri->gate_addr); -+} -+ -+static unsigned short slip_protocol(struct sk_buff *skbuff) -+{ -+ return(htons(ETH_P_IP)); -+} -+ -+static int slip_read(int fd, struct sk_buff **skb, -+ struct uml_net_private *lp) -+{ -+ return(slip_user_read(fd, (*skb)->mac.raw, (*skb)->dev->mtu, -+ (struct slip_data *) &lp->user)); -+} -+ -+static int slip_write(int fd, struct sk_buff **skb, -+ struct uml_net_private *lp) -+{ -+ return(slip_user_write(fd, (*skb)->data, (*skb)->len, -+ (struct slip_data *) &lp->user)); -+} -+ -+struct net_kern_info slip_kern_info = { -+ .init = slip_init, -+ .protocol = slip_protocol, -+ .read = slip_read, -+ .write = slip_write, -+}; -+ -+static int slip_setup(char *str, char **mac_out, void *data) -+{ -+ struct slip_init *init = data; -+ -+ *init = ((struct slip_init) -+ { .gate_addr = NULL }); -+ -+ if(str[0] != '\0') -+ init->gate_addr = str; -+ return(1); -+} -+ -+static struct transport slip_transport = { -+ .list = LIST_HEAD_INIT(slip_transport.list), -+ .name = "slip", -+ .setup = slip_setup, -+ .user = &slip_user_info, -+ .kern = &slip_kern_info, -+ .private_size = sizeof(struct slip_data), -+ .setup_size = sizeof(struct slip_init), -+}; -+ -+static int register_slip(void) -+{ -+ register_transport(&slip_transport); -+ return(1); -+} -+ -+__initcall(register_slip); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/slip_proto.h um/arch/um/drivers/slip_proto.h ---- orig/arch/um/drivers/slip_proto.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/slip_proto.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,93 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __UM_SLIP_PROTO_H__ -+#define __UM_SLIP_PROTO_H__ -+ -+/* SLIP protocol characters. */ -+#define SLIP_END 0300 /* indicates end of frame */ -+#define SLIP_ESC 0333 /* indicates byte stuffing */ -+#define SLIP_ESC_END 0334 /* ESC ESC_END means END 'data' */ -+#define SLIP_ESC_ESC 0335 /* ESC ESC_ESC means ESC 'data' */ -+ -+static inline int slip_unesc(unsigned char c,char *buf,int *pos, int *esc) -+{ -+ int ret; -+ -+ switch(c){ -+ case SLIP_END: -+ *esc = 0; -+ ret=*pos; -+ *pos=0; -+ return(ret); -+ case SLIP_ESC: -+ *esc = 1; -+ return(0); -+ case SLIP_ESC_ESC: -+ if(*esc){ -+ *esc = 0; -+ c = SLIP_ESC; -+ } -+ break; -+ case SLIP_ESC_END: -+ if(*esc){ -+ *esc = 0; -+ c = SLIP_END; -+ } -+ break; -+ } -+ buf[(*pos)++] = c; -+ return(0); -+} -+ -+static inline int slip_esc(unsigned char *s, unsigned char *d, int len) -+{ -+ unsigned char *ptr = d; -+ unsigned char c; -+ -+ /* -+ * Send an initial END character to flush out any -+ * data that may have accumulated in the receiver -+ * due to line noise. -+ */ -+ -+ *ptr++ = SLIP_END; -+ -+ /* -+ * For each byte in the packet, send the appropriate -+ * character sequence, according to the SLIP protocol. -+ */ -+ -+ while (len-- > 0) { -+ switch(c = *s++) { -+ case SLIP_END: -+ *ptr++ = SLIP_ESC; -+ *ptr++ = SLIP_ESC_END; -+ break; -+ case SLIP_ESC: -+ *ptr++ = SLIP_ESC; -+ *ptr++ = SLIP_ESC_ESC; -+ break; -+ default: -+ *ptr++ = c; -+ break; -+ } -+ } -+ *ptr++ = SLIP_END; -+ return (ptr - d); -+} -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/slip_user.c um/arch/um/drivers/slip_user.c ---- orig/arch/um/drivers/slip_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/slip_user.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,274 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "user_util.h" -+#include "kern_util.h" -+#include "user.h" -+#include "net_user.h" -+#include "slip.h" -+#include "slip_proto.h" -+#include "helper.h" -+#include "os.h" -+ -+void slip_user_init(void *data, void *dev) -+{ -+ struct slip_data *pri = data; -+ -+ pri->dev = dev; -+} -+ -+static int set_up_tty(int fd) -+{ -+ int i; -+ struct termios tios; -+ -+ if (tcgetattr(fd, &tios) < 0) { -+ printk("could not get initial terminal attributes\n"); -+ return(-1); -+ } -+ -+ tios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL; -+ tios.c_iflag = IGNBRK | IGNPAR; -+ tios.c_oflag = 0; -+ tios.c_lflag = 0; -+ for (i = 0; i < NCCS; i++) -+ tios.c_cc[i] = 0; -+ tios.c_cc[VMIN] = 1; -+ tios.c_cc[VTIME] = 0; -+ -+ cfsetospeed(&tios, B38400); -+ cfsetispeed(&tios, B38400); -+ -+ if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) { -+ printk("failed to set terminal attributes\n"); -+ return(-1); -+ } -+ return(0); -+} -+ -+struct slip_pre_exec_data { -+ int stdin; -+ int stdout; -+ int close_me; -+}; -+ -+static void slip_pre_exec(void *arg) -+{ -+ struct slip_pre_exec_data *data = arg; -+ -+ if(data->stdin >= 0) dup2(data->stdin, 0); -+ dup2(data->stdout, 1); -+ if(data->close_me >= 0) os_close_file(data->close_me); -+} -+ -+static int slip_tramp(char **argv, int fd) -+{ -+ struct slip_pre_exec_data pe_data; -+ char *output; -+ int status, pid, fds[2], err, output_len; -+ -+ err = os_pipe(fds, 1, 0); -+ if(err < 0){ -+ printk("slip_tramp : pipe failed, err = %d\n", -err); -+ return(err); -+ } -+ -+ err = 0; -+ pe_data.stdin = fd; -+ pe_data.stdout = fds[1]; -+ pe_data.close_me = fds[0]; -+ pid = run_helper(slip_pre_exec, &pe_data, argv, NULL); -+ -+ if(pid < 0) err = pid; -+ else { -+ output_len = page_size(); -+ output = um_kmalloc(output_len); -+ if(output == NULL) -+ printk("slip_tramp : failed to allocate output " -+ "buffer\n"); -+ -+ os_close_file(fds[1]); -+ read_output(fds[0], output, output_len); -+ if(output != NULL){ -+ printk("%s", output); -+ kfree(output); -+ } -+ if(waitpid(pid, &status, 0) < 0) err = errno; -+ else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){ -+ printk("'%s' didn't exit with status 0\n", argv[0]); -+ err = -EINVAL; -+ } -+ } -+ return(err); -+} -+ -+static int slip_open(void *data) -+{ -+ struct slip_data *pri = data; -+ char version_buf[sizeof("nnnnn\0")]; -+ char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")]; -+ char *argv[] = { "uml_net", version_buf, "slip", "up", gate_buf, -+ NULL }; -+ int sfd, mfd, err; -+ -+ mfd = get_pty(); -+ if(mfd < 0){ -+ printk("umn : Failed to open pty, err = %d\n", -mfd); -+ return(mfd); -+ } -+ sfd = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0); -+ if(sfd < 0){ -+ printk("Couldn't open tty for slip line, err = %d\n", -sfd); -+ return(sfd); -+ } -+ if(set_up_tty(sfd)) return(-1); -+ pri->slave = sfd; -+ pri->pos = 0; -+ pri->esc = 0; -+ if(pri->gate_addr != NULL){ -+ sprintf(version_buf, "%d", UML_NET_VERSION); -+ strcpy(gate_buf, pri->gate_addr); -+ -+ err = slip_tramp(argv, sfd); -+ -+ if(err < 0){ -+ printk("slip_tramp failed - err = %d\n", -err); -+ return(err); -+ } -+ err = os_get_ifname(pri->slave, pri->name); -+ if(err < 0){ -+ printk("get_ifname failed, err = %d\n", -err); -+ return(err); -+ } -+ iter_addresses(pri->dev, open_addr, pri->name); -+ } -+ else { -+ err = os_set_slip(sfd); -+ if(err < 0){ -+ printk("Failed to set slip discipline encapsulation - " -+ "err = %d\n", -err); -+ return(err); -+ } -+ } -+ return(mfd); -+} -+ -+static void slip_close(int fd, void *data) -+{ -+ struct slip_data *pri = data; -+ char version_buf[sizeof("nnnnn\0")]; -+ char *argv[] = { "uml_net", version_buf, "slip", "down", pri->name, -+ NULL }; -+ int err; -+ -+ if(pri->gate_addr != NULL) -+ iter_addresses(pri->dev, close_addr, pri->name); -+ -+ sprintf(version_buf, "%d", UML_NET_VERSION); -+ -+ err = slip_tramp(argv, -1); -+ -+ if(err != 0) -+ printk("slip_tramp failed - errno = %d\n", -err); -+ os_close_file(fd); -+ os_close_file(pri->slave); -+ pri->slave = -1; -+} -+ -+int slip_user_read(int fd, void *buf, int len, struct slip_data *pri) -+{ -+ int i, n, size, start; -+ -+ if(pri->more>0) { -+ i = 0; -+ while(i < pri->more) { -+ size = slip_unesc(pri->ibuf[i++], -+ pri->ibuf, &pri->pos, &pri->esc); -+ if(size){ -+ memcpy(buf, pri->ibuf, size); -+ memmove(pri->ibuf, &pri->ibuf[i], pri->more-i); -+ pri->more=pri->more-i; -+ return(size); -+ } -+ } -+ pri->more=0; -+ } -+ -+ n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos); -+ if(n <= 0) return(n); -+ -+ start = pri->pos; -+ for(i = 0; i < n; i++){ -+ size = slip_unesc(pri->ibuf[start + i], -+ pri->ibuf, &pri->pos, &pri->esc); -+ if(size){ -+ memcpy(buf, pri->ibuf, size); -+ memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1)); -+ pri->more=n-(i+1); -+ return(size); -+ } -+ } -+ return(0); -+} -+ -+int slip_user_write(int fd, void *buf, int len, struct slip_data *pri) -+{ -+ int actual, n; -+ -+ actual = slip_esc(buf, pri->obuf, len); -+ n = net_write(fd, pri->obuf, actual); -+ if(n < 0) return(n); -+ else return(len); -+} -+ -+static int slip_set_mtu(int mtu, void *data) -+{ -+ return(mtu); -+} -+ -+static void slip_add_addr(unsigned char *addr, unsigned char *netmask, -+ void *data) -+{ -+ struct slip_data *pri = data; -+ -+ if(pri->slave < 0) return; -+ open_addr(addr, netmask, pri->name); -+} -+ -+static void slip_del_addr(unsigned char *addr, unsigned char *netmask, -+ void *data) -+{ -+ struct slip_data *pri = data; -+ -+ if(pri->slave < 0) return; -+ close_addr(addr, netmask, pri->name); -+} -+ -+struct net_user_info slip_user_info = { -+ .init = slip_user_init, -+ .open = slip_open, -+ .close = slip_close, -+ .remove = NULL, -+ .set_mtu = slip_set_mtu, -+ .add_address = slip_add_addr, -+ .delete_address = slip_del_addr, -+ .max_packet = BUF_SIZE -+}; -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/slirp.h um/arch/um/drivers/slirp.h ---- orig/arch/um/drivers/slirp.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/slirp.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,51 @@ -+#ifndef __UM_SLIRP_H -+#define __UM_SLIRP_H -+ -+#define BUF_SIZE 1500 -+ /* two bytes each for a (pathological) max packet of escaped chars + * -+ * terminating END char + initial END char */ -+#define ENC_BUF_SIZE (2 * BUF_SIZE + 2) -+ -+#define SLIRP_MAX_ARGS 100 -+/* -+ * XXX this next definition is here because I don't understand why this -+ * initializer doesn't work in slirp_kern.c: -+ * -+ * argv : { init->argv[ 0 ... SLIRP_MAX_ARGS-1 ] }, -+ * -+ * or why I can't typecast like this: -+ * -+ * argv : (char* [SLIRP_MAX_ARGS])(init->argv), -+ */ -+struct arg_list_dummy_wrapper { char *argv[SLIRP_MAX_ARGS]; }; -+ -+struct slirp_data { -+ void *dev; -+ struct arg_list_dummy_wrapper argw; -+ int pid; -+ int slave; -+ char ibuf[ENC_BUF_SIZE]; -+ char obuf[ENC_BUF_SIZE]; -+ int more; /* more data: do not read fd until ibuf has been drained */ -+ int pos; -+ int esc; -+}; -+ -+extern struct net_user_info slirp_user_info; -+ -+extern int set_umn_addr(int fd, char *addr, char *ptp_addr); -+extern int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri); -+extern int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/slirp_kern.c um/arch/um/drivers/slirp_kern.c ---- orig/arch/um/drivers/slirp_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/slirp_kern.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,132 @@ -+#include "linux/kernel.h" -+#include "linux/stddef.h" -+#include "linux/init.h" -+#include "linux/netdevice.h" -+#include "linux/if_arp.h" -+#include "net_kern.h" -+#include "net_user.h" -+#include "kern.h" -+#include "slirp.h" -+ -+struct slirp_init { -+ struct arg_list_dummy_wrapper argw; /* XXX should be simpler... */ -+}; -+ -+void slirp_init(struct net_device *dev, void *data) -+{ -+ struct uml_net_private *private; -+ struct slirp_data *spri; -+ struct slirp_init *init = data; -+ int i; -+ -+ private = dev->priv; -+ spri = (struct slirp_data *) private->user; -+ *spri = ((struct slirp_data) -+ { .argw = init->argw, -+ .pid = -1, -+ .slave = -1, -+ .ibuf = { '\0' }, -+ .obuf = { '\0' }, -+ .pos = 0, -+ .esc = 0, -+ .dev = dev }); -+ -+ dev->init = NULL; -+ dev->hard_header_len = 0; -+ dev->addr_len = 4; -+ dev->type = ARPHRD_ETHER; -+ dev->tx_queue_len = 256; -+ dev->flags = IFF_NOARP; -+ printk("SLIRP backend - command line:"); -+ for(i=0;spri->argw.argv[i]!=NULL;i++) { -+ printk(" '%s'",spri->argw.argv[i]); -+ } -+ printk("\n"); -+} -+ -+static unsigned short slirp_protocol(struct sk_buff *skbuff) -+{ -+ return(htons(ETH_P_IP)); -+} -+ -+static int slirp_read(int fd, struct sk_buff **skb, -+ struct uml_net_private *lp) -+{ -+ return(slirp_user_read(fd, (*skb)->mac.raw, (*skb)->dev->mtu, -+ (struct slirp_data *) &lp->user)); -+} -+ -+static int slirp_write(int fd, struct sk_buff **skb, -+ struct uml_net_private *lp) -+{ -+ return(slirp_user_write(fd, (*skb)->data, (*skb)->len, -+ (struct slirp_data *) &lp->user)); -+} -+ -+struct net_kern_info slirp_kern_info = { -+ .init = slirp_init, -+ .protocol = slirp_protocol, -+ .read = slirp_read, -+ .write = slirp_write, -+}; -+ -+static int slirp_setup(char *str, char **mac_out, void *data) -+{ -+ struct slirp_init *init = data; -+ int i=0; -+ -+ *init = ((struct slirp_init) -+ { argw : { { "slirp", NULL } } }); -+ -+ str = split_if_spec(str, mac_out, NULL); -+ -+ if(str == NULL) { /* no command line given after MAC addr */ -+ return(1); -+ } -+ -+ do { -+ if(i>=SLIRP_MAX_ARGS-1) { -+ printk("slirp_setup: truncating slirp arguments\n"); -+ break; -+ } -+ init->argw.argv[i++] = str; -+ while(*str && *str!=',') { -+ if(*str=='_') *str=' '; -+ str++; -+ } -+ if(*str!=',') -+ break; -+ *str++='\0'; -+ } while(1); -+ init->argw.argv[i]=NULL; -+ return(1); -+} -+ -+static struct transport slirp_transport = { -+ .list = LIST_HEAD_INIT(slirp_transport.list), -+ .name = "slirp", -+ .setup = slirp_setup, -+ .user = &slirp_user_info, -+ .kern = &slirp_kern_info, -+ .private_size = sizeof(struct slirp_data), -+ .setup_size = sizeof(struct slirp_init), -+}; -+ -+static int register_slirp(void) -+{ -+ register_transport(&slirp_transport); -+ return(1); -+} -+ -+__initcall(register_slirp); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/slirp_user.c um/arch/um/drivers/slirp_user.c ---- orig/arch/um/drivers/slirp_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/slirp_user.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,201 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "user_util.h" -+#include "kern_util.h" -+#include "user.h" -+#include "net_user.h" -+#include "slirp.h" -+#include "slip_proto.h" -+#include "helper.h" -+#include "os.h" -+ -+void slirp_user_init(void *data, void *dev) -+{ -+ struct slirp_data *pri = data; -+ -+ pri->dev = dev; -+} -+ -+struct slirp_pre_exec_data { -+ int stdin; -+ int stdout; -+}; -+ -+static void slirp_pre_exec(void *arg) -+{ -+ struct slirp_pre_exec_data *data = arg; -+ -+ if(data->stdin != -1) dup2(data->stdin, 0); -+ if(data->stdout != -1) dup2(data->stdout, 1); -+} -+ -+static int slirp_tramp(char **argv, int fd) -+{ -+ struct slirp_pre_exec_data pe_data; -+ int pid; -+ -+ pe_data.stdin = fd; -+ pe_data.stdout = fd; -+ pid = run_helper(slirp_pre_exec, &pe_data, argv, NULL); -+ -+ return(pid); -+} -+ -+/* XXX This is just a trivial wrapper around os_pipe */ -+static int slirp_datachan(int *mfd, int *sfd) -+{ -+ int fds[2], err; -+ -+ err = os_pipe(fds, 1, 1); -+ if(err < 0){ -+ printk("slirp_datachan: Failed to open pipe, err = %d\n", -err); -+ return(err); -+ } -+ -+ *mfd = fds[0]; -+ *sfd = fds[1]; -+ return(0); -+} -+ -+static int slirp_open(void *data) -+{ -+ struct slirp_data *pri = data; -+ int sfd, mfd, pid, err; -+ -+ err = slirp_datachan(&mfd, &sfd); -+ if(err) -+ return(err); -+ -+ pid = slirp_tramp(pri->argw.argv, sfd); -+ -+ if(pid < 0){ -+ printk("slirp_tramp failed - errno = %d\n", -pid); -+ os_close_file(sfd); -+ os_close_file(mfd); -+ return(pid); -+ } -+ -+ pri->slave = sfd; -+ pri->pos = 0; -+ pri->esc = 0; -+ -+ pri->pid = pid; -+ -+ return(mfd); -+} -+ -+static void slirp_close(int fd, void *data) -+{ -+ struct slirp_data *pri = data; -+ int status,err; -+ -+ os_close_file(fd); -+ os_close_file(pri->slave); -+ -+ pri->slave = -1; -+ -+ if(pri->pid<1) { -+ printk("slirp_close: no child process to shut down\n"); -+ return; -+ } -+ -+#if 0 -+ if(kill(pri->pid, SIGHUP)<0) { -+ printk("slirp_close: sending hangup to %d failed (%d)\n", -+ pri->pid, errno); -+ } -+#endif -+ -+ err = waitpid(pri->pid, &status, WNOHANG); -+ if(err<0) { -+ printk("slirp_close: waitpid returned %d\n", errno); -+ return; -+ } -+ -+ if(err==0) { -+ printk("slirp_close: process %d has not exited\n"); -+ return; -+ } -+ -+ pri->pid = -1; -+} -+ -+int slirp_user_read(int fd, void *buf, int len, struct slirp_data *pri) -+{ -+ int i, n, size, start; -+ -+ if(pri->more>0) { -+ i = 0; -+ while(i < pri->more) { -+ size = slip_unesc(pri->ibuf[i++], -+ pri->ibuf,&pri->pos,&pri->esc); -+ if(size){ -+ memcpy(buf, pri->ibuf, size); -+ memmove(pri->ibuf, &pri->ibuf[i], pri->more-i); -+ pri->more=pri->more-i; -+ return(size); -+ } -+ } -+ pri->more=0; -+ } -+ -+ n = net_read(fd, &pri->ibuf[pri->pos], sizeof(pri->ibuf) - pri->pos); -+ if(n <= 0) return(n); -+ -+ start = pri->pos; -+ for(i = 0; i < n; i++){ -+ size = slip_unesc(pri->ibuf[start + i], -+ pri->ibuf,&pri->pos,&pri->esc); -+ if(size){ -+ memcpy(buf, pri->ibuf, size); -+ memmove(pri->ibuf, &pri->ibuf[start+i+1], n-(i+1)); -+ pri->more=n-(i+1); -+ return(size); -+ } -+ } -+ return(0); -+} -+ -+int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri) -+{ -+ int actual, n; -+ -+ actual = slip_esc(buf, pri->obuf, len); -+ n = net_write(fd, pri->obuf, actual); -+ if(n < 0) return(n); -+ else return(len); -+} -+ -+static int slirp_set_mtu(int mtu, void *data) -+{ -+ return(mtu); -+} -+ -+struct net_user_info slirp_user_info = { -+ .init = slirp_user_init, -+ .open = slirp_open, -+ .close = slirp_close, -+ .remove = NULL, -+ .set_mtu = slirp_set_mtu, -+ .add_address = NULL, -+ .delete_address = NULL, -+ .max_packet = BUF_SIZE -+}; -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/ssl.c um/arch/um/drivers/ssl.c ---- orig/arch/um/drivers/ssl.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/ssl.c 2004-01-10 06:20:17.000000000 -0500 -@@ -0,0 +1,300 @@ -+/* -+ * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/config.h" -+#include "linux/fs.h" -+#include "linux/tty.h" -+#include "linux/tty_driver.h" -+#include "linux/major.h" -+#include "linux/mm.h" -+#include "linux/init.h" -+#include "linux/console.h" -+#include "asm/termbits.h" -+#include "asm/irq.h" -+#include "line.h" -+#include "ssl.h" -+#include "chan_kern.h" -+#include "user_util.h" -+#include "kern_util.h" -+#include "kern.h" -+#include "init.h" -+#include "irq_user.h" -+#include "mconsole_kern.h" -+#include "2_5compat.h" -+ -+static int ssl_version = 1; -+ -+/* Referenced only by tty_driver below - presumably it's locked correctly -+ * by the tty driver. -+ */ -+static int ssl_refcount = 0; -+ -+static struct tty_driver ssl_driver; -+ -+#define NR_PORTS 64 -+ -+void ssl_announce(char *dev_name, int dev) -+{ -+ printk(KERN_INFO "Serial line %d assigned device '%s'\n", dev, -+ dev_name); -+} -+ -+static struct chan_opts opts = { -+ .announce = ssl_announce, -+ .xterm_title = "Serial Line #%d", -+ .raw = 1, -+ .tramp_stack = 0, -+ .in_kernel = 1, -+}; -+ -+static int ssl_config(char *str); -+static int ssl_get_config(char *dev, char *str, int size, char **error_out); -+static int ssl_remove(char *str); -+ -+static struct line_driver driver = { -+ .name = "UML serial line", -+ .devfs_name = "tts/%d", -+ .major = TTY_MAJOR, -+ .minor_start = 64, -+ .type = TTY_DRIVER_TYPE_SERIAL, -+ .subtype = 0, -+ .read_irq = SSL_IRQ, -+ .read_irq_name = "ssl", -+ .write_irq = SSL_WRITE_IRQ, -+ .write_irq_name = "ssl-write", -+ .symlink_from = "serial", -+ .symlink_to = "tts", -+ .mc = { -+ .name = "ssl", -+ .config = ssl_config, -+ .get_config = ssl_get_config, -+ .remove = ssl_remove, -+ }, -+}; -+ -+/* The array is initialized by line_init, which is an initcall. The -+ * individual elements are protected by individual semaphores. -+ */ -+static struct line serial_lines[NR_PORTS] = -+ { [0 ... NR_PORTS - 1] = LINE_INIT(CONFIG_SSL_CHAN, &driver) }; -+ -+static struct lines lines = LINES_INIT(NR_PORTS); -+ -+static int ssl_config(char *str) -+{ -+ return(line_config(serial_lines, -+ sizeof(serial_lines)/sizeof(serial_lines[0]), str)); -+} -+ -+static int ssl_get_config(char *dev, char *str, int size, char **error_out) -+{ -+ return(line_get_config(dev, serial_lines, -+ sizeof(serial_lines)/sizeof(serial_lines[0]), -+ str, size, error_out)); -+} -+ -+static int ssl_remove(char *str) -+{ -+ return(line_remove(serial_lines, -+ sizeof(serial_lines)/sizeof(serial_lines[0]), str)); -+} -+ -+int ssl_open(struct tty_struct *tty, struct file *filp) -+{ -+ return(line_open(serial_lines, tty, &opts)); -+} -+ -+static void ssl_close(struct tty_struct *tty, struct file * filp) -+{ -+ line_close(serial_lines, tty); -+} -+ -+static int ssl_write(struct tty_struct * tty, int from_user, -+ const unsigned char *buf, int count) -+{ -+ return(line_write(serial_lines, tty, from_user, buf, count)); -+} -+ -+static void ssl_put_char(struct tty_struct *tty, unsigned char ch) -+{ -+ line_write(serial_lines, tty, 0, &ch, sizeof(ch)); -+} -+ -+static void ssl_flush_chars(struct tty_struct *tty) -+{ -+ return; -+} -+ -+static int ssl_chars_in_buffer(struct tty_struct *tty) -+{ -+ return(0); -+} -+ -+static void ssl_flush_buffer(struct tty_struct *tty) -+{ -+ return; -+} -+ -+static int ssl_ioctl(struct tty_struct *tty, struct file * file, -+ unsigned int cmd, unsigned long arg) -+{ -+ int ret; -+ -+ ret = 0; -+ switch(cmd){ -+ case TCGETS: -+ case TCSETS: -+ case TCFLSH: -+ case TCSETSF: -+ case TCSETSW: -+ case TCGETA: -+ case TIOCMGET: -+ case TCSBRK: -+ case TCSBRKP: -+ case TIOCMSET: -+ ret = -ENOIOCTLCMD; -+ break; -+ default: -+ printk(KERN_ERR -+ "Unimplemented ioctl in ssl_ioctl : 0x%x\n", cmd); -+ ret = -ENOIOCTLCMD; -+ break; -+ } -+ return(ret); -+} -+ -+static void ssl_throttle(struct tty_struct * tty) -+{ -+ printk(KERN_ERR "Someone should implement ssl_throttle\n"); -+} -+ -+static void ssl_unthrottle(struct tty_struct * tty) -+{ -+ printk(KERN_ERR "Someone should implement ssl_unthrottle\n"); -+} -+ -+static void ssl_set_termios(struct tty_struct *tty, -+ struct termios *old_termios) -+{ -+} -+ -+static void ssl_stop(struct tty_struct *tty) -+{ -+ printk(KERN_ERR "Someone should implement ssl_stop\n"); -+} -+ -+static void ssl_start(struct tty_struct *tty) -+{ -+ printk(KERN_ERR "Someone should implement ssl_start\n"); -+} -+ -+void ssl_hangup(struct tty_struct *tty) -+{ -+} -+ -+static struct tty_driver ssl_driver = { -+ .refcount = &ssl_refcount, -+ .open = ssl_open, -+ .close = ssl_close, -+ .write = ssl_write, -+ .put_char = ssl_put_char, -+ .flush_chars = ssl_flush_chars, -+ .chars_in_buffer = ssl_chars_in_buffer, -+ .flush_buffer = ssl_flush_buffer, -+ .ioctl = ssl_ioctl, -+ .throttle = ssl_throttle, -+ .unthrottle = ssl_unthrottle, -+ .set_termios = ssl_set_termios, -+ .stop = ssl_stop, -+ .start = ssl_start, -+ .hangup = ssl_hangup -+}; -+ -+/* Changed by ssl_init and referenced by ssl_exit, which are both serialized -+ * by being an initcall and exitcall, respectively. -+ */ -+static int ssl_init_done = 0; -+ -+static void ssl_console_write(struct console *c, const char *string, -+ unsigned len) -+{ -+ struct line *line = &serial_lines[c->index]; -+ if(ssl_init_done) -+ down(&line->sem); -+ console_write_chan(&line->chan_list, string, len); -+ if(ssl_init_done) -+ up(&line->sem); -+} -+ -+static kdev_t ssl_console_device(struct console *c) -+{ -+ return mk_kdev(TTY_MAJOR, c->index); -+} -+ -+static int ssl_console_setup(struct console *co, char *options) -+{ -+ return(0); -+} -+ -+static struct console ssl_cons = { -+ name: "ttyS", -+ write: ssl_console_write, -+ device: ssl_console_device, -+ setup: ssl_console_setup, -+ flags: CON_PRINTBUFFER, -+ index: -1, -+}; -+ -+int ssl_init(void) -+{ -+ char *new_title; -+ -+ printk(KERN_INFO "Initializing software serial port version %d\n", -+ ssl_version); -+ -+ line_register_devfs(&lines, &driver, &ssl_driver, serial_lines, -+ sizeof(serial_lines)/sizeof(serial_lines[0])); -+ -+ lines_init(serial_lines, sizeof(serial_lines)/sizeof(serial_lines[0])); -+ -+ new_title = add_xterm_umid(opts.xterm_title); -+ if(new_title != NULL) opts.xterm_title = new_title; -+ -+ register_console(&ssl_cons); -+ ssl_init_done = 1; -+ return(0); -+} -+ -+__initcall(ssl_init); -+ -+static int ssl_chan_setup(char *str) -+{ -+ return(line_setup(serial_lines, -+ sizeof(serial_lines)/sizeof(serial_lines[0]), -+ str, 1)); -+} -+ -+__setup("ssl", ssl_chan_setup); -+__channel_help(ssl_chan_setup, "ssl"); -+ -+static void ssl_exit(void) -+{ -+ if(!ssl_init_done) return; -+ close_lines(serial_lines, -+ sizeof(serial_lines)/sizeof(serial_lines[0])); -+} -+ -+__uml_exitcall(ssl_exit); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/ssl.h um/arch/um/drivers/ssl.h ---- orig/arch/um/drivers/ssl.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/ssl.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,23 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __SSL_H__ -+#define __SSL_H__ -+ -+extern int ssl_read(int fd, int line); -+extern void ssl_receive_char(int line, char ch); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/stdio_console.c um/arch/um/drivers/stdio_console.c ---- orig/arch/um/drivers/stdio_console.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/stdio_console.c 2003-11-07 03:03:03.000000000 -0500 -@@ -0,0 +1,258 @@ -+/* -+ * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/config.h" -+#include "linux/posix_types.h" -+#include "linux/tty.h" -+#include "linux/tty_flip.h" -+#include "linux/types.h" -+#include "linux/major.h" -+#include "linux/kdev_t.h" -+#include "linux/console.h" -+#include "linux/string.h" -+#include "linux/sched.h" -+#include "linux/list.h" -+#include "linux/init.h" -+#include "linux/interrupt.h" -+#include "linux/slab.h" -+#include "asm/current.h" -+#include "asm/softirq.h" -+#include "asm/hardirq.h" -+#include "asm/irq.h" -+#include "stdio_console.h" -+#include "line.h" -+#include "chan_kern.h" -+#include "user_util.h" -+#include "kern_util.h" -+#include "irq_user.h" -+#include "mconsole_kern.h" -+#include "init.h" -+#include "2_5compat.h" -+ -+#define MAX_TTYS (8) -+ -+/* Referenced only by tty_driver below - presumably it's locked correctly -+ * by the tty driver. -+ */ -+ -+static struct tty_driver console_driver; -+ -+static int console_refcount = 0; -+ -+static struct chan_ops init_console_ops = { -+ .type = "you shouldn't see this", -+ .init = NULL, -+ .open = NULL, -+ .close = NULL, -+ .read = NULL, -+ .write = NULL, -+ .console_write = generic_write, -+ .window_size = NULL, -+ .free = NULL, -+ .winch = 0, -+}; -+ -+static struct chan init_console_chan = { -+ .list = { }, -+ .primary = 1, -+ .input = 0, -+ .output = 1, -+ .opened = 1, -+ .fd = 1, -+ .pri = INIT_STATIC, -+ .ops = &init_console_ops, -+ .data = NULL -+}; -+ -+void stdio_announce(char *dev_name, int dev) -+{ -+ printk(KERN_INFO "Virtual console %d assigned device '%s'\n", dev, -+ dev_name); -+} -+ -+static struct chan_opts opts = { -+ .announce = stdio_announce, -+ .xterm_title = "Virtual Console #%d", -+ .raw = 1, -+ .tramp_stack = 0, -+ .in_kernel = 1, -+}; -+ -+static int con_config(char *str); -+static int con_get_config(char *dev, char *str, int size, char **error_out); -+static int con_remove(char *str); -+ -+static struct line_driver driver = { -+ .name = "UML console", -+ .devfs_name = "vc/%d", -+ .major = TTY_MAJOR, -+ .minor_start = 0, -+ .type = TTY_DRIVER_TYPE_CONSOLE, -+ .subtype = SYSTEM_TYPE_CONSOLE, -+ .read_irq = CONSOLE_IRQ, -+ .read_irq_name = "console", -+ .write_irq = CONSOLE_WRITE_IRQ, -+ .write_irq_name = "console-write", -+ .symlink_from = "ttys", -+ .symlink_to = "vc", -+ .mc = { -+ .name = "con", -+ .config = con_config, -+ .get_config = con_get_config, -+ .remove = con_remove, -+ }, -+}; -+ -+static struct lines console_lines = LINES_INIT(MAX_TTYS); -+ -+/* The array is initialized by line_init, which is an initcall. The -+ * individual elements are protected by individual semaphores. -+ */ -+struct line vts[MAX_TTYS] = { LINE_INIT(CONFIG_CON_ZERO_CHAN, &driver), -+ [ 1 ... MAX_TTYS - 1 ] = -+ LINE_INIT(CONFIG_CON_CHAN, &driver) }; -+ -+static int con_config(char *str) -+{ -+ return(line_config(vts, sizeof(vts)/sizeof(vts[0]), str)); -+} -+ -+static int con_get_config(char *dev, char *str, int size, char **error_out) -+{ -+ return(line_get_config(dev, vts, sizeof(vts)/sizeof(vts[0]), str, -+ size, error_out)); -+} -+ -+static int con_remove(char *str) -+{ -+ return(line_remove(vts, sizeof(vts)/sizeof(vts[0]), str)); -+} -+ -+static int open_console(struct tty_struct *tty) -+{ -+ return(line_open(vts, tty, &opts)); -+} -+ -+static int con_open(struct tty_struct *tty, struct file *filp) -+{ -+ return(open_console(tty)); -+} -+ -+static void con_close(struct tty_struct *tty, struct file *filp) -+{ -+ line_close(vts, tty); -+} -+ -+static int con_write(struct tty_struct *tty, int from_user, -+ const unsigned char *buf, int count) -+{ -+ return(line_write(vts, tty, from_user, buf, count)); -+} -+ -+static void set_termios(struct tty_struct *tty, struct termios * old) -+{ -+} -+ -+static int chars_in_buffer(struct tty_struct *tty) -+{ -+ return(0); -+} -+ -+static int con_init_done = 0; -+ -+int stdio_init(void) -+{ -+ char *new_title; -+ -+ printk(KERN_INFO "Initializing stdio console driver\n"); -+ -+ line_register_devfs(&console_lines, &driver, &console_driver, vts, -+ sizeof(vts)/sizeof(vts[0])); -+ -+ lines_init(vts, sizeof(vts)/sizeof(vts[0])); -+ -+ new_title = add_xterm_umid(opts.xterm_title); -+ if(new_title != NULL) opts.xterm_title = new_title; -+ -+ open_console(NULL); -+ con_init_done = 1; -+ return(0); -+} -+ -+__initcall(stdio_init); -+ -+static void console_write(struct console *console, const char *string, -+ unsigned len) -+{ -+ struct line *line = &vts[console->index]; -+ -+ if(con_init_done) -+ down(&line->sem); -+ console_write_chan(&line->chan_list, string, len); -+ if(con_init_done) -+ up(&line->sem); -+} -+ -+static struct tty_driver console_driver = { -+ .refcount = &console_refcount, -+ .open = con_open, -+ .close = con_close, -+ .write = con_write, -+ .chars_in_buffer = chars_in_buffer, -+ .set_termios = set_termios -+}; -+ -+static kdev_t console_device(struct console *c) -+{ -+ return mk_kdev(TTY_MAJOR, c->index); -+} -+ -+static int console_setup(struct console *co, char *options) -+{ -+ return(0); -+} -+ -+static struct console stdiocons = { -+ name: "tty", -+ write: console_write, -+ device: console_device, -+ setup: console_setup, -+ flags: CON_PRINTBUFFER, -+ index: -1, -+}; -+ -+void stdio_console_init(void) -+{ -+ INIT_LIST_HEAD(&vts[0].chan_list); -+ list_add(&init_console_chan.list, &vts[0].chan_list); -+ register_console(&stdiocons); -+} -+ -+static int console_chan_setup(char *str) -+{ -+ return(line_setup(vts, sizeof(vts)/sizeof(vts[0]), str, 1)); -+} -+ -+__setup("con", console_chan_setup); -+__channel_help(console_chan_setup, "con"); -+ -+static void console_exit(void) -+{ -+ if(!con_init_done) return; -+ close_lines(vts, sizeof(vts)/sizeof(vts[0])); -+} -+ -+__uml_exitcall(console_exit); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/stdio_console.h um/arch/um/drivers/stdio_console.h ---- orig/arch/um/drivers/stdio_console.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/stdio_console.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,21 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __STDIO_CONSOLE_H -+#define __STDIO_CONSOLE_H -+ -+extern void save_console_flags(void); -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/tty.c um/arch/um/drivers/tty.c ---- orig/arch/um/drivers/tty.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/tty.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,86 @@ -+/* -+ * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include -+#include -+#include -+#include -+#include "chan_user.h" -+#include "user_util.h" -+#include "user.h" -+#include "os.h" -+ -+struct tty_chan { -+ char *dev; -+ int raw; -+ struct termios tt; -+}; -+ -+void *tty_chan_init(char *str, int device, struct chan_opts *opts) -+{ -+ struct tty_chan *data; -+ -+ if(*str != ':'){ -+ printk("tty_init : channel type 'tty' must specify " -+ "a device\n"); -+ return(NULL); -+ } -+ str++; -+ -+ data = um_kmalloc(sizeof(*data)); -+ if(data == NULL) -+ return(NULL); -+ *data = ((struct tty_chan) { .dev = str, -+ .raw = opts->raw }); -+ -+ return(data); -+} -+ -+int tty_open(int input, int output, int primary, void *d, char **dev_out) -+{ -+ struct tty_chan *data = d; -+ int fd; -+ -+ fd = os_open_file(data->dev, of_set_rw(OPENFLAGS(), input, output), 0); -+ if(fd < 0) return(fd); -+ if(data->raw){ -+ tcgetattr(fd, &data->tt); -+ raw(fd, 0); -+ } -+ -+ *dev_out = data->dev; -+ return(fd); -+} -+ -+int tty_console_write(int fd, const char *buf, int n, void *d) -+{ -+ struct tty_chan *data = d; -+ -+ return(generic_console_write(fd, buf, n, &data->tt)); -+} -+ -+struct chan_ops tty_ops = { -+ .type = "tty", -+ .init = tty_chan_init, -+ .open = tty_open, -+ .close = generic_close, -+ .read = generic_read, -+ .write = generic_write, -+ .console_write = tty_console_write, -+ .window_size = generic_window_size, -+ .free = generic_free, -+ .winch = 0, -+}; -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/ubd_kern.c um/arch/um/drivers/ubd_kern.c ---- orig/arch/um/drivers/ubd_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/ubd_kern.c 2004-01-21 01:28:43.000000000 -0500 -@@ -0,0 +1,1396 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+/* 2001-09-28...2002-04-17 -+ * Partition stuff by James_McMechan@hotmail.com -+ * old style ubd by setting UBD_SHIFT to 0 -+ */ -+ -+#define MAJOR_NR UBD_MAJOR -+#define UBD_SHIFT 4 -+ -+#include "linux/config.h" -+#include "linux/blk.h" -+#include "linux/blkdev.h" -+#include "linux/hdreg.h" -+#include "linux/init.h" -+#include "linux/devfs_fs_kernel.h" -+#include "linux/cdrom.h" -+#include "linux/proc_fs.h" -+#include "linux/ctype.h" -+#include "linux/capability.h" -+#include "linux/mm.h" -+#include "linux/vmalloc.h" -+#include "linux/blkpg.h" -+#include "linux/genhd.h" -+#include "linux/spinlock.h" -+#include "asm/segment.h" -+#include "asm/uaccess.h" -+#include "asm/irq.h" -+#include "asm/types.h" -+#include "user_util.h" -+#include "mem_user.h" -+#include "kern_util.h" -+#include "kern.h" -+#include "mconsole_kern.h" -+#include "init.h" -+#include "irq_user.h" -+#include "irq_kern.h" -+#include "ubd_user.h" -+#include "2_5compat.h" -+#include "os.h" -+#include "mem.h" -+#include "mem_kern.h" -+ -+static int ubd_open(struct inode * inode, struct file * filp); -+static int ubd_release(struct inode * inode, struct file * file); -+static int ubd_ioctl(struct inode * inode, struct file * file, -+ unsigned int cmd, unsigned long arg); -+static int ubd_revalidate(kdev_t rdev); -+static int ubd_revalidate1(kdev_t rdev); -+ -+#define MAX_DEV (8) -+#define MAX_MINOR (MAX_DEV << UBD_SHIFT) -+ -+/* Changed in early boot */ -+static int ubd_do_mmap = 0; -+#define UBD_MMAP_BLOCK_SIZE PAGE_SIZE -+ -+/* Not modified by this driver */ -+static int blk_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = BLOCK_SIZE }; -+static int hardsect_sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 512 }; -+ -+/* Protected by ubd_lock */ -+static int sizes[MAX_MINOR] = { [ 0 ... MAX_MINOR - 1 ] = 0 }; -+ -+static struct block_device_operations ubd_blops = { -+ .open = ubd_open, -+ .release = ubd_release, -+ .ioctl = ubd_ioctl, -+ .revalidate = ubd_revalidate, -+}; -+ -+/* Protected by ubd_lock, except in prepare_request and ubd_ioctl because -+ * the block layer should ensure that the device is idle before closing it. -+ */ -+static struct hd_struct ubd_part[MAX_MINOR] = -+ { [ 0 ... MAX_MINOR - 1 ] = { 0, 0, 0 } }; -+ -+/* Protected by io_request_lock */ -+static request_queue_t *ubd_queue; -+ -+/* Protected by ubd_lock */ -+static int fake_major = MAJOR_NR; -+ -+static spinlock_t ubd_lock = SPIN_LOCK_UNLOCKED; -+ -+#define INIT_GENDISK(maj, name, parts, shift, bsizes, max, blops) \ -+{ \ -+ .major = maj, \ -+ .major_name = name, \ -+ .minor_shift = shift, \ -+ .max_p = 1 << shift, \ -+ .part = parts, \ -+ .sizes = bsizes, \ -+ .nr_real = max, \ -+ .real_devices = NULL, \ -+ .next = NULL, \ -+ .fops = blops, \ -+ .de_arr = NULL, \ -+ .flags = 0 \ -+} -+ -+static struct gendisk ubd_gendisk = INIT_GENDISK(MAJOR_NR, "ubd", ubd_part, -+ UBD_SHIFT, sizes, MAX_DEV, -+ &ubd_blops); -+static struct gendisk fake_gendisk = INIT_GENDISK(0, "ubd", ubd_part, -+ UBD_SHIFT, sizes, MAX_DEV, -+ &ubd_blops); -+ -+#ifdef CONFIG_BLK_DEV_UBD_SYNC -+#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 1, .c = 0, \ -+ .cl = 1 }) -+#else -+#define OPEN_FLAGS ((struct openflags) { .r = 1, .w = 1, .s = 0, .c = 0, \ -+ .cl = 1 }) -+#endif -+ -+/* Not protected - changed only in ubd_setup_common and then only to -+ * to enable O_SYNC. -+ */ -+static struct openflags global_openflags = OPEN_FLAGS; -+ -+struct cow { -+ char *file; -+ int fd; -+ unsigned long *bitmap; -+ unsigned long bitmap_len; -+ int bitmap_offset; -+ int data_offset; -+}; -+ -+struct ubd { -+ char *file; -+ int count; -+ int fd; -+ __u64 size; -+ struct openflags boot_openflags; -+ struct openflags openflags; -+ devfs_handle_t devfs; -+ int no_cow; -+ struct cow cow; -+ -+ int map_writes; -+ int map_reads; -+ int nomap_writes; -+ int nomap_reads; -+ int write_maps; -+}; -+ -+#define DEFAULT_COW { \ -+ .file = NULL, \ -+ .fd = -1, \ -+ .bitmap = NULL, \ -+ .bitmap_offset = 0, \ -+ .data_offset = 0, \ -+} -+ -+#define DEFAULT_UBD { \ -+ .file = NULL, \ -+ .count = 0, \ -+ .fd = -1, \ -+ .size = -1, \ -+ .boot_openflags = OPEN_FLAGS, \ -+ .openflags = OPEN_FLAGS, \ -+ .devfs = NULL, \ -+ .no_cow = 0, \ -+ .cow = DEFAULT_COW, \ -+ .map_writes = 0, \ -+ .map_reads = 0, \ -+ .nomap_writes = 0, \ -+ .nomap_reads = 0, \ -+ .write_maps = 0, \ -+} -+ -+struct ubd ubd_dev[MAX_DEV] = { [ 0 ... MAX_DEV - 1 ] = DEFAULT_UBD }; -+ -+static int ubd0_init(void) -+{ -+ struct ubd *dev = &ubd_dev[0]; -+ -+ if(dev->file == NULL) -+ dev->file = "root_fs"; -+ return(0); -+} -+ -+__initcall(ubd0_init); -+ -+/* Only changed by fake_ide_setup which is a setup */ -+static int fake_ide = 0; -+static struct proc_dir_entry *proc_ide_root = NULL; -+static struct proc_dir_entry *proc_ide = NULL; -+ -+static void make_proc_ide(void) -+{ -+ proc_ide_root = proc_mkdir("ide", 0); -+ proc_ide = proc_mkdir("ide0", proc_ide_root); -+} -+ -+static int proc_ide_read_media(char *page, char **start, off_t off, int count, -+ int *eof, void *data) -+{ -+ int len; -+ -+ strcpy(page, "disk\n"); -+ len = strlen("disk\n"); -+ len -= off; -+ if (len < count){ -+ *eof = 1; -+ if (len <= 0) return 0; -+ } -+ else len = count; -+ *start = page + off; -+ return len; -+} -+ -+static void make_ide_entries(char *dev_name) -+{ -+ struct proc_dir_entry *dir, *ent; -+ char name[64]; -+ -+ if(!fake_ide) return; -+ -+ /* Without locking this could race if a UML was booted with no -+ * disks and then two mconsole requests which add disks came in -+ * at the same time. -+ */ -+ spin_lock(&ubd_lock); -+ if(proc_ide_root == NULL) make_proc_ide(); -+ spin_unlock(&ubd_lock); -+ -+ dir = proc_mkdir(dev_name, proc_ide); -+ if(!dir) return; -+ -+ ent = create_proc_entry("media", S_IFREG|S_IRUGO, dir); -+ if(!ent) return; -+ ent->nlink = 1; -+ ent->data = NULL; -+ ent->read_proc = proc_ide_read_media; -+ ent->write_proc = NULL; -+ sprintf(name,"ide0/%s", dev_name); -+ proc_symlink(dev_name, proc_ide_root, name); -+} -+ -+static int fake_ide_setup(char *str) -+{ -+ fake_ide = 1; -+ return(1); -+} -+ -+__setup("fake_ide", fake_ide_setup); -+ -+__uml_help(fake_ide_setup, -+"fake_ide\n" -+" Create ide0 entries that map onto ubd devices.\n\n" -+); -+ -+static int parse_unit(char **ptr) -+{ -+ char *str = *ptr, *end; -+ int n = -1; -+ -+ if(isdigit(*str)) { -+ n = simple_strtoul(str, &end, 0); -+ if(end == str) -+ return(-1); -+ *ptr = end; -+ } -+ else if (('a' <= *str) && (*str <= 'h')) { -+ n = *str - 'a'; -+ str++; -+ *ptr = str; -+ } -+ return(n); -+} -+ -+static int ubd_setup_common(char *str, int *index_out) -+{ -+ struct openflags flags = global_openflags; -+ struct ubd *dev; -+ char *backing_file; -+ int n, err; -+ -+ if(index_out) *index_out = -1; -+ n = *str; -+ if(n == '='){ -+ char *end; -+ int major; -+ -+ str++; -+ if(!strcmp(str, "mmap")){ -+ CHOOSE_MODE(printk("mmap not supported by the ubd " -+ "driver in tt mode\n"), -+ ubd_do_mmap = 1); -+ return(0); -+ } -+ -+ if(!strcmp(str, "sync")){ -+ global_openflags.s = 1; -+ return(0); -+ } -+ major = simple_strtoul(str, &end, 0); -+ if((*end != '\0') || (end == str)){ -+ printk(KERN_ERR -+ "ubd_setup : didn't parse major number\n"); -+ return(1); -+ } -+ -+ err = 1; -+ spin_lock(&ubd_lock); -+ if(fake_major != MAJOR_NR){ -+ printk(KERN_ERR "Can't assign a fake major twice\n"); -+ goto out1; -+ } -+ -+ fake_gendisk.major = major; -+ fake_major = major; -+ -+ printk(KERN_INFO "Setting extra ubd major number to %d\n", -+ major); -+ err = 0; -+ out1: -+ spin_unlock(&ubd_lock); -+ return(err); -+ } -+ -+ n = parse_unit(&str); -+ if(n < 0){ -+ printk(KERN_ERR "ubd_setup : couldn't parse unit number " -+ "'%s'\n", str); -+ return(1); -+ } -+ -+ if(n >= MAX_DEV){ -+ printk(KERN_ERR "ubd_setup : index %d out of range " -+ "(%d devices)\n", n, MAX_DEV); -+ return(1); -+ } -+ -+ err = 1; -+ spin_lock(&ubd_lock); -+ -+ dev = &ubd_dev[n]; -+ if(dev->file != NULL){ -+ printk(KERN_ERR "ubd_setup : device already configured\n"); -+ goto out2; -+ } -+ -+ if(index_out) *index_out = n; -+ -+ if(*str == 'r'){ -+ flags.w = 0; -+ str++; -+ } -+ if(*str == 's'){ -+ flags.s = 1; -+ str++; -+ } -+ if(*str == 'd'){ -+ dev->no_cow = 1; -+ str++; -+ } -+ -+ if(*str++ != '='){ -+ printk(KERN_ERR "ubd_setup : Expected '='\n"); -+ goto out2; -+ } -+ -+ err = 0; -+ backing_file = strchr(str, ','); -+ if(backing_file){ -+ if(dev->no_cow) -+ printk(KERN_ERR "Can't specify both 'd' and a " -+ "cow file\n"); -+ else { -+ *backing_file = '\0'; -+ backing_file++; -+ } -+ } -+ dev->file = str; -+ dev->cow.file = backing_file; -+ dev->boot_openflags = flags; -+ out2: -+ spin_unlock(&ubd_lock); -+ return(err); -+} -+ -+static int ubd_setup(char *str) -+{ -+ ubd_setup_common(str, NULL); -+ return(1); -+} -+ -+__setup("ubd", ubd_setup); -+__uml_help(ubd_setup, -+"ubd=\n" -+" This is used to associate a device with a file in the underlying\n" -+" filesystem. Usually, there is a filesystem in the file, but \n" -+" that's not required. Swap devices containing swap files can be\n" -+" specified like this. Also, a file which doesn't contain a\n" -+" filesystem can have its contents read in the virtual \n" -+" machine by running dd on the device. n must be in the range\n" -+" 0 to 7. Appending an 'r' to the number will cause that device\n" -+" to be mounted read-only. For example ubd1r=./ext_fs. Appending\n" -+" an 's' (has to be _after_ 'r', if there is one) will cause data\n" -+" to be written to disk on the host immediately.\n\n" -+); -+ -+static int fakehd(char *str) -+{ -+ printk(KERN_INFO -+ "fakehd : Changing ubd_gendisk.major_name to \"hd\".\n"); -+ ubd_gendisk.major_name = "hd"; -+ return(1); -+} -+ -+__setup("fakehd", fakehd); -+__uml_help(fakehd, -+"fakehd\n" -+" Change the ubd device name to \"hd\".\n\n" -+); -+ -+static void do_ubd_request(request_queue_t * q); -+ -+/* Only changed by ubd_init, which is an initcall. */ -+int thread_fd = -1; -+ -+/* Changed by ubd_handler, which is serialized because interrupts only -+ * happen on CPU 0. -+ */ -+int intr_count = 0; -+ -+static void ubd_finish(int error) -+{ -+ int nsect; -+ -+ if(error){ -+ end_request(0); -+ return; -+ } -+ nsect = CURRENT->current_nr_sectors; -+ CURRENT->sector += nsect; -+ CURRENT->buffer += nsect << 9; -+ CURRENT->errors = 0; -+ CURRENT->nr_sectors -= nsect; -+ CURRENT->current_nr_sectors = 0; -+ end_request(1); -+} -+ -+static void ubd_handler(void) -+{ -+ struct io_thread_req req; -+ int n, err; -+ -+ DEVICE_INTR = NULL; -+ intr_count++; -+ n = read_ubd_fs(thread_fd, &req, sizeof(req)); -+ if(n != sizeof(req)){ -+ printk(KERN_ERR "Pid %d - spurious interrupt in ubd_handler, " -+ "err = %d\n", os_getpid(), -n); -+ spin_lock(&io_request_lock); -+ end_request(0); -+ spin_unlock(&io_request_lock); -+ return; -+ } -+ -+ if((req.op != UBD_MMAP) && -+ ((req.offset != ((__u64) (CURRENT->sector)) << 9) || -+ (req.length != (CURRENT->current_nr_sectors) << 9))) -+ panic("I/O op mismatch"); -+ -+ if(req.map_fd != -1){ -+ err = physmem_subst_mapping(req.buffer, req.map_fd, -+ req.map_offset, 1); -+ if(err) -+ printk("ubd_handler - physmem_subst_mapping failed, " -+ "err = %d\n", -err); -+ } -+ -+ spin_lock(&io_request_lock); -+ ubd_finish(req.error); -+ reactivate_fd(thread_fd, UBD_IRQ); -+ do_ubd_request(ubd_queue); -+ spin_unlock(&io_request_lock); -+} -+ -+static void ubd_intr(int irq, void *dev, struct pt_regs *unused) -+{ -+ ubd_handler(); -+} -+ -+/* Only changed by ubd_init, which is an initcall. */ -+static int io_pid = -1; -+ -+void kill_io_thread(void) -+{ -+ if(io_pid != -1) -+ os_kill_process(io_pid, 1); -+} -+ -+__uml_exitcall(kill_io_thread); -+ -+/* Initialized in an initcall, and unchanged thereafter */ -+devfs_handle_t ubd_dir_handle; -+ -+static int ubd_add(int n) -+{ -+ struct ubd *dev = &ubd_dev[n]; -+ char name[sizeof("nnnnnn\0")], dev_name[sizeof("ubd0x")]; -+ int err = -EISDIR; -+ -+ if(dev->file == NULL) -+ goto out; -+ -+ err = ubd_revalidate1(MKDEV(MAJOR_NR, n << UBD_SHIFT)); -+ if(err) -+ goto out; -+ -+ if(dev->cow.file == NULL) -+ blk_sizes[n] = UBD_MMAP_BLOCK_SIZE; -+ -+ sprintf(name, "%d", n); -+ dev->devfs = devfs_register(ubd_dir_handle, name, DEVFS_FL_REMOVABLE, -+ MAJOR_NR, n << UBD_SHIFT, S_IFBLK | -+ S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP, -+ &ubd_blops, NULL); -+ -+#if 0 /* 2.5 ... */ -+ sprintf(disk->disk_name, "ubd%c", 'a' + unit); -+#endif -+ -+ sprintf(dev_name, "%s%c", ubd_gendisk.major_name, -+ n + 'a'); -+ -+ make_ide_entries(dev_name); -+ return(0); -+ -+ out: -+ return(err); -+} -+ -+static int ubd_config(char *str) -+{ -+ int n, err; -+ -+ str = uml_strdup(str); -+ if(str == NULL){ -+ printk(KERN_ERR "ubd_config failed to strdup string\n"); -+ return(1); -+ } -+ err = ubd_setup_common(str, &n); -+ if(err){ -+ kfree(str); -+ return(-1); -+ } -+ if(n == -1) return(0); -+ -+ spin_lock(&ubd_lock); -+ err = ubd_add(n); -+ if(err) -+ ubd_dev[n].file = NULL; -+ spin_unlock(&ubd_lock); -+ -+ return(err); -+} -+ -+static int ubd_get_config(char *name, char *str, int size, char **error_out) -+{ -+ struct ubd *dev; -+ char *end; -+ int n, len = 0; -+ -+ n = simple_strtoul(name, &end, 0); -+ if((*end != '\0') || (end == name)){ -+ *error_out = "ubd_get_config : didn't parse device number"; -+ return(-1); -+ } -+ -+ if((n >= MAX_DEV) || (n < 0)){ -+ *error_out = "ubd_get_config : device number out of range"; -+ return(-1); -+ } -+ -+ dev = &ubd_dev[n]; -+ spin_lock(&ubd_lock); -+ -+ if(dev->file == NULL){ -+ CONFIG_CHUNK(str, size, len, "", 1); -+ goto out; -+ } -+ -+ CONFIG_CHUNK(str, size, len, dev->file, 0); -+ -+ if(dev->cow.file != NULL){ -+ CONFIG_CHUNK(str, size, len, ",", 0); -+ CONFIG_CHUNK(str, size, len, dev->cow.file, 1); -+ } -+ else CONFIG_CHUNK(str, size, len, "", 1); -+ -+ out: -+ spin_unlock(&ubd_lock); -+ return(len); -+} -+ -+static int ubd_remove(char *str) -+{ -+ struct ubd *dev; -+ int n, err = -ENODEV; -+ -+ if(isdigit(*str)){ -+ char *end; -+ n = simple_strtoul(str, &end, 0); -+ if ((*end != '\0') || (end == str)) -+ return(err); -+ } -+ else if (('a' <= *str) && (*str <= 'h')) -+ n = *str - 'a'; -+ else -+ return(err); /* it should be a number 0-7/a-h */ -+ -+ if((n < 0) || (n >= MAX_DEV)) -+ return(err); -+ -+ dev = &ubd_dev[n]; -+ -+ spin_lock(&ubd_lock); -+ err = 0; -+ if(dev->file == NULL) -+ goto out; -+ err = -1; -+ if(dev->count > 0) -+ goto out; -+ if(dev->devfs != NULL) -+ devfs_unregister(dev->devfs); -+ -+ *dev = ((struct ubd) DEFAULT_UBD); -+ err = 0; -+ out: -+ spin_unlock(&ubd_lock); -+ return(err); -+} -+ -+static struct mc_device ubd_mc = { -+ .name = "ubd", -+ .config = ubd_config, -+ .get_config = ubd_get_config, -+ .remove = ubd_remove, -+}; -+ -+static int ubd_mc_init(void) -+{ -+ mconsole_register_dev(&ubd_mc); -+ return(0); -+} -+ -+__initcall(ubd_mc_init); -+ -+static request_queue_t *ubd_get_queue(kdev_t device) -+{ -+ return(ubd_queue); -+} -+ -+int ubd_init(void) -+{ -+ unsigned long stack; -+ int i, err; -+ -+ ubd_dir_handle = devfs_mk_dir (NULL, "ubd", NULL); -+ if (devfs_register_blkdev(MAJOR_NR, "ubd", &ubd_blops)) { -+ printk(KERN_ERR "ubd: unable to get major %d\n", MAJOR_NR); -+ return -1; -+ } -+ read_ahead[MAJOR_NR] = 8; /* 8 sector (4kB) read-ahead */ -+ blksize_size[MAJOR_NR] = blk_sizes; -+ blk_size[MAJOR_NR] = sizes; -+ INIT_HARDSECT(hardsect_size, MAJOR_NR, hardsect_sizes); -+ -+ ubd_queue = BLK_DEFAULT_QUEUE(MAJOR_NR); -+ blk_init_queue(ubd_queue, DEVICE_REQUEST); -+ INIT_ELV(ubd_queue, &ubd_queue->elevator); -+ -+ add_gendisk(&ubd_gendisk); -+ if (fake_major != MAJOR_NR){ -+ /* major number 0 is used to auto select */ -+ err = devfs_register_blkdev(fake_major, "fake", &ubd_blops); -+ if(fake_major == 0){ -+ /* auto device number case */ -+ fake_major = err; -+ if(err == 0) -+ return(-ENODEV); -+ } -+ else if (err){ -+ /* not auto so normal error */ -+ printk(KERN_ERR "ubd: error %d getting major %d\n", -+ -err, fake_major); -+ return(-ENODEV); -+ } -+ -+ blk_dev[fake_major].queue = ubd_get_queue; -+ read_ahead[fake_major] = 8; /* 8 sector (4kB) read-ahead */ -+ blksize_size[fake_major] = blk_sizes; -+ blk_size[fake_major] = sizes; -+ INIT_HARDSECT(hardsect_size, fake_major, hardsect_sizes); -+ add_gendisk(&fake_gendisk); -+ } -+ -+ for(i=0;ifd); -+ os_close_file(dev->fd); -+ if(dev->cow.file != NULL) -+ return; -+ -+ if(ubd_do_mmap) -+ physmem_forget_descriptor(dev->cow.fd); -+ os_close_file(dev->cow.fd); -+ vfree(dev->cow.bitmap); -+ dev->cow.bitmap = NULL; -+} -+ -+static int ubd_open_dev(struct ubd *dev) -+{ -+ struct openflags flags; -+ char **back_ptr; -+ int err, create_cow, *create_ptr; -+ -+ dev->openflags = dev->boot_openflags; -+ create_cow = 0; -+ create_ptr = (dev->cow.file != NULL) ? &create_cow : NULL; -+ back_ptr = dev->no_cow ? NULL : &dev->cow.file; -+ dev->fd = open_ubd_file(dev->file, &dev->openflags, back_ptr, -+ &dev->cow.bitmap_offset, &dev->cow.bitmap_len, -+ &dev->cow.data_offset, create_ptr); -+ -+ if((dev->fd == -ENOENT) && create_cow){ -+ dev->fd = create_cow_file(dev->file, dev->cow.file, -+ dev->openflags, 1 << 9, PAGE_SIZE, -+ &dev->cow.bitmap_offset, -+ &dev->cow.bitmap_len, -+ &dev->cow.data_offset); -+ if(dev->fd >= 0){ -+ printk(KERN_INFO "Creating \"%s\" as COW file for " -+ "\"%s\"\n", dev->file, dev->cow.file); -+ } -+ } -+ -+ if(dev->fd < 0) return(dev->fd); -+ -+ if(dev->cow.file != NULL){ -+ err = -ENOMEM; -+ dev->cow.bitmap = (void *) vmalloc(dev->cow.bitmap_len); -+ if(dev->cow.bitmap == NULL){ -+ printk(KERN_ERR "Failed to vmalloc COW bitmap\n"); -+ goto error; -+ } -+ flush_tlb_kernel_vm(); -+ -+ err = read_cow_bitmap(dev->fd, dev->cow.bitmap, -+ dev->cow.bitmap_offset, -+ dev->cow.bitmap_len); -+ if(err < 0) -+ goto error; -+ -+ flags = dev->openflags; -+ flags.w = 0; -+ err = open_ubd_file(dev->cow.file, &flags, NULL, NULL, NULL, -+ NULL, NULL); -+ if(err < 0) goto error; -+ dev->cow.fd = err; -+ } -+ return(0); -+ error: -+ os_close_file(dev->fd); -+ return(err); -+} -+ -+static int ubd_file_size(struct ubd *dev, __u64 *size_out) -+{ -+ char *file; -+ -+ file = dev->cow.file ? dev->cow.file : dev->file; -+ return(os_file_size(file, size_out)); -+} -+ -+static int ubd_open(struct inode *inode, struct file *filp) -+{ -+ struct ubd *dev; -+ int n, offset, err = 0; -+ -+ n = DEVICE_NR(inode->i_rdev); -+ dev = &ubd_dev[n]; -+ if(n >= MAX_DEV) -+ return -ENODEV; -+ -+ spin_lock(&ubd_lock); -+ offset = n << UBD_SHIFT; -+ -+ if(dev->count == 0){ -+ err = ubd_open_dev(dev); -+ if(err){ -+ printk(KERN_ERR "ubd%d: Can't open \"%s\": " -+ "errno = %d\n", n, dev->file, -err); -+ goto out; -+ } -+ err = ubd_file_size(dev, &dev->size); -+ if(err < 0) -+ goto out; -+ sizes[offset] = dev->size / BLOCK_SIZE; -+ ubd_part[offset].nr_sects = dev->size / hardsect_sizes[offset]; -+ } -+ dev->count++; -+ if((filp->f_mode & FMODE_WRITE) && !dev->openflags.w){ -+ if(--dev->count == 0) ubd_close(dev); -+ err = -EROFS; -+ } -+ out: -+ spin_unlock(&ubd_lock); -+ return(err); -+} -+ -+static int ubd_release(struct inode * inode, struct file * file) -+{ -+ int n, offset; -+ -+ n = DEVICE_NR(inode->i_rdev); -+ offset = n << UBD_SHIFT; -+ if(n >= MAX_DEV) -+ return -ENODEV; -+ -+ spin_lock(&ubd_lock); -+ if(--ubd_dev[n].count == 0) -+ ubd_close(&ubd_dev[n]); -+ spin_unlock(&ubd_lock); -+ -+ return(0); -+} -+ -+static void cowify_bitmap(__u64 io_offset, int length, unsigned long *cow_mask, -+ __u64 *cow_offset, unsigned long *bitmap, -+ __u64 bitmap_offset, unsigned long *bitmap_words, -+ __u64 bitmap_len) -+{ -+ __u64 sector = io_offset >> 9; -+ int i, update_bitmap = 0; -+ -+ for(i = 0; i < length >> 9; i++){ -+ if(cow_mask != NULL) -+ ubd_set_bit(i, (unsigned char *) cow_mask); -+ if(ubd_test_bit(sector + i, (unsigned char *) bitmap)) -+ continue; -+ -+ update_bitmap = 1; -+ ubd_set_bit(sector + i, (unsigned char *) bitmap); -+ } -+ -+ if(!update_bitmap) -+ return; -+ -+ *cow_offset = sector / (sizeof(unsigned long) * 8); -+ -+ /* This takes care of the case where we're exactly at the end of the -+ * device, and *cow_offset + 1 is off the end. So, just back it up -+ * by one word. Thanks to Lynn Kerby for the fix and James McMechan -+ * for the original diagnosis. -+ */ -+ if(*cow_offset == ((bitmap_len + sizeof(unsigned long) - 1) / -+ sizeof(unsigned long) - 1)) -+ (*cow_offset)--; -+ -+ bitmap_words[0] = bitmap[*cow_offset]; -+ bitmap_words[1] = bitmap[*cow_offset + 1]; -+ -+ *cow_offset *= sizeof(unsigned long); -+ *cow_offset += bitmap_offset; -+} -+ -+static void cowify_req(struct io_thread_req *req, unsigned long *bitmap, -+ __u64 bitmap_offset, __u64 bitmap_len) -+{ -+ __u64 sector = req->offset >> 9; -+ int i; -+ -+ if(req->length > (sizeof(req->sector_mask) * 8) << 9) -+ panic("Operation too long"); -+ -+ if(req->op == UBD_READ) { -+ for(i = 0; i < req->length >> 9; i++){ -+ if(ubd_test_bit(sector + i, (unsigned char *) bitmap)){ -+ ubd_set_bit(i, (unsigned char *) -+ &req->sector_mask); -+ } -+ } -+ } -+ else cowify_bitmap(req->offset, req->length, &req->sector_mask, -+ &req->cow_offset, bitmap, bitmap_offset, -+ req->bitmap_words, bitmap_len); -+} -+ -+static int mmap_fd(struct request *req, struct ubd *dev, __u64 offset) -+{ -+ __u64 sector; -+ unsigned char *bitmap; -+ int bit, i; -+ -+ /* mmap must have been requested on the command line */ -+ if(!ubd_do_mmap) -+ return(-1); -+ -+ /* The buffer must be page aligned */ -+ if(((unsigned long) req->buffer % UBD_MMAP_BLOCK_SIZE) != 0) -+ return(-1); -+ -+ /* The request must be a page long */ -+ if((req->current_nr_sectors << 9) != PAGE_SIZE) -+ return(-1); -+ -+ if(dev->cow.file == NULL) -+ return(dev->fd); -+ -+ sector = offset >> 9; -+ bitmap = (unsigned char *) dev->cow.bitmap; -+ bit = ubd_test_bit(sector, bitmap); -+ -+ for(i = 1; i < req->current_nr_sectors; i++){ -+ if(ubd_test_bit(sector + i, bitmap) != bit) -+ return(-1); -+ } -+ -+ if(bit || (req->cmd == WRITE)) -+ offset += dev->cow.data_offset; -+ -+ /* The data on disk must be page aligned */ -+ if((offset % UBD_MMAP_BLOCK_SIZE) != 0) -+ return(-1); -+ -+ return(bit ? dev->fd : dev->cow.fd); -+} -+ -+static int prepare_mmap_request(struct ubd *dev, int fd, __u64 offset, -+ struct request *req, -+ struct io_thread_req *io_req) -+{ -+ int err; -+ -+ if(req->cmd == WRITE){ -+ /* Writes are almost no-ops since the new data is already in the -+ * host page cache -+ */ -+ dev->map_writes++; -+ if(dev->cow.file != NULL) -+ cowify_bitmap(io_req->offset, io_req->length, -+ &io_req->sector_mask, &io_req->cow_offset, -+ dev->cow.bitmap, dev->cow.bitmap_offset, -+ io_req->bitmap_words, -+ dev->cow.bitmap_len); -+ } -+ else { -+ int w; -+ -+ if((dev->cow.file != NULL) && (fd == dev->cow.fd)) -+ w = 0; -+ else w = dev->openflags.w; -+ -+ if((dev->cow.file != NULL) && (fd == dev->fd)) -+ offset += dev->cow.data_offset; -+ -+ err = physmem_subst_mapping(req->buffer, fd, offset, w); -+ if(err){ -+ printk("physmem_subst_mapping failed, err = %d\n", -+ -err); -+ return(1); -+ } -+ dev->map_reads++; -+ } -+ io_req->op = UBD_MMAP; -+ io_req->buffer = req->buffer; -+ return(0); -+} -+ -+static int prepare_request(struct request *req, struct io_thread_req *io_req) -+{ -+ struct ubd *dev; -+ __u64 offset; -+ int minor, n, len, fd; -+ -+ if(req->rq_status == RQ_INACTIVE) return(1); -+ -+ minor = MINOR(req->rq_dev); -+ n = minor >> UBD_SHIFT; -+ dev = &ubd_dev[n]; -+ -+ if(IS_WRITE(req) && !dev->openflags.w){ -+ printk("Write attempted on readonly ubd device %d\n", n); -+ end_request(0); -+ return(1); -+ } -+ -+ req->sector += ubd_part[minor].start_sect; -+ offset = ((__u64) req->sector) << 9; -+ len = req->current_nr_sectors << 9; -+ -+ io_req->fds[0] = (dev->cow.file != NULL) ? dev->cow.fd : dev->fd; -+ io_req->fds[1] = dev->fd; -+ io_req->map_fd = -1; -+ io_req->cow_offset = -1; -+ io_req->offset = offset; -+ io_req->length = len; -+ io_req->error = 0; -+ io_req->sector_mask = 0; -+ -+ fd = mmap_fd(req, dev, io_req->offset); -+ if(fd > 0){ -+ /* If mmapping is otherwise OK, but the first access to the -+ * page is a write, then it's not mapped in yet. So we have -+ * to write the data to disk first, then we can map the disk -+ * page in and continue normally from there. -+ */ -+ if((req->cmd == WRITE) && !is_remapped(req->buffer)){ -+ io_req->map_fd = dev->fd; -+ io_req->map_offset = io_req->offset + -+ dev->cow.data_offset; -+ dev->write_maps++; -+ } -+ else return(prepare_mmap_request(dev, fd, io_req->offset, req, -+ io_req)); -+ } -+ -+ if(req->cmd == READ) -+ dev->nomap_reads++; -+ else dev->nomap_writes++; -+ -+ io_req->op = (req->cmd == READ) ? UBD_READ : UBD_WRITE; -+ io_req->offsets[0] = 0; -+ io_req->offsets[1] = dev->cow.data_offset; -+ io_req->buffer = req->buffer; -+ io_req->sectorsize = 1 << 9; -+ -+ if(dev->cow.file != NULL) -+ cowify_req(io_req, dev->cow.bitmap, dev->cow.bitmap_offset, -+ dev->cow.bitmap_len); -+ return(0); -+} -+ -+static void do_ubd_request(request_queue_t *q) -+{ -+ struct io_thread_req io_req; -+ struct request *req; -+ int err, n; -+ -+ if(thread_fd == -1){ -+ while(!list_empty(&q->queue_head)){ -+ req = blkdev_entry_next_request(&q->queue_head); -+ err = prepare_request(req, &io_req); -+ if(!err){ -+ do_io(&io_req); -+ ubd_finish(io_req.error); -+ } -+ } -+ } -+ else { -+ if(DEVICE_INTR || list_empty(&q->queue_head)) return; -+ req = blkdev_entry_next_request(&q->queue_head); -+ err = prepare_request(req, &io_req); -+ if(!err){ -+ SET_INTR(ubd_handler); -+ n = write_ubd_fs(thread_fd, (char *) &io_req, -+ sizeof(io_req)); -+ if(n != sizeof(io_req)) -+ printk("write to io thread failed, " -+ "errno = %d\n", -n); -+ } -+ } -+} -+ -+static int ubd_ioctl(struct inode * inode, struct file * file, -+ unsigned int cmd, unsigned long arg) -+{ -+ struct hd_geometry *loc = (struct hd_geometry *) arg; -+ struct ubd *dev; -+ int n, minor, err; -+ struct hd_driveid ubd_id = { -+ .cyls = 0, -+ .heads = 128, -+ .sectors = 32, -+ }; -+ -+ if(!inode) return(-EINVAL); -+ minor = MINOR(inode->i_rdev); -+ n = minor >> UBD_SHIFT; -+ if(n >= MAX_DEV) -+ return(-EINVAL); -+ dev = &ubd_dev[n]; -+ switch (cmd) { -+ struct hd_geometry g; -+ struct cdrom_volctrl volume; -+ case HDIO_GETGEO: -+ if(!loc) return(-EINVAL); -+ g.heads = 128; -+ g.sectors = 32; -+ g.cylinders = dev->size / (128 * 32 * hardsect_sizes[minor]); -+ g.start = ubd_part[minor].start_sect; -+ return(copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0); -+ case BLKGETSIZE: /* Return device size */ -+ if(!arg) return(-EINVAL); -+ err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long)); -+ if(err) -+ return(err); -+ put_user(ubd_part[minor].nr_sects, (long *) arg); -+ return(0); -+ case BLKRRPART: /* Re-read partition tables */ -+ return(ubd_revalidate(inode->i_rdev)); -+ -+ case HDIO_SET_UNMASKINTR: -+ if(!capable(CAP_SYS_ADMIN)) return(-EACCES); -+ if((arg > 1) || (minor & 0x3F)) return(-EINVAL); -+ return(0); -+ -+ case HDIO_GET_UNMASKINTR: -+ if(!arg) return(-EINVAL); -+ err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long)); -+ if(err) -+ return(err); -+ return(0); -+ -+ case HDIO_GET_MULTCOUNT: -+ if(!arg) return(-EINVAL); -+ err = verify_area(VERIFY_WRITE, (long *) arg, sizeof(long)); -+ if(err) -+ return(err); -+ return(0); -+ -+ case HDIO_SET_MULTCOUNT: -+ if(!capable(CAP_SYS_ADMIN)) return(-EACCES); -+ if(MINOR(inode->i_rdev) & 0x3F) return(-EINVAL); -+ return(0); -+ -+ case HDIO_GET_IDENTITY: -+ ubd_id.cyls = dev->size / (128 * 32 * hardsect_sizes[minor]); -+ if(copy_to_user((char *) arg, (char *) &ubd_id, -+ sizeof(ubd_id))) -+ return(-EFAULT); -+ return(0); -+ -+ case CDROMVOLREAD: -+ if(copy_from_user(&volume, (char *) arg, sizeof(volume))) -+ return(-EFAULT); -+ volume.channel0 = 255; -+ volume.channel1 = 255; -+ volume.channel2 = 255; -+ volume.channel3 = 255; -+ if(copy_to_user((char *) arg, &volume, sizeof(volume))) -+ return(-EFAULT); -+ return(0); -+ -+ default: -+ return blk_ioctl(inode->i_rdev, cmd, arg); -+ } -+} -+ -+static int ubd_revalidate1(kdev_t rdev) -+{ -+ int i, n, offset, err = 0, pcount = 1 << UBD_SHIFT; -+ struct ubd *dev; -+ struct hd_struct *part; -+ -+ n = DEVICE_NR(rdev); -+ offset = n << UBD_SHIFT; -+ dev = &ubd_dev[n]; -+ -+ part = &ubd_part[offset]; -+ -+ /* clear all old partition counts */ -+ for(i = 1; i < pcount; i++) { -+ part[i].start_sect = 0; -+ part[i].nr_sects = 0; -+ } -+ -+ /* If it already has been opened we can check the partitions -+ * directly -+ */ -+ if(dev->count){ -+ part->start_sect = 0; -+ register_disk(&ubd_gendisk, MKDEV(MAJOR_NR, offset), pcount, -+ &ubd_blops, part->nr_sects); -+ } -+ else if(dev->file){ -+ err = ubd_open_dev(dev); -+ if(err){ -+ printk(KERN_ERR "unable to open %s for validation\n", -+ dev->file); -+ goto out; -+ } -+ -+ /* have to recompute sizes since we opened it */ -+ err = ubd_file_size(dev, &dev->size); -+ if(err < 0) { -+ ubd_close(dev); -+ goto out; -+ } -+ part->start_sect = 0; -+ part->nr_sects = dev->size / hardsect_sizes[offset]; -+ register_disk(&ubd_gendisk, MKDEV(MAJOR_NR, offset), pcount, -+ &ubd_blops, part->nr_sects); -+ -+ /* we are done so close it */ -+ ubd_close(dev); -+ } -+ else err = -ENODEV; -+ out: -+ return(err); -+} -+ -+static int ubd_revalidate(kdev_t rdev) -+{ -+ int err; -+ -+ spin_lock(&ubd_lock); -+ err = ubd_revalidate1(rdev); -+ spin_unlock(&ubd_lock); -+ return(err); -+} -+ -+static int ubd_check_remapped(int fd, unsigned long address, int is_write, -+ __u64 offset) -+{ -+ __u64 bitmap_offset; -+ unsigned long new_bitmap[2]; -+ int i, err, n; -+ -+ /* If it's not a write access, we can't do anything about it */ -+ if(!is_write) -+ return(0); -+ -+ /* We have a write */ -+ for(i = 0; i < sizeof(ubd_dev) / sizeof(ubd_dev[0]); i++){ -+ struct ubd *dev = &ubd_dev[i]; -+ -+ if((dev->fd != fd) && (dev->cow.fd != fd)) -+ continue; -+ -+ /* It's a write to a ubd device */ -+ -+ if(!dev->openflags.w){ -+ /* It's a write access on a read-only device - probably -+ * shouldn't happen. If the kernel is trying to change -+ * something with no intention of writing it back out, -+ * then this message will clue us in that this needs -+ * fixing -+ */ -+ printk("Write access to mapped page from readonly ubd " -+ "device %d\n", i); -+ return(0); -+ } -+ -+ /* It's a write to a writeable ubd device - it must be COWed -+ * because, otherwise, the page would have been mapped in -+ * writeable -+ */ -+ -+ if(!dev->cow.file) -+ panic("Write fault on writeable non-COW ubd device %d", -+ i); -+ -+ /* It should also be an access to the backing file since the -+ * COW pages should be mapped in read-write -+ */ -+ -+ if(fd == dev->fd) -+ panic("Write fault on a backing page of ubd " -+ "device %d\n", i); -+ -+ /* So, we do the write, copying the backing data to the COW -+ * file... -+ */ -+ -+ err = os_seek_file(dev->fd, offset + dev->cow.data_offset); -+ if(err < 0) -+ panic("Couldn't seek to %lld in COW file of ubd " -+ "device %d, err = %d", -+ offset + dev->cow.data_offset, i, -err); -+ -+ n = os_write_file(dev->fd, (void *) address, PAGE_SIZE); -+ if(n != PAGE_SIZE) -+ panic("Couldn't copy data to COW file of ubd " -+ "device %d, err = %d", i, -n); -+ -+ /* ... updating the COW bitmap... */ -+ -+ cowify_bitmap(offset, PAGE_SIZE, NULL, &bitmap_offset, -+ dev->cow.bitmap, dev->cow.bitmap_offset, -+ new_bitmap, dev->cow.bitmap_len); -+ -+ err = os_seek_file(dev->fd, bitmap_offset); -+ if(err < 0) -+ panic("Couldn't seek to %lld in COW file of ubd " -+ "device %d, err = %d", bitmap_offset, i, -err); -+ -+ n = os_write_file(dev->fd, new_bitmap, sizeof(new_bitmap)); -+ if(n != sizeof(new_bitmap)) -+ panic("Couldn't update bitmap of ubd device %d, " -+ "err = %d", i, -n); -+ -+ /* Maybe we can map the COW page in, and maybe we can't. If -+ * it is a pre-V3 COW file, we can't, since the alignment will -+ * be wrong. If it is a V3 or later COW file which has been -+ * moved to a system with a larger page size, then maybe we -+ * can't, depending on the exact location of the page. -+ */ -+ -+ offset += dev->cow.data_offset; -+ -+ /* Remove the remapping, putting the original anonymous page -+ * back. If the COW file can be mapped in, that is done. -+ * Otherwise, the COW page is read in. -+ */ -+ -+ if(!physmem_remove_mapping((void *) address)) -+ panic("Address 0x%lx not remapped by ubd device %d", -+ address, i); -+ if((offset % UBD_MMAP_BLOCK_SIZE) == 0) -+ physmem_subst_mapping((void *) address, dev->fd, -+ offset, 1); -+ else { -+ err = os_seek_file(dev->fd, offset); -+ if(err < 0) -+ panic("Couldn't seek to %lld in COW file of " -+ "ubd device %d, err = %d", offset, i, -+ -err); -+ -+ n = os_read_file(dev->fd, (void *) address, PAGE_SIZE); -+ if(n != PAGE_SIZE) -+ panic("Failed to read page from offset %llx of " -+ "COW file of ubd device %d, err = %d", -+ offset, i, -n); -+ } -+ -+ return(1); -+ } -+ -+ /* It's not a write on a ubd device */ -+ return(0); -+} -+ -+static struct remapper ubd_remapper = { -+ .list = LIST_HEAD_INIT(ubd_remapper.list), -+ .proc = ubd_check_remapped, -+}; -+ -+static int ubd_remapper_setup(void) -+{ -+ if(ubd_do_mmap) -+ register_remapper(&ubd_remapper); -+ -+ return(0); -+} -+ -+__initcall(ubd_remapper_setup); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/ubd_user.c um/arch/um/drivers/ubd_user.c ---- orig/arch/um/drivers/ubd_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/ubd_user.c 2004-01-10 06:24:52.000000000 -0500 -@@ -0,0 +1,377 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Copyright (C) 2001 Ridgerun,Inc (glonnon@ridgerun.com) -+ * Licensed under the GPL -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "asm/types.h" -+#include "user_util.h" -+#include "kern_util.h" -+#include "user.h" -+#include "ubd_user.h" -+#include "os.h" -+#include "cow.h" -+ -+#include -+#include -+ -+static int same_backing_files(char *from_cmdline, char *from_cow, char *cow) -+{ -+ struct uml_stat buf1, buf2; -+ int err; -+ -+ if(from_cmdline == NULL) return(1); -+ if(!strcmp(from_cmdline, from_cow)) return(1); -+ -+ err = os_stat_file(from_cmdline, &buf1); -+ if(err < 0){ -+ printk("Couldn't stat '%s', err = %d\n", from_cmdline, -err); -+ return(1); -+ } -+ err = os_stat_file(from_cow, &buf2); -+ if(err < 0){ -+ printk("Couldn't stat '%s', err = %d\n", from_cow, -err); -+ return(1); -+ } -+ if((buf1.ust_dev == buf2.ust_dev) && (buf1.ust_ino == buf2.ust_ino)) -+ return(1); -+ -+ printk("Backing file mismatch - \"%s\" requested,\n" -+ "\"%s\" specified in COW header of \"%s\"\n", -+ from_cmdline, from_cow, cow); -+ return(0); -+} -+ -+static int backing_file_mismatch(char *file, __u64 size, time_t mtime) -+{ -+ unsigned long modtime; -+ long long actual; -+ int err; -+ -+ err = os_file_modtime(file, &modtime); -+ if(err < 0){ -+ printk("Failed to get modification time of backing file " -+ "\"%s\", err = %d\n", file, -err); -+ return(err); -+ } -+ -+ err = os_file_size(file, &actual); -+ if(err < 0){ -+ printk("Failed to get size of backing file \"%s\", " -+ "err = %d\n", file, -err); -+ return(err); -+ } -+ -+ if(actual != size){ -+ printk("Size mismatch (%ld vs %ld) of COW header vs backing " -+ "file\n", size, actual); -+ return(-EINVAL); -+ } -+ if(modtime != mtime){ -+ printk("mtime mismatch (%ld vs %ld) of COW header vs backing " -+ "file\n", mtime, modtime); -+ return(-EINVAL); -+ } -+ return(0); -+} -+ -+int read_cow_bitmap(int fd, void *buf, int offset, int len) -+{ -+ int err; -+ -+ err = os_seek_file(fd, offset); -+ if(err < 0) -+ return(err); -+ -+ err = os_read_file(fd, buf, len); -+ if(err < 0) -+ return(err); -+ -+ return(0); -+} -+ -+int open_ubd_file(char *file, struct openflags *openflags, -+ char **backing_file_out, int *bitmap_offset_out, -+ unsigned long *bitmap_len_out, int *data_offset_out, -+ int *create_cow_out) -+{ -+ time_t mtime; -+ __u64 size; -+ __u32 version, align; -+ char *backing_file; -+ int fd, err, sectorsize, same, mode = 0644; -+ -+ fd = os_open_file(file, *openflags, mode); -+ if(fd < 0){ -+ if((fd == -ENOENT) && (create_cow_out != NULL)) -+ *create_cow_out = 1; -+ if(!openflags->w || -+ ((errno != EROFS) && (errno != EACCES))) return(-errno); -+ openflags->w = 0; -+ fd = os_open_file(file, *openflags, mode); -+ if(fd < 0) -+ return(fd); -+ } -+ -+ err = os_lock_file(fd, openflags->w); -+ if(err < 0){ -+ printk("Failed to lock '%s', err = %d\n", file, -err); -+ goto out_close; -+ } -+ -+ if(backing_file_out == NULL) return(fd); -+ -+ err = read_cow_header(file_reader, &fd, &version, &backing_file, &mtime, -+ &size, §orsize, &align, bitmap_offset_out); -+ if(err && (*backing_file_out != NULL)){ -+ printk("Failed to read COW header from COW file \"%s\", " -+ "errno = %d\n", file, -err); -+ goto out_close; -+ } -+ if(err) return(fd); -+ -+ if(backing_file_out == NULL) return(fd); -+ -+ same = same_backing_files(*backing_file_out, backing_file, file); -+ -+ if(!same && !backing_file_mismatch(*backing_file_out, size, mtime)){ -+ printk("Switching backing file to '%s'\n", *backing_file_out); -+ err = write_cow_header(file, fd, *backing_file_out, -+ sectorsize, align, &size); -+ if(err){ -+ printk("Switch failed, errno = %d\n", -err); -+ return(err); -+ } -+ } -+ else { -+ *backing_file_out = backing_file; -+ err = backing_file_mismatch(*backing_file_out, size, mtime); -+ if(err) goto out_close; -+ } -+ -+ cow_sizes(version, size, sectorsize, align, *bitmap_offset_out, -+ bitmap_len_out, data_offset_out); -+ -+ return(fd); -+ out_close: -+ os_close_file(fd); -+ return(err); -+} -+ -+int create_cow_file(char *cow_file, char *backing_file, struct openflags flags, -+ int sectorsize, int alignment, int *bitmap_offset_out, -+ unsigned long *bitmap_len_out, int *data_offset_out) -+{ -+ int err, fd; -+ -+ flags.c = 1; -+ fd = open_ubd_file(cow_file, &flags, NULL, NULL, NULL, NULL, NULL); -+ if(fd < 0){ -+ err = fd; -+ printk("Open of COW file '%s' failed, errno = %d\n", cow_file, -+ -err); -+ goto out; -+ } -+ -+ err = init_cow_file(fd, cow_file, backing_file, sectorsize, alignment, -+ bitmap_offset_out, bitmap_len_out, -+ data_offset_out); -+ if(!err) -+ return(fd); -+ -+ os_close_file(fd); -+ out: -+ return(err); -+} -+ -+/* XXX Just trivial wrappers around os_read_file and os_write_file */ -+int read_ubd_fs(int fd, void *buffer, int len) -+{ -+ return(os_read_file(fd, buffer, len)); -+} -+ -+int write_ubd_fs(int fd, char *buffer, int len) -+{ -+ return(os_write_file(fd, buffer, len)); -+} -+ -+static int update_bitmap(struct io_thread_req *req) -+{ -+ int n; -+ -+ if(req->cow_offset == -1) -+ return(0); -+ -+ n = os_seek_file(req->fds[1], req->cow_offset); -+ if(n < 0){ -+ printk("do_io - bitmap lseek failed : err = %d\n", -n); -+ return(1); -+ } -+ -+ n = os_write_file(req->fds[1], &req->bitmap_words, -+ sizeof(req->bitmap_words)); -+ if(n != sizeof(req->bitmap_words)){ -+ printk("do_io - bitmap update failed, err = %d fd = %d\n", -n, -+ req->fds[1]); -+ return(1); -+ } -+ -+ return(0); -+} -+ -+void do_io(struct io_thread_req *req) -+{ -+ char *buf; -+ unsigned long len; -+ int n, nsectors, start, end, bit; -+ int err; -+ __u64 off; -+ -+ if(req->op == UBD_MMAP){ -+ /* Touch the page to force the host to do any necessary IO to -+ * get it into memory -+ */ -+ n = *((volatile int *) req->buffer); -+ req->error = update_bitmap(req); -+ return; -+ } -+ -+ nsectors = req->length / req->sectorsize; -+ start = 0; -+ do { -+ bit = ubd_test_bit(start, (unsigned char *) &req->sector_mask); -+ end = start; -+ while((end < nsectors) && -+ (ubd_test_bit(end, (unsigned char *) -+ &req->sector_mask) == bit)) -+ end++; -+ -+ off = req->offset + req->offsets[bit] + -+ start * req->sectorsize; -+ len = (end - start) * req->sectorsize; -+ buf = &req->buffer[start * req->sectorsize]; -+ -+ err = os_seek_file(req->fds[bit], off); -+ if(err < 0){ -+ printk("do_io - lseek failed : err = %d\n", -err); -+ req->error = 1; -+ return; -+ } -+ if(req->op == UBD_READ){ -+ n = 0; -+ do { -+ buf = &buf[n]; -+ len -= n; -+ n = os_read_file(req->fds[bit], buf, len); -+ if (n < 0) { -+ printk("do_io - read failed, err = %d " -+ "fd = %d\n", -n, req->fds[bit]); -+ req->error = 1; -+ return; -+ } -+ } while((n < len) && (n != 0)); -+ if (n < len) memset(&buf[n], 0, len - n); -+ } -+ else { -+ n = os_write_file(req->fds[bit], buf, len); -+ if(n != len){ -+ printk("do_io - write failed err = %d " -+ "fd = %d\n", -n, req->fds[bit]); -+ req->error = 1; -+ return; -+ } -+ } -+ -+ start = end; -+ } while(start < nsectors); -+ -+ req->error = update_bitmap(req); -+} -+ -+/* Changed in start_io_thread, which is serialized by being called only -+ * from ubd_init, which is an initcall. -+ */ -+int kernel_fd = -1; -+ -+/* Only changed by the io thread */ -+int io_count = 0; -+ -+int io_thread(void *arg) -+{ -+ struct io_thread_req req; -+ int n; -+ -+ signal(SIGWINCH, SIG_IGN); -+ while(1){ -+ n = os_read_file(kernel_fd, &req, sizeof(req)); -+ if(n != sizeof(req)){ -+ if(n < 0) -+ printk("io_thread - read failed, fd = %d, " -+ "err = %d\n", kernel_fd, -n); -+ else { -+ printk("io_thread - short read, fd = %d, " -+ "length = %d\n", kernel_fd, n); -+ } -+ continue; -+ } -+ io_count++; -+ do_io(&req); -+ n = os_write_file(kernel_fd, &req, sizeof(req)); -+ if(n != sizeof(req)) -+ printk("io_thread - write failed, fd = %d, err = %d\n", -+ kernel_fd, -n); -+ } -+} -+ -+int start_io_thread(unsigned long sp, int *fd_out) -+{ -+ int pid, fds[2], err; -+ -+ err = os_pipe(fds, 1, 1); -+ if(err < 0){ -+ printk("start_io_thread - os_pipe failed, err = %d\n", -err); -+ goto out; -+ } -+ -+ kernel_fd = fds[0]; -+ *fd_out = fds[1]; -+ -+ pid = clone(io_thread, (void *) sp, CLONE_FILES | CLONE_VM | SIGCHLD, -+ NULL); -+ if(pid < 0){ -+ printk("start_io_thread - clone failed : errno = %d\n", errno); -+ goto out_close; -+ } -+ -+ return(pid); -+ -+ out_close: -+ os_close_file(fds[0]); -+ os_close_file(fds[1]); -+ kernel_fd = -1; -+ *fd_out = -1; -+ out: -+ return(err); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/xterm.c um/arch/um/drivers/xterm.c ---- orig/arch/um/drivers/xterm.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/xterm.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,201 @@ -+/* -+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "kern_util.h" -+#include "chan_user.h" -+#include "helper.h" -+#include "user_util.h" -+#include "user.h" -+#include "os.h" -+#include "xterm.h" -+ -+struct xterm_chan { -+ int pid; -+ int helper_pid; -+ char *title; -+ int device; -+ int raw; -+ struct termios tt; -+ unsigned long stack; -+ int direct_rcv; -+}; -+ -+void *xterm_init(char *str, int device, struct chan_opts *opts) -+{ -+ struct xterm_chan *data; -+ -+ data = malloc(sizeof(*data)); -+ if(data == NULL) return(NULL); -+ *data = ((struct xterm_chan) { .pid = -1, -+ .helper_pid = -1, -+ .device = device, -+ .title = opts->xterm_title, -+ .raw = opts->raw, -+ .stack = opts->tramp_stack, -+ .direct_rcv = !opts->in_kernel } ); -+ return(data); -+} -+ -+/* Only changed by xterm_setup, which is a setup */ -+static char *terminal_emulator = "xterm"; -+static char *title_switch = "-T"; -+static char *exec_switch = "-e"; -+ -+static int __init xterm_setup(char *line, int *add) -+{ -+ *add = 0; -+ terminal_emulator = line; -+ -+ line = strchr(line, ','); -+ if(line == NULL) return(0); -+ *line++ = '\0'; -+ if(*line) title_switch = line; -+ -+ line = strchr(line, ','); -+ if(line == NULL) return(0); -+ *line++ = '\0'; -+ if(*line) exec_switch = line; -+ -+ return(0); -+} -+ -+__uml_setup("xterm=", xterm_setup, -+"xterm=,,<exec switch>\n" -+" Specifies an alternate terminal emulator to use for the debugger,\n" -+" consoles, and serial lines when they are attached to the xterm channel.\n" -+" The values are the terminal emulator binary, the switch it uses to set\n" -+" its title, and the switch it uses to execute a subprocess,\n" -+" respectively. The title switch must have the form '<switch> title',\n" -+" not '<switch>=title'. Similarly, the exec switch must have the form\n" -+" '<switch> command arg1 arg2 ...'.\n" -+" The default values are 'xterm=xterm,-T,-e'. Values for gnome-terminal\n" -+" are 'xterm=gnome-terminal,-t,-x'.\n\n" -+); -+ -+int xterm_open(int input, int output, int primary, void *d, char **dev_out) -+{ -+ struct xterm_chan *data = d; -+ unsigned long stack; -+ int pid, fd, new, err; -+ char title[256], file[] = "/tmp/xterm-pipeXXXXXX"; -+ char *argv[] = { terminal_emulator, title_switch, title, exec_switch, -+ "/usr/lib/uml/port-helper", "-uml-socket", -+ file, NULL }; -+ -+ if(os_access(argv[4], OS_ACC_X_OK) < 0) -+ argv[4] = "port-helper"; -+ -+ fd = mkstemp(file); -+ if(fd < 0){ -+ printk("xterm_open : mkstemp failed, errno = %d\n", errno); -+ return(-errno); -+ } -+ -+ if(unlink(file)){ -+ printk("xterm_open : unlink failed, errno = %d\n", errno); -+ return(-errno); -+ } -+ os_close_file(fd); -+ -+ fd = os_create_unix_socket(file, sizeof(file), 1); -+ if(fd < 0){ -+ printk("xterm_open : create_unix_socket failed, errno = %d\n", -+ -fd); -+ return(fd); -+ } -+ -+ sprintf(title, data->title, data->device); -+ stack = data->stack; -+ pid = run_helper(NULL, NULL, argv, &stack); -+ if(pid < 0){ -+ printk("xterm_open : run_helper failed, errno = %d\n", -pid); -+ return(pid); -+ } -+ -+ if(data->stack == 0) free_stack(stack, 0); -+ -+ if(data->direct_rcv) -+ new = os_rcv_fd(fd, &data->helper_pid); -+ else { -+ err = os_set_fd_block(fd, 0); -+ if(err < 0){ -+ printk("xterm_open : failed to set descriptor " -+ "non-blocking, err = %d\n", -err); -+ return(err); -+ } -+ new = xterm_fd(fd, &data->helper_pid); -+ } -+ if(new < 0){ -+ printk("xterm_open : os_rcv_fd failed, err = %d\n", -new); -+ goto out; -+ } -+ -+ tcgetattr(new, &data->tt); -+ if(data->raw) raw(new, 0); -+ -+ data->pid = pid; -+ *dev_out = NULL; -+ out: -+ unlink(file); -+ return(new); -+} -+ -+void xterm_close(int fd, void *d) -+{ -+ struct xterm_chan *data = d; -+ -+ if(data->pid != -1) -+ os_kill_process(data->pid, 1); -+ data->pid = -1; -+ if(data->helper_pid != -1) -+ os_kill_process(data->helper_pid, 0); -+ data->helper_pid = -1; -+ os_close_file(fd); -+} -+ -+void xterm_free(void *d) -+{ -+ free(d); -+} -+ -+int xterm_console_write(int fd, const char *buf, int n, void *d) -+{ -+ struct xterm_chan *data = d; -+ -+ return(generic_console_write(fd, buf, n, &data->tt)); -+} -+ -+struct chan_ops xterm_ops = { -+ .type = "xterm", -+ .init = xterm_init, -+ .open = xterm_open, -+ .close = xterm_close, -+ .read = generic_read, -+ .write = generic_write, -+ .console_write = xterm_console_write, -+ .window_size = generic_window_size, -+ .free = xterm_free, -+ .winch = 1, -+}; -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/xterm.h um/arch/um/drivers/xterm.h ---- orig/arch/um/drivers/xterm.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/xterm.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,22 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __XTERM_H__ -+#define __XTERM_H__ -+ -+extern int xterm_fd(int socket, int *pid_out); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/drivers/xterm_kern.c um/arch/um/drivers/xterm_kern.c ---- orig/arch/um/drivers/xterm_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/drivers/xterm_kern.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,82 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/errno.h" -+#include "linux/slab.h" -+#include "asm/semaphore.h" -+#include "asm/irq.h" -+#include "irq_user.h" -+#include "irq_kern.h" -+#include "kern_util.h" -+#include "os.h" -+#include "xterm.h" -+ -+struct xterm_wait { -+ struct semaphore sem; -+ int fd; -+ int pid; -+ int new_fd; -+}; -+ -+static void xterm_interrupt(int irq, void *data, struct pt_regs *regs) -+{ -+ struct xterm_wait *xterm = data; -+ int fd; -+ -+ fd = os_rcv_fd(xterm->fd, &xterm->pid); -+ if(fd == -EAGAIN) -+ return; -+ -+ xterm->new_fd = fd; -+ up(&xterm->sem); -+} -+ -+int xterm_fd(int socket, int *pid_out) -+{ -+ struct xterm_wait *data; -+ int err, ret; -+ -+ data = kmalloc(sizeof(*data), GFP_KERNEL); -+ if(data == NULL){ -+ printk(KERN_ERR "xterm_fd : failed to allocate xterm_wait\n"); -+ return(-ENOMEM); -+ } -+ *data = ((struct xterm_wait) -+ { .sem = __SEMAPHORE_INITIALIZER(data->sem, 0), -+ .fd = socket, -+ .pid = -1, -+ .new_fd = -1 }); -+ -+ err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt, -+ SA_INTERRUPT | SA_SHIRQ | SA_SAMPLE_RANDOM, -+ "xterm", data); -+ if(err){ -+ printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, " -+ "err = %d\n", err); -+ ret = err; -+ goto out; -+ } -+ down(&data->sem); -+ -+ free_irq(XTERM_IRQ, data); -+ -+ ret = data->new_fd; -+ *pid_out = data->pid; -+ out: -+ kfree(data); -+ -+ return(ret); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/dyn_link.ld.in um/arch/um/dyn_link.ld.in ---- orig/arch/um/dyn_link.ld.in 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/dyn_link.ld.in 2004-01-10 04:28:44.000000000 -0500 -@@ -0,0 +1,171 @@ -+OUTPUT_FORMAT("ELF_FORMAT") -+OUTPUT_ARCH(ELF_ARCH) -+ENTRY(_start) -+SEARCH_DIR("/usr/local/i686-pc-linux-gnu/lib"); SEARCH_DIR("/usr/local/lib"); SEARCH_DIR("/lib"); SEARCH_DIR("/usr/lib"); -+/* Do we need any of these for elf? -+ __DYNAMIC = 0; */ -+SECTIONS -+{ -+ . = START() + SIZEOF_HEADERS; -+ .interp : { *(.interp) } -+ __binary_start = .; -+ . = ALIGN(4096); /* Init code and data */ -+ _stext = .; -+ __init_begin = .; -+ .text.init : { *(.text.init) } -+ -+ . = ALIGN(4096); -+ -+ /* Read-only sections, merged into text segment: */ -+ .hash : { *(.hash) } -+ .dynsym : { *(.dynsym) } -+ .dynstr : { *(.dynstr) } -+ .gnu.version : { *(.gnu.version) } -+ .gnu.version_d : { *(.gnu.version_d) } -+ .gnu.version_r : { *(.gnu.version_r) } -+ .rel.init : { *(.rel.init) } -+ .rela.init : { *(.rela.init) } -+ .rel.text : { *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) } -+ .rela.text : { *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) } -+ .rel.fini : { *(.rel.fini) } -+ .rela.fini : { *(.rela.fini) } -+ .rel.rodata : { *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) } -+ .rela.rodata : { *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) } -+ .rel.data : { *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) } -+ .rela.data : { *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) } -+ .rel.tdata : { *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) } -+ .rela.tdata : { *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) } -+ .rel.tbss : { *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) } -+ .rela.tbss : { *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) } -+ .rel.ctors : { *(.rel.ctors) } -+ .rela.ctors : { *(.rela.ctors) } -+ .rel.dtors : { *(.rel.dtors) } -+ .rela.dtors : { *(.rela.dtors) } -+ .rel.got : { *(.rel.got) } -+ .rela.got : { *(.rela.got) } -+ .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) } -+ .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) } -+ .rel.plt : { *(.rel.plt) } -+ .rela.plt : { *(.rela.plt) } -+ .init : { -+ KEEP (*(.init)) -+ } =0x90909090 -+ .plt : { *(.plt) } -+ .text : { -+ *(.text .stub .text.* .gnu.linkonce.t.*) -+ /* .gnu.warning sections are handled specially by elf32.em. */ -+ *(.gnu.warning) -+ } =0x90909090 -+ .fini : { -+ KEEP (*(.fini)) -+ } =0x90909090 -+ -+ PROVIDE (__etext = .); -+ PROVIDE (_etext = .); -+ PROVIDE (etext = .); -+ .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } -+ .rodata1 : { *(.rodata1) } -+ .eh_frame_hdr : { *(.eh_frame_hdr) } -+ -+ -+ . = ALIGN(4096); -+ PROVIDE (_sdata = .); -+ -+include(`arch/um/common.ld.in') -+ -+ /* Ensure the __preinit_array_start label is properly aligned. We -+ could instead move the label definition inside the section, but -+ the linker would then create the section even if it turns out to -+ be empty, which isn't pretty. */ -+ . = ALIGN(32 / 8); -+ .preinit_array : { *(.preinit_array) } -+ .init_array : { *(.init_array) } -+ .fini_array : { *(.fini_array) } -+ .data : { -+ . = ALIGN(KERNEL_STACK_SIZE); /* init_task */ -+ *(.data.init_task) -+ *(.data .data.* .gnu.linkonce.d.*) -+ SORT(CONSTRUCTORS) -+ } -+ .data1 : { *(.data1) } -+ .tdata : { *(.tdata .tdata.* .gnu.linkonce.td.*) } -+ .tbss : { *(.tbss .tbss.* .gnu.linkonce.tb.*) *(.tcommon) } -+ .eh_frame : { KEEP (*(.eh_frame)) } -+ .gcc_except_table : { *(.gcc_except_table) } -+ .dynamic : { *(.dynamic) } -+ .ctors : { -+ /* gcc uses crtbegin.o to find the start of -+ the constructors, so we make sure it is -+ first. Because this is a wildcard, it -+ doesn't matter if the user does not -+ actually link against crtbegin.o; the -+ linker won't look for a file to match a -+ wildcard. The wildcard also means that it -+ doesn't matter which directory crtbegin.o -+ is in. */ -+ KEEP (*crtbegin.o(.ctors)) -+ /* We don't want to include the .ctor section from -+ from the crtend.o file until after the sorted ctors. -+ The .ctor section from the crtend file contains the -+ end of ctors marker and it must be last */ -+ KEEP (*(EXCLUDE_FILE (*crtend.o ) .ctors)) -+ KEEP (*(SORT(.ctors.*))) -+ KEEP (*(.ctors)) -+ } -+ .dtors : { -+ KEEP (*crtbegin.o(.dtors)) -+ KEEP (*(EXCLUDE_FILE (*crtend.o ) .dtors)) -+ KEEP (*(SORT(.dtors.*))) -+ KEEP (*(.dtors)) -+ } -+ .jcr : { KEEP (*(.jcr)) } -+ .got : { *(.got.plt) *(.got) } -+ _edata = .; -+ PROVIDE (edata = .); -+ __bss_start = .; -+ .bss : { -+ *(.dynbss) -+ *(.bss .bss.* .gnu.linkonce.b.*) -+ *(COMMON) -+ /* Align here to ensure that the .bss section occupies space up to -+ _end. Align after .bss to ensure correct alignment even if the -+ .bss section disappears because there are no input sections. */ -+ . = ALIGN(32 / 8); -+ . = ALIGN(32 / 8); -+ } -+ _end = .; -+ PROVIDE (end = .); -+ /* Stabs debugging sections. */ -+ .stab 0 : { *(.stab) } -+ .stabstr 0 : { *(.stabstr) } -+ .stab.excl 0 : { *(.stab.excl) } -+ .stab.exclstr 0 : { *(.stab.exclstr) } -+ .stab.index 0 : { *(.stab.index) } -+ .stab.indexstr 0 : { *(.stab.indexstr) } -+ .comment 0 : { *(.comment) } -+ /* DWARF debug sections. -+ Symbols in the DWARF debugging sections are relative to the beginning -+ of the section so we begin them at 0. */ -+ /* DWARF 1 */ -+ .debug 0 : { *(.debug) } -+ .line 0 : { *(.line) } -+ /* GNU DWARF 1 extensions */ -+ .debug_srcinfo 0 : { *(.debug_srcinfo) } -+ .debug_sfnames 0 : { *(.debug_sfnames) } -+ /* DWARF 1.1 and DWARF 2 */ -+ .debug_aranges 0 : { *(.debug_aranges) } -+ .debug_pubnames 0 : { *(.debug_pubnames) } -+ /* DWARF 2 */ -+ .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } -+ .debug_abbrev 0 : { *(.debug_abbrev) } -+ .debug_line 0 : { *(.debug_line) } -+ .debug_frame 0 : { *(.debug_frame) } -+ .debug_str 0 : { *(.debug_str) } -+ .debug_loc 0 : { *(.debug_loc) } -+ .debug_macinfo 0 : { *(.debug_macinfo) } -+ /* SGI/MIPS DWARF 2 extensions */ -+ .debug_weaknames 0 : { *(.debug_weaknames) } -+ .debug_funcnames 0 : { *(.debug_funcnames) } -+ .debug_typenames 0 : { *(.debug_typenames) } -+ .debug_varnames 0 : { *(.debug_varnames) } -+} -diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/hostfs.h um/arch/um/fs/hostfs/hostfs.h ---- orig/arch/um/fs/hostfs/hostfs.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/fs/hostfs/hostfs.h 2003-12-17 10:52:50.000000000 -0500 -@@ -0,0 +1,69 @@ -+#ifndef __UM_FS_HOSTFS -+#define __UM_FS_HOSTFS -+ -+#include "os.h" -+ -+/* These are exactly the same definitions as in fs.h, but the names are -+ * changed so that this file can be included in both kernel and user files. -+ */ -+ -+#define HOSTFS_ATTR_MODE 1 -+#define HOSTFS_ATTR_UID 2 -+#define HOSTFS_ATTR_GID 4 -+#define HOSTFS_ATTR_SIZE 8 -+#define HOSTFS_ATTR_ATIME 16 -+#define HOSTFS_ATTR_MTIME 32 -+#define HOSTFS_ATTR_CTIME 64 -+#define HOSTFS_ATTR_ATIME_SET 128 -+#define HOSTFS_ATTR_MTIME_SET 256 -+#define HOSTFS_ATTR_FORCE 512 /* Not a change, but a change it */ -+#define HOSTFS_ATTR_ATTR_FLAG 1024 -+ -+struct hostfs_iattr { -+ unsigned int ia_valid; -+ mode_t ia_mode; -+ uid_t ia_uid; -+ gid_t ia_gid; -+ loff_t ia_size; -+ time_t ia_atime; -+ time_t ia_mtime; -+ time_t ia_ctime; -+ unsigned int ia_attr_flags; -+}; -+ -+extern int stat_file(const char *path, int *dev_out, -+ unsigned long long *inode_out, int *mode_out, -+ int *nlink_out, int *uid_out, int *gid_out, -+ unsigned long long *size_out, unsigned long *atime_out, -+ unsigned long *mtime_out, unsigned long *ctime_out, -+ int *blksize_out, unsigned long long *blocks_out); -+extern int access_file(char *path, int r, int w, int x); -+extern int open_file(char *path, int r, int w, int append); -+extern int file_type(const char *path, int *rdev); -+extern void *open_dir(char *path, int *err_out); -+extern char *read_dir(void *stream, unsigned long long *pos, -+ unsigned long long *ino_out, int *len_out); -+extern void close_file(void *stream); -+extern void close_dir(void *stream); -+extern int read_file(int fd, unsigned long long *offset, char *buf, int len); -+extern int write_file(int fd, unsigned long long *offset, const char *buf, -+ int len); -+extern int lseek_file(int fd, long long offset, int whence); -+extern int file_create(char *name, int ur, int uw, int ux, int gr, -+ int gw, int gx, int or, int ow, int ox); -+extern int set_attr(const char *file, struct hostfs_iattr *attrs); -+extern int make_symlink(const char *from, const char *to); -+extern int unlink_file(const char *file); -+extern int do_mkdir(const char *file, int mode); -+extern int do_rmdir(const char *file); -+extern int do_mknod(const char *file, int mode, int dev); -+extern int link_file(const char *from, const char *to); -+extern int do_readlink(char *file, char *buf, int size); -+extern int rename_file(char *from, char *to); -+extern int do_statfs(char *root, long *bsize_out, long long *blocks_out, -+ long long *bfree_out, long long *bavail_out, -+ long long *files_out, long long *ffree_out, -+ void *fsid_out, int fsid_size, long *namelen_out, -+ long *spare_out); -+ -+#endif -diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/hostfs_kern.c um/arch/um/fs/hostfs/hostfs_kern.c ---- orig/arch/um/fs/hostfs/hostfs_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/fs/hostfs/hostfs_kern.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,965 @@ -+/* -+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) -+ * Licensed under the GPL -+ */ -+ -+#include <linux/stddef.h> -+#include <linux/fs.h> -+#include <linux/version.h> -+#include <linux/module.h> -+#include <linux/init.h> -+#include <linux/slab.h> -+#include <linux/pagemap.h> -+#include <linux/blkdev.h> -+#include <asm/uaccess.h> -+#include "hostfs.h" -+#include "kern_util.h" -+#include "kern.h" -+#include "user_util.h" -+#include "2_5compat.h" -+#include "init.h" -+ -+#define file_hostfs_i(file) (&(file)->f_dentry->d_inode->u.hostfs_i) -+ -+int hostfs_d_delete(struct dentry *dentry) -+{ -+ return(1); -+} -+ -+struct dentry_operations hostfs_dentry_ops = { -+ .d_delete = hostfs_d_delete, -+}; -+ -+#define DEFAULT_ROOT "/" -+ -+/* Changed in hostfs_args before the kernel starts running */ -+static char *jail_dir = NULL; -+static int append = 0; -+ -+#define HOSTFS_SUPER_MAGIC 0x00c0ffee -+ -+static struct inode_operations hostfs_iops; -+static struct inode_operations hostfs_dir_iops; -+static struct address_space_operations hostfs_link_aops; -+ -+static int __init hostfs_args(char *options, int *add) -+{ -+ char *ptr; -+ -+ ptr = strchr(options, ','); -+ if(ptr != NULL) -+ *ptr++ = '\0'; -+ if(*options != '\0') -+ jail_dir = options; -+ -+ options = ptr; -+ while(options){ -+ ptr = strchr(options, ','); -+ if(ptr != NULL) -+ *ptr++ = '\0'; -+ if(*options != '\0'){ -+ if(!strcmp(options, "append")) -+ append = 1; -+ else printf("hostfs_args - unsupported option - %s\n", -+ options); -+ } -+ options = ptr; -+ } -+ return(0); -+} -+ -+__uml_setup("hostfs=", hostfs_args, -+"hostfs=<root dir>,<flags>,...\n" -+" This is used to set hostfs parameters. The root directory argument\n" -+" is used to confine all hostfs mounts to within the specified directory\n" -+" tree on the host. If this isn't specified, then a user inside UML can\n" -+" mount anything on the host that's accessible to the user that's running\n" -+" it.\n" -+" The only flag currently supported is 'append', which specifies that all\n" -+" files opened by hostfs will be opened in append mode.\n\n" -+); -+ -+static char *dentry_name(struct dentry *dentry, int extra) -+{ -+ struct dentry *parent; -+ char *root, *name; -+ int len; -+ -+ len = 0; -+ parent = dentry; -+ while(parent->d_parent != parent){ -+ len += parent->d_name.len + 1; -+ parent = parent->d_parent; -+ } -+ -+ root = parent->d_inode->u.hostfs_i.host_filename; -+ len += strlen(root); -+ name = kmalloc(len + extra + 1, GFP_KERNEL); -+ if(name == NULL) return(NULL); -+ -+ name[len] = '\0'; -+ parent = dentry; -+ while(parent->d_parent != parent){ -+ len -= parent->d_name.len + 1; -+ name[len] = '/'; -+ strncpy(&name[len + 1], parent->d_name.name, -+ parent->d_name.len); -+ parent = parent->d_parent; -+ } -+ strncpy(name, root, strlen(root)); -+ return(name); -+} -+ -+static char *inode_name(struct inode *ino, int extra) -+{ -+ struct dentry *dentry; -+ -+ dentry = list_entry(ino->i_dentry.next, struct dentry, d_alias); -+ return(dentry_name(dentry, extra)); -+} -+ -+static int read_name(struct inode *ino, char *name) -+{ -+ /* The non-int inode fields are copied into ints by stat_file and -+ * then copied into the inode because passing the actual pointers -+ * in and having them treated as int * breaks on big-endian machines -+ */ -+ int err; -+ int i_dev, i_mode, i_nlink, i_blksize; -+ unsigned long long i_size; -+ unsigned long long i_ino; -+ unsigned long long i_blocks; -+ err = stat_file(name, &i_dev, &i_ino, &i_mode, &i_nlink, -+ &ino->i_uid, &ino->i_gid, &i_size, &ino->i_atime, -+ &ino->i_mtime, &ino->i_ctime, &i_blksize, &i_blocks); -+ if(err) return(err); -+ ino->i_ino = i_ino; -+ ino->i_dev = i_dev; -+ ino->i_mode = i_mode; -+ ino->i_nlink = i_nlink; -+ ino->i_size = i_size; -+ ino->i_blksize = i_blksize; -+ ino->i_blocks = i_blocks; -+ if(kdev_same(ino->i_sb->s_dev, ROOT_DEV) && (ino->i_uid == getuid())) -+ ino->i_uid = 0; -+ return(0); -+} -+ -+static char *follow_link(char *link) -+{ -+ int len, n; -+ char *name, *resolved, *end; -+ -+ len = 64; -+ while(1){ -+ n = -ENOMEM; -+ name = kmalloc(len, GFP_KERNEL); -+ if(name == NULL) -+ goto out; -+ -+ n = do_readlink(link, name, len); -+ if(n < len) -+ break; -+ len *= 2; -+ kfree(name); -+ } -+ if(n < 0) -+ goto out_free; -+ -+ if(*name == '/') -+ return(name); -+ -+ end = strrchr(link, '/'); -+ if(end == NULL) -+ return(name); -+ -+ *(end + 1) = '\0'; -+ len = strlen(link) + strlen(name) + 1; -+ -+ resolved = kmalloc(len, GFP_KERNEL); -+ if(resolved == NULL){ -+ n = -ENOMEM; -+ goto out_free; -+ } -+ -+ sprintf(resolved, "%s%s", link, name); -+ kfree(name); -+ kfree(link); -+ return(resolved); -+ -+ out_free: -+ kfree(name); -+ out: -+ return(ERR_PTR(n)); -+} -+ -+static int read_inode(struct inode *ino) -+{ -+ char *name; -+ int err; -+ -+ err = -ENOMEM; -+ name = inode_name(ino, 0); -+ if(name == NULL) -+ goto out; -+ -+ if(file_type(name, NULL) == OS_TYPE_SYMLINK){ -+ name = follow_link(name); -+ if(IS_ERR(name)){ -+ err = PTR_ERR(name); -+ goto out; -+ } -+ } -+ -+ err = read_name(ino, name); -+ kfree(name); -+ out: -+ return(err); -+} -+ -+void hostfs_delete_inode(struct inode *ino) -+{ -+ if(ino->u.hostfs_i.host_filename) -+ kfree(ino->u.hostfs_i.host_filename); -+ ino->u.hostfs_i.host_filename = NULL; -+ -+ if(ino->u.hostfs_i.fd != -1) -+ close_file(&ino->u.hostfs_i.fd); -+ -+ ino->u.hostfs_i.mode = 0; -+ clear_inode(ino); -+} -+ -+int hostfs_statfs(struct super_block *sb, struct statfs *sf) -+{ -+ /* do_statfs uses struct statfs64 internally, but the linux kernel -+ * struct statfs still has 32-bit versions for most of these fields, -+ * so we convert them here -+ */ -+ int err; -+ long long f_blocks; -+ long long f_bfree; -+ long long f_bavail; -+ long long f_files; -+ long long f_ffree; -+ -+ err = do_statfs(sb->s_root->d_inode->u.hostfs_i.host_filename, -+ &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files, -+ &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid), -+ &sf->f_namelen, sf->f_spare); -+ if(err) return(err); -+ sf->f_blocks = f_blocks; -+ sf->f_bfree = f_bfree; -+ sf->f_bavail = f_bavail; -+ sf->f_files = f_files; -+ sf->f_ffree = f_ffree; -+ sf->f_type = HOSTFS_SUPER_MAGIC; -+ return(0); -+} -+ -+static struct super_operations hostfs_sbops = { -+ .put_inode = force_delete, -+ .delete_inode = hostfs_delete_inode, -+ .statfs = hostfs_statfs, -+}; -+ -+int hostfs_readdir(struct file *file, void *ent, filldir_t filldir) -+{ -+ void *dir; -+ char *name; -+ unsigned long long next, ino; -+ int error, len; -+ -+ name = dentry_name(file->f_dentry, 0); -+ if(name == NULL) return(-ENOMEM); -+ dir = open_dir(name, &error); -+ kfree(name); -+ if(dir == NULL) return(-error); -+ next = file->f_pos; -+ while((name = read_dir(dir, &next, &ino, &len)) != NULL){ -+ error = (*filldir)(ent, name, len, file->f_pos, -+ ino, DT_UNKNOWN); -+ if(error) break; -+ file->f_pos = next; -+ } -+ close_dir(dir); -+ return(0); -+} -+ -+int hostfs_file_open(struct inode *ino, struct file *file) -+{ -+ char *name; -+ int mode = 0, r = 0, w = 0, fd; -+ -+ mode = file->f_mode & (FMODE_READ | FMODE_WRITE); -+ if((mode & ino->u.hostfs_i.mode) == mode) -+ return(0); -+ -+ /* The file may already have been opened, but with the wrong access, -+ * so this resets things and reopens the file with the new access. -+ */ -+ if(ino->u.hostfs_i.fd != -1){ -+ close_file(&ino->u.hostfs_i.fd); -+ ino->u.hostfs_i.fd = -1; -+ } -+ -+ ino->u.hostfs_i.mode |= mode; -+ if(ino->u.hostfs_i.mode & FMODE_READ) -+ r = 1; -+ if(ino->u.hostfs_i.mode & FMODE_WRITE) -+ w = 1; -+ if(w) -+ r = 1; -+ -+ name = dentry_name(file->f_dentry, 0); -+ if(name == NULL) -+ return(-ENOMEM); -+ -+ fd = open_file(name, r, w, append); -+ kfree(name); -+ if(fd < 0) return(fd); -+ file_hostfs_i(file)->fd = fd; -+ -+ return(0); -+} -+ -+int hostfs_dir_open(struct inode *ino, struct file *file) -+{ -+ return(0); -+} -+ -+int hostfs_dir_release(struct inode *ino, struct file *file) -+{ -+ return(0); -+} -+ -+int hostfs_fsync(struct file *file, struct dentry *dentry, int datasync) -+{ -+ return(0); -+} -+ -+static struct file_operations hostfs_file_fops = { -+ .owner = NULL, -+ .read = generic_file_read, -+ .write = generic_file_write, -+ .mmap = generic_file_mmap, -+ .open = hostfs_file_open, -+ .release = NULL, -+ .fsync = hostfs_fsync, -+}; -+ -+static struct file_operations hostfs_dir_fops = { -+ .owner = NULL, -+ .readdir = hostfs_readdir, -+ .open = hostfs_dir_open, -+ .release = hostfs_dir_release, -+ .fsync = hostfs_fsync, -+}; -+ -+int hostfs_writepage(struct page *page) -+{ -+ struct address_space *mapping = page->mapping; -+ struct inode *inode = mapping->host; -+ char *buffer; -+ unsigned long long base; -+ int count = PAGE_CACHE_SIZE; -+ int end_index = inode->i_size >> PAGE_CACHE_SHIFT; -+ int err; -+ -+ if (page->index >= end_index) -+ count = inode->i_size & (PAGE_CACHE_SIZE-1); -+ -+ buffer = kmap(page); -+ base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT; -+ -+ err = write_file(inode->u.hostfs_i.fd, &base, buffer, count); -+ if(err != count){ -+ ClearPageUptodate(page); -+ goto out; -+ } -+ -+ if (base > inode->i_size) -+ inode->i_size = base; -+ -+ if (PageError(page)) -+ ClearPageError(page); -+ err = 0; -+ -+ out: -+ kunmap(page); -+ -+ UnlockPage(page); -+ return err; -+} -+ -+int hostfs_readpage(struct file *file, struct page *page) -+{ -+ char *buffer; -+ long long start; -+ int err = 0; -+ -+ start = (long long) page->index << PAGE_CACHE_SHIFT; -+ buffer = kmap(page); -+ err = read_file(file_hostfs_i(file)->fd, &start, buffer, -+ PAGE_CACHE_SIZE); -+ if(err < 0) goto out; -+ -+ memset(&buffer[err], 0, PAGE_CACHE_SIZE - err); -+ -+ flush_dcache_page(page); -+ SetPageUptodate(page); -+ if (PageError(page)) ClearPageError(page); -+ err = 0; -+ out: -+ kunmap(page); -+ UnlockPage(page); -+ return(err); -+} -+ -+int hostfs_prepare_write(struct file *file, struct page *page, -+ unsigned int from, unsigned int to) -+{ -+ char *buffer; -+ long long start, tmp; -+ int err; -+ -+ start = (long long) page->index << PAGE_CACHE_SHIFT; -+ buffer = kmap(page); -+ if(from != 0){ -+ tmp = start; -+ err = read_file(file_hostfs_i(file)->fd, &tmp, buffer, -+ from); -+ if(err < 0) goto out; -+ } -+ if(to != PAGE_CACHE_SIZE){ -+ start += to; -+ err = read_file(file_hostfs_i(file)->fd, &start, buffer + to, -+ PAGE_CACHE_SIZE - to); -+ if(err < 0) goto out; -+ } -+ err = 0; -+ out: -+ kunmap(page); -+ return(err); -+} -+ -+int hostfs_commit_write(struct file *file, struct page *page, unsigned from, -+ unsigned to) -+{ -+ struct address_space *mapping = page->mapping; -+ struct inode *inode = mapping->host; -+ char *buffer; -+ long long start; -+ int err = 0; -+ -+ start = (long long) (page->index << PAGE_CACHE_SHIFT) + from; -+ buffer = kmap(page); -+ err = write_file(file_hostfs_i(file)->fd, &start, buffer + from, -+ to - from); -+ if(err > 0) err = 0; -+ if(!err && (start > inode->i_size)) -+ inode->i_size = start; -+ -+ kunmap(page); -+ return(err); -+} -+ -+static struct address_space_operations hostfs_aops = { -+ .writepage = hostfs_writepage, -+ .readpage = hostfs_readpage, -+/* .set_page_dirty = __set_page_dirty_nobuffers, */ -+ .prepare_write = hostfs_prepare_write, -+ .commit_write = hostfs_commit_write -+}; -+ -+static struct inode *get_inode(struct super_block *sb, struct dentry *dentry, -+ int *error) -+{ -+ struct inode *inode; -+ char *name; -+ int type, err = -ENOMEM, rdev; -+ -+ inode = new_inode(sb); -+ if(inode == NULL) -+ goto out; -+ -+ inode->u.hostfs_i.host_filename = NULL; -+ inode->u.hostfs_i.fd = -1; -+ inode->u.hostfs_i.mode = 0; -+ insert_inode_hash(inode); -+ if(dentry){ -+ name = dentry_name(dentry, 0); -+ if(name == NULL){ -+ err = -ENOMEM; -+ goto out_put; -+ } -+ type = file_type(name, &rdev); -+ kfree(name); -+ } -+ else type = OS_TYPE_DIR; -+ inode->i_sb = sb; -+ -+ err = 0; -+ if(type == OS_TYPE_SYMLINK) -+ inode->i_op = &page_symlink_inode_operations; -+ else if(type == OS_TYPE_DIR) -+ inode->i_op = &hostfs_dir_iops; -+ else inode->i_op = &hostfs_iops; -+ -+ if(type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops; -+ else inode->i_fop = &hostfs_file_fops; -+ -+ if(type == OS_TYPE_SYMLINK) -+ inode->i_mapping->a_ops = &hostfs_link_aops; -+ else inode->i_mapping->a_ops = &hostfs_aops; -+ -+ switch (type) { -+ case OS_TYPE_CHARDEV: -+ init_special_inode(inode, S_IFCHR, rdev); -+ break; -+ case OS_TYPE_BLOCKDEV: -+ init_special_inode(inode, S_IFBLK, rdev); -+ break; -+ case OS_TYPE_FIFO: -+ init_special_inode(inode, S_IFIFO, 0); -+ break; -+ case OS_TYPE_SOCK: -+ init_special_inode(inode, S_IFSOCK, 0); -+ break; -+ } -+ -+ if(error) *error = err; -+ return(inode); -+ out_put: -+ make_bad_inode(inode); -+ iput(inode); -+ out: -+ if(error) *error = err; -+ return(NULL); -+} -+ -+int hostfs_create(struct inode *dir, struct dentry *dentry, int mode) -+{ -+ struct inode *inode; -+ char *name; -+ int error, fd; -+ -+ inode = get_inode(dir->i_sb, dentry, &error); -+ if(error) return(error); -+ name = dentry_name(dentry, 0); -+ if(name == NULL){ -+ iput(inode); -+ return(-ENOMEM); -+ } -+ fd = file_create(name, -+ mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR, -+ mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP, -+ mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH); -+ if(fd < 0) -+ error = fd; -+ else error = read_name(inode, name); -+ -+ kfree(name); -+ if(error){ -+ iput(inode); -+ return(error); -+ } -+ inode->u.hostfs_i.fd = fd; -+ inode->u.hostfs_i.mode = FMODE_READ | FMODE_WRITE; -+ d_instantiate(dentry, inode); -+ return(0); -+} -+ -+struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry) -+{ -+ struct inode *inode; -+ char *name; -+ int error; -+ -+ inode = get_inode(ino->i_sb, dentry, &error); -+ if(error != 0) return(ERR_PTR(error)); -+ name = dentry_name(dentry, 0); -+ if(name == NULL) return(ERR_PTR(-ENOMEM)); -+ error = read_name(inode, name); -+ kfree(name); -+ if(error){ -+ iput(inode); -+ if(error == -ENOENT) inode = NULL; -+ else return(ERR_PTR(error)); -+ } -+ d_add(dentry, inode); -+ dentry->d_op = &hostfs_dentry_ops; -+ return(NULL); -+} -+ -+static char *inode_dentry_name(struct inode *ino, struct dentry *dentry) -+{ -+ char *file; -+ int len; -+ -+ file = inode_name(ino, dentry->d_name.len + 1); -+ if(file == NULL) return(NULL); -+ strcat(file, "/"); -+ len = strlen(file); -+ strncat(file, dentry->d_name.name, dentry->d_name.len); -+ file[len + dentry->d_name.len] = '\0'; -+ return(file); -+} -+ -+int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from) -+{ -+ char *from_name, *to_name; -+ int err; -+ -+ from_name = inode_dentry_name(ino, from); -+ if(from_name == NULL) -+ return(-ENOMEM); -+ to_name = dentry_name(to, 0); -+ if(to_name == NULL){ -+ kfree(from_name); -+ return(-ENOMEM); -+ } -+ err = link_file(to_name, from_name); -+ kfree(from_name); -+ kfree(to_name); -+ return(err); -+} -+ -+int hostfs_unlink(struct inode *ino, struct dentry *dentry) -+{ -+ char *file; -+ int err; -+ -+ file = inode_dentry_name(ino, dentry); -+ if(file == NULL) return(-ENOMEM); -+ if(append) -+ return(-EPERM); -+ -+ err = unlink_file(file); -+ kfree(file); -+ return(err); -+} -+ -+int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to) -+{ -+ char *file; -+ int err; -+ -+ file = inode_dentry_name(ino, dentry); -+ if(file == NULL) return(-ENOMEM); -+ err = make_symlink(file, to); -+ kfree(file); -+ return(err); -+} -+ -+int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode) -+{ -+ char *file; -+ int err; -+ -+ file = inode_dentry_name(ino, dentry); -+ if(file == NULL) return(-ENOMEM); -+ err = do_mkdir(file, mode); -+ kfree(file); -+ return(err); -+} -+ -+int hostfs_rmdir(struct inode *ino, struct dentry *dentry) -+{ -+ char *file; -+ int err; -+ -+ file = inode_dentry_name(ino, dentry); -+ if(file == NULL) return(-ENOMEM); -+ err = do_rmdir(file); -+ kfree(file); -+ return(err); -+} -+ -+int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, int dev) -+{ -+ struct inode *inode; -+ char *name; -+ int error; -+ -+ inode = get_inode(dir->i_sb, dentry, &error); -+ if(error) return(error); -+ name = dentry_name(dentry, 0); -+ if(name == NULL){ -+ iput(inode); -+ return(-ENOMEM); -+ } -+ init_special_inode(inode, mode, dev); -+ error = do_mknod(name, mode, dev); -+ if(!error) error = read_name(inode, name); -+ kfree(name); -+ if(error){ -+ iput(inode); -+ return(error); -+ } -+ d_instantiate(dentry, inode); -+ return(0); -+} -+ -+int hostfs_rename(struct inode *from_ino, struct dentry *from, -+ struct inode *to_ino, struct dentry *to) -+{ -+ char *from_name, *to_name; -+ int err; -+ -+ from_name = inode_dentry_name(from_ino, from); -+ if(from_name == NULL) -+ return(-ENOMEM); -+ to_name = inode_dentry_name(to_ino, to); -+ if(to_name == NULL){ -+ kfree(from_name); -+ return(-ENOMEM); -+ } -+ err = rename_file(from_name, to_name); -+ kfree(from_name); -+ kfree(to_name); -+ return(err); -+} -+ -+void hostfs_truncate(struct inode *ino) -+{ -+ not_implemented(); -+} -+ -+int hostfs_permission(struct inode *ino, int desired) -+{ -+ char *name; -+ int r = 0, w = 0, x = 0, err; -+ -+ if(desired & MAY_READ) r = 1; -+ if(desired & MAY_WRITE) w = 1; -+ if(desired & MAY_EXEC) x = 1; -+ name = inode_name(ino, 0); -+ if(name == NULL) return(-ENOMEM); -+ err = access_file(name, r, w, x); -+ kfree(name); -+ if(!err) err = vfs_permission(ino, desired); -+ return(err); -+} -+ -+int hostfs_setattr(struct dentry *dentry, struct iattr *attr) -+{ -+ struct hostfs_iattr attrs; -+ char *name; -+ int err; -+ -+ if(append) -+ attr->ia_valid &= ~ATTR_SIZE; -+ -+ attrs.ia_valid = 0; -+ if(attr->ia_valid & ATTR_MODE){ -+ attrs.ia_valid |= HOSTFS_ATTR_MODE; -+ attrs.ia_mode = attr->ia_mode; -+ } -+ if(attr->ia_valid & ATTR_UID){ -+ if(kdev_same(dentry->d_inode->i_sb->s_dev, ROOT_DEV) && -+ (attr->ia_uid == 0)) -+ attr->ia_uid = getuid(); -+ attrs.ia_valid |= HOSTFS_ATTR_UID; -+ attrs.ia_uid = attr->ia_uid; -+ } -+ if(attr->ia_valid & ATTR_GID){ -+ if(kdev_same(dentry->d_inode->i_sb->s_dev, ROOT_DEV) && -+ (attr->ia_gid == 0)) -+ attr->ia_gid = getuid(); -+ attrs.ia_valid |= HOSTFS_ATTR_GID; -+ attrs.ia_gid = attr->ia_gid; -+ } -+ if(attr->ia_valid & ATTR_SIZE){ -+ attrs.ia_valid |= HOSTFS_ATTR_SIZE; -+ attrs.ia_size = attr->ia_size; -+ } -+ if(attr->ia_valid & ATTR_ATIME){ -+ attrs.ia_valid |= HOSTFS_ATTR_ATIME; -+ attrs.ia_atime = attr->ia_atime; -+ } -+ if(attr->ia_valid & ATTR_MTIME){ -+ attrs.ia_valid |= HOSTFS_ATTR_MTIME; -+ attrs.ia_mtime = attr->ia_mtime; -+ } -+ if(attr->ia_valid & ATTR_CTIME){ -+ attrs.ia_valid |= HOSTFS_ATTR_CTIME; -+ attrs.ia_ctime = attr->ia_ctime; -+ } -+ if(attr->ia_valid & ATTR_ATIME_SET){ -+ attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET; -+ } -+ if(attr->ia_valid & ATTR_MTIME_SET){ -+ attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET; -+ } -+ name = dentry_name(dentry, 0); -+ if(name == NULL) return(-ENOMEM); -+ err = set_attr(name, &attrs); -+ kfree(name); -+ if(err) -+ return(err); -+ -+ return(inode_setattr(dentry->d_inode, attr)); -+} -+ -+int hostfs_getattr(struct dentry *dentry, struct iattr *attr) -+{ -+ not_implemented(); -+ return(-EINVAL); -+} -+ -+static struct inode_operations hostfs_iops = { -+ .create = hostfs_create, -+ .link = hostfs_link, -+ .unlink = hostfs_unlink, -+ .symlink = hostfs_symlink, -+ .mkdir = hostfs_mkdir, -+ .rmdir = hostfs_rmdir, -+ .mknod = hostfs_mknod, -+ .rename = hostfs_rename, -+ .truncate = hostfs_truncate, -+ .permission = hostfs_permission, -+ .setattr = hostfs_setattr, -+ .getattr = hostfs_getattr, -+}; -+ -+static struct inode_operations hostfs_dir_iops = { -+ .create = hostfs_create, -+ .lookup = hostfs_lookup, -+ .link = hostfs_link, -+ .unlink = hostfs_unlink, -+ .symlink = hostfs_symlink, -+ .mkdir = hostfs_mkdir, -+ .rmdir = hostfs_rmdir, -+ .mknod = hostfs_mknod, -+ .rename = hostfs_rename, -+ .truncate = hostfs_truncate, -+ .permission = hostfs_permission, -+ .setattr = hostfs_setattr, -+ .getattr = hostfs_getattr, -+}; -+ -+int hostfs_link_readpage(struct file *file, struct page *page) -+{ -+ char *buffer, *name; -+ long long start; -+ int err; -+ -+ start = page->index << PAGE_CACHE_SHIFT; -+ buffer = kmap(page); -+ name = inode_name(page->mapping->host, 0); -+ if(name == NULL) return(-ENOMEM); -+ err = do_readlink(name, buffer, PAGE_CACHE_SIZE); -+ kfree(name); -+ if(err == PAGE_CACHE_SIZE) -+ err = -E2BIG; -+ else if(err > 0){ -+ flush_dcache_page(page); -+ SetPageUptodate(page); -+ if (PageError(page)) ClearPageError(page); -+ err = 0; -+ } -+ kunmap(page); -+ UnlockPage(page); -+ return(err); -+} -+ -+static struct address_space_operations hostfs_link_aops = { -+ .readpage = hostfs_link_readpage, -+}; -+ -+static char *get_root(char *mount_arg) -+{ -+ char *root, *slash = ""; -+ int len = 0; -+ -+ if(jail_dir != NULL){ -+ len += strlen(jail_dir); -+ if((*jail_dir == '\0') || -+ (jail_dir[strlen(jail_dir) - 1] != '/')) -+ slash = "/"; -+ len += strlen(slash); -+ } -+ -+ if((mount_arg == NULL) || (*mount_arg == '\0')) -+ mount_arg = DEFAULT_ROOT; -+ -+ len += strlen(mount_arg) + 1; -+ -+ root = kmalloc(len, GFP_KERNEL); -+ if(root == NULL) -+ return(NULL); -+ -+ if(jail_dir != NULL) -+ sprintf(root, "%s%s%s", jail_dir, slash, mount_arg); -+ else -+ strcpy(root, mount_arg); -+ -+ return(root); -+} -+ -+struct super_block *hostfs_read_super(struct super_block *sb, void *data, -+ int silent) -+{ -+ struct inode *root_inode; -+ char *root_dir; -+ -+ sb->s_blocksize = 1024; -+ sb->s_blocksize_bits = 10; -+ sb->s_magic = HOSTFS_SUPER_MAGIC; -+ sb->s_op = &hostfs_sbops; -+ -+ root_inode = get_inode(sb, NULL, NULL); -+ if(root_inode == NULL) -+ goto out; -+ -+ root_dir = get_root(data); -+ if(root_dir == NULL) -+ goto out_put; -+ -+ root_inode->u.hostfs_i.host_filename = root_dir; -+ sb->s_root = d_alloc_root(root_inode); -+ if(sb->s_root == NULL) -+ goto out_free; -+ -+ if(read_inode(root_inode)) -+ goto out_dput; -+ return(sb); -+ -+ out_dput: -+ dput(sb->s_root); -+ out_free: -+ kfree(root_dir); -+ out_put: -+ make_bad_inode(root_inode); -+ iput(root_inode); -+ out: -+ return(NULL); -+} -+ -+DECLARE_FSTYPE(hostfs_type, "hostfs", hostfs_read_super, 0); -+ -+static int __init init_hostfs(void) -+{ -+ return(register_filesystem(&hostfs_type)); -+} -+ -+static void __exit exit_hostfs(void) -+{ -+ unregister_filesystem(&hostfs_type); -+} -+ -+module_init(init_hostfs) -+module_exit(exit_hostfs) -+MODULE_LICENSE("GPL"); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/hostfs_user.c um/arch/um/fs/hostfs/hostfs_user.c ---- orig/arch/um/fs/hostfs/hostfs_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/fs/hostfs/hostfs_user.c 2003-11-14 08:51:20.000000000 -0500 -@@ -0,0 +1,359 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <unistd.h> -+#include <stdio.h> -+#include <fcntl.h> -+#include <dirent.h> -+#include <errno.h> -+#include <utime.h> -+#include <string.h> -+#include <sys/stat.h> -+#include <sys/time.h> -+#include <sys/vfs.h> -+#include "hostfs.h" -+#include "kern_util.h" -+#include "user.h" -+ -+int stat_file(const char *path, int *dev_out, unsigned long long *inode_out, -+ int *mode_out, int *nlink_out, int *uid_out, int *gid_out, -+ unsigned long long *size_out, unsigned long *atime_out, -+ unsigned long *mtime_out, unsigned long *ctime_out, -+ int *blksize_out, unsigned long long *blocks_out) -+{ -+ struct stat64 buf; -+ -+ if(lstat64(path, &buf) < 0) -+ return(-errno); -+ if(dev_out != NULL) *dev_out = buf.st_dev; -+ -+ /* See the Makefile for why STAT64_INO_FIELD is passed in -+ * by the build -+ */ -+ if(inode_out != NULL) *inode_out = buf.STAT64_INO_FIELD; -+ if(mode_out != NULL) *mode_out = buf.st_mode; -+ if(nlink_out != NULL) *nlink_out = buf.st_nlink; -+ if(uid_out != NULL) *uid_out = buf.st_uid; -+ if(gid_out != NULL) *gid_out = buf.st_gid; -+ if(size_out != NULL) *size_out = buf.st_size; -+ if(atime_out != NULL) *atime_out = buf.st_atime; -+ if(mtime_out != NULL) *mtime_out = buf.st_mtime; -+ if(ctime_out != NULL) *ctime_out = buf.st_ctime; -+ if(blksize_out != NULL) *blksize_out = buf.st_blksize; -+ if(blocks_out != NULL) *blocks_out = buf.st_blocks; -+ return(0); -+} -+ -+int file_type(const char *path, int *rdev) -+{ -+ struct stat64 buf; -+ -+ if(lstat64(path, &buf) < 0) -+ return(-errno); -+ if(rdev != NULL) -+ *rdev = buf.st_rdev; -+ -+ if(S_ISDIR(buf.st_mode)) return(OS_TYPE_DIR); -+ else if(S_ISLNK(buf.st_mode)) return(OS_TYPE_SYMLINK); -+ else if(S_ISCHR(buf.st_mode)) return(OS_TYPE_CHARDEV); -+ else if(S_ISBLK(buf.st_mode)) return(OS_TYPE_BLOCKDEV); -+ else if(S_ISFIFO(buf.st_mode))return(OS_TYPE_FIFO); -+ else if(S_ISSOCK(buf.st_mode))return(OS_TYPE_SOCK); -+ else return(OS_TYPE_FILE); -+} -+ -+int access_file(char *path, int r, int w, int x) -+{ -+ int mode = 0; -+ -+ if(r) mode = R_OK; -+ if(w) mode |= W_OK; -+ if(x) mode |= X_OK; -+ if(access(path, mode) != 0) return(-errno); -+ else return(0); -+} -+ -+int open_file(char *path, int r, int w, int append) -+{ -+ int mode = 0, fd; -+ -+ if(r && !w) -+ mode = O_RDONLY; -+ else if(!r && w) -+ mode = O_WRONLY; -+ else if(r && w) -+ mode = O_RDWR; -+ else panic("Impossible mode in open_file"); -+ -+ if(append) -+ mode |= O_APPEND; -+ fd = open64(path, mode); -+ if(fd < 0) return(-errno); -+ else return(fd); -+} -+ -+void *open_dir(char *path, int *err_out) -+{ -+ DIR *dir; -+ -+ dir = opendir(path); -+ *err_out = errno; -+ if(dir == NULL) return(NULL); -+ return(dir); -+} -+ -+char *read_dir(void *stream, unsigned long long *pos, -+ unsigned long long *ino_out, int *len_out) -+{ -+ DIR *dir = stream; -+ struct dirent *ent; -+ -+ seekdir(dir, *pos); -+ ent = readdir(dir); -+ if(ent == NULL) return(NULL); -+ *len_out = strlen(ent->d_name); -+ *ino_out = ent->d_ino; -+ *pos = telldir(dir); -+ return(ent->d_name); -+} -+ -+int read_file(int fd, unsigned long long *offset, char *buf, int len) -+{ -+ int n, err; -+ -+ err = os_seek_file(fd, *offset); -+ if(err) -+ return(err); -+ -+ n = os_read_file(fd, buf, len); -+ if(n < 0) -+ return(n); -+ -+ *offset += n; -+ return(n); -+} -+ -+int write_file(int fd, unsigned long long *offset, const char *buf, int len) -+{ -+ int n, err; -+ -+ err = os_seek_file(fd, *offset); -+ if(err) -+ return(err); -+ -+ n = os_write_file(fd, buf, len); -+ if(n < 0) -+ return(n); -+ -+ *offset += n; -+ return(n); -+} -+ -+int lseek_file(int fd, long long offset, int whence) -+{ -+ int ret; -+ -+ ret = lseek64(fd, offset, whence); -+ if(ret < 0) return(-errno); -+ return(0); -+} -+ -+void close_file(void *stream) -+{ -+ close(*((int *) stream)); -+} -+ -+void close_dir(void *stream) -+{ -+ closedir(stream); -+} -+ -+int file_create(char *name, int ur, int uw, int ux, int gr, -+ int gw, int gx, int or, int ow, int ox) -+{ -+ int mode, fd; -+ -+ mode = 0; -+ mode |= ur ? S_IRUSR : 0; -+ mode |= uw ? S_IWUSR : 0; -+ mode |= ux ? S_IXUSR : 0; -+ mode |= gr ? S_IRGRP : 0; -+ mode |= gw ? S_IWGRP : 0; -+ mode |= gx ? S_IXGRP : 0; -+ mode |= or ? S_IROTH : 0; -+ mode |= ow ? S_IWOTH : 0; -+ mode |= ox ? S_IXOTH : 0; -+ fd = open64(name, O_CREAT | O_RDWR, mode); -+ if(fd < 0) -+ return(-errno); -+ return(fd); -+} -+ -+int set_attr(const char *file, struct hostfs_iattr *attrs) -+{ -+ struct utimbuf buf; -+ int err, ma; -+ -+ if(attrs->ia_valid & HOSTFS_ATTR_MODE){ -+ if(chmod(file, attrs->ia_mode) != 0) return(-errno); -+ } -+ if(attrs->ia_valid & HOSTFS_ATTR_UID){ -+ if(chown(file, attrs->ia_uid, -1)) return(-errno); -+ } -+ if(attrs->ia_valid & HOSTFS_ATTR_GID){ -+ if(chown(file, -1, attrs->ia_gid)) return(-errno); -+ } -+ if(attrs->ia_valid & HOSTFS_ATTR_SIZE){ -+ if(truncate(file, attrs->ia_size)) return(-errno); -+ } -+ ma = HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET; -+ if((attrs->ia_valid & ma) == ma){ -+ buf.actime = attrs->ia_atime; -+ buf.modtime = attrs->ia_mtime; -+ if(utime(file, &buf) != 0) return(-errno); -+ } -+ else { -+ if(attrs->ia_valid & HOSTFS_ATTR_ATIME_SET){ -+ err = stat_file(file, NULL, NULL, NULL, NULL, NULL, -+ NULL, NULL, NULL, &buf.modtime, NULL, -+ NULL, NULL); -+ if(err != 0) return(err); -+ buf.actime = attrs->ia_atime; -+ if(utime(file, &buf) != 0) return(-errno); -+ } -+ if(attrs->ia_valid & HOSTFS_ATTR_MTIME_SET){ -+ err = stat_file(file, NULL, NULL, NULL, NULL, NULL, -+ NULL, NULL, &buf.actime, NULL, NULL, -+ NULL, NULL); -+ if(err != 0) return(err); -+ buf.modtime = attrs->ia_mtime; -+ if(utime(file, &buf) != 0) return(-errno); -+ } -+ } -+ if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ; -+ if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){ -+ err = stat_file(file, NULL, NULL, NULL, NULL, NULL, -+ NULL, NULL, &attrs->ia_atime, &attrs->ia_mtime, -+ NULL, NULL, NULL); -+ if(err != 0) return(err); -+ } -+ return(0); -+} -+ -+int make_symlink(const char *from, const char *to) -+{ -+ int err; -+ -+ err = symlink(to, from); -+ if(err) return(-errno); -+ return(0); -+} -+ -+int unlink_file(const char *file) -+{ -+ int err; -+ -+ err = unlink(file); -+ if(err) return(-errno); -+ return(0); -+} -+ -+int do_mkdir(const char *file, int mode) -+{ -+ int err; -+ -+ err = mkdir(file, mode); -+ if(err) return(-errno); -+ return(0); -+} -+ -+int do_rmdir(const char *file) -+{ -+ int err; -+ -+ err = rmdir(file); -+ if(err) return(-errno); -+ return(0); -+} -+ -+int do_mknod(const char *file, int mode, int dev) -+{ -+ int err; -+ -+ err = mknod(file, mode, dev); -+ if(err) return(-errno); -+ return(0); -+} -+ -+int link_file(const char *to, const char *from) -+{ -+ int err; -+ -+ err = link(to, from); -+ if(err) return(-errno); -+ return(0); -+} -+ -+int do_readlink(char *file, char *buf, int size) -+{ -+ int n; -+ -+ n = readlink(file, buf, size); -+ if(n < 0) -+ return(-errno); -+ if(n < size) -+ buf[n] = '\0'; -+ return(n); -+} -+ -+int rename_file(char *from, char *to) -+{ -+ int err; -+ -+ err = rename(from, to); -+ if(err < 0) return(-errno); -+ return(0); -+} -+ -+int do_statfs(char *root, long *bsize_out, long long *blocks_out, -+ long long *bfree_out, long long *bavail_out, -+ long long *files_out, long long *ffree_out, -+ void *fsid_out, int fsid_size, long *namelen_out, -+ long *spare_out) -+{ -+ struct statfs64 buf; -+ int err; -+ -+ err = statfs64(root, &buf); -+ if(err < 0) return(-errno); -+ *bsize_out = buf.f_bsize; -+ *blocks_out = buf.f_blocks; -+ *bfree_out = buf.f_bfree; -+ *bavail_out = buf.f_bavail; -+ *files_out = buf.f_files; -+ *ffree_out = buf.f_ffree; -+ memcpy(fsid_out, &buf.f_fsid, -+ sizeof(buf.f_fsid) > fsid_size ? fsid_size : -+ sizeof(buf.f_fsid)); -+ *namelen_out = buf.f_namelen; -+ spare_out[0] = buf.f_spare[0]; -+ spare_out[1] = buf.f_spare[1]; -+ spare_out[2] = buf.f_spare[2]; -+ spare_out[3] = buf.f_spare[3]; -+ spare_out[4] = buf.f_spare[4]; -+ spare_out[5] = buf.f_spare[5]; -+ return(0); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/fs/hostfs/Makefile um/arch/um/fs/hostfs/Makefile ---- orig/arch/um/fs/hostfs/Makefile 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/fs/hostfs/Makefile 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,24 @@ -+# -+# Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+# Licensed under the GPL -+# -+ -+# struct stat64 changed the inode field name between 2.2 and 2.4 from st_ino -+# to __st_ino. It stayed in the same place, so as long as the correct name -+# is used, hostfs compiled on 2.2 should work on 2.4 and vice versa. -+ -+STAT64_INO_FIELD := $(shell grep -q __st_ino /usr/include/bits/stat.h && \ -+ echo __)st_ino -+ -+USER_CFLAGS := $(USER_CFLAGS) -DSTAT64_INO_FIELD=$(STAT64_INO_FIELD) -+ -+O_TARGET := hostfs.o -+obj-y = hostfs_kern.o hostfs_user.o -+obj-m = $(O_TARGET) -+ -+USER_OBJS = $(filter %_user.o,$(obj-y)) -+ -+include $(TOPDIR)/Rules.make -+ -+$(USER_OBJS) : %.o: %.c -+ $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $< -diff -Naur -X ../exclude-files orig/arch/um/fs/hppfs/hppfs_kern.c um/arch/um/fs/hppfs/hppfs_kern.c ---- orig/arch/um/fs/hppfs/hppfs_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/fs/hppfs/hppfs_kern.c 2004-01-08 23:35:58.000000000 -0500 -@@ -0,0 +1,737 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <linux/fs.h> -+#include <linux/module.h> -+#include <linux/slab.h> -+#include <linux/list.h> -+#include <linux/kernel.h> -+#include <linux/ctype.h> -+#include <asm/uaccess.h> -+#include "os.h" -+ -+struct hppfs_data { -+ struct list_head list; -+ char contents[PAGE_SIZE - sizeof(struct list_head)]; -+}; -+ -+struct hppfs_private { -+ struct file proc_file; -+ int host_fd; -+ loff_t len; -+ struct hppfs_data *contents; -+}; -+ -+#define HPPFS_SUPER_MAGIC 0xb00000ee -+ -+static struct super_operations hppfs_sbops; -+ -+static struct inode *get_inode(struct super_block *sb, struct dentry *dentry, -+ int *error); -+ -+static int is_pid(struct dentry *dentry) -+{ -+ struct super_block *sb; -+ int i; -+ -+ sb = dentry->d_sb; -+ if((sb->s_op != &hppfs_sbops) || (dentry->d_parent != sb->s_root)) -+ return(0); -+ -+ for(i = 0; i < dentry->d_name.len; i++){ -+ if(!isdigit(dentry->d_name.name[i])) -+ return(0); -+ } -+ return(1); -+} -+ -+static char *dentry_name(struct dentry *dentry, int extra) -+{ -+ struct dentry *parent; -+ char *root, *name; -+ const char *seg_name; -+ int len, seg_len; -+ -+ len = 0; -+ parent = dentry; -+ while(parent->d_parent != parent){ -+ if(is_pid(parent)) -+ len += strlen("pid") + 1; -+ else len += parent->d_name.len + 1; -+ parent = parent->d_parent; -+ } -+ -+ root = "proc"; -+ len += strlen(root); -+ name = kmalloc(len + extra + 1, GFP_KERNEL); -+ if(name == NULL) return(NULL); -+ -+ name[len] = '\0'; -+ parent = dentry; -+ while(parent->d_parent != parent){ -+ if(is_pid(parent)){ -+ seg_name = "pid"; -+ seg_len = strlen("pid"); -+ } -+ else { -+ seg_name = parent->d_name.name; -+ seg_len = parent->d_name.len; -+ } -+ -+ len -= seg_len + 1; -+ name[len] = '/'; -+ strncpy(&name[len + 1], seg_name, seg_len); -+ parent = parent->d_parent; -+ } -+ strncpy(name, root, strlen(root)); -+ return(name); -+} -+ -+struct dentry_operations hppfs_dentry_ops = { -+}; -+ -+static int file_removed(struct dentry *dentry, const char *file) -+{ -+ char *host_file; -+ int extra, fd; -+ -+ extra = 0; -+ if(file != NULL) extra += strlen(file) + 1; -+ -+ host_file = dentry_name(dentry, extra + strlen("/remove")); -+ if(host_file == NULL){ -+ printk("file_removed : allocation failed\n"); -+ return(-ENOMEM); -+ } -+ -+ if(file != NULL){ -+ strcat(host_file, "/"); -+ strcat(host_file, file); -+ } -+ strcat(host_file, "/remove"); -+ -+ fd = os_open_file(host_file, of_read(OPENFLAGS()), 0); -+ kfree(host_file); -+ if(fd >= 0){ -+ os_close_file(fd); -+ return(1); -+ } -+ return(0); -+} -+ -+static struct dentry *hppfs_lookup(struct inode *ino, struct dentry *dentry) -+{ -+ struct dentry *proc_dentry; -+ struct inode *inode; -+ int err, deleted; -+ -+ deleted = file_removed(dentry, NULL); -+ if(deleted < 0) -+ return(ERR_PTR(deleted)); -+ else if(deleted) -+ return(ERR_PTR(-ENOENT)); -+ -+ proc_dentry = lookup_hash(&dentry->d_name, ino->u.hppfs_i.proc_dentry); -+ if(IS_ERR(proc_dentry)) -+ return(proc_dentry); -+ -+ inode = get_inode(ino->i_sb, proc_dentry, &err); -+ if(err != 0) -+ return(ERR_PTR(err)); -+ -+ d_add(dentry, inode); -+ dentry->d_op = &hppfs_dentry_ops; -+ return(NULL); -+} -+ -+static struct inode_operations hppfs_file_iops = { -+}; -+ -+static struct inode_operations hppfs_dir_iops = { -+ .lookup = hppfs_lookup, -+}; -+ -+static ssize_t read_proc(struct file *file, char *buf, ssize_t count, -+ loff_t *ppos, int is_user) -+{ -+ ssize_t (*read)(struct file *, char *, size_t, loff_t *); -+ ssize_t n; -+ -+ read = file->f_dentry->d_inode->i_fop->read; -+ if(read == NULL) -+ return(-EOPNOTSUPP); -+ -+ if(!is_user) -+ set_fs(KERNEL_DS); -+ -+ n = (*read)(file, buf, count, &file->f_pos); -+ -+ if(!is_user) -+ set_fs(USER_DS); -+ -+ if(ppos) *ppos = file->f_pos; -+ return(n); -+} -+ -+static ssize_t hppfs_read_file(int fd, char *buf, ssize_t count) -+{ -+ ssize_t n; -+ int cur, err; -+ char *new_buf; -+ -+ n = -ENOMEM; -+ new_buf = kmalloc(PAGE_SIZE, GFP_KERNEL); -+ if(new_buf == NULL){ -+ printk("hppfs_read_file : kmalloc failed\n"); -+ goto out; -+ } -+ n = 0; -+ while(count > 0){ -+ cur = min_t(ssize_t, count, PAGE_SIZE); -+ err = os_read_file(fd, new_buf, cur); -+ if(err < 0){ -+ printk("hppfs_read : read failed, err = %d\n", -err); -+ n = err; -+ goto out_free; -+ } -+ else if(err == 0) -+ break; -+ -+ if(copy_to_user(buf, new_buf, err)){ -+ n = -EFAULT; -+ goto out_free; -+ } -+ n += err; -+ count -= err; -+ } -+ out_free: -+ kfree(new_buf); -+ out: -+ return(n); -+} -+ -+static ssize_t hppfs_read(struct file *file, char *buf, size_t count, -+ loff_t *ppos) -+{ -+ struct hppfs_private *hppfs = file->private_data; -+ struct hppfs_data *data; -+ loff_t off; -+ int err; -+ -+ if(hppfs->contents != NULL){ -+ if(*ppos >= hppfs->len) return(0); -+ -+ data = hppfs->contents; -+ off = *ppos; -+ while(off >= sizeof(data->contents)){ -+ data = list_entry(data->list.next, struct hppfs_data, -+ list); -+ off -= sizeof(data->contents); -+ } -+ -+ if(off + count > hppfs->len) -+ count = hppfs->len - off; -+ copy_to_user(buf, &data->contents[off], count); -+ *ppos += count; -+ } -+ else if(hppfs->host_fd != -1){ -+ err = os_seek_file(hppfs->host_fd, *ppos); -+ if(err < 0){ -+ printk("hppfs_read : seek failed, err = %d\n", -err); -+ return(err); -+ } -+ count = hppfs_read_file(hppfs->host_fd, buf, count); -+ if(count > 0) -+ *ppos += count; -+ } -+ else count = read_proc(&hppfs->proc_file, buf, count, ppos, 1); -+ -+ return(count); -+} -+ -+static ssize_t hppfs_write(struct file *file, const char *buf, size_t len, -+ loff_t *ppos) -+{ -+ struct hppfs_private *data = file->private_data; -+ struct file *proc_file = &data->proc_file; -+ ssize_t (*write)(struct file *, const char *, size_t, loff_t *); -+ int err; -+ -+ write = proc_file->f_dentry->d_inode->i_fop->write; -+ if(write == NULL) -+ return(-EOPNOTSUPP); -+ -+ proc_file->f_pos = file->f_pos; -+ err = (*write)(proc_file, buf, len, &proc_file->f_pos); -+ file->f_pos = proc_file->f_pos; -+ -+ return(err); -+} -+ -+static int open_host_sock(char *host_file, int *filter_out) -+{ -+ char *end; -+ int fd; -+ -+ end = &host_file[strlen(host_file)]; -+ strcpy(end, "/rw"); -+ *filter_out = 1; -+ fd = os_connect_socket(host_file); -+ if(fd >= 0) -+ return(fd); -+ -+ strcpy(end, "/r"); -+ *filter_out = 0; -+ fd = os_connect_socket(host_file); -+ return(fd); -+} -+ -+static void free_contents(struct hppfs_data *head) -+{ -+ struct hppfs_data *data; -+ struct list_head *ele, *next; -+ -+ if(head == NULL) return; -+ -+ list_for_each_safe(ele, next, &head->list){ -+ data = list_entry(ele, struct hppfs_data, list); -+ kfree(data); -+ } -+ kfree(head); -+} -+ -+static struct hppfs_data *hppfs_get_data(int fd, int filter, -+ struct file *proc_file, -+ struct file *hppfs_file, -+ loff_t *size_out) -+{ -+ struct hppfs_data *data, *new, *head; -+ int n, err; -+ -+ err = -ENOMEM; -+ data = kmalloc(sizeof(*data), GFP_KERNEL); -+ if(data == NULL){ -+ printk("hppfs_get_data : head allocation failed\n"); -+ goto failed; -+ } -+ -+ INIT_LIST_HEAD(&data->list); -+ -+ head = data; -+ *size_out = 0; -+ -+ if(filter){ -+ while((n = read_proc(proc_file, data->contents, -+ sizeof(data->contents), NULL, 0)) > 0) { -+ err = os_write_file(fd, data->contents, n); -+ if(err != n) -+ printk("hppfs_get_data : failed to write out " -+ "%d bytes, err = %d\n", n, -err); -+ } -+ err = os_shutdown_socket(fd, 0, 1); -+ if(err < 0){ -+ printk("hppfs_get_data : failed to shut down " -+ "socket\n"); -+ goto failed_free; -+ } -+ } -+ while(1){ -+ n = os_read_file(fd, data->contents, sizeof(data->contents)); -+ if(n < 0){ -+ err = n; -+ printk("hppfs_get_data : read failed, err = %d\n", -n); -+ goto failed_free; -+ } -+ else if(n == 0) -+ break; -+ -+ *size_out += n; -+ -+ if(n < sizeof(data->contents)) -+ break; -+ -+ new = kmalloc(sizeof(*data), GFP_KERNEL); -+ if(new == 0){ -+ printk("hppfs_get_data : data allocation failed\n"); -+ err = -ENOMEM; -+ goto failed_free; -+ } -+ -+ INIT_LIST_HEAD(&new->list); -+ list_add(&new->list, &data->list); -+ data = new; -+ } -+ return(head); -+ -+ failed_free: -+ free_contents(head); -+ failed: -+ return(ERR_PTR(err)); -+} -+ -+static struct hppfs_private *hppfs_data(void) -+{ -+ struct hppfs_private *data; -+ -+ data = kmalloc(sizeof(*data), GFP_KERNEL); -+ if(data == NULL) -+ return(data); -+ -+ *data = ((struct hppfs_private ) { .host_fd = -1, -+ .len = -1, -+ .contents = NULL } ); -+ return(data); -+} -+ -+static int hppfs_open(struct inode *inode, struct file *file) -+{ -+ struct hppfs_private *data; -+ struct dentry *proc_dentry; -+ char *host_file; -+ int err, fd, type, filter; -+ -+ err = -ENOMEM; -+ data = hppfs_data(); -+ if(data == NULL) -+ goto out; -+ -+ host_file = dentry_name(file->f_dentry, strlen("/rw")); -+ if(host_file == NULL) -+ goto out_free2; -+ -+ proc_dentry = inode->u.hppfs_i.proc_dentry; -+ err = init_private_file(&data->proc_file, proc_dentry, file->f_mode); -+ if(err) -+ goto out_free1; -+ -+ type = os_file_type(host_file); -+ if(type == OS_TYPE_FILE){ -+ fd = os_open_file(host_file, of_read(OPENFLAGS()), 0); -+ if(fd >= 0) -+ data->host_fd = fd; -+ else printk("hppfs_open : failed to open '%s', err = %d\n", -+ host_file, -fd); -+ -+ data->contents = NULL; -+ } -+ else if(type == OS_TYPE_DIR){ -+ fd = open_host_sock(host_file, &filter); -+ if(fd >= 0){ -+ data->contents = hppfs_get_data(fd, filter, -+ &data->proc_file, -+ file, &data->len); -+ if(!IS_ERR(data->contents)) -+ data->host_fd = fd; -+ } -+ else printk("hppfs_open : failed to open a socket in " -+ "'%s', err = %d\n", host_file, -fd); -+ } -+ kfree(host_file); -+ -+ file->private_data = data; -+ return(0); -+ -+ out_free1: -+ kfree(host_file); -+ out_free2: -+ free_contents(data->contents); -+ kfree(data); -+ out: -+ return(err); -+} -+ -+static int hppfs_dir_open(struct inode *inode, struct file *file) -+{ -+ struct hppfs_private *data; -+ struct dentry *proc_dentry; -+ int err; -+ -+ err = -ENOMEM; -+ data = hppfs_data(); -+ if(data == NULL) -+ goto out; -+ -+ proc_dentry = inode->u.hppfs_i.proc_dentry; -+ err = init_private_file(&data->proc_file, proc_dentry, file->f_mode); -+ if(err) -+ goto out_free; -+ -+ file->private_data = data; -+ return(0); -+ -+ out_free: -+ kfree(data); -+ out: -+ return(err); -+} -+ -+static loff_t hppfs_llseek(struct file *file, loff_t off, int where) -+{ -+ struct hppfs_private *data = file->private_data; -+ struct file *proc_file = &data->proc_file; -+ loff_t (*llseek)(struct file *, loff_t, int); -+ loff_t ret; -+ -+ llseek = proc_file->f_dentry->d_inode->i_fop->llseek; -+ if(llseek != NULL){ -+ ret = (*llseek)(proc_file, off, where); -+ if(ret < 0) -+ return(ret); -+ } -+ -+ return(default_llseek(file, off, where)); -+} -+ -+struct hppfs_dirent { -+ void *vfs_dirent; -+ filldir_t filldir; -+ struct dentry *dentry; -+}; -+ -+static int hppfs_filldir(void *d, const char *name, int size, -+ loff_t offset, ino_t inode, unsigned int type) -+{ -+ struct hppfs_dirent *dirent = d; -+ -+ if(file_removed(dirent->dentry, name)) -+ return(0); -+ -+ return((*dirent->filldir)(dirent->vfs_dirent, name, size, offset, -+ inode, type)); -+} -+ -+static int hppfs_readdir(struct file *file, void *ent, filldir_t filldir) -+{ -+ struct hppfs_private *data = file->private_data; -+ struct file *proc_file = &data->proc_file; -+ int (*readdir)(struct file *, void *, filldir_t); -+ struct hppfs_dirent dirent = ((struct hppfs_dirent) -+ { .vfs_dirent = ent, -+ .filldir = filldir, -+ .dentry = file->f_dentry } ); -+ int err; -+ -+ readdir = proc_file->f_dentry->d_inode->i_fop->readdir; -+ if(readdir == NULL) -+ return(-EOPNOTSUPP); -+ -+ proc_file->f_pos = file->f_pos; -+ err = (*readdir)(proc_file, &dirent, hppfs_filldir); -+ file->f_pos = proc_file->f_pos; -+ -+ return(err); -+} -+ -+static int hppfs_fsync(struct file *file, struct dentry *dentry, int datasync) -+{ -+ return(0); -+} -+ -+static struct file_operations hppfs_file_fops = { -+ .owner = NULL, -+ .llseek = hppfs_llseek, -+ .read = hppfs_read, -+ .write = hppfs_write, -+ .open = hppfs_open, -+}; -+ -+static struct file_operations hppfs_dir_fops = { -+ .owner = NULL, -+ .readdir = hppfs_readdir, -+ .open = hppfs_dir_open, -+ .fsync = hppfs_fsync, -+}; -+ -+static int hppfs_statfs(struct super_block *sb, struct statfs *sf) -+{ -+ sf->f_blocks = 0; -+ sf->f_bfree = 0; -+ sf->f_bavail = 0; -+ sf->f_files = 0; -+ sf->f_ffree = 0; -+ sf->f_type = HPPFS_SUPER_MAGIC; -+ return(0); -+} -+ -+static struct super_operations hppfs_sbops = { -+ .put_inode = force_delete, -+ .delete_inode = NULL, -+ .statfs = hppfs_statfs, -+}; -+ -+static int hppfs_readlink(struct dentry *dentry, char *buffer, int buflen) -+{ -+ struct file proc_file; -+ struct dentry *proc_dentry; -+ int (*readlink)(struct dentry *, char *, int); -+ int err, n; -+ -+ proc_dentry = dentry->d_inode->u.hppfs_i.proc_dentry; -+ err = init_private_file(&proc_file, proc_dentry, FMODE_READ); -+ if(err) -+ return(err); -+ -+ readlink = proc_dentry->d_inode->i_op->readlink; -+ if(readlink == NULL) -+ return(-EOPNOTSUPP); -+ n = (*readlink)(proc_dentry, buffer, buflen); -+ -+ if(proc_file.f_op->release) -+ (*proc_file.f_op->release)(proc_dentry->d_inode, &proc_file); -+ -+ return(n); -+} -+ -+static int hppfs_follow_link(struct dentry *dentry, struct nameidata *nd) -+{ -+ struct file proc_file; -+ struct dentry *proc_dentry; -+ int (*follow_link)(struct dentry *, struct nameidata *); -+ int err, n; -+ -+ proc_dentry = dentry->d_inode->u.hppfs_i.proc_dentry; -+ err = init_private_file(&proc_file, proc_dentry, FMODE_READ); -+ if(err) -+ return(err); -+ -+ follow_link = proc_dentry->d_inode->i_op->follow_link; -+ if(follow_link == NULL) -+ return(-EOPNOTSUPP); -+ n = (*follow_link)(proc_dentry, nd); -+ -+ if(proc_file.f_op->release) -+ (*proc_file.f_op->release)(proc_dentry->d_inode, &proc_file); -+ -+ return(n); -+} -+ -+static struct inode_operations hppfs_link_iops = { -+ .readlink = hppfs_readlink, -+ .follow_link = hppfs_follow_link, -+}; -+ -+static void read_inode(struct inode *ino) -+{ -+ struct inode *proc_ino; -+ -+ proc_ino = ino->u.hppfs_i.proc_dentry->d_inode; -+ ino->i_uid = proc_ino->i_uid; -+ ino->i_gid = proc_ino->i_gid; -+ ino->i_atime = proc_ino->i_atime; -+ ino->i_mtime = proc_ino->i_mtime; -+ ino->i_ctime = proc_ino->i_ctime; -+ ino->i_ino = proc_ino->i_ino; -+ ino->i_dev = proc_ino->i_dev; -+ ino->i_mode = proc_ino->i_mode; -+ ino->i_nlink = proc_ino->i_nlink; -+ ino->i_size = proc_ino->i_size; -+ ino->i_blksize = proc_ino->i_blksize; -+ ino->i_blocks = proc_ino->i_blocks; -+} -+ -+static struct inode *get_inode(struct super_block *sb, struct dentry *dentry, -+ int *error) -+{ -+ struct inode *inode; -+ int err = -ENOMEM; -+ -+ inode = new_inode(sb); -+ if(inode == NULL) -+ goto out; -+ -+ insert_inode_hash(inode); -+ if(S_ISDIR(dentry->d_inode->i_mode)){ -+ inode->i_op = &hppfs_dir_iops; -+ inode->i_fop = &hppfs_dir_fops; -+ } -+ else if(S_ISLNK(dentry->d_inode->i_mode)){ -+ inode->i_op = &hppfs_link_iops; -+ inode->i_fop = &hppfs_file_fops; -+ } -+ else { -+ inode->i_op = &hppfs_file_iops; -+ inode->i_fop = &hppfs_file_fops; -+ } -+ -+ inode->i_sb = sb; -+ inode->u.hppfs_i.proc_dentry = dentry; -+ -+ read_inode(inode); -+ err = 0; -+ -+ if(error) *error = err; -+ return(inode); -+ out: -+ if(error) *error = err; -+ return(NULL); -+} -+ -+static struct super_block *hppfs_read_super(struct super_block *sb, void *d, -+ int silent) -+{ -+ struct inode *root_inode; -+ struct file_system_type *procfs; -+ struct super_block *proc_sb; -+ -+ procfs = get_fs_type("proc"); -+ if(procfs == NULL) -+ goto out; -+ -+ if(list_empty(&procfs->fs_supers)) -+ goto out; -+ -+ proc_sb = list_entry(procfs->fs_supers.next, struct super_block, -+ s_instances); -+ -+ sb->s_blocksize = 1024; -+ sb->s_blocksize_bits = 10; -+ sb->s_magic = HPPFS_SUPER_MAGIC; -+ sb->s_op = &hppfs_sbops; -+ -+ dget(proc_sb->s_root); -+ root_inode = get_inode(sb, proc_sb->s_root, NULL); -+ if(root_inode == NULL) -+ goto out_dput; -+ -+ sb->s_root = d_alloc_root(root_inode); -+ if(sb->s_root == NULL) -+ goto out_put; -+ -+ return(sb); -+ -+ out_put: -+ iput(root_inode); -+ out_dput: -+ dput(proc_sb->s_root); -+ out: -+ return(NULL); -+} -+ -+DECLARE_FSTYPE(hppfs_type, "hppfs", hppfs_read_super, 0); -+ -+static int __init init_hppfs(void) -+{ -+ return(register_filesystem(&hppfs_type)); -+} -+ -+static void __exit exit_hppfs(void) -+{ -+ unregister_filesystem(&hppfs_type); -+} -+ -+module_init(init_hppfs) -+module_exit(exit_hppfs) -+MODULE_LICENSE("GPL"); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/fs/hppfs/Makefile um/arch/um/fs/hppfs/Makefile ---- orig/arch/um/fs/hppfs/Makefile 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/fs/hppfs/Makefile 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,10 @@ -+O_TARGET := hppfs.o -+obj-y = hppfs_kern.o #hppfs_user.o -+obj-m = $(O_TARGET) -+ -+CFLAGS_hppfs_kern.o := $(CFLAGS) -+#CFLAGS_hppfs_user.o := $(USER_CFLAGS) -+ -+override CFLAGS = -+ -+include $(TOPDIR)/Rules.make -diff -Naur -X ../exclude-files orig/arch/um/fs/Makefile um/arch/um/fs/Makefile ---- orig/arch/um/fs/Makefile 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/fs/Makefile 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,23 @@ -+# -+# Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+# Licensed under the GPL -+# -+ -+O_TARGET := built-in.o -+ -+subdir-y = -+subdir-m = -+ -+subdir-$(CONFIG_HOSTFS) += hostfs -+subdir-$(CONFIG_HPPFS) += hppfs -+ -+obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o)) -+obj-m += $(join $(subdir-m),$(subdir-m:%=/%.o)) -+ -+include $(TOPDIR)/Rules.make -+ -+dep: -+ -+clean: -+ -+archmrproper: -diff -Naur -X ../exclude-files orig/arch/um/include/2_5compat.h um/arch/um/include/2_5compat.h ---- orig/arch/um/include/2_5compat.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/2_5compat.h 2003-11-07 02:49:26.000000000 -0500 -@@ -0,0 +1,33 @@ -+/* -+ * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __2_5_COMPAT_H__ -+#define __2_5_COMPAT_H__ -+ -+#include "linux/version.h" -+ -+#define INIT_ELV(queue, elv) elevator_init(elv, ELV_NOOP) -+ -+#define ELV_NOOP ELEVATOR_NOOP -+ -+#define INIT_HARDSECT(arr, maj, sizes) arr[maj] = sizes -+ -+#define IS_WRITE(req) ((req)->cmd == WRITE) -+ -+#define SET_PRI(task) \ -+ do { (task)->nice = 20; (task)->counter = -100; } while(0); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/chan_kern.h um/arch/um/include/chan_kern.h ---- orig/arch/um/include/chan_kern.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/chan_kern.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,56 @@ -+/* -+ * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __CHAN_KERN_H__ -+#define __CHAN_KERN_H__ -+ -+#include "linux/tty.h" -+#include "linux/list.h" -+#include "chan_user.h" -+ -+struct chan { -+ struct list_head list; -+ char *dev; -+ unsigned int primary:1; -+ unsigned int input:1; -+ unsigned int output:1; -+ unsigned int opened:1; -+ int fd; -+ enum chan_init_pri pri; -+ struct chan_ops *ops; -+ void *data; -+}; -+ -+extern void chan_interrupt(struct list_head *chans, struct tq_struct *task, -+ struct tty_struct *tty, int irq, void *dev); -+extern int parse_chan_pair(char *str, struct list_head *chans, int pri, -+ int device, struct chan_opts *opts); -+extern int open_chan(struct list_head *chans); -+extern int write_chan(struct list_head *chans, const char *buf, int len, -+ int write_irq); -+extern int console_write_chan(struct list_head *chans, const char *buf, -+ int len); -+extern void close_chan(struct list_head *chans); -+extern void chan_enable_winch(struct list_head *chans, void *line); -+extern void enable_chan(struct list_head *chans, void *data); -+extern int chan_window_size(struct list_head *chans, -+ unsigned short *rows_out, -+ unsigned short *cols_out); -+extern int chan_out_fd(struct list_head *chans); -+extern int chan_config_string(struct list_head *chans, char *str, int size, -+ char **error_out); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/chan_user.h um/arch/um/include/chan_user.h ---- orig/arch/um/include/chan_user.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/chan_user.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,66 @@ -+/* -+ * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __CHAN_USER_H__ -+#define __CHAN_USER_H__ -+ -+#include "init.h" -+ -+struct chan_opts { -+ void (*announce)(char *dev_name, int dev); -+ char *xterm_title; -+ int raw; -+ unsigned long tramp_stack; -+ int in_kernel; -+}; -+ -+enum chan_init_pri { INIT_STATIC, INIT_ALL, INIT_ONE }; -+ -+struct chan_ops { -+ char *type; -+ void *(*init)(char *, int, struct chan_opts *); -+ int (*open)(int, int, int, void *, char **); -+ void (*close)(int, void *); -+ int (*read)(int, char *, void *); -+ int (*write)(int, const char *, int, void *); -+ int (*console_write)(int, const char *, int, void *); -+ int (*window_size)(int, void *, unsigned short *, unsigned short *); -+ void (*free)(void *); -+ int winch; -+}; -+ -+extern struct chan_ops fd_ops, null_ops, port_ops, pts_ops, pty_ops, tty_ops, -+ xterm_ops; -+ -+extern void generic_close(int fd, void *unused); -+extern int generic_read(int fd, char *c_out, void *unused); -+extern int generic_write(int fd, const char *buf, int n, void *unused); -+extern int generic_console_write(int fd, const char *buf, int n, void *state); -+extern int generic_window_size(int fd, void *unused, unsigned short *rows_out, -+ unsigned short *cols_out); -+extern void generic_free(void *data); -+ -+extern void register_winch(int fd, void *device_data); -+extern void register_winch_irq(int fd, int tty_fd, int pid, void *line); -+ -+#define __channel_help(fn, prefix) \ -+__uml_help(fn, prefix "[0-9]*=<channel description>\n" \ -+" Attach a console or serial line to a host channel. See\n" \ -+" http://user-mode-linux.sourceforge.net/input.html for a complete\n" \ -+" description of this switch.\n\n" \ -+); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/choose-mode.h um/arch/um/include/choose-mode.h ---- orig/arch/um/include/choose-mode.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/choose-mode.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,35 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __CHOOSE_MODE_H__ -+#define __CHOOSE_MODE_H__ -+ -+#include "uml-config.h" -+ -+#if defined(UML_CONFIG_MODE_TT) && defined(UML_CONFIG_MODE_SKAS) -+#define CHOOSE_MODE(tt, skas) (mode_tt ? (tt) : (skas)) -+ -+#elif defined(UML_CONFIG_MODE_SKAS) -+#define CHOOSE_MODE(tt, skas) (skas) -+ -+#elif defined(UML_CONFIG_MODE_TT) -+#define CHOOSE_MODE(tt, skas) (tt) -+#endif -+ -+#define CHOOSE_MODE_PROC(tt, skas, args...) \ -+ CHOOSE_MODE(tt(args), skas(args)) -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/frame.h um/arch/um/include/frame.h ---- orig/arch/um/include/frame.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/frame.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,53 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __FRAME_H_ -+#define __FRAME_H_ -+ -+#include "sysdep/frame.h" -+ -+struct frame_common { -+ void *data; -+ int len; -+ int sig_index; -+ int sr_index; -+ int sr_relative; -+ int sp_index; -+ struct arch_frame_data arch; -+}; -+ -+struct sc_frame { -+ struct frame_common common; -+ int sc_index; -+}; -+ -+extern struct sc_frame signal_frame_sc; -+ -+extern struct sc_frame signal_frame_sc_sr; -+ -+struct si_frame { -+ struct frame_common common; -+ int sip_index; -+ int si_index; -+ int ucp_index; -+ int uc_index; -+}; -+ -+extern struct si_frame signal_frame_si; -+ -+extern void capture_signal_stack(void); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/frame_kern.h um/arch/um/include/frame_kern.h ---- orig/arch/um/include/frame_kern.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/frame_kern.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,34 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __FRAME_KERN_H_ -+#define __FRAME_KERN_H_ -+ -+#include "frame.h" -+#include "sysdep/frame_kern.h" -+ -+extern int setup_signal_stack_sc(unsigned long stack_top, int sig, -+ unsigned long handler, -+ void (*restorer)(void), -+ struct pt_regs *regs, -+ sigset_t *mask); -+extern int setup_signal_stack_si(unsigned long stack_top, int sig, -+ unsigned long handler, -+ void (*restorer)(void), -+ struct pt_regs *regs, siginfo_t *info, -+ sigset_t *mask); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/frame_user.h um/arch/um/include/frame_user.h ---- orig/arch/um/include/frame_user.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/frame_user.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,23 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __FRAME_USER_H_ -+#define __FRAME_USER_H_ -+ -+#include "sysdep/frame_user.h" -+#include "frame.h" -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/helper.h um/arch/um/include/helper.h ---- orig/arch/um/include/helper.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/helper.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,27 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __HELPER_H__ -+#define __HELPER_H__ -+ -+extern int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, -+ unsigned long *stack_out); -+extern int run_helper_thread(int (*proc)(void *), void *arg, -+ unsigned int flags, unsigned long *stack_out, -+ int stack_order); -+extern int helper_wait(int pid); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/init.h um/arch/um/include/init.h ---- orig/arch/um/include/init.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/init.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,114 @@ -+#ifndef _LINUX_UML_INIT_H -+#define _LINUX_UML_INIT_H -+ -+/* These macros are used to mark some functions or -+ * initialized data (doesn't apply to uninitialized data) -+ * as `initialization' functions. The kernel can take this -+ * as hint that the function is used only during the initialization -+ * phase and free up used memory resources after -+ * -+ * Usage: -+ * For functions: -+ * -+ * You should add __init immediately before the function name, like: -+ * -+ * static void __init initme(int x, int y) -+ * { -+ * extern int z; z = x * y; -+ * } -+ * -+ * If the function has a prototype somewhere, you can also add -+ * __init between closing brace of the prototype and semicolon: -+ * -+ * extern int initialize_foobar_device(int, int, int) __init; -+ * -+ * For initialized data: -+ * You should insert __initdata between the variable name and equal -+ * sign followed by value, e.g.: -+ * -+ * static int init_variable __initdata = 0; -+ * static char linux_logo[] __initdata = { 0x32, 0x36, ... }; -+ * -+ * Don't forget to initialize data not at file scope, i.e. within a function, -+ * as gcc otherwise puts the data into the bss section and not into the init -+ * section. -+ * -+ * Also note, that this data cannot be "const". -+ */ -+ -+#ifndef _LINUX_INIT_H -+typedef int (*initcall_t)(void); -+typedef void (*exitcall_t)(void); -+ -+#define __init __attribute__ ((__section__ (".text.init"))) -+#define __exit __attribute__ ((unused, __section__(".text.exit"))) -+#define __initdata __attribute__ ((__section__ (".data.init"))) -+ -+#endif -+ -+#ifndef MODULE -+struct uml_param { -+ const char *str; -+ int (*setup_func)(char *, int *); -+}; -+ -+extern initcall_t __uml_initcall_start, __uml_initcall_end; -+extern initcall_t __uml_postsetup_start, __uml_postsetup_end; -+extern const char *__uml_help_start, *__uml_help_end; -+#endif -+ -+#define __uml_initcall(fn) \ -+ static initcall_t __uml_initcall_##fn __uml_init_call = fn -+ -+#define __uml_exitcall(fn) \ -+ static exitcall_t __uml_exitcall_##fn __uml_exit_call = fn -+ -+extern struct uml_param __uml_setup_start, __uml_setup_end; -+ -+#define __uml_postsetup(fn) \ -+ static initcall_t __uml_postsetup_##fn __uml_postsetup_call = fn -+ -+#define __non_empty_string(dummyname,string) \ -+ struct __uml_non_empty_string_struct_##dummyname \ -+ { \ -+ char _string[sizeof(string)-2]; \ -+ } -+ -+#ifndef MODULE -+#define __uml_setup(str, fn, help...) \ -+ __non_empty_string(fn ##_setup, str); \ -+ __uml_help(fn, help); \ -+ static char __uml_setup_str_##fn[] __initdata = str; \ -+ static struct uml_param __uml_setup_##fn __uml_init_setup = { __uml_setup_str_##fn, fn } -+#else -+#define __uml_setup(str, fn, help...) \ -+ -+#endif -+ -+#define __uml_help(fn, help...) \ -+ __non_empty_string(fn ##__help, help); \ -+ static char __uml_help_str_##fn[] __initdata = help; \ -+ static const char *__uml_help_##fn __uml_setup_help = __uml_help_str_##fn -+ -+/* -+ * Mark functions and data as being only used at initialization -+ * or exit time. -+ */ -+#define __uml_init_setup __attribute__ ((unused,__section__ (".uml.setup.init"))) -+#define __uml_setup_help __attribute__ ((unused,__section__ (".uml.help.init"))) -+#define __uml_init_call __attribute__ ((unused,__section__ (".uml.initcall.init"))) -+#define __uml_postsetup_call __attribute__ ((unused,__section__ (".uml.postsetup.init"))) -+#define __uml_exit_call __attribute__ ((unused,__section__ (".uml.exitcall.exit"))) -+ -+#endif /* _LINUX_UML_INIT_H */ -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/initrd.h um/arch/um/include/initrd.h ---- orig/arch/um/include/initrd.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/initrd.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,22 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __INITRD_USER_H__ -+#define __INITRD_USER_H__ -+ -+extern int load_initrd(char *filename, void *buf, int size); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/irq_kern.h um/arch/um/include/irq_kern.h ---- orig/arch/um/include/irq_kern.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/irq_kern.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,27 @@ -+/* -+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __IRQ_KERN_H__ -+#define __IRQ_KERN_H__ -+ -+#include "linux/interrupt.h" -+ -+extern int um_request_irq(unsigned int irq, int fd, int type, -+ void (*handler)(int, void *, struct pt_regs *), -+ unsigned long irqflags, const char * devname, -+ void *dev_id); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/irq_user.h um/arch/um/include/irq_user.h ---- orig/arch/um/include/irq_user.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/irq_user.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,35 @@ -+/* -+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __IRQ_USER_H__ -+#define __IRQ_USER_H__ -+ -+enum { IRQ_READ, IRQ_WRITE }; -+ -+extern void sigio_handler(int sig, union uml_pt_regs *regs); -+extern int activate_fd(int irq, int fd, int type, void *dev_id); -+extern void free_irq_by_irq_and_dev(int irq, void *dev_id); -+extern void free_irq_by_fd(int fd); -+extern void reactivate_fd(int fd, int irqnum); -+extern void deactivate_fd(int fd, int irqnum); -+extern void forward_interrupts(int pid); -+extern void init_irq_signals(int on_sigstack); -+extern void forward_ipi(int fd, int pid); -+extern void free_irq_later(int irq, void *dev_id); -+extern int activate_ipi(int fd, int pid); -+extern unsigned long irq_lock(void); -+extern void irq_unlock(unsigned long flags); -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/kern.h um/arch/um/include/kern.h ---- orig/arch/um/include/kern.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/kern.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,48 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __KERN_H__ -+#define __KERN_H__ -+ -+/* These are all user-mode things which are convenient to call directly -+ * from kernel code and for which writing a wrapper is too much of a pain. -+ * The regular include files can't be included because this file is included -+ * only into kernel code, and user-space includes conflict with kernel -+ * includes. -+ */ -+ -+extern int errno; -+ -+extern int clone(int (*proc)(void *), void *sp, int flags, void *data); -+extern int sleep(int); -+extern int printf(char *fmt, ...); -+extern char *strerror(int errnum); -+extern char *ptsname(int __fd); -+extern int munmap(void *, int); -+extern void *sbrk(int increment); -+extern void *malloc(int size); -+extern void perror(char *err); -+extern int kill(int pid, int sig); -+extern int getuid(void); -+extern int pause(void); -+extern int write(int, const void *, int); -+extern int exit(int); -+extern int close(int); -+extern int read(unsigned int, char *, int); -+extern int pipe(int *); -+extern int sched_yield(void); -+extern int ptrace(int op, int pid, long addr, long data); -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/kern_util.h um/arch/um/include/kern_util.h ---- orig/arch/um/include/kern_util.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/kern_util.h 2003-11-10 00:58:10.000000000 -0500 -@@ -0,0 +1,123 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __KERN_UTIL_H__ -+#define __KERN_UTIL_H__ -+ -+#include "sysdep/ptrace.h" -+ -+extern int ncpus; -+extern char *linux_prog; -+extern char *gdb_init; -+extern int kmalloc_ok; -+extern int timer_irq_inited; -+extern int jail; -+extern int nsyscalls; -+ -+#define UML_ROUND_DOWN(addr) ((void *)(((unsigned long) addr) & PAGE_MASK)) -+#define UML_ROUND_UP(addr) \ -+ UML_ROUND_DOWN(((unsigned long) addr) + PAGE_SIZE - 1) -+ -+extern int kernel_fork(unsigned long flags, int (*fn)(void *), void * arg); -+extern unsigned long stack_sp(unsigned long page); -+extern int kernel_thread_proc(void *data); -+extern void syscall_segv(int sig); -+extern int current_pid(void); -+extern unsigned long alloc_stack(int order, int atomic); -+extern int do_signal(int error); -+extern int is_stack_fault(unsigned long sp); -+extern unsigned long segv(unsigned long address, unsigned long ip, -+ int is_write, int is_user, void *sc); -+extern unsigned long handle_page_fault(unsigned long address, unsigned long ip, -+ int is_write, int is_user, -+ int *code_out); -+extern void syscall_ready(void); -+extern int segv_syscall(void); -+extern void kern_finish_exec(void *task, int new_pid, unsigned long stack); -+extern int page_size(void); -+extern int page_mask(void); -+extern int need_finish_fork(void); -+extern void free_stack(unsigned long stack, int order); -+extern void add_input_request(int op, void (*proc)(int), void *arg); -+extern int sys_execve(char *file, char **argv, char **env); -+extern char *current_cmd(void); -+extern void timer_handler(int sig, union uml_pt_regs *regs); -+extern int set_signals(int enable); -+extern void force_sigbus(void); -+extern int pid_to_processor_id(int pid); -+extern void block_signals(void); -+extern void unblock_signals(void); -+extern void deliver_signals(void *t); -+extern int next_syscall_index(int max); -+extern int next_trap_index(int max); -+extern void cpu_idle(void); -+extern void finish_fork(void); -+extern void paging_init(void); -+extern void init_flush_vm(void); -+extern void *syscall_sp(void *t); -+extern void syscall_trace(void); -+extern int hz(void); -+extern void idle_timer(void); -+extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs); -+extern int external_pid(void *t); -+extern void boot_timer_handler(int sig); -+extern void interrupt_end(void); -+extern void initial_thread_cb(void (*proc)(void *), void *arg); -+extern int debugger_signal(int status, int pid); -+extern void debugger_parent_signal(int status, int pid); -+extern void child_signal(int pid, int status); -+extern int init_ptrace_proxy(int idle_pid, int startup, int stop); -+extern int init_parent_proxy(int pid); -+extern void check_stack_overflow(void *ptr); -+extern void relay_signal(int sig, union uml_pt_regs *regs); -+extern void not_implemented(void); -+extern int user_context(unsigned long sp); -+extern void timer_irq(union uml_pt_regs *regs); -+extern void unprotect_stack(unsigned long stack); -+extern void do_uml_exitcalls(void); -+extern int attach_debugger(int idle_pid, int pid, int stop); -+extern void bad_segv(unsigned long address, unsigned long ip, int is_write); -+extern int config_gdb(char *str); -+extern int remove_gdb(void); -+extern char *uml_strdup(char *string); -+extern void unprotect_kernel_mem(void); -+extern void protect_kernel_mem(void); -+extern void set_kmem_end(unsigned long); -+extern void uml_cleanup(void); -+extern void set_current(void *t); -+extern void lock_signalled_task(void *t); -+extern void IPI_handler(int cpu); -+extern int jail_setup(char *line, int *add); -+extern void *get_init_task(void); -+extern int clear_user_proc(void *buf, int size); -+extern int copy_to_user_proc(void *to, void *from, int size); -+extern int copy_from_user_proc(void *to, void *from, int size); -+extern int strlen_user_proc(char *str); -+extern void bus_handler(int sig, union uml_pt_regs *regs); -+extern void winch(int sig, union uml_pt_regs *regs); -+extern long execute_syscall(void *r); -+extern int smp_sigio_handler(void); -+extern void *get_current(void); -+extern struct task_struct *get_task(int pid, int require); -+extern void machine_halt(void); -+extern int is_syscall(unsigned long addr); -+extern void arch_switch(void); -+extern void free_irq(unsigned int, void *); -+extern int um_in_interrupt(void); -+extern int cpu(void); -+extern unsigned long long time_stamp(void); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/line.h um/arch/um/include/line.h ---- orig/arch/um/include/line.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/line.h 2003-11-07 02:25:37.000000000 -0500 -@@ -0,0 +1,103 @@ -+/* -+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __LINE_H__ -+#define __LINE_H__ -+ -+#include "linux/list.h" -+#include "linux/tqueue.h" -+#include "linux/tty.h" -+#include "asm/semaphore.h" -+#include "chan_user.h" -+#include "mconsole_kern.h" -+ -+struct line_driver { -+ char *name; -+ char *devfs_name; -+ short major; -+ short minor_start; -+ short type; -+ short subtype; -+ int read_irq; -+ char *read_irq_name; -+ int write_irq; -+ char *write_irq_name; -+ char *symlink_from; -+ char *symlink_to; -+ struct mc_device mc; -+}; -+ -+struct line { -+ char *init_str; -+ int init_pri; -+ struct list_head chan_list; -+ int valid; -+ int count; -+ struct tty_struct *tty; -+ struct semaphore sem; -+ char *buffer; -+ char *head; -+ char *tail; -+ int sigio; -+ struct tq_struct task; -+ struct line_driver *driver; -+ int have_irq; -+}; -+ -+#define LINE_INIT(str, d) \ -+ { init_str : str, \ -+ init_pri : INIT_STATIC, \ -+ chan_list : { }, \ -+ valid : 1, \ -+ count : 0, \ -+ tty : NULL, \ -+ sem : { }, \ -+ buffer : NULL, \ -+ head : NULL, \ -+ tail : NULL, \ -+ sigio : 0, \ -+ driver : d, \ -+ have_irq : 0 } -+ -+struct lines { -+ int num; -+}; -+ -+#define LINES_INIT(n) { num : n } -+ -+extern void line_close(struct line *lines, struct tty_struct *tty); -+extern int line_open(struct line *lines, struct tty_struct *tty, -+ struct chan_opts *opts); -+extern int line_setup(struct line *lines, int num, char *init, -+ int all_allowed); -+extern int line_write(struct line *line, struct tty_struct *tty, int from_user, -+ const char *buf, int len); -+extern char *add_xterm_umid(char *base); -+extern int line_setup_irq(int fd, int input, int output, void *data); -+extern void line_close_chan(struct line *line); -+extern void line_disable(struct line *line, int current_irq); -+extern void line_register_devfs(struct lines *set, -+ struct line_driver *line_driver, -+ struct tty_driver *driver, struct line *lines, -+ int nlines); -+extern void lines_init(struct line *lines, int nlines); -+extern void close_lines(struct line *lines, int nlines); -+extern int line_config(struct line *lines, int num, char *str); -+extern int line_remove(struct line *lines, int num, char *str); -+extern int line_get_config(char *dev, struct line *lines, int num, char *str, -+ int size, char **error_out); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/Makefile um/arch/um/include/Makefile ---- orig/arch/um/include/Makefile 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/Makefile 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,7 @@ -+all : sc.h -+ -+sc.h : ../util/mk_sc -+ ../util/mk_sc > $@ -+ -+../util/mk_sc : -+ $(MAKE) -C ../util mk_sc -diff -Naur -X ../exclude-files orig/arch/um/include/mconsole.h um/arch/um/include/mconsole.h ---- orig/arch/um/include/mconsole.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/mconsole.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,103 @@ -+/* -+ * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) -+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __MCONSOLE_H__ -+#define __MCONSOLE_H__ -+ -+#ifndef __KERNEL__ -+#include <stdint.h> -+#define u32 uint32_t -+#endif -+ -+#define MCONSOLE_MAGIC (0xcafebabe) -+#define MCONSOLE_MAX_DATA (512) -+#define MCONSOLE_VERSION 2 -+ -+struct mconsole_request { -+ u32 magic; -+ u32 version; -+ u32 len; -+ char data[MCONSOLE_MAX_DATA]; -+}; -+ -+struct mconsole_reply { -+ u32 err; -+ u32 more; -+ u32 len; -+ char data[MCONSOLE_MAX_DATA]; -+}; -+ -+struct mconsole_notify { -+ u32 magic; -+ u32 version; -+ enum { MCONSOLE_SOCKET, MCONSOLE_PANIC, MCONSOLE_HANG, -+ MCONSOLE_USER_NOTIFY } type; -+ u32 len; -+ char data[MCONSOLE_MAX_DATA]; -+}; -+ -+struct mc_request; -+ -+enum mc_context { MCONSOLE_INTR, MCONSOLE_PROC }; -+ -+struct mconsole_command -+{ -+ char *command; -+ void (*handler)(struct mc_request *req); -+ enum mc_context context; -+}; -+ -+struct mc_request -+{ -+ int len; -+ int as_interrupt; -+ -+ int originating_fd; -+ int originlen; -+ unsigned char origin[128]; /* sockaddr_un */ -+ -+ struct mconsole_request request; -+ struct mconsole_command *cmd; -+}; -+ -+extern char mconsole_socket_name[]; -+ -+extern int mconsole_unlink_socket(void); -+extern int mconsole_reply(struct mc_request *req, char *reply, int err, -+ int more); -+ -+extern void mconsole_version(struct mc_request *req); -+extern void mconsole_help(struct mc_request *req); -+extern void mconsole_halt(struct mc_request *req); -+extern void mconsole_reboot(struct mc_request *req); -+extern void mconsole_config(struct mc_request *req); -+extern void mconsole_remove(struct mc_request *req); -+extern void mconsole_sysrq(struct mc_request *req); -+extern void mconsole_cad(struct mc_request *req); -+extern void mconsole_stop(struct mc_request *req); -+extern void mconsole_go(struct mc_request *req); -+extern void mconsole_log(struct mc_request *req); -+extern void mconsole_proc(struct mc_request *req); -+ -+extern int mconsole_get_request(int fd, struct mc_request *req); -+extern int mconsole_notify(char *sock_name, int type, const void *data, -+ int len); -+extern char *mconsole_notify_socket(void); -+extern void lock_notify(void); -+extern void unlock_notify(void); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/mconsole_kern.h um/arch/um/include/mconsole_kern.h ---- orig/arch/um/include/mconsole_kern.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/mconsole_kern.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,62 @@ -+/* -+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __MCONSOLE_KERN_H__ -+#define __MCONSOLE_KERN_H__ -+ -+#include "linux/config.h" -+#include "linux/list.h" -+#include "mconsole.h" -+ -+struct mconsole_entry { -+ struct list_head list; -+ struct mc_request request; -+}; -+ -+struct mc_device { -+ struct list_head list; -+ char *name; -+ int (*config)(char *); -+ int (*get_config)(char *, char *, int, char **); -+ int (*remove)(char *); -+}; -+ -+#define CONFIG_CHUNK(str, size, current, chunk, end) \ -+do { \ -+ current += strlen(chunk); \ -+ if(current >= size) \ -+ str = NULL; \ -+ if(str != NULL){ \ -+ strcpy(str, chunk); \ -+ str += strlen(chunk); \ -+ } \ -+ if(end) \ -+ current++; \ -+} while(0) -+ -+#ifdef CONFIG_MCONSOLE -+ -+extern void mconsole_register_dev(struct mc_device *new); -+ -+#else -+ -+static inline void mconsole_register_dev(struct mc_device *new) -+{ -+} -+ -+#endif -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/mem.h um/arch/um/include/mem.h ---- orig/arch/um/include/mem.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/mem.h 2004-01-16 11:14:38.000000000 -0500 -@@ -0,0 +1,29 @@ -+/* -+ * Copyright (C) 2002, 2003 Jeff Dike (jdike@addtoit.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __MEM_H__ -+#define __MEM_H__ -+ -+#include "linux/types.h" -+ -+extern void set_kmem_end(unsigned long new); -+extern int phys_mapping(unsigned long phys, __u64 *offset_out); -+extern int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w); -+extern int is_remapped(void *virt); -+extern int physmem_remove_mapping(void *virt); -+extern void physmem_forget_descriptor(int fd); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/mem_kern.h um/arch/um/include/mem_kern.h ---- orig/arch/um/include/mem_kern.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/mem_kern.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,30 @@ -+/* -+ * Copyright (C) 2003 Jeff Dike (jdike@addtoit.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __MEM_KERN_H__ -+#define __MEM_KERN_H__ -+ -+#include "linux/list.h" -+#include "linux/types.h" -+ -+struct remapper { -+ struct list_head list; -+ int (*proc)(int, unsigned long, int, __u64); -+}; -+ -+extern void register_remapper(struct remapper *info); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/mem_user.h um/arch/um/include/mem_user.h ---- orig/arch/um/include/mem_user.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/mem_user.h 2004-01-10 00:11:06.000000000 -0500 -@@ -0,0 +1,81 @@ -+/* -+ * arch/um/include/mem_user.h -+ * -+ * BRIEF MODULE DESCRIPTION -+ * user side memory interface for support IO memory inside user mode linux -+ * -+ * Copyright (C) 2001 RidgeRun, Inc. -+ * Author: RidgeRun, Inc. -+ * Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ * -+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN -+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#ifndef _MEM_USER_H -+#define _MEM_USER_H -+ -+struct iomem_region { -+ struct iomem_region *next; -+ char *driver; -+ int fd; -+ int size; -+ unsigned long phys; -+ unsigned long virt; -+}; -+ -+extern struct iomem_region *iomem_regions; -+extern int iomem_size; -+ -+#define ROUND_4M(n) ((((unsigned long) (n)) + (1 << 22)) & ~((1 << 22) - 1)) -+ -+extern unsigned long host_task_size; -+extern unsigned long task_size; -+ -+extern int init_mem_user(void); -+extern int create_mem_file(unsigned long len); -+extern void setup_memory(void *entry); -+extern unsigned long find_iomem(char *driver, unsigned long *len_out); -+extern int init_maps(unsigned long physmem, unsigned long iomem, -+ unsigned long highmem); -+extern unsigned long get_vm(unsigned long len); -+extern void setup_physmem(unsigned long start, unsigned long usable, -+ unsigned long len, unsigned long highmem); -+extern void add_iomem(char *name, int fd, unsigned long size); -+extern unsigned long phys_offset(unsigned long phys); -+extern void unmap_physmem(void); -+extern void map_memory(unsigned long virt, unsigned long phys, -+ unsigned long len, int r, int w, int x); -+extern int protect_memory(unsigned long addr, unsigned long len, -+ int r, int w, int x, int must_succeed); -+extern unsigned long get_kmem_end(void); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/mode.h um/arch/um/include/mode.h ---- orig/arch/um/include/mode.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/mode.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,30 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __MODE_H__ -+#define __MODE_H__ -+ -+#include "uml-config.h" -+ -+#ifdef UML_CONFIG_MODE_TT -+#include "../kernel/tt/include/mode.h" -+#endif -+ -+#ifdef UML_CONFIG_MODE_SKAS -+#include "../kernel/skas/include/mode.h" -+#endif -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/mode_kern.h um/arch/um/include/mode_kern.h ---- orig/arch/um/include/mode_kern.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/mode_kern.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,30 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __MODE_KERN_H__ -+#define __MODE_KERN_H__ -+ -+#include "linux/config.h" -+ -+#ifdef CONFIG_MODE_TT -+#include "../kernel/tt/include/mode_kern.h" -+#endif -+ -+#ifdef CONFIG_MODE_SKAS -+#include "../kernel/skas/include/mode_kern.h" -+#endif -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/net_kern.h um/arch/um/include/net_kern.h ---- orig/arch/um/include/net_kern.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/net_kern.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,81 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __UM_NET_KERN_H -+#define __UM_NET_KERN_H -+ -+#include "linux/netdevice.h" -+#include "linux/skbuff.h" -+#include "linux/socket.h" -+#include "linux/list.h" -+ -+struct uml_net { -+ struct list_head list; -+ struct net_device *dev; -+ int index; -+ unsigned char mac[ETH_ALEN]; -+ int have_mac; -+}; -+ -+struct uml_net_private { -+ struct list_head list; -+ spinlock_t lock; -+ struct net_device *dev; -+ struct timer_list tl; -+ struct net_device_stats stats; -+ int fd; -+ unsigned char mac[ETH_ALEN]; -+ int have_mac; -+ unsigned short (*protocol)(struct sk_buff *); -+ int (*open)(void *); -+ void (*close)(int, void *); -+ void (*remove)(void *); -+ int (*read)(int, struct sk_buff **skb, struct uml_net_private *); -+ int (*write)(int, struct sk_buff **skb, struct uml_net_private *); -+ -+ void (*add_address)(unsigned char *, unsigned char *, void *); -+ void (*delete_address)(unsigned char *, unsigned char *, void *); -+ int (*set_mtu)(int mtu, void *); -+ int user[1]; -+}; -+ -+struct net_kern_info { -+ void (*init)(struct net_device *, void *); -+ unsigned short (*protocol)(struct sk_buff *); -+ int (*read)(int, struct sk_buff **skb, struct uml_net_private *); -+ int (*write)(int, struct sk_buff **skb, struct uml_net_private *); -+}; -+ -+struct transport { -+ struct list_head list; -+ char *name; -+ int (*setup)(char *, char **, void *); -+ struct net_user_info *user; -+ struct net_kern_info *kern; -+ int private_size; -+ int setup_size; -+}; -+ -+extern struct net_device *ether_init(int); -+extern unsigned short ether_protocol(struct sk_buff *); -+extern int setup_etheraddr(char *str, unsigned char *addr); -+extern struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra); -+extern int tap_setup_common(char *str, char *type, char **dev_name, -+ char **mac_out, char **gate_addr); -+extern void register_transport(struct transport *new); -+extern unsigned short eth_protocol(struct sk_buff *skb); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/net_user.h um/arch/um/include/net_user.h ---- orig/arch/um/include/net_user.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/net_user.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,66 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __UM_NET_USER_H__ -+#define __UM_NET_USER_H__ -+ -+#define ETH_ADDR_LEN (6) -+#define ETH_HEADER_ETHERTAP (16) -+#define ETH_HEADER_OTHER (14) -+#define ETH_MAX_PACKET (1500) -+ -+#define UML_NET_VERSION (4) -+ -+struct net_user_info { -+ void (*init)(void *, void *); -+ int (*open)(void *); -+ void (*close)(int, void *); -+ void (*remove)(void *); -+ int (*set_mtu)(int mtu, void *); -+ void (*add_address)(unsigned char *, unsigned char *, void *); -+ void (*delete_address)(unsigned char *, unsigned char *, void *); -+ int max_packet; -+}; -+ -+extern void ether_user_init(void *data, void *dev); -+extern void dev_ip_addr(void *d, char *buf, char *bin_buf); -+extern void set_ether_mac(void *d, unsigned char *addr); -+extern void iter_addresses(void *d, void (*cb)(unsigned char *, -+ unsigned char *, void *), -+ void *arg); -+ -+extern void *get_output_buffer(int *len_out); -+extern void free_output_buffer(void *buffer); -+ -+extern int tap_open_common(void *dev, char *gate_addr); -+extern void tap_check_ips(char *gate_addr, char *eth_addr); -+ -+extern void read_output(int fd, char *output_out, int len); -+ -+extern int net_read(int fd, void *buf, int len); -+extern int net_recvfrom(int fd, void *buf, int len); -+extern int net_write(int fd, void *buf, int len); -+extern int net_send(int fd, void *buf, int len); -+extern int net_sendto(int fd, void *buf, int len, void *to, int sock_len); -+ -+extern void open_addr(unsigned char *addr, unsigned char *netmask, void *arg); -+extern void close_addr(unsigned char *addr, unsigned char *netmask, void *arg); -+ -+extern char *split_if_spec(char *str, ...); -+ -+extern int dev_netmask(void *d, void *m); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/os.h um/arch/um/include/os.h ---- orig/arch/um/include/os.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/os.h 2003-12-17 10:48:12.000000000 -0500 -@@ -0,0 +1,180 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __OS_H__ -+#define __OS_H__ -+ -+#include "asm/types.h" -+#include "../os/include/file.h" -+ -+#define OS_TYPE_FILE 1 -+#define OS_TYPE_DIR 2 -+#define OS_TYPE_SYMLINK 3 -+#define OS_TYPE_CHARDEV 4 -+#define OS_TYPE_BLOCKDEV 5 -+#define OS_TYPE_FIFO 6 -+#define OS_TYPE_SOCK 7 -+ -+/* os_access() flags */ -+#define OS_ACC_F_OK 0 /* Test for existence. */ -+#define OS_ACC_X_OK 1 /* Test for execute permission. */ -+#define OS_ACC_W_OK 2 /* Test for write permission. */ -+#define OS_ACC_R_OK 4 /* Test for read permission. */ -+#define OS_ACC_RW_OK (OS_ACC_W_OK | OS_ACC_R_OK) /* Test for RW permission */ -+ -+/* -+ * types taken from stat_file() in hostfs_user.c -+ * (if they are wrong here, they are wrong there...). -+ */ -+struct uml_stat { -+ int ust_dev; /* device */ -+ unsigned long long ust_ino; /* inode */ -+ int ust_mode; /* protection */ -+ int ust_nlink; /* number of hard links */ -+ int ust_uid; /* user ID of owner */ -+ int ust_gid; /* group ID of owner */ -+ unsigned long long ust_size; /* total size, in bytes */ -+ int ust_blksize; /* blocksize for filesystem I/O */ -+ unsigned long long ust_blocks; /* number of blocks allocated */ -+ unsigned long ust_atime; /* time of last access */ -+ unsigned long ust_mtime; /* time of last modification */ -+ unsigned long ust_ctime; /* time of last change */ -+}; -+ -+struct openflags { -+ unsigned int r : 1; -+ unsigned int w : 1; -+ unsigned int s : 1; /* O_SYNC */ -+ unsigned int c : 1; /* O_CREAT */ -+ unsigned int t : 1; /* O_TRUNC */ -+ unsigned int a : 1; /* O_APPEND */ -+ unsigned int e : 1; /* O_EXCL */ -+ unsigned int cl : 1; /* FD_CLOEXEC */ -+}; -+ -+#define OPENFLAGS() ((struct openflags) { .r = 0, .w = 0, .s = 0, .c = 0, \ -+ .t = 0, .a = 0, .e = 0, .cl = 0 }) -+ -+static inline struct openflags of_read(struct openflags flags) -+{ -+ flags.r = 1; -+ return(flags); -+} -+ -+static inline struct openflags of_write(struct openflags flags) -+{ -+ flags.w = 1; -+ return(flags); -+} -+ -+static inline struct openflags of_rdwr(struct openflags flags) -+{ -+ return(of_read(of_write(flags))); -+} -+ -+static inline struct openflags of_set_rw(struct openflags flags, int r, int w) -+{ -+ flags.r = r; -+ flags.w = w; -+ return(flags); -+} -+ -+static inline struct openflags of_sync(struct openflags flags) -+{ -+ flags.s = 1; -+ return(flags); -+} -+ -+static inline struct openflags of_create(struct openflags flags) -+{ -+ flags.c = 1; -+ return(flags); -+} -+ -+static inline struct openflags of_trunc(struct openflags flags) -+{ -+ flags.t = 1; -+ return(flags); -+} -+ -+static inline struct openflags of_append(struct openflags flags) -+{ -+ flags.a = 1; -+ return(flags); -+} -+ -+static inline struct openflags of_excl(struct openflags flags) -+{ -+ flags.e = 1; -+ return(flags); -+} -+ -+static inline struct openflags of_cloexec(struct openflags flags) -+{ -+ flags.cl = 1; -+ return(flags); -+} -+ -+extern int os_stat_file(const char *file_name, struct uml_stat *buf); -+extern int os_stat_fd(const int fd, struct uml_stat *buf); -+extern int os_access(const char *file, int mode); -+extern void os_print_error(int error, const char* str); -+extern int os_get_exec_close(int fd, int *close_on_exec); -+extern int os_set_exec_close(int fd, int close_on_exec); -+extern int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg); -+extern int os_window_size(int fd, int *rows, int *cols); -+extern int os_new_tty_pgrp(int fd, int pid); -+extern int os_get_ifname(int fd, char *namebuf); -+extern int os_set_slip(int fd); -+extern int os_set_owner(int fd, int pid); -+extern int os_sigio_async(int master, int slave); -+extern int os_mode_fd(int fd, int mode); -+ -+extern int os_seek_file(int fd, __u64 offset); -+extern int os_open_file(char *file, struct openflags flags, int mode); -+extern int os_read_file(int fd, void *buf, int len); -+extern int os_write_file(int fd, const void *buf, int count); -+extern int os_file_size(char *file, long long *size_out); -+extern int os_file_modtime(char *file, unsigned long *modtime); -+extern int os_pipe(int *fd, int stream, int close_on_exec); -+extern int os_set_fd_async(int fd, int owner); -+extern int os_set_fd_block(int fd, int blocking); -+extern int os_accept_connection(int fd); -+extern int os_create_unix_socket(char *file, int len, int close_on_exec); -+extern int os_shutdown_socket(int fd, int r, int w); -+extern void os_close_file(int fd); -+extern int os_rcv_fd(int fd, int *helper_pid_out); -+extern int create_unix_socket(char *file, int len, int close_on_exec); -+extern int os_connect_socket(char *name); -+extern int os_file_type(char *file); -+extern int os_file_mode(char *file, struct openflags *mode_out); -+extern int os_lock_file(int fd, int excl); -+ -+extern unsigned long os_process_pc(int pid); -+extern int os_process_parent(int pid); -+extern void os_stop_process(int pid); -+extern void os_kill_process(int pid, int reap_child); -+extern void os_usr1_process(int pid); -+extern int os_getpid(void); -+ -+extern int os_map_memory(void *virt, int fd, unsigned long long off, -+ unsigned long len, int r, int w, int x); -+extern int os_protect_memory(void *addr, unsigned long len, -+ int r, int w, int x); -+extern int os_unmap_memory(void *addr, int len); -+extern void os_flush_stdout(void); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/process.h um/arch/um/include/process.h ---- orig/arch/um/include/process.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/process.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,25 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __PROCESS_H__ -+#define __PROCESS_H__ -+ -+#include <asm/sigcontext.h> -+ -+extern void sig_handler(int sig, struct sigcontext sc); -+extern void alarm_handler(int sig, struct sigcontext sc); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/ptrace_user.h um/arch/um/include/ptrace_user.h ---- orig/arch/um/include/ptrace_user.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/ptrace_user.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,18 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __PTRACE_USER_H__ -+#define __PTRACE_USER_H__ -+ -+#include "sysdep/ptrace_user.h" -+ -+extern int ptrace_getregs(long pid, unsigned long *regs_out); -+extern int ptrace_setregs(long pid, unsigned long *regs_in); -+extern int ptrace_getfpregs(long pid, unsigned long *regs_out); -+extern void arch_enter_kernel(void *task, int pid); -+extern void arch_leave_kernel(void *task, int pid); -+extern void ptrace_pokeuser(unsigned long addr, unsigned long data); -+ -+#endif -diff -Naur -X ../exclude-files orig/arch/um/include/sigcontext.h um/arch/um/include/sigcontext.h ---- orig/arch/um/include/sigcontext.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/sigcontext.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,25 @@ -+/* -+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __UML_SIGCONTEXT_H__ -+#define __UML_SIGCONTEXT_H__ -+ -+#include "sysdep/sigcontext.h" -+ -+extern int sc_size(void *data); -+extern void sc_to_sc(void *to_ptr, void *from_ptr); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/sigio.h um/arch/um/include/sigio.h ---- orig/arch/um/include/sigio.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/sigio.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,28 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __SIGIO_H__ -+#define __SIGIO_H__ -+ -+extern int write_sigio_irq(int fd); -+extern int register_sigio_fd(int fd); -+extern int read_sigio_fd(int fd); -+extern int add_sigio_fd(int fd, int read); -+extern int ignore_sigio_fd(int fd); -+extern void sigio_lock(void); -+extern void sigio_unlock(void); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/signal_kern.h um/arch/um/include/signal_kern.h ---- orig/arch/um/include/signal_kern.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/signal_kern.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,22 @@ -+/* -+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __SIGNAL_KERN_H__ -+#define __SIGNAL_KERN_H__ -+ -+extern int have_signals(void *t); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/signal_user.h um/arch/um/include/signal_user.h ---- orig/arch/um/include/signal_user.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/signal_user.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,26 @@ -+/* -+ * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __SIGNAL_USER_H__ -+#define __SIGNAL_USER_H__ -+ -+extern int signal_stack_size; -+ -+extern int change_sig(int signal, int on); -+extern void set_sigstack(void *stack, int size); -+extern void set_handler(int sig, void (*handler)(int), int flags, ...); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/skas_ptrace.h um/arch/um/include/skas_ptrace.h ---- orig/arch/um/include/skas_ptrace.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/skas_ptrace.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,36 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __SKAS_PTRACE_H -+#define __SKAS_PTRACE_H -+ -+struct ptrace_faultinfo { -+ int is_write; -+ unsigned long addr; -+}; -+ -+struct ptrace_ldt { -+ int func; -+ void *ptr; -+ unsigned long bytecount; -+}; -+ -+#define PTRACE_FAULTINFO 52 -+#define PTRACE_SIGPENDING 53 -+#define PTRACE_LDT 54 -+#define PTRACE_SWITCH_MM 55 -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/syscall_user.h um/arch/um/include/syscall_user.h ---- orig/arch/um/include/syscall_user.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/syscall_user.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,23 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __SYSCALL_USER_H -+#define __SYSCALL_USER_H -+ -+extern int record_syscall_start(int syscall); -+extern void record_syscall_end(int index, int result); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/checksum.h um/arch/um/include/sysdep-i386/checksum.h ---- orig/arch/um/include/sysdep-i386/checksum.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/sysdep-i386/checksum.h 2004-01-13 23:40:05.000000000 -0500 -@@ -0,0 +1,218 @@ -+/* -+ * Licensed under the GPL -+ */ -+ -+#ifndef __UM_SYSDEP_CHECKSUM_H -+#define __UM_SYSDEP_CHECKSUM_H -+ -+#include "linux/string.h" -+#include "asm/uaccess.h" -+ -+/* -+ * computes the checksum of a memory block at buff, length len, -+ * and adds in "sum" (32-bit) -+ * -+ * returns a 32-bit number suitable for feeding into itself -+ * or csum_tcpudp_magic -+ * -+ * this function must be called with even lengths, except -+ * for the last fragment, which may be odd -+ * -+ * it's best to have buff aligned on a 32-bit boundary -+ */ -+unsigned int csum_partial(const unsigned char * buff, int len, -+ unsigned int sum); -+ -+/* -+ * the same as csum_partial, but copies from src while it -+ * checksums, and handles user-space pointer exceptions correctly, when needed. -+ * -+ * here even more important to align src and dst on a 32-bit (or even -+ * better 64-bit) boundary -+ */ -+ -+unsigned int csum_partial_copy_to(const char *src, char *dst, int len, -+ int sum, int *err_ptr); -+unsigned int csum_partial_copy_from(const char *src, char *dst, int len, -+ int sum, int *err_ptr); -+ -+/* -+ * Note: when you get a NULL pointer exception here this means someone -+ * passed in an incorrect kernel address to one of these functions. -+ * -+ * If you use these functions directly please don't forget the -+ * verify_area(). -+ */ -+ -+static __inline__ -+unsigned int csum_partial_copy_nocheck(const char *src, char *dst, -+ int len, int sum) -+{ -+ memcpy(dst, src, len); -+ return(csum_partial(dst, len, sum)); -+} -+ -+static __inline__ -+unsigned int csum_partial_copy_from_user(const char *src, char *dst, -+ int len, int sum, int *err_ptr) -+{ -+ return csum_partial_copy_from(src, dst, len, sum, err_ptr); -+} -+ -+/* -+ * These are the old (and unsafe) way of doing checksums, a warning message -+ * will be printed if they are used and an exception occurs. -+ * -+ * these functions should go away after some time. -+ */ -+ -+#define csum_partial_copy_fromuser csum_partial_copy_from_user -+unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum); -+ -+/* -+ * This is a version of ip_compute_csum() optimized for IP headers, -+ * which always checksum on 4 octet boundaries. -+ * -+ * By Jorge Cwik <jorge@laser.satlink.net>, adapted for linux by -+ * Arnt Gulbrandsen. -+ */ -+static inline unsigned short ip_fast_csum(unsigned char * iph, -+ unsigned int ihl) -+{ -+ unsigned int sum; -+ -+ __asm__ __volatile__( -+ "movl (%1), %0 ;\n" -+ "subl $4, %2 ;\n" -+ "jbe 2f ;\n" -+ "addl 4(%1), %0 ;\n" -+ "adcl 8(%1), %0 ;\n" -+ "adcl 12(%1), %0 ;\n" -+"1: adcl 16(%1), %0 ;\n" -+ "lea 4(%1), %1 ;\n" -+ "decl %2 ;\n" -+ "jne 1b ;\n" -+ "adcl $0, %0 ;\n" -+ "movl %0, %2 ;\n" -+ "shrl $16, %0 ;\n" -+ "addw %w2, %w0 ;\n" -+ "adcl $0, %0 ;\n" -+ "notl %0 ;\n" -+"2: ;\n" -+ /* Since the input registers which are loaded with iph and ipl -+ are modified, we must also specify them as outputs, or gcc -+ will assume they contain their original values. */ -+ : "=r" (sum), "=r" (iph), "=r" (ihl) -+ : "1" (iph), "2" (ihl)); -+ return(sum); -+} -+ -+/* -+ * Fold a partial checksum -+ */ -+ -+static inline unsigned int csum_fold(unsigned int sum) -+{ -+ __asm__( -+ "addl %1, %0 ;\n" -+ "adcl $0xffff, %0 ;\n" -+ : "=r" (sum) -+ : "r" (sum << 16), "0" (sum & 0xffff0000) -+ ); -+ return (~sum) >> 16; -+} -+ -+static inline unsigned long csum_tcpudp_nofold(unsigned long saddr, -+ unsigned long daddr, -+ unsigned short len, -+ unsigned short proto, -+ unsigned int sum) -+{ -+ __asm__( -+ "addl %1, %0 ;\n" -+ "adcl %2, %0 ;\n" -+ "adcl %3, %0 ;\n" -+ "adcl $0, %0 ;\n" -+ : "=r" (sum) -+ : "g" (daddr), "g"(saddr), "g"((ntohs(len)<<16)+proto*256), "0"(sum)); -+ return sum; -+} -+ -+/* -+ * computes the checksum of the TCP/UDP pseudo-header -+ * returns a 16-bit checksum, already complemented -+ */ -+static inline unsigned short int csum_tcpudp_magic(unsigned long saddr, -+ unsigned long daddr, -+ unsigned short len, -+ unsigned short proto, -+ unsigned int sum) -+{ -+ return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); -+} -+ -+/* -+ * this routine is used for miscellaneous IP-like checksums, mainly -+ * in icmp.c -+ */ -+ -+static inline unsigned short ip_compute_csum(unsigned char * buff, int len) -+{ -+ return csum_fold (csum_partial(buff, len, 0)); -+} -+ -+#define _HAVE_ARCH_IPV6_CSUM -+static __inline__ unsigned short int csum_ipv6_magic(struct in6_addr *saddr, -+ struct in6_addr *daddr, -+ __u32 len, -+ unsigned short proto, -+ unsigned int sum) -+{ -+ __asm__( -+ "addl 0(%1), %0 ;\n" -+ "adcl 4(%1), %0 ;\n" -+ "adcl 8(%1), %0 ;\n" -+ "adcl 12(%1), %0 ;\n" -+ "adcl 0(%2), %0 ;\n" -+ "adcl 4(%2), %0 ;\n" -+ "adcl 8(%2), %0 ;\n" -+ "adcl 12(%2), %0 ;\n" -+ "adcl %3, %0 ;\n" -+ "adcl %4, %0 ;\n" -+ "adcl $0, %0 ;\n" -+ : "=&r" (sum) -+ : "r" (saddr), "r" (daddr), -+ "r"(htonl(len)), "r"(htonl(proto)), "0"(sum)); -+ -+ return csum_fold(sum); -+} -+ -+/* -+ * Copy and checksum to user -+ */ -+#define HAVE_CSUM_COPY_USER -+static __inline__ unsigned int csum_and_copy_to_user(const char *src, -+ char *dst, int len, -+ int sum, int *err_ptr) -+{ -+ if (access_ok(VERIFY_WRITE, dst, len)) -+ return(csum_partial_copy_to(src, dst, len, sum, err_ptr)); -+ -+ if (len) -+ *err_ptr = -EFAULT; -+ -+ return -1; /* invalid checksum */ -+} -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/frame.h um/arch/um/include/sysdep-i386/frame.h ---- orig/arch/um/include/sysdep-i386/frame.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/sysdep-i386/frame.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,29 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __FRAME_I386_H -+#define __FRAME_I386_H -+ -+struct arch_frame_data_raw { -+ unsigned long fp_start; -+ unsigned long sr; -+}; -+ -+struct arch_frame_data { -+ int fpstate_size; -+}; -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/frame_kern.h um/arch/um/include/sysdep-i386/frame_kern.h ---- orig/arch/um/include/sysdep-i386/frame_kern.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/sysdep-i386/frame_kern.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,69 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __FRAME_KERN_I386_H -+#define __FRAME_KERN_I386_H -+ -+/* This is called from sys_sigreturn. It takes the sp at the point of the -+ * sigreturn system call and returns the address of the sigcontext struct -+ * on the stack. -+ */ -+ -+static inline void *sp_to_sc(unsigned long sp) -+{ -+ return((void *) sp); -+} -+ -+static inline void *sp_to_uc(unsigned long sp) -+{ -+ unsigned long uc; -+ -+ uc = sp + signal_frame_si.uc_index - -+ signal_frame_si.common.sp_index - 4; -+ return((void *) uc); -+} -+ -+static inline void *sp_to_rt_sc(unsigned long sp) -+{ -+ unsigned long sc; -+ -+ sc = sp - signal_frame_si.common.sp_index + -+ signal_frame_si.common.len - 4; -+ return((void *) sc); -+} -+ -+static inline void *sp_to_mask(unsigned long sp) -+{ -+ unsigned long mask; -+ -+ mask = sp - signal_frame_sc.common.sp_index + -+ signal_frame_sc.common.len - 8; -+ return((void *) mask); -+} -+ -+extern int sc_size(void *data); -+ -+static inline void *sp_to_rt_mask(unsigned long sp) -+{ -+ unsigned long mask; -+ -+ mask = sp - signal_frame_si.common.sp_index + -+ signal_frame_si.common.len + -+ sc_size(&signal_frame_si.common.arch) - 4; -+ return((void *) mask); -+} -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/frame_user.h um/arch/um/include/sysdep-i386/frame_user.h ---- orig/arch/um/include/sysdep-i386/frame_user.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/sysdep-i386/frame_user.h 2004-01-14 03:54:47.000000000 -0500 -@@ -0,0 +1,91 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __FRAME_USER_I386_H -+#define __FRAME_USER_I386_H -+ -+#include <asm/page.h> -+#include "sysdep/frame.h" -+ -+/* This stuff is to calculate the size of the fp state struct at runtime -+ * because it has changed between 2.2 and 2.4 and it would be good for a -+ * UML compiled on one to work on the other. -+ * So, setup_arch_frame_raw fills in the arch struct with the raw data, which -+ * just contains the address of the end of the sigcontext. This is invoked -+ * from the signal handler. -+ * setup_arch_frame uses that data to figure out what -+ * arch_frame_data.fpstate_size should be. It really has no idea, since it's -+ * not allowed to do sizeof(struct fpstate) but it's safe to consider that it's -+ * everything from the end of the sigcontext up to the top of the stack. So, -+ * it masks off the page number to get the offset within the page and subtracts -+ * that from the page size, and that's how big the fpstate struct will be -+ * considered to be. -+ */ -+ -+static inline void setup_arch_frame_raw(struct arch_frame_data_raw *data, -+ void *end, unsigned long srp) -+{ -+ unsigned long sr = *((unsigned long *) srp); -+ -+ data->fp_start = (unsigned long) end; -+ if((sr & PAGE_MASK) == ((unsigned long) end & PAGE_MASK)) -+ data->sr = sr; -+ else data->sr = 0; -+} -+ -+static inline void setup_arch_frame(struct arch_frame_data_raw *in, -+ struct arch_frame_data *out) -+{ -+ unsigned long fpstate_start = in->fp_start; -+ -+ if(in->sr == 0){ -+ fpstate_start &= ~PAGE_MASK; -+ out->fpstate_size = PAGE_SIZE - fpstate_start; -+ } -+ else { -+ out->fpstate_size = in->sr - fpstate_start; -+ } -+} -+ -+/* This figures out where on the stack the SA_RESTORER function address -+ * is stored. For i386, it's the signal handler return address, so it's -+ * located next to the frame pointer. -+ * This is inlined, so __builtin_frame_address(0) is correct. Otherwise, -+ * it would have to be __builtin_frame_address(1). -+ */ -+ -+#define frame_restorer() \ -+({ \ -+ unsigned long *fp; \ -+\ -+ fp = __builtin_frame_address(0); \ -+ ((unsigned long) (fp + 1)); \ -+}) -+ -+/* Similarly, this returns the value of sp when the handler was first -+ * entered. This is used to calculate the proper sp when delivering -+ * signals. -+ */ -+ -+#define frame_sp() \ -+({ \ -+ unsigned long *fp; \ -+\ -+ fp = __builtin_frame_address(0); \ -+ ((unsigned long) (fp + 1)); \ -+}) -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/ptrace.h um/arch/um/include/sysdep-i386/ptrace.h ---- orig/arch/um/include/sysdep-i386/ptrace.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/sysdep-i386/ptrace.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,193 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __SYSDEP_I386_PTRACE_H -+#define __SYSDEP_I386_PTRACE_H -+ -+#include "uml-config.h" -+ -+#ifdef UML_CONFIG_MODE_TT -+#include "ptrace-tt.h" -+#endif -+ -+#ifdef UML_CONFIG_MODE_SKAS -+#include "ptrace-skas.h" -+#endif -+ -+#include "choose-mode.h" -+ -+union uml_pt_regs { -+#ifdef UML_CONFIG_MODE_TT -+ struct tt_regs { -+ long syscall; -+ void *sc; -+ } tt; -+#endif -+#ifdef UML_CONFIG_MODE_SKAS -+ struct skas_regs { -+ unsigned long regs[HOST_FRAME_SIZE]; -+ unsigned long fp[HOST_FP_SIZE]; -+ unsigned long xfp[HOST_XFP_SIZE]; -+ unsigned long fault_addr; -+ unsigned long fault_type; -+ unsigned long trap_type; -+ long syscall; -+ int is_user; -+ } skas; -+#endif -+}; -+ -+#define EMPTY_UML_PT_REGS { } -+ -+extern int mode_tt; -+ -+#define UPT_SC(r) ((r)->tt.sc) -+#define UPT_IP(r) \ -+ CHOOSE_MODE(SC_IP(UPT_SC(r)), REGS_IP((r)->skas.regs)) -+#define UPT_SP(r) \ -+ CHOOSE_MODE(SC_SP(UPT_SC(r)), REGS_SP((r)->skas.regs)) -+#define UPT_EFLAGS(r) \ -+ CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs)) -+#define UPT_EAX(r) \ -+ CHOOSE_MODE(SC_EAX(UPT_SC(r)), REGS_EAX((r)->skas.regs)) -+#define UPT_EBX(r) \ -+ CHOOSE_MODE(SC_EBX(UPT_SC(r)), REGS_EBX((r)->skas.regs)) -+#define UPT_ECX(r) \ -+ CHOOSE_MODE(SC_ECX(UPT_SC(r)), REGS_ECX((r)->skas.regs)) -+#define UPT_EDX(r) \ -+ CHOOSE_MODE(SC_EDX(UPT_SC(r)), REGS_EDX((r)->skas.regs)) -+#define UPT_ESI(r) \ -+ CHOOSE_MODE(SC_ESI(UPT_SC(r)), REGS_ESI((r)->skas.regs)) -+#define UPT_EDI(r) \ -+ CHOOSE_MODE(SC_EDI(UPT_SC(r)), REGS_EDI((r)->skas.regs)) -+#define UPT_EBP(r) \ -+ CHOOSE_MODE(SC_EBP(UPT_SC(r)), REGS_EBP((r)->skas.regs)) -+#define UPT_ORIG_EAX(r) \ -+ CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall) -+#define UPT_CS(r) \ -+ CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs)) -+#define UPT_SS(r) \ -+ CHOOSE_MODE(SC_SS(UPT_SC(r)), REGS_SS((r)->skas.regs)) -+#define UPT_DS(r) \ -+ CHOOSE_MODE(SC_DS(UPT_SC(r)), REGS_DS((r)->skas.regs)) -+#define UPT_ES(r) \ -+ CHOOSE_MODE(SC_ES(UPT_SC(r)), REGS_ES((r)->skas.regs)) -+#define UPT_FS(r) \ -+ CHOOSE_MODE(SC_FS(UPT_SC(r)), REGS_FS((r)->skas.regs)) -+#define UPT_GS(r) \ -+ CHOOSE_MODE(SC_GS(UPT_SC(r)), REGS_GS((r)->skas.regs)) -+ -+#define UPT_SYSCALL_ARG1(r) UPT_EBX(r) -+#define UPT_SYSCALL_ARG2(r) UPT_ECX(r) -+#define UPT_SYSCALL_ARG3(r) UPT_EDX(r) -+#define UPT_SYSCALL_ARG4(r) UPT_ESI(r) -+#define UPT_SYSCALL_ARG5(r) UPT_EDI(r) -+#define UPT_SYSCALL_ARG6(r) UPT_EBP(r) -+ -+extern int user_context(unsigned long sp); -+ -+#define UPT_IS_USER(r) \ -+ CHOOSE_MODE(user_context(UPT_SP(r)), (r)->skas.is_user) -+ -+struct syscall_args { -+ unsigned long args[6]; -+}; -+ -+#define SYSCALL_ARGS(r) ((struct syscall_args) \ -+ { .args = { UPT_SYSCALL_ARG1(r), \ -+ UPT_SYSCALL_ARG2(r), \ -+ UPT_SYSCALL_ARG3(r), \ -+ UPT_SYSCALL_ARG4(r), \ -+ UPT_SYSCALL_ARG5(r), \ -+ UPT_SYSCALL_ARG6(r) } } ) -+ -+#define UPT_REG(regs, reg) \ -+ ({ unsigned long val; \ -+ switch(reg){ \ -+ case EIP: val = UPT_IP(regs); break; \ -+ case UESP: val = UPT_SP(regs); break; \ -+ case EAX: val = UPT_EAX(regs); break; \ -+ case EBX: val = UPT_EBX(regs); break; \ -+ case ECX: val = UPT_ECX(regs); break; \ -+ case EDX: val = UPT_EDX(regs); break; \ -+ case ESI: val = UPT_ESI(regs); break; \ -+ case EDI: val = UPT_EDI(regs); break; \ -+ case EBP: val = UPT_EBP(regs); break; \ -+ case ORIG_EAX: val = UPT_ORIG_EAX(regs); break; \ -+ case CS: val = UPT_CS(regs); break; \ -+ case SS: val = UPT_SS(regs); break; \ -+ case DS: val = UPT_DS(regs); break; \ -+ case ES: val = UPT_ES(regs); break; \ -+ case FS: val = UPT_FS(regs); break; \ -+ case GS: val = UPT_GS(regs); break; \ -+ case EFL: val = UPT_EFLAGS(regs); break; \ -+ default : \ -+ panic("Bad register in UPT_REG : %d\n", reg); \ -+ val = -1; \ -+ } \ -+ val; \ -+ }) -+ -+ -+#define UPT_SET(regs, reg, val) \ -+ do { \ -+ switch(reg){ \ -+ case EIP: UPT_IP(regs) = val; break; \ -+ case UESP: UPT_SP(regs) = val; break; \ -+ case EAX: UPT_EAX(regs) = val; break; \ -+ case EBX: UPT_EBX(regs) = val; break; \ -+ case ECX: UPT_ECX(regs) = val; break; \ -+ case EDX: UPT_EDX(regs) = val; break; \ -+ case ESI: UPT_ESI(regs) = val; break; \ -+ case EDI: UPT_EDI(regs) = val; break; \ -+ case EBP: UPT_EBP(regs) = val; break; \ -+ case ORIG_EAX: UPT_ORIG_EAX(regs) = val; break; \ -+ case CS: UPT_CS(regs) = val; break; \ -+ case SS: UPT_SS(regs) = val; break; \ -+ case DS: UPT_DS(regs) = val; break; \ -+ case ES: UPT_ES(regs) = val; break; \ -+ case FS: UPT_FS(regs) = val; break; \ -+ case GS: UPT_GS(regs) = val; break; \ -+ case EFL: UPT_EFLAGS(regs) = val; break; \ -+ default : \ -+ panic("Bad register in UPT_SET : %d\n", reg); \ -+ break; \ -+ } \ -+ } while (0) -+ -+#define UPT_SET_SYSCALL_RETURN(r, res) \ -+ CHOOSE_MODE(SC_SET_SYSCALL_RETURN(UPT_SC(r), (res)), \ -+ REGS_SET_SYSCALL_RETURN((r)->skas.regs, (res))) -+ -+#define UPT_RESTART_SYSCALL(r) \ -+ CHOOSE_MODE(SC_RESTART_SYSCALL(UPT_SC(r)), \ -+ REGS_RESTART_SYSCALL((r)->skas.regs)) -+ -+#define UPT_ORIG_SYSCALL(r) UPT_EAX(r) -+#define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r) -+#define UPT_SYSCALL_RET(r) UPT_EAX(r) -+ -+#define UPT_SEGV_IS_FIXABLE(r) \ -+ CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \ -+ REGS_SEGV_IS_FIXABLE(&r->skas)) -+ -+#define UPT_FAULT_ADDR(r) \ -+ CHOOSE_MODE(SC_FAULT_ADDR(UPT_SC(r)), REGS_FAULT_ADDR(&r->skas)) -+ -+#define UPT_FAULT_WRITE(r) \ -+ CHOOSE_MODE(SC_FAULT_WRITE(UPT_SC(r)), REGS_FAULT_WRITE(&r->skas)) -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/ptrace_user.h um/arch/um/include/sysdep-i386/ptrace_user.h ---- orig/arch/um/include/sysdep-i386/ptrace_user.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/sysdep-i386/ptrace_user.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,62 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __SYSDEP_I386_PTRACE_USER_H__ -+#define __SYSDEP_I386_PTRACE_USER_H__ -+ -+#include <asm/ptrace.h> -+ -+#define PT_OFFSET(r) ((r) * sizeof(long)) -+ -+#define PT_SYSCALL_NR(regs) ((regs)[ORIG_EAX]) -+#define PT_SYSCALL_NR_OFFSET PT_OFFSET(ORIG_EAX) -+ -+#define PT_SYSCALL_ARG1_OFFSET PT_OFFSET(EBX) -+#define PT_SYSCALL_ARG2_OFFSET PT_OFFSET(ECX) -+#define PT_SYSCALL_ARG3_OFFSET PT_OFFSET(EDX) -+#define PT_SYSCALL_ARG4_OFFSET PT_OFFSET(ESI) -+#define PT_SYSCALL_ARG5_OFFSET PT_OFFSET(EDI) -+ -+#define PT_SYSCALL_RET_OFFSET PT_OFFSET(EAX) -+ -+#define PT_IP_OFFSET PT_OFFSET(EIP) -+#define PT_IP(regs) ((regs)[EIP]) -+#define PT_SP(regs) ((regs)[UESP]) -+ -+#ifndef FRAME_SIZE -+#define FRAME_SIZE (17) -+#endif -+#define FRAME_SIZE_OFFSET (FRAME_SIZE * sizeof(unsigned long)) -+ -+#define FP_FRAME_SIZE (27) -+#define FPX_FRAME_SIZE (128) -+ -+#ifdef PTRACE_GETREGS -+#define UM_HAVE_GETREGS -+#endif -+ -+#ifdef PTRACE_SETREGS -+#define UM_HAVE_SETREGS -+#endif -+ -+#ifdef PTRACE_GETFPREGS -+#define UM_HAVE_GETFPREGS -+#endif -+ -+#ifdef PTRACE_SETFPREGS -+#define UM_HAVE_SETFPREGS -+#endif -+ -+#ifdef PTRACE_GETFPXREGS -+#define UM_HAVE_GETFPXREGS -+#endif -+ -+#ifdef PTRACE_SETFPXREGS -+#define UM_HAVE_SETFPXREGS -+#endif -+ -+extern void update_debugregs(int seq); -+ -+#endif -diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/sigcontext.h um/arch/um/include/sysdep-i386/sigcontext.h ---- orig/arch/um/include/sysdep-i386/sigcontext.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/sysdep-i386/sigcontext.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,49 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __SYS_SIGCONTEXT_I386_H -+#define __SYS_SIGCONTEXT_I386_H -+ -+#include "sc.h" -+ -+#define IP_RESTART_SYSCALL(ip) ((ip) -= 2) -+ -+#define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc)) -+#define SC_SET_SYSCALL_RETURN(sc, result) SC_EAX(sc) = (result) -+ -+#define SC_FAULT_ADDR(sc) SC_CR2(sc) -+#define SC_FAULT_TYPE(sc) SC_ERR(sc) -+ -+#define FAULT_WRITE(err) (err & 2) -+#define TO_SC_ERR(is_write) ((is_write) ? 2 : 0) -+ -+#define SC_FAULT_WRITE(sc) (FAULT_WRITE(SC_ERR(sc))) -+ -+#define SC_TRAP_TYPE(sc) SC_TRAPNO(sc) -+ -+/* ptrace expects that, at the start of a system call, %eax contains -+ * -ENOSYS, so this makes it so. -+ */ -+#define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0) -+ -+/* This is Page Fault */ -+#define SEGV_IS_FIXABLE(trap) (trap == 14) -+ -+#define SC_SEGV_IS_FIXABLE(sc) (SEGV_IS_FIXABLE(SC_TRAPNO(sc))) -+ -+extern unsigned long *sc_sigmask(void *sc_ptr); -+extern int sc_get_fpregs(unsigned long buf, void *sc_ptr); -+ -+#endif -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-i386/syscalls.h um/arch/um/include/sysdep-i386/syscalls.h ---- orig/arch/um/include/sysdep-i386/syscalls.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/sysdep-i386/syscalls.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,61 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "asm/unistd.h" -+#include "sysdep/ptrace.h" -+ -+typedef long syscall_handler_t(struct pt_regs); -+ -+#define EXECUTE_SYSCALL(syscall, regs) \ -+ ((long (*)(struct syscall_args)) (*sys_call_table[syscall]))(SYSCALL_ARGS(®s->regs)) -+ -+extern syscall_handler_t sys_modify_ldt; -+extern syscall_handler_t old_mmap_i386; -+extern syscall_handler_t old_select; -+extern syscall_handler_t sys_ni_syscall; -+ -+#define ARCH_SYSCALLS \ -+ [ __NR_mmap ] = old_mmap_i386, \ -+ [ __NR_select ] = old_select, \ -+ [ __NR_vm86old ] = sys_ni_syscall, \ -+ [ __NR_modify_ldt ] = sys_modify_ldt, \ -+ [ __NR_lchown32 ] = sys_lchown, \ -+ [ __NR_getuid32 ] = sys_getuid, \ -+ [ __NR_getgid32 ] = sys_getgid, \ -+ [ __NR_geteuid32 ] = sys_geteuid, \ -+ [ __NR_getegid32 ] = sys_getegid, \ -+ [ __NR_setreuid32 ] = sys_setreuid, \ -+ [ __NR_setregid32 ] = sys_setregid, \ -+ [ __NR_getgroups32 ] = sys_getgroups, \ -+ [ __NR_setgroups32 ] = sys_setgroups, \ -+ [ __NR_fchown32 ] = sys_fchown, \ -+ [ __NR_setresuid32 ] = sys_setresuid, \ -+ [ __NR_getresuid32 ] = sys_getresuid, \ -+ [ __NR_setresgid32 ] = sys_setresgid, \ -+ [ __NR_getresgid32 ] = sys_getresgid, \ -+ [ __NR_chown32 ] = sys_chown, \ -+ [ __NR_setuid32 ] = sys_setuid, \ -+ [ __NR_setgid32 ] = sys_setgid, \ -+ [ __NR_setfsuid32 ] = sys_setfsuid, \ -+ [ __NR_setfsgid32 ] = sys_setfsgid, \ -+ [ __NR_pivot_root ] = sys_pivot_root, \ -+ [ __NR_mincore ] = sys_mincore, \ -+ [ __NR_madvise ] = sys_madvise, \ -+ [ 222 ] = sys_ni_syscall, -+ -+/* 222 doesn't yet have a name in include/asm-i386/unistd.h */ -+ -+#define LAST_ARCH_SYSCALL 222 -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ia64/ptrace.h um/arch/um/include/sysdep-ia64/ptrace.h ---- orig/arch/um/include/sysdep-ia64/ptrace.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/sysdep-ia64/ptrace.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,26 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __SYSDEP_IA64_PTRACE_H -+#define __SYSDEP_IA64_PTRACE_H -+ -+struct sys_pt_regs { -+ int foo; -+}; -+ -+#define EMPTY_REGS { 0 } -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ia64/sigcontext.h um/arch/um/include/sysdep-ia64/sigcontext.h ---- orig/arch/um/include/sysdep-ia64/sigcontext.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/sysdep-ia64/sigcontext.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,20 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __SYSDEP_IA64_SIGCONTEXT_H -+#define __SYSDEP_IA64_SIGCONTEXT_H -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ia64/syscalls.h um/arch/um/include/sysdep-ia64/syscalls.h ---- orig/arch/um/include/sysdep-ia64/syscalls.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/sysdep-ia64/syscalls.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,20 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __SYSDEP_IA64_SYSCALLS_H -+#define __SYSDEP_IA64_SYSCALLS_H -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ppc/ptrace.h um/arch/um/include/sysdep-ppc/ptrace.h ---- orig/arch/um/include/sysdep-ppc/ptrace.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/sysdep-ppc/ptrace.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,104 @@ -+/* -+ * Licensed under the GPL -+ */ -+ -+#ifndef __SYS_PTRACE_PPC_H -+#define __SYS_PTRACE_PPC_H -+ -+#include "linux/config.h" -+#include "linux/types.h" -+ -+/* the following taken from <asm-ppc/ptrace.h> */ -+ -+#ifdef CONFIG_PPC64 -+#define PPC_REG unsigned long /*long*/ -+#else -+#define PPC_REG unsigned long -+#endif -+struct sys_pt_regs_s { -+ PPC_REG gpr[32]; -+ PPC_REG nip; -+ PPC_REG msr; -+ PPC_REG orig_gpr3; /* Used for restarting system calls */ -+ PPC_REG ctr; -+ PPC_REG link; -+ PPC_REG xer; -+ PPC_REG ccr; -+ PPC_REG mq; /* 601 only (not used at present) */ -+ /* Used on APUS to hold IPL value. */ -+ PPC_REG trap; /* Reason for being here */ -+ PPC_REG dar; /* Fault registers */ -+ PPC_REG dsisr; -+ PPC_REG result; /* Result of a system call */ -+}; -+ -+#define NUM_REGS (sizeof(struct sys_pt_regs_s) / sizeof(PPC_REG)) -+ -+struct sys_pt_regs { -+ PPC_REG regs[sizeof(struct sys_pt_regs_s) / sizeof(PPC_REG)]; -+}; -+ -+#define UM_MAX_REG (PT_FPR0) -+#define UM_MAX_REG_OFFSET (UM_MAX_REG * sizeof(PPC_REG)) -+ -+#define EMPTY_REGS { { [ 0 ... NUM_REGS - 1] = 0 } } -+ -+#define UM_REG(r, n) ((r)->regs[n]) -+ -+#define UM_SYSCALL_RET(r) UM_REG(r, PT_R3) -+#define UM_SP(r) UM_REG(r, PT_R1) -+#define UM_IP(r) UM_REG(r, PT_NIP) -+#define UM_ELF_ZERO(r) UM_REG(r, PT_FPSCR) -+#define UM_SYSCALL_NR(r) UM_REG(r, PT_R0) -+#define UM_SYSCALL_ARG1(r) UM_REG(r, PT_ORIG_R3) -+#define UM_SYSCALL_ARG2(r) UM_REG(r, PT_R4) -+#define UM_SYSCALL_ARG3(r) UM_REG(r, PT_R5) -+#define UM_SYSCALL_ARG4(r) UM_REG(r, PT_R6) -+#define UM_SYSCALL_ARG5(r) UM_REG(r, PT_R7) -+#define UM_SYSCALL_ARG6(r) UM_REG(r, PT_R8) -+ -+#define UM_SYSCALL_NR_OFFSET (PT_R0 * sizeof(PPC_REG)) -+#define UM_SYSCALL_RET_OFFSET (PT_R3 * sizeof(PPC_REG)) -+#define UM_SYSCALL_ARG1_OFFSET (PT_R3 * sizeof(PPC_REG)) -+#define UM_SYSCALL_ARG2_OFFSET (PT_R4 * sizeof(PPC_REG)) -+#define UM_SYSCALL_ARG3_OFFSET (PT_R5 * sizeof(PPC_REG)) -+#define UM_SYSCALL_ARG4_OFFSET (PT_R6 * sizeof(PPC_REG)) -+#define UM_SYSCALL_ARG5_OFFSET (PT_R7 * sizeof(PPC_REG)) -+#define UM_SYSCALL_ARG6_OFFSET (PT_R8 * sizeof(PPC_REG)) -+#define UM_SP_OFFSET (PT_R1 * sizeof(PPC_REG)) -+#define UM_IP_OFFSET (PT_NIP * sizeof(PPC_REG)) -+#define UM_ELF_ZERO_OFFSET (PT_R3 * sizeof(PPC_REG)) -+ -+#define UM_SET_SYSCALL_RETURN(_regs, result) \ -+do { \ -+ if (result < 0) { \ -+ (_regs)->regs[PT_CCR] |= 0x10000000; \ -+ UM_SYSCALL_RET((_regs)) = -result; \ -+ } else { \ -+ UM_SYSCALL_RET((_regs)) = result; \ -+ } \ -+} while(0) -+ -+extern void shove_aux_table(unsigned long sp); -+#define UM_FIX_EXEC_STACK(sp) shove_aux_table(sp); -+ -+/* These aren't actually defined. The undefs are just to make sure -+ * everyone's clear on the concept. -+ */ -+#undef UML_HAVE_GETREGS -+#undef UML_HAVE_GETFPREGS -+#undef UML_HAVE_SETREGS -+#undef UML_HAVE_SETFPREGS -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ppc/sigcontext.h um/arch/um/include/sysdep-ppc/sigcontext.h ---- orig/arch/um/include/sysdep-ppc/sigcontext.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/sysdep-ppc/sigcontext.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,62 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __SYS_SIGCONTEXT_PPC_H -+#define __SYS_SIGCONTEXT_PPC_H -+ -+#define DSISR_WRITE 0x02000000 -+ -+#define SC_FAULT_ADDR(sc) ({ \ -+ struct sigcontext *_sc = (sc); \ -+ long retval = -1; \ -+ switch (_sc->regs->trap) { \ -+ case 0x300: \ -+ /* data exception */ \ -+ retval = _sc->regs->dar; \ -+ break; \ -+ case 0x400: \ -+ /* instruction exception */ \ -+ retval = _sc->regs->nip; \ -+ break; \ -+ default: \ -+ panic("SC_FAULT_ADDR: unhandled trap type\n"); \ -+ } \ -+ retval; \ -+ }) -+ -+#define SC_FAULT_WRITE(sc) ({ \ -+ struct sigcontext *_sc = (sc); \ -+ long retval = -1; \ -+ switch (_sc->regs->trap) { \ -+ case 0x300: \ -+ /* data exception */ \ -+ retval = !!(_sc->regs->dsisr & DSISR_WRITE); \ -+ break; \ -+ case 0x400: \ -+ /* instruction exception: not a write */ \ -+ retval = 0; \ -+ break; \ -+ default: \ -+ panic("SC_FAULT_ADDR: unhandled trap type\n"); \ -+ } \ -+ retval; \ -+ }) -+ -+#define SC_IP(sc) ((sc)->regs->nip) -+#define SC_SP(sc) ((sc)->regs->gpr[1]) -+#define SEGV_IS_FIXABLE(sc) (1) -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/sysdep-ppc/syscalls.h um/arch/um/include/sysdep-ppc/syscalls.h ---- orig/arch/um/include/sysdep-ppc/syscalls.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/sysdep-ppc/syscalls.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,50 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+typedef long syscall_handler_t(unsigned long arg1, unsigned long arg2, -+ unsigned long arg3, unsigned long arg4, -+ unsigned long arg5, unsigned long arg6); -+ -+#define EXECUTE_SYSCALL(syscall, regs) \ -+ (*sys_call_table[syscall])(UM_SYSCALL_ARG1(®s), \ -+ UM_SYSCALL_ARG2(®s), \ -+ UM_SYSCALL_ARG3(®s), \ -+ UM_SYSCALL_ARG4(®s), \ -+ UM_SYSCALL_ARG5(®s), \ -+ UM_SYSCALL_ARG6(®s)) -+ -+extern syscall_handler_t sys_mincore; -+extern syscall_handler_t sys_madvise; -+ -+/* old_mmap needs the correct prototype since syscall_kern.c includes -+ * this file. -+ */ -+int old_mmap(unsigned long addr, unsigned long len, -+ unsigned long prot, unsigned long flags, -+ unsigned long fd, unsigned long offset); -+ -+#define ARCH_SYSCALLS \ -+ [ __NR_modify_ldt ] = sys_ni_syscall, \ -+ [ __NR_pciconfig_read ] = sys_ni_syscall, \ -+ [ __NR_pciconfig_write ] = sys_ni_syscall, \ -+ [ __NR_pciconfig_iobase ] = sys_ni_syscall, \ -+ [ __NR_pivot_root ] = sys_ni_syscall, \ -+ [ __NR_multiplexer ] = sys_ni_syscall, \ -+ [ __NR_mmap ] = old_mmap, \ -+ [ __NR_madvise ] = sys_madvise, \ -+ [ __NR_mincore ] = sys_mincore, -+ -+#define LAST_ARCH_SYSCALL __NR_mincore -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/sysrq.h um/arch/um/include/sysrq.h ---- orig/arch/um/include/sysrq.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/sysrq.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_SYSRQ_H -+#define __UM_SYSRQ_H -+ -+extern void show_trace(unsigned long *stack); -+ -+#endif -diff -Naur -X ../exclude-files orig/arch/um/include/tempfile.h um/arch/um/include/tempfile.h ---- orig/arch/um/include/tempfile.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/tempfile.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,21 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __TEMPFILE_H__ -+#define __TEMPFILE_H__ -+ -+extern int make_tempfile(const char *template, char **tempname, int do_unlink); -+ -+#endif -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/time_user.h um/arch/um/include/time_user.h ---- orig/arch/um/include/time_user.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/time_user.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,17 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __TIME_USER_H__ -+#define __TIME_USER_H__ -+ -+extern void timer(void); -+extern void switch_timers(int to_real); -+extern void set_interval(int timer_type); -+extern void idle_sleep(int secs); -+extern void enable_timer(void); -+extern unsigned long time_lock(void); -+extern void time_unlock(unsigned long); -+ -+#endif -diff -Naur -X ../exclude-files orig/arch/um/include/tlb.h um/arch/um/include/tlb.h ---- orig/arch/um/include/tlb.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/tlb.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,23 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __TLB_H__ -+#define __TLB_H__ -+ -+extern void mprotect_kernel_vm(int w); -+extern void force_flush_all(void); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/ubd_user.h um/arch/um/include/ubd_user.h ---- orig/arch/um/include/ubd_user.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/ubd_user.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,79 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Copyright (C) 2001 RidgeRun, Inc (glonnon@ridgerun.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __UM_UBD_USER_H -+#define __UM_UBD_USER_H -+ -+#include "os.h" -+ -+enum ubd_req { UBD_READ, UBD_WRITE, UBD_MMAP }; -+ -+struct io_thread_req { -+ enum ubd_req op; -+ int fds[2]; -+ unsigned long offsets[2]; -+ unsigned long long offset; -+ unsigned long length; -+ char *buffer; -+ int sectorsize; -+ unsigned long sector_mask; -+ unsigned long long cow_offset; -+ unsigned long bitmap_words[2]; -+ int map_fd; -+ unsigned long long map_offset; -+ int error; -+}; -+ -+extern int open_ubd_file(char *file, struct openflags *openflags, -+ char **backing_file_out, int *bitmap_offset_out, -+ unsigned long *bitmap_len_out, int *data_offset_out, -+ int *create_cow_out); -+extern int create_cow_file(char *cow_file, char *backing_file, -+ struct openflags flags, int sectorsize, -+ int alignment, int *bitmap_offset_out, -+ unsigned long *bitmap_len_out, -+ int *data_offset_out); -+extern int read_cow_bitmap(int fd, void *buf, int offset, int len); -+extern int read_ubd_fs(int fd, void *buffer, int len); -+extern int write_ubd_fs(int fd, char *buffer, int len); -+extern int start_io_thread(unsigned long sp, int *fds_out); -+extern void do_io(struct io_thread_req *req); -+ -+static inline int ubd_test_bit(__u64 bit, unsigned char *data) -+{ -+ __u64 n; -+ int bits, off; -+ -+ bits = sizeof(data[0]) * 8; -+ n = bit / bits; -+ off = bit % bits; -+ return((data[n] & (1 << off)) != 0); -+} -+ -+static inline void ubd_set_bit(__u64 bit, unsigned char *data) -+{ -+ __u64 n; -+ int bits, off; -+ -+ bits = sizeof(data[0]) * 8; -+ n = bit / bits; -+ off = bit % bits; -+ data[n] |= (1 << off); -+} -+ -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/umid.h um/arch/um/include/umid.h ---- orig/arch/um/include/umid.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/umid.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,22 @@ -+/* -+ * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __UMID_H__ -+#define __UMID_H__ -+ -+extern int umid_file_name(char *name, char *buf, int len); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/uml_uaccess.h um/arch/um/include/uml_uaccess.h ---- orig/arch/um/include/uml_uaccess.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/uml_uaccess.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,28 @@ -+/* -+ * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __UML_UACCESS_H__ -+#define __UML_UACCESS_H__ -+ -+extern int __do_copy_to_user(void *to, const void *from, int n, -+ void **fault_addr, void **fault_catcher); -+extern unsigned long __do_user_copy(void *to, const void *from, int n, -+ void **fault_addr, void **fault_catcher, -+ void (*op)(void *to, const void *from, -+ int n), int *faulted_out); -+void __do_copy(void *to, const void *from, int n); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/um_mmu.h um/arch/um/include/um_mmu.h ---- orig/arch/um/include/um_mmu.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/um_mmu.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,40 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __ARCH_UM_MMU_H -+#define __ARCH_UM_MMU_H -+ -+#include "linux/config.h" -+#include "choose-mode.h" -+ -+#ifdef CONFIG_MODE_TT -+#include "../kernel/tt/include/mmu.h" -+#endif -+ -+#ifdef CONFIG_MODE_SKAS -+#include "../kernel/skas/include/mmu.h" -+#endif -+ -+typedef union { -+#ifdef CONFIG_MODE_TT -+ struct mmu_context_tt tt; -+#endif -+#ifdef CONFIG_MODE_SKAS -+ struct mmu_context_skas skas; -+#endif -+} mm_context_t; -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/umn.h um/arch/um/include/umn.h ---- orig/arch/um/include/umn.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/umn.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,27 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __UMN_H -+#define __UMN_H -+ -+extern int open_umn_tty(int *slave_out, int *slipno_out); -+extern void close_umn_tty(int master, int slave); -+extern int umn_send_packet(int fd, void *data, int len); -+extern int set_umn_addr(int fd, char *addr, char *ptp_addr); -+extern void slip_unesc(unsigned char s); -+extern void umn_read(int fd); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/um_uaccess.h um/arch/um/include/um_uaccess.h ---- orig/arch/um/include/um_uaccess.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/um_uaccess.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,124 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __ARCH_UM_UACCESS_H -+#define __ARCH_UM_UACCESS_H -+ -+#include "linux/config.h" -+#include "choose-mode.h" -+ -+#ifdef CONFIG_MODE_TT -+#include "../kernel/tt/include/uaccess.h" -+#endif -+ -+#ifdef CONFIG_MODE_SKAS -+#include "../kernel/skas/include/uaccess.h" -+#endif -+ -+#define access_ok(type, addr, size) \ -+ CHOOSE_MODE_PROC(access_ok_tt, access_ok_skas, type, addr, size) -+ -+static inline int verify_area(int type, const void * addr, unsigned long size) -+{ -+ return(CHOOSE_MODE_PROC(verify_area_tt, verify_area_skas, type, addr, -+ size)); -+} -+ -+static inline int copy_from_user(void *to, const void *from, int n) -+{ -+ return(CHOOSE_MODE_PROC(copy_from_user_tt, copy_from_user_skas, to, -+ from, n)); -+} -+ -+static inline int copy_to_user(void *to, const void *from, int n) -+{ -+ return(CHOOSE_MODE_PROC(copy_to_user_tt, copy_to_user_skas, to, -+ from, n)); -+} -+ -+/* -+ * strncpy_from_user: - Copy a NUL terminated string from userspace. -+ * @dst: Destination address, in kernel space. This buffer must be at -+ * least @count bytes long. -+ * @src: Source address, in user space. -+ * @count: Maximum number of bytes to copy, including the trailing NUL. -+ * -+ * Copies a NUL-terminated string from userspace to kernel space. -+ * -+ * On success, returns the length of the string (not including the trailing -+ * NUL). -+ * -+ * If access to userspace fails, returns -EFAULT (some data may have been -+ * copied). -+ * -+ * If @count is smaller than the length of the string, copies @count bytes -+ * and returns @count. -+ */ -+ -+static inline int strncpy_from_user(char *dst, const char *src, int count) -+{ -+ return(CHOOSE_MODE_PROC(strncpy_from_user_tt, strncpy_from_user_skas, -+ dst, src, count)); -+} -+ -+/* -+ * __clear_user: - Zero a block of memory in user space, with less checking. -+ * @to: Destination address, in user space. -+ * @n: Number of bytes to zero. -+ * -+ * Zero a block of memory in user space. Caller must check -+ * the specified block with access_ok() before calling this function. -+ * -+ * Returns number of bytes that could not be cleared. -+ * On success, this will be zero. -+ */ -+static inline int __clear_user(void *mem, int len) -+{ -+ return(CHOOSE_MODE_PROC(__clear_user_tt, __clear_user_skas, mem, len)); -+} -+ -+/* -+ * clear_user: - Zero a block of memory in user space. -+ * @to: Destination address, in user space. -+ * @n: Number of bytes to zero. -+ * -+ * Zero a block of memory in user space. -+ * -+ * Returns number of bytes that could not be cleared. -+ * On success, this will be zero. -+ */ -+static inline int clear_user(void *mem, int len) -+{ -+ return(CHOOSE_MODE_PROC(clear_user_tt, clear_user_skas, mem, len)); -+} -+ -+/* -+ * strlen_user: - Get the size of a string in user space. -+ * @str: The string to measure. -+ * @n: The maximum valid length -+ * -+ * Get the size of a NUL-terminated string in user space. -+ * -+ * Returns the size of the string INCLUDING the terminating NUL. -+ * On exception, returns 0. -+ * If the string is too long, returns a value greater than @n. -+ */ -+static inline int strnlen_user(const void *str, int len) -+{ -+ return(CHOOSE_MODE_PROC(strnlen_user_tt, strnlen_user_skas, str, len)); -+} -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/user.h um/arch/um/include/user.h ---- orig/arch/um/include/user.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/user.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,29 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __USER_H__ -+#define __USER_H__ -+ -+extern void panic(const char *fmt, ...); -+extern int printk(const char *fmt, ...); -+extern void schedule(void); -+extern void *um_kmalloc(int size); -+extern void *um_kmalloc_atomic(int size); -+extern void kfree(void *ptr); -+extern int in_aton(char *str); -+extern int open_gdb_chan(void); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/include/user_util.h um/arch/um/include/user_util.h ---- orig/arch/um/include/user_util.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/include/user_util.h 2003-11-09 11:36:31.000000000 -0500 -@@ -0,0 +1,103 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __USER_UTIL_H__ -+#define __USER_UTIL_H__ -+ -+#include "sysdep/ptrace.h" -+ -+extern int mode_tt; -+ -+extern int grantpt(int __fd); -+extern int unlockpt(int __fd); -+extern char *ptsname(int __fd); -+ -+struct cpu_task { -+ int pid; -+ void *task; -+}; -+ -+extern struct cpu_task cpu_tasks[]; -+ -+struct signal_info { -+ void (*handler)(int, union uml_pt_regs *); -+ int is_irq; -+}; -+ -+extern struct signal_info sig_info[]; -+ -+extern unsigned long low_physmem; -+extern unsigned long high_physmem; -+extern unsigned long uml_physmem; -+extern unsigned long uml_reserved; -+extern unsigned long end_vm; -+extern unsigned long start_vm; -+extern unsigned long highmem; -+ -+extern char host_info[]; -+ -+extern char saved_command_line[]; -+extern char command_line[]; -+ -+extern char *tempdir; -+ -+extern unsigned long _stext, _etext, _sdata, _edata, __bss_start, _end; -+extern unsigned long _unprotected_end; -+extern unsigned long brk_start; -+ -+extern int pty_output_sigio; -+extern int pty_close_sigio; -+ -+extern void stop(void); -+extern void stack_protections(unsigned long address); -+extern void task_protections(unsigned long address); -+extern int wait_for_stop(int pid, int sig, int cont_type, void *relay); -+extern void *add_signal_handler(int sig, void (*handler)(int)); -+extern int start_fork_tramp(void *arg, unsigned long temp_stack, -+ int clone_flags, int (*tramp)(void *)); -+extern int linux_main(int argc, char **argv); -+extern void set_cmdline(char *cmd); -+extern void input_cb(void (*proc)(void *), void *arg, int arg_len); -+extern int get_pty(void); -+extern void *um_kmalloc(int size); -+extern int raw(int fd, int complain); -+extern int switcheroo(int fd, int prot, void *from, void *to, int size); -+extern void setup_machinename(char *machine_out); -+extern void setup_hostinfo(void); -+extern void add_arg(char *cmd_line, char *arg); -+extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)); -+extern void init_new_thread_signals(int altstack); -+extern void do_exec(int old_pid, int new_pid); -+extern void tracer_panic(char *msg, ...); -+extern char *get_umid(int only_if_set); -+extern void do_longjmp(void *p, int val); -+extern void suspend_new_thread(int fd); -+extern int detach(int pid, int sig); -+extern int attach(int pid); -+extern void kill_child_dead(int pid); -+extern int cont(int pid); -+extern void check_ptrace(void); -+extern void check_sigio(void); -+extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr); -+extern void write_sigio_workaround(void); -+extern void arch_check_bugs(void); -+extern int cpu_feature(char *what, char *buf, int len); -+extern int arch_handle_signal(int sig, union uml_pt_regs *regs); -+extern int arch_fixup(unsigned long address, void *sc_ptr); -+extern int can_do_skas(void); -+extern void arch_init_thread(void); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/checksum.c um/arch/um/kernel/checksum.c ---- orig/arch/um/kernel/checksum.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/checksum.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,42 @@ -+#include "asm/uaccess.h" -+#include "linux/errno.h" -+ -+extern unsigned int arch_csum_partial(const char *buff, int len, int sum); -+ -+extern unsigned int csum_partial(char *buff, int len, int sum) -+{ -+ return(arch_csum_partial(buff, len, sum)); -+} -+ -+unsigned int csum_partial_copy_to(const char *src, char *dst, int len, -+ int sum, int *err_ptr) -+{ -+ if(copy_to_user(dst, src, len)){ -+ *err_ptr = -EFAULT; -+ return(-1); -+ } -+ -+ return(arch_csum_partial(src, len, sum)); -+} -+ -+unsigned int csum_partial_copy_from(const char *src, char *dst, int len, -+ int sum, int *err_ptr) -+{ -+ if(copy_from_user(dst, src, len)){ -+ *err_ptr = -EFAULT; -+ return(-1); -+ } -+ -+ return(arch_csum_partial(dst, len, sum)); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/config.c.in um/arch/um/kernel/config.c.in ---- orig/arch/um/kernel/config.c.in 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/config.c.in 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,32 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <stdio.h> -+#include <stdlib.h> -+#include "init.h" -+ -+static __initdata char *config = "CONFIG"; -+ -+static int __init print_config(char *line, int *add) -+{ -+ printf("%s", config); -+ exit(0); -+} -+ -+__uml_setup("--showconfig", print_config, -+"--showconfig\n" -+" Prints the config file that this UML binary was generated from.\n\n" -+); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/exec_kern.c um/arch/um/kernel/exec_kern.c ---- orig/arch/um/kernel/exec_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/exec_kern.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,86 @@ -+/* -+ * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/slab.h" -+#include "linux/smp_lock.h" -+#include "asm/ptrace.h" -+#include "asm/pgtable.h" -+#include "asm/pgalloc.h" -+#include "asm/uaccess.h" -+#include "user_util.h" -+#include "kern_util.h" -+#include "mem_user.h" -+#include "kern.h" -+#include "irq_user.h" -+#include "tlb.h" -+#include "2_5compat.h" -+#include "os.h" -+#include "time_user.h" -+#include "choose-mode.h" -+#include "mode_kern.h" -+ -+void flush_thread(void) -+{ -+ CHOOSE_MODE(flush_thread_tt(), flush_thread_skas()); -+} -+ -+void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp) -+{ -+ CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp); -+} -+ -+extern void log_exec(char **argv, void *tty); -+ -+static int execve1(char *file, char **argv, char **env) -+{ -+ int error; -+ -+#ifdef CONFIG_TTY_LOG -+ log_exec(argv, current->tty); -+#endif -+ error = do_execve(file, argv, env, ¤t->thread.regs); -+ if (error == 0){ -+ current->ptrace &= ~PT_DTRACE; -+ set_cmdline(current_cmd()); -+ } -+ return(error); -+} -+ -+int um_execve(char *file, char **argv, char **env) -+{ -+ int err; -+ -+ err = execve1(file, argv, env); -+ if(!err) -+ do_longjmp(current->thread.exec_buf, 1); -+ return(err); -+} -+ -+int sys_execve(char *file, char **argv, char **env) -+{ -+ int error; -+ char *filename; -+ -+ lock_kernel(); -+ filename = getname((char *) file); -+ error = PTR_ERR(filename); -+ if (IS_ERR(filename)) goto out; -+ error = execve1(filename, argv, env); -+ putname(filename); -+ out: -+ unlock_kernel(); -+ return(error); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/exitcode.c um/arch/um/kernel/exitcode.c ---- orig/arch/um/kernel/exitcode.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/exitcode.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,73 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/init.h" -+#include "linux/ctype.h" -+#include "linux/proc_fs.h" -+#include "asm/uaccess.h" -+ -+/* If read and write race, the read will still atomically read a valid -+ * value. -+ */ -+int uml_exitcode = 0; -+ -+static int read_proc_exitcode(char *page, char **start, off_t off, -+ int count, int *eof, void *data) -+{ -+ int len; -+ -+ len = sprintf(page, "%d\n", uml_exitcode); -+ len -= off; -+ if(len <= off+count) *eof = 1; -+ *start = page + off; -+ if(len > count) len = count; -+ if(len < 0) len = 0; -+ return(len); -+} -+ -+static int write_proc_exitcode(struct file *file, const char *buffer, -+ unsigned long count, void *data) -+{ -+ char *end, buf[sizeof("nnnnn\0")]; -+ int tmp; -+ -+ if(copy_from_user(buf, buffer, count)) -+ return(-EFAULT); -+ tmp = simple_strtol(buf, &end, 0); -+ if((*end != '\0') && !isspace(*end)) -+ return(-EINVAL); -+ uml_exitcode = tmp; -+ return(count); -+} -+ -+static int make_proc_exitcode(void) -+{ -+ struct proc_dir_entry *ent; -+ -+ ent = create_proc_entry("exitcode", 0600, &proc_root); -+ if(ent == NULL){ -+ printk("make_proc_exitcode : Failed to register " -+ "/proc/exitcode\n"); -+ return(0); -+ } -+ -+ ent->read_proc = read_proc_exitcode; -+ ent->write_proc = write_proc_exitcode; -+ -+ return(0); -+} -+ -+__initcall(make_proc_exitcode); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/frame.c um/arch/um/kernel/frame.c ---- orig/arch/um/kernel/frame.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/frame.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,341 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <stdio.h> -+#include <stdlib.h> -+#include <unistd.h> -+#include <string.h> -+#include <signal.h> -+#include <wait.h> -+#include <sched.h> -+#include <errno.h> -+#include <sys/ptrace.h> -+#include <sys/syscall.h> -+#include <sys/mman.h> -+#include <asm/page.h> -+#include <asm/ptrace.h> -+#include <asm/sigcontext.h> -+#include "sysdep/ptrace.h" -+#include "sysdep/sigcontext.h" -+#include "frame_user.h" -+#include "kern_util.h" -+#include "ptrace_user.h" -+#include "os.h" -+ -+static int capture_stack(int (*child)(void *arg), void *arg, void *sp, -+ unsigned long top, void **data_out) -+{ -+ unsigned long regs[FRAME_SIZE]; -+ int pid, status, n, len; -+ -+ /* Start the child as a thread */ -+ pid = clone(child, sp, CLONE_VM | SIGCHLD, arg); -+ if(pid < 0){ -+ printf("capture_stack : clone failed - errno = %d\n", errno); -+ exit(1); -+ } -+ -+ /* Wait for it to stop itself and continue it with a SIGUSR1 to force -+ * it into the signal handler. -+ */ -+ n = waitpid(pid, &status, WUNTRACED); -+ if(n < 0){ -+ printf("capture_stack : waitpid failed - errno = %d\n", errno); -+ exit(1); -+ } -+ if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){ -+ fprintf(stderr, "capture_stack : Expected SIGSTOP, " -+ "got status = 0x%x\n", status); -+ exit(1); -+ } -+ if(ptrace(PTRACE_CONT, pid, 0, SIGUSR1) < 0){ -+ printf("capture_stack : PTRACE_CONT failed - errno = %d\n", -+ errno); -+ exit(1); -+ } -+ -+ /* Wait for it to stop itself again and grab its registers again. -+ * At this point, the handler has stuffed the addresses of -+ * sig, sc, and SA_RESTORER in raw. -+ */ -+ n = waitpid(pid, &status, WUNTRACED); -+ if(n < 0){ -+ printf("capture_stack : waitpid failed - errno = %d\n", errno); -+ exit(1); -+ } -+ if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){ -+ fprintf(stderr, "capture_stack : Expected SIGSTOP, " -+ "got status = 0x%x\n", status); -+ exit(1); -+ } -+ if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0){ -+ printf("capture_stack : PTRACE_GETREGS failed - errno = %d\n", -+ errno); -+ exit(1); -+ } -+ -+ /* It has outlived its usefulness, so continue it so it can exit */ -+ if(ptrace(PTRACE_CONT, pid, 0, 0) < 0){ -+ printf("capture_stack : PTRACE_CONT failed - errno = %d\n", -+ errno); -+ exit(1); -+ } -+ if(waitpid(pid, &status, 0) < 0){ -+ printf("capture_stack : waitpid failed - errno = %d\n", errno); -+ exit(1); -+ } -+ if(!WIFSIGNALED(status) || (WTERMSIG(status) != 9)){ -+ printf("capture_stack : Expected exit signal 9, " -+ "got status = 0x%x\n", status); -+ exit(1); -+ } -+ -+ /* The frame that we want is the top of the signal stack */ -+ -+ len = top - PT_SP(regs); -+ *data_out = malloc(len); -+ if(*data_out == NULL){ -+ printf("capture_stack : malloc failed - errno = %d\n", errno); -+ exit(1); -+ } -+ memcpy(*data_out, (void *) PT_SP(regs), len); -+ -+ return(len); -+} -+ -+struct common_raw { -+ void *stack; -+ int size; -+ unsigned long sig; -+ unsigned long sr; -+ unsigned long sp; -+ struct arch_frame_data_raw arch; -+}; -+ -+#define SA_RESTORER (0x04000000) -+ -+typedef unsigned long old_sigset_t; -+ -+struct old_sigaction { -+ __sighandler_t handler; -+ old_sigset_t sa_mask; -+ unsigned long sa_flags; -+ void (*sa_restorer)(void); -+}; -+ -+static void child_common(struct common_raw *common, sighandler_t handler, -+ int restorer, int flags) -+{ -+ stack_t ss = ((stack_t) { .ss_sp = common->stack, -+ .ss_flags = 0, -+ .ss_size = common->size }); -+ int err; -+ -+ if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){ -+ printf("PTRACE_TRACEME failed, errno = %d\n", errno); -+ } -+ if(sigaltstack(&ss, NULL) < 0){ -+ printf("sigaltstack failed - errno = %d\n", errno); -+ kill(getpid(), SIGKILL); -+ } -+ -+ if(restorer){ -+ struct sigaction sa; -+ -+ sa.sa_handler = handler; -+ sigemptyset(&sa.sa_mask); -+ sa.sa_flags = SA_ONSTACK | flags; -+ err = sigaction(SIGUSR1, &sa, NULL); -+ } -+ else { -+ struct old_sigaction sa; -+ -+ sa.handler = handler; -+ sa.sa_mask = 0; -+ sa.sa_flags = (SA_ONSTACK | flags) & ~SA_RESTORER; -+ err = syscall(__NR_sigaction, SIGUSR1, &sa, NULL); -+ } -+ -+ if(err < 0){ -+ printf("sigaction failed - errno = %d\n", errno); -+ kill(getpid(), SIGKILL); -+ } -+ -+ os_stop_process(os_getpid()); -+} -+ -+/* Changed only during early boot */ -+struct sc_frame signal_frame_sc; -+ -+struct sc_frame signal_frame_sc_sr; -+ -+struct sc_frame_raw { -+ struct common_raw common; -+ unsigned long sc; -+ int restorer; -+}; -+ -+/* Changed only during early boot */ -+static struct sc_frame_raw *raw_sc = NULL; -+ -+static void sc_handler(int sig, struct sigcontext sc) -+{ -+ raw_sc->common.sig = (unsigned long) &sig; -+ raw_sc->common.sr = frame_restorer(); -+ raw_sc->common.sp = frame_sp(); -+ raw_sc->sc = (unsigned long) ≻ -+ setup_arch_frame_raw(&raw_sc->common.arch, &sc + 1, raw_sc->common.sr); -+ -+ os_stop_process(os_getpid()); -+ kill(getpid(), SIGKILL); -+} -+ -+static int sc_child(void *arg) -+{ -+ raw_sc = arg; -+ child_common(&raw_sc->common, (sighandler_t) sc_handler, -+ raw_sc->restorer, 0); -+ return(-1); -+} -+ -+/* Changed only during early boot */ -+struct si_frame signal_frame_si; -+ -+struct si_frame_raw { -+ struct common_raw common; -+ unsigned long sip; -+ unsigned long si; -+ unsigned long ucp; -+ unsigned long uc; -+}; -+ -+/* Changed only during early boot */ -+static struct si_frame_raw *raw_si = NULL; -+ -+static void si_handler(int sig, siginfo_t *si, struct ucontext *ucontext) -+{ -+ raw_si->common.sig = (unsigned long) &sig; -+ raw_si->common.sr = frame_restorer(); -+ raw_si->common.sp = frame_sp(); -+ raw_si->sip = (unsigned long) &si; -+ raw_si->si = (unsigned long) si; -+ raw_si->ucp = (unsigned long) &ucontext; -+ raw_si->uc = (unsigned long) ucontext; -+ setup_arch_frame_raw(&raw_si->common.arch, -+ ucontext->uc_mcontext.fpregs, raw_si->common.sr); -+ -+ os_stop_process(os_getpid()); -+ kill(getpid(), SIGKILL); -+} -+ -+static int si_child(void *arg) -+{ -+ raw_si = arg; -+ child_common(&raw_si->common, (sighandler_t) si_handler, 1, -+ SA_SIGINFO); -+ return(-1); -+} -+ -+static int relative_sr(unsigned long sr, int sr_index, void *stack, -+ void *framep) -+{ -+ unsigned long *srp = (unsigned long *) sr; -+ unsigned long frame = (unsigned long) framep; -+ -+ if((*srp & PAGE_MASK) == (unsigned long) stack){ -+ *srp -= sr; -+ *((unsigned long *) (frame + sr_index)) = *srp; -+ return(1); -+ } -+ else return(0); -+} -+ -+static unsigned long capture_stack_common(int (*proc)(void *), void *arg, -+ struct common_raw *common_in, -+ void *top, void *sigstack, -+ int stack_len, -+ struct frame_common *common_out) -+{ -+ unsigned long sig_top = (unsigned long) sigstack + stack_len, base; -+ -+ common_in->stack = (void *) sigstack; -+ common_in->size = stack_len; -+ common_out->len = capture_stack(proc, arg, top, sig_top, -+ &common_out->data); -+ base = sig_top - common_out->len; -+ common_out->sig_index = common_in->sig - base; -+ common_out->sp_index = common_in->sp - base; -+ common_out->sr_index = common_in->sr - base; -+ common_out->sr_relative = relative_sr(common_in->sr, -+ common_out->sr_index, sigstack, -+ common_out->data); -+ return(base); -+} -+ -+void capture_signal_stack(void) -+{ -+ struct sc_frame_raw raw_sc; -+ struct si_frame_raw raw_si; -+ void *stack, *sigstack; -+ unsigned long top, base; -+ -+ stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, -+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); -+ sigstack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, -+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); -+ if((stack == MAP_FAILED) || (sigstack == MAP_FAILED)){ -+ printf("capture_signal_stack : mmap failed - errno = %d\n", -+ errno); -+ exit(1); -+ } -+ -+ top = (unsigned long) stack + PAGE_SIZE - sizeof(void *); -+ -+ /* Get the sigcontext, no sigrestorer layout */ -+ raw_sc.restorer = 0; -+ base = capture_stack_common(sc_child, &raw_sc, &raw_sc.common, -+ (void *) top, sigstack, PAGE_SIZE, -+ &signal_frame_sc.common); -+ -+ signal_frame_sc.sc_index = raw_sc.sc - base; -+ setup_arch_frame(&raw_sc.common.arch, &signal_frame_sc.common.arch); -+ -+ /* Ditto for the sigcontext, sigrestorer layout */ -+ raw_sc.restorer = 1; -+ base = capture_stack_common(sc_child, &raw_sc, &raw_sc.common, -+ (void *) top, sigstack, PAGE_SIZE, -+ &signal_frame_sc_sr.common); -+ signal_frame_sc_sr.sc_index = raw_sc.sc - base; -+ setup_arch_frame(&raw_sc.common.arch, &signal_frame_sc_sr.common.arch); -+ -+ /* And the siginfo layout */ -+ -+ base = capture_stack_common(si_child, &raw_si, &raw_si.common, -+ (void *) top, sigstack, PAGE_SIZE, -+ &signal_frame_si.common); -+ signal_frame_si.sip_index = raw_si.sip - base; -+ signal_frame_si.si_index = raw_si.si - base; -+ signal_frame_si.ucp_index = raw_si.ucp - base; -+ signal_frame_si.uc_index = raw_si.uc - base; -+ setup_arch_frame(&raw_si.common.arch, &signal_frame_si.common.arch); -+ -+ if((munmap(stack, PAGE_SIZE) < 0) || -+ (munmap(sigstack, PAGE_SIZE) < 0)){ -+ printf("capture_signal_stack : munmap failed - errno = %d\n", -+ errno); -+ exit(1); -+ } -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/frame_kern.c um/arch/um/kernel/frame_kern.c ---- orig/arch/um/kernel/frame_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/frame_kern.c 2003-11-19 03:32:43.000000000 -0500 -@@ -0,0 +1,174 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "asm/ptrace.h" -+#include "asm/uaccess.h" -+#include "asm/signal.h" -+#include "asm/uaccess.h" -+#include "asm/ucontext.h" -+#include "frame_kern.h" -+#include "sigcontext.h" -+#include "sysdep/ptrace.h" -+#include "choose-mode.h" -+#include "mode.h" -+ -+int copy_siginfo_to_user(siginfo_t *to, siginfo_t *from) -+{ -+ if (!access_ok (VERIFY_WRITE, to, sizeof(siginfo_t))) -+ return -EFAULT; -+ if (from->si_code < 0) -+ return __copy_to_user(to, from, sizeof(siginfo_t)); -+ else { -+ int err; -+ -+ /* If you change siginfo_t structure, please be sure -+ this code is fixed accordingly. -+ It should never copy any pad contained in the structure -+ to avoid security leaks, but must copy the generic -+ 3 ints plus the relevant union member. */ -+ err = __put_user(from->si_signo, &to->si_signo); -+ err |= __put_user(from->si_errno, &to->si_errno); -+ err |= __put_user((short)from->si_code, &to->si_code); -+ /* First 32bits of unions are always present. */ -+ err |= __put_user(from->si_pid, &to->si_pid); -+ switch (from->si_code >> 16) { -+ case __SI_FAULT >> 16: -+ break; -+ case __SI_CHLD >> 16: -+ err |= __put_user(from->si_utime, &to->si_utime); -+ err |= __put_user(from->si_stime, &to->si_stime); -+ err |= __put_user(from->si_status, &to->si_status); -+ default: -+ err |= __put_user(from->si_uid, &to->si_uid); -+ break; -+ } -+ return err; -+ } -+} -+ -+static int copy_restorer(void (*restorer)(void), unsigned long start, -+ unsigned long sr_index, int sr_relative) -+{ -+ unsigned long sr; -+ -+ if(sr_relative){ -+ sr = (unsigned long) restorer; -+ sr += start + sr_index; -+ restorer = (void (*)(void)) sr; -+ } -+ -+ return(copy_to_user((void *) (start + sr_index), &restorer, -+ sizeof(restorer))); -+} -+ -+extern int userspace_pid[]; -+ -+static int copy_sc_to_user(void *to, void *fp, struct pt_regs *from, -+ struct arch_frame_data *arch) -+{ -+ return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs), -+ arch), -+ copy_sc_to_user_skas(userspace_pid[0], to, fp, -+ &from->regs, -+ current->thread.cr2, -+ current->thread.err))); -+} -+ -+static int copy_ucontext_to_user(struct ucontext *uc, void *fp, sigset_t *set, -+ unsigned long sp) -+{ -+ int err = 0; -+ -+ err |= put_user(current->sas_ss_sp, &uc->uc_stack.ss_sp); -+ err |= put_user(sas_ss_flags(sp), &uc->uc_stack.ss_flags); -+ err |= put_user(current->sas_ss_size, &uc->uc_stack.ss_size); -+ err |= copy_sc_to_user(&uc->uc_mcontext, fp, ¤t->thread.regs, -+ &signal_frame_si.common.arch); -+ err |= copy_to_user(&uc->uc_sigmask, set, sizeof(*set)); -+ return(err); -+} -+ -+int setup_signal_stack_si(unsigned long stack_top, int sig, -+ unsigned long handler, void (*restorer)(void), -+ struct pt_regs *regs, siginfo_t *info, -+ sigset_t *mask) -+{ -+ unsigned long start; -+ void *sip, *ucp, *fp; -+ -+ start = stack_top - signal_frame_si.common.len; -+ sip = (void *) (start + signal_frame_si.si_index); -+ ucp = (void *) (start + signal_frame_si.uc_index); -+ fp = (void *) (((unsigned long) ucp) + sizeof(struct ucontext)); -+ -+ if(restorer == NULL) -+ panic("setup_signal_stack_si - no restorer"); -+ -+ if(copy_to_user((void *) start, signal_frame_si.common.data, -+ signal_frame_si.common.len) || -+ copy_to_user((void *) (start + signal_frame_si.common.sig_index), -+ &sig, sizeof(sig)) || -+ copy_siginfo_to_user(sip, info) || -+ copy_to_user((void *) (start + signal_frame_si.sip_index), &sip, -+ sizeof(sip)) || -+ copy_ucontext_to_user(ucp, fp, mask, PT_REGS_SP(regs)) || -+ copy_to_user((void *) (start + signal_frame_si.ucp_index), &ucp, -+ sizeof(ucp)) || -+ copy_restorer(restorer, start, signal_frame_si.common.sr_index, -+ signal_frame_si.common.sr_relative)) -+ return(1); -+ -+ PT_REGS_IP(regs) = handler; -+ PT_REGS_SP(regs) = start + signal_frame_si.common.sp_index; -+ return(0); -+} -+ -+int setup_signal_stack_sc(unsigned long stack_top, int sig, -+ unsigned long handler, void (*restorer)(void), -+ struct pt_regs *regs, sigset_t *mask) -+{ -+ struct frame_common *frame = &signal_frame_sc_sr.common; -+ void *user_sc; -+ int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long); -+ unsigned long sigs, sr; -+ unsigned long start = stack_top - frame->len - sig_size; -+ -+ user_sc = (void *) (start + signal_frame_sc_sr.sc_index); -+ if(restorer == NULL){ -+ frame = &signal_frame_sc.common; -+ user_sc = (void *) (start + signal_frame_sc.sc_index); -+ sr = (unsigned long) frame->data; -+ sr += frame->sr_index; -+ sr = *((unsigned long *) sr); -+ restorer = ((void (*)(void)) sr); -+ } -+ -+ sigs = start + frame->len; -+ if(copy_to_user((void *) start, frame->data, frame->len) || -+ copy_to_user((void *) (start + frame->sig_index), &sig, -+ sizeof(sig)) || -+ copy_sc_to_user(user_sc, NULL, regs, -+ &signal_frame_sc.common.arch) || -+ copy_to_user(sc_sigmask(user_sc), mask, sizeof(mask->sig[0])) || -+ copy_to_user((void *) sigs, &mask->sig[1], sig_size) || -+ copy_restorer(restorer, start, frame->sr_index, frame->sr_relative)) -+ return(1); -+ -+ PT_REGS_IP(regs) = handler; -+ PT_REGS_SP(regs) = start + frame->sp_index; -+ -+ return(0); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/gmon_syms.c um/arch/um/kernel/gmon_syms.c ---- orig/arch/um/kernel/gmon_syms.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/gmon_syms.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,20 @@ -+/* -+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/module.h" -+ -+extern void __bb_init_func(void *); -+EXPORT_SYMBOL(__bb_init_func); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/gprof_syms.c um/arch/um/kernel/gprof_syms.c ---- orig/arch/um/kernel/gprof_syms.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/gprof_syms.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,20 @@ -+/* -+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/module.h" -+ -+extern void mcount(void); -+EXPORT_SYMBOL(mcount); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/helper.c um/arch/um/kernel/helper.c ---- orig/arch/um/kernel/helper.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/helper.c 2003-11-08 07:41:30.000000000 -0500 -@@ -0,0 +1,170 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <stdio.h> -+#include <stdlib.h> -+#include <unistd.h> -+#include <errno.h> -+#include <sched.h> -+#include <sys/signal.h> -+#include <sys/wait.h> -+#include "user.h" -+#include "kern_util.h" -+#include "os.h" -+ -+struct helper_data { -+ void (*pre_exec)(void*); -+ void *pre_data; -+ char **argv; -+ int fd; -+}; -+ -+/* Debugging aid, changed only from gdb */ -+int helper_pause = 0; -+ -+static void helper_hup(int sig) -+{ -+} -+ -+static int helper_child(void *arg) -+{ -+ struct helper_data *data = arg; -+ char **argv = data->argv; -+ int errval; -+ -+ if(helper_pause){ -+ signal(SIGHUP, helper_hup); -+ pause(); -+ } -+ if(data->pre_exec != NULL) -+ (*data->pre_exec)(data->pre_data); -+ execvp(argv[0], argv); -+ errval = errno; -+ printk("execvp of '%s' failed - errno = %d\n", argv[0], errno); -+ os_write_file(data->fd, &errval, sizeof(errval)); -+ os_kill_process(os_getpid(), 0); -+ return(0); -+} -+ -+/* XXX The alloc_stack here breaks if this is called in the tracing thread */ -+ -+int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv, -+ unsigned long *stack_out) -+{ -+ struct helper_data data; -+ unsigned long stack, sp; -+ int pid, fds[2], err, n; -+ -+ if((stack_out != NULL) && (*stack_out != 0)) -+ stack = *stack_out; -+ else stack = alloc_stack(0, um_in_interrupt()); -+ if(stack == 0) -+ return(-ENOMEM); -+ -+ err = os_pipe(fds, 1, 0); -+ if(err < 0){ -+ printk("run_helper : pipe failed, err = %d\n", -err); -+ goto out_free; -+ } -+ -+ err = os_set_exec_close(fds[1], 1); -+ if(err < 0){ -+ printk("run_helper : setting FD_CLOEXEC failed, err = %d\n", -+ -err); -+ goto out_close; -+ } -+ -+ sp = stack + page_size() - sizeof(void *); -+ data.pre_exec = pre_exec; -+ data.pre_data = pre_data; -+ data.argv = argv; -+ data.fd = fds[1]; -+ pid = clone(helper_child, (void *) sp, CLONE_VM | SIGCHLD, &data); -+ if(pid < 0){ -+ printk("run_helper : clone failed, errno = %d\n", errno); -+ err = -errno; -+ goto out_close; -+ } -+ -+ os_close_file(fds[1]); -+ n = os_read_file(fds[0], &err, sizeof(err)); -+ if(n < 0){ -+ printk("run_helper : read on pipe failed, err = %d\n", -n); -+ err = n; -+ goto out_kill; -+ } -+ else if(n != 0){ -+ waitpid(pid, NULL, 0); -+ pid = -errno; -+ } -+ -+ if(stack_out == NULL) free_stack(stack, 0); -+ else *stack_out = stack; -+ return(pid); -+ -+ out_kill: -+ os_kill_process(pid, 1); -+ out_close: -+ os_close_file(fds[0]); -+ os_close_file(fds[1]); -+ out_free: -+ free_stack(stack, 0); -+ return(err); -+} -+ -+int run_helper_thread(int (*proc)(void *), void *arg, unsigned int flags, -+ unsigned long *stack_out, int stack_order) -+{ -+ unsigned long stack, sp; -+ int pid, status; -+ -+ stack = alloc_stack(stack_order, um_in_interrupt()); -+ if(stack == 0) return(-ENOMEM); -+ -+ sp = stack + (page_size() << stack_order) - sizeof(void *); -+ pid = clone(proc, (void *) sp, flags | SIGCHLD, arg); -+ if(pid < 0){ -+ printk("run_helper_thread : clone failed, errno = %d\n", -+ errno); -+ return(-errno); -+ } -+ if(stack_out == NULL){ -+ pid = waitpid(pid, &status, 0); -+ if(pid < 0){ -+ printk("run_helper_thread - wait failed, errno = %d\n", -+ errno); -+ pid = -errno; -+ } -+ if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) -+ printk("run_helper_thread - thread returned status " -+ "0x%x\n", status); -+ free_stack(stack, stack_order); -+ } -+ else *stack_out = stack; -+ return(pid); -+} -+ -+int helper_wait(int pid, int block) -+{ -+ int ret; -+ -+ ret = waitpid(pid, NULL, WNOHANG); -+ if(ret < 0){ -+ printk("helper_wait : waitpid failed, errno = %d\n", errno); -+ return(-errno); -+ } -+ return(ret); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/initrd_kern.c um/arch/um/kernel/initrd_kern.c ---- orig/arch/um/kernel/initrd_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/initrd_kern.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,59 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/init.h" -+#include "linux/bootmem.h" -+#include "linux/blk.h" -+#include "asm/types.h" -+#include "user_util.h" -+#include "kern_util.h" -+#include "initrd.h" -+#include "init.h" -+#include "os.h" -+ -+/* Changed by uml_initrd_setup, which is a setup */ -+static char *initrd __initdata = NULL; -+ -+static int __init read_initrd(void) -+{ -+ void *area; -+ long long size; -+ int err; -+ -+ if(initrd == NULL) return 0; -+ err = os_file_size(initrd, &size); -+ if(err) return 0; -+ area = alloc_bootmem(size); -+ if(area == NULL) return 0; -+ if(load_initrd(initrd, area, size) == -1) return 0; -+ initrd_start = (unsigned long) area; -+ initrd_end = initrd_start + size; -+ return 0; -+} -+ -+__uml_postsetup(read_initrd); -+ -+static int __init uml_initrd_setup(char *line, int *add) -+{ -+ initrd = line; -+ return 0; -+} -+ -+__uml_setup("initrd=", uml_initrd_setup, -+"initrd=<initrd image>\n" -+" This is used to boot UML from an initrd image. The argument is the\n" -+" name of the file containing the image.\n\n" -+); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/initrd_user.c um/arch/um/kernel/initrd_user.c ---- orig/arch/um/kernel/initrd_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/initrd_user.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,44 @@ -+/* -+ * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <unistd.h> -+#include <sys/types.h> -+#include <sys/stat.h> -+#include <errno.h> -+ -+#include "user_util.h" -+#include "kern_util.h" -+#include "user.h" -+#include "initrd.h" -+#include "os.h" -+ -+int load_initrd(char *filename, void *buf, int size) -+{ -+ int fd, n; -+ -+ fd = os_open_file(filename, of_read(OPENFLAGS()), 0); -+ if(fd < 0){ -+ printk("Opening '%s' failed - err = %d\n", filename, -fd); -+ return(-1); -+ } -+ n = os_read_file(fd, buf, size); -+ if(n != size){ -+ printk("Read of %d bytes from '%s' failed, err = %d\n", size, -+ filename, -n); -+ return(-1); -+ } -+ return(0); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/init_task.c um/arch/um/kernel/init_task.c ---- orig/arch/um/kernel/init_task.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/init_task.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,61 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/config.h" -+#include "linux/mm.h" -+#include "linux/sched.h" -+#include "linux/version.h" -+#include "asm/uaccess.h" -+#include "asm/pgtable.h" -+#include "user_util.h" -+#include "mem_user.h" -+ -+static struct fs_struct init_fs = INIT_FS; -+static struct files_struct init_files = INIT_FILES; -+static struct signal_struct init_signals = INIT_SIGNALS; -+struct mm_struct init_mm = INIT_MM(init_mm); -+ -+/* -+ * Initial task structure. -+ * -+ * We need to make sure that this is 16384-byte aligned due to the -+ * way process stacks are handled. This is done by having a special -+ * "init_task" linker map entry.. -+ */ -+ -+union task_union init_task_union -+__attribute__((__section__(".data.init_task"))) = -+{ INIT_TASK(init_task_union.task) }; -+ -+struct task_struct *alloc_task_struct(void) -+{ -+ return((struct task_struct *) -+ __get_free_pages(GFP_KERNEL, CONFIG_KERNEL_STACK_ORDER)); -+} -+ -+void unprotect_stack(unsigned long stack) -+{ -+ protect_memory(stack, (1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE, -+ 1, 1, 0, 1); -+} -+ -+void free_task_struct(struct task_struct *task) -+{ -+ /* free_pages decrements the page counter and only actually frees -+ * the pages if they are now not accessed by anything. -+ */ -+ free_pages((unsigned long) task, CONFIG_KERNEL_STACK_ORDER); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/irq.c um/arch/um/kernel/irq.c ---- orig/arch/um/kernel/irq.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/irq.c 2003-12-16 22:45:27.000000000 -0500 -@@ -0,0 +1,840 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ * Derived (i.e. mostly copied) from arch/i386/kernel/irq.c: -+ * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar -+ */ -+ -+#include "linux/config.h" -+#include "linux/kernel.h" -+#include "linux/smp.h" -+#include "linux/irq.h" -+#include "linux/kernel_stat.h" -+#include "linux/interrupt.h" -+#include "linux/random.h" -+#include "linux/slab.h" -+#include "linux/file.h" -+#include "linux/proc_fs.h" -+#include "linux/init.h" -+#include "linux/seq_file.h" -+#include "asm/irq.h" -+#include "asm/hw_irq.h" -+#include "asm/hardirq.h" -+#include "asm/atomic.h" -+#include "asm/signal.h" -+#include "asm/system.h" -+#include "asm/errno.h" -+#include "asm/uaccess.h" -+#include "user_util.h" -+#include "kern_util.h" -+#include "irq_user.h" -+#include "irq_kern.h" -+ -+static void register_irq_proc (unsigned int irq); -+ -+irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = -+ { [0 ... NR_IRQS-1] = { 0, &no_irq_type, NULL, 0, SPIN_LOCK_UNLOCKED}}; -+ -+/* -+ * Generic no controller code -+ */ -+ -+static void enable_none(unsigned int irq) { } -+static unsigned int startup_none(unsigned int irq) { return 0; } -+static void disable_none(unsigned int irq) { } -+static void ack_none(unsigned int irq) -+{ -+/* -+ * 'what should we do if we get a hw irq event on an illegal vector'. -+ * each architecture has to answer this themselves, it doesnt deserve -+ * a generic callback i think. -+ */ -+#if CONFIG_X86 -+ printk(KERN_ERR "unexpected IRQ trap at vector %02x\n", irq); -+#ifdef CONFIG_X86_LOCAL_APIC -+ /* -+ * Currently unexpected vectors happen only on SMP and APIC. -+ * We _must_ ack these because every local APIC has only N -+ * irq slots per priority level, and a 'hanging, unacked' IRQ -+ * holds up an irq slot - in excessive cases (when multiple -+ * unexpected vectors occur) that might lock up the APIC -+ * completely. -+ */ -+ ack_APIC_irq(); -+#endif -+#endif -+} -+ -+/* startup is the same as "enable", shutdown is same as "disable" */ -+#define shutdown_none disable_none -+#define end_none enable_none -+ -+struct hw_interrupt_type no_irq_type = { -+ "none", -+ startup_none, -+ shutdown_none, -+ enable_none, -+ disable_none, -+ ack_none, -+ end_none -+}; -+ -+/* -+ * Generic, controller-independent functions: -+ */ -+ -+int get_irq_list(char *buf) -+{ -+ int i, j; -+ unsigned long flags; -+ struct irqaction * action; -+ char *p = buf; -+ -+ p += sprintf(p, " "); -+ for (j=0; j<smp_num_cpus; j++) -+ p += sprintf(p, "CPU%d ",j); -+ *p++ = '\n'; -+ -+ for (i = 0 ; i < NR_IRQS ; i++) { -+ spin_lock_irqsave(&irq_desc[i].lock, flags); -+ action = irq_desc[i].action; -+ if (!action) -+ goto end; -+ p += sprintf(p, "%3d: ",i); -+#ifndef CONFIG_SMP -+ p += sprintf(p, "%10u ", kstat_irqs(i)); -+#else -+ for (j = 0; j < smp_num_cpus; j++) -+ p += sprintf(p, "%10u ", -+ kstat.irqs[cpu_logical_map(j)][i]); -+#endif -+ p += sprintf(p, " %14s", irq_desc[i].handler->typename); -+ p += sprintf(p, " %s", action->name); -+ -+ for (action=action->next; action; action = action->next) -+ p += sprintf(p, ", %s", action->name); -+ *p++ = '\n'; -+ end: -+ spin_unlock_irqrestore(&irq_desc[i].lock, flags); -+ } -+ p += sprintf(p, "\n"); -+#ifdef notdef -+#if CONFIG_SMP -+ p += sprintf(p, "LOC: "); -+ for (j = 0; j < smp_num_cpus; j++) -+ p += sprintf(p, "%10u ", -+ apic_timer_irqs[cpu_logical_map(j)]); -+ p += sprintf(p, "\n"); -+#endif -+#endif -+ p += sprintf(p, "ERR: %10lu\n", 0L); -+ return p - buf; -+} -+ -+/* -+ * This should really return information about whether -+ * we should do bottom half handling etc. Right now we -+ * end up _always_ checking the bottom half, which is a -+ * waste of time and is not what some drivers would -+ * prefer. -+ */ -+int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, -+ struct irqaction * action) -+{ -+ int status; -+ int cpu = smp_processor_id(); -+ -+ irq_enter(cpu, irq); -+ -+ status = 1; /* Force the "do bottom halves" bit */ -+ -+ if (!(action->flags & SA_INTERRUPT)) -+ __sti(); -+ -+ do { -+ status |= action->flags; -+ action->handler(irq, action->dev_id, regs); -+ action = action->next; -+ } while (action); -+ if (status & SA_SAMPLE_RANDOM) -+ add_interrupt_randomness(irq); -+ __cli(); -+ -+ irq_exit(cpu, irq); -+ -+ return status; -+} -+ -+/* -+ * Generic enable/disable code: this just calls -+ * down into the PIC-specific version for the actual -+ * hardware disable after having gotten the irq -+ * controller lock. -+ */ -+ -+/** -+ * disable_irq_nosync - disable an irq without waiting -+ * @irq: Interrupt to disable -+ * -+ * Disable the selected interrupt line. Disables of an interrupt -+ * stack. Unlike disable_irq(), this function does not ensure existing -+ * instances of the IRQ handler have completed before returning. -+ * -+ * This function may be called from IRQ context. -+ */ -+ -+void inline disable_irq_nosync(unsigned int irq) -+{ -+ irq_desc_t *desc = irq_desc + irq; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&desc->lock, flags); -+ if (!desc->depth++) { -+ desc->status |= IRQ_DISABLED; -+ desc->handler->disable(irq); -+ } -+ spin_unlock_irqrestore(&desc->lock, flags); -+} -+ -+/** -+ * disable_irq - disable an irq and wait for completion -+ * @irq: Interrupt to disable -+ * -+ * Disable the selected interrupt line. Disables of an interrupt -+ * stack. That is for two disables you need two enables. This -+ * function waits for any pending IRQ handlers for this interrupt -+ * to complete before returning. If you use this function while -+ * holding a resource the IRQ handler may need you will deadlock. -+ * -+ * This function may be called - with care - from IRQ context. -+ */ -+ -+void disable_irq(unsigned int irq) -+{ -+ disable_irq_nosync(irq); -+ -+ if (!local_irq_count(smp_processor_id())) { -+ do { -+ barrier(); -+ } while (irq_desc[irq].status & IRQ_INPROGRESS); -+ } -+} -+ -+/** -+ * enable_irq - enable interrupt handling on an irq -+ * @irq: Interrupt to enable -+ * -+ * Re-enables the processing of interrupts on this IRQ line -+ * providing no disable_irq calls are now in effect. -+ * -+ * This function may be called from IRQ context. -+ */ -+ -+void enable_irq(unsigned int irq) -+{ -+ irq_desc_t *desc = irq_desc + irq; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&desc->lock, flags); -+ switch (desc->depth) { -+ case 1: { -+ unsigned int status = desc->status & ~IRQ_DISABLED; -+ desc->status = status; -+ if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) { -+ desc->status = status | IRQ_REPLAY; -+ hw_resend_irq(desc->handler,irq); -+ } -+ desc->handler->enable(irq); -+ /* fall-through */ -+ } -+ default: -+ desc->depth--; -+ break; -+ case 0: -+ printk(KERN_ERR "enable_irq() unbalanced from %p\n", -+ __builtin_return_address(0)); -+ } -+ spin_unlock_irqrestore(&desc->lock, flags); -+} -+ -+/* -+ * do_IRQ handles all normal device IRQ's (the special -+ * SMP cross-CPU interrupts have their own specific -+ * handlers). -+ */ -+unsigned int do_IRQ(int irq, union uml_pt_regs *regs) -+{ -+ /* -+ * 0 return value means that this irq is already being -+ * handled by some other CPU. (or is disabled) -+ */ -+ int cpu = smp_processor_id(); -+ irq_desc_t *desc = irq_desc + irq; -+ struct irqaction * action; -+ unsigned int status; -+ -+ kstat.irqs[cpu][irq]++; -+ spin_lock(&desc->lock); -+ desc->handler->ack(irq); -+ /* -+ REPLAY is when Linux resends an IRQ that was dropped earlier -+ WAITING is used by probe to mark irqs that are being tested -+ */ -+ status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING); -+ status |= IRQ_PENDING; /* we _want_ to handle it */ -+ -+ /* -+ * If the IRQ is disabled for whatever reason, we cannot -+ * use the action we have. -+ */ -+ action = NULL; -+ if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) { -+ action = desc->action; -+ status &= ~IRQ_PENDING; /* we commit to handling */ -+ status |= IRQ_INPROGRESS; /* we are handling it */ -+ } -+ desc->status = status; -+ -+ /* -+ * If there is no IRQ handler or it was disabled, exit early. -+ Since we set PENDING, if another processor is handling -+ a different instance of this same irq, the other processor -+ will take care of it. -+ */ -+ if (!action) -+ goto out; -+ -+ /* -+ * Edge triggered interrupts need to remember -+ * pending events. -+ * This applies to any hw interrupts that allow a second -+ * instance of the same irq to arrive while we are in do_IRQ -+ * or in the handler. But the code here only handles the _second_ -+ * instance of the irq, not the third or fourth. So it is mostly -+ * useful for irq hardware that does not mask cleanly in an -+ * SMP environment. -+ */ -+ for (;;) { -+ spin_unlock(&desc->lock); -+ handle_IRQ_event(irq, (struct pt_regs *) regs, action); -+ spin_lock(&desc->lock); -+ -+ if (!(desc->status & IRQ_PENDING)) -+ break; -+ desc->status &= ~IRQ_PENDING; -+ } -+ desc->status &= ~IRQ_INPROGRESS; -+out: -+ /* -+ * The ->end() handler has to deal with interrupts which got -+ * disabled while the handler was running. -+ */ -+ desc->handler->end(irq); -+ spin_unlock(&desc->lock); -+ -+ if (softirq_pending(cpu)) -+ do_softirq(); -+ return 1; -+} -+ -+/** -+ * request_irq - allocate an interrupt line -+ * @irq: Interrupt line to allocate -+ * @handler: Function to be called when the IRQ occurs -+ * @irqflags: Interrupt type flags -+ * @devname: An ascii name for the claiming device -+ * @dev_id: A cookie passed back to the handler function -+ * -+ * This call allocates interrupt resources and enables the -+ * interrupt line and IRQ handling. From the point this -+ * call is made your handler function may be invoked. Since -+ * your handler function must clear any interrupt the board -+ * raises, you must take care both to initialise your hardware -+ * and to set up the interrupt handler in the right order. -+ * -+ * Dev_id must be globally unique. Normally the address of the -+ * device data structure is used as the cookie. Since the handler -+ * receives this value it makes sense to use it. -+ * -+ * If your interrupt is shared you must pass a non NULL dev_id -+ * as this is required when freeing the interrupt. -+ * -+ * Flags: -+ * -+ * SA_SHIRQ Interrupt is shared -+ * -+ * SA_INTERRUPT Disable local interrupts while processing -+ * -+ * SA_SAMPLE_RANDOM The interrupt can be used for entropy -+ * -+ */ -+ -+int request_irq(unsigned int irq, -+ void (*handler)(int, void *, struct pt_regs *), -+ unsigned long irqflags, -+ const char * devname, -+ void *dev_id) -+{ -+ int retval; -+ struct irqaction * action; -+ -+#if 1 -+ /* -+ * Sanity-check: shared interrupts should REALLY pass in -+ * a real dev-ID, otherwise we'll have trouble later trying -+ * to figure out which interrupt is which (messes up the -+ * interrupt freeing logic etc). -+ */ -+ if (irqflags & SA_SHIRQ) { -+ if (!dev_id) -+ printk(KERN_ERR "Bad boy: %s (at 0x%x) called us " -+ "without a dev_id!\n", devname, (&irq)[-1]); -+ } -+#endif -+ -+ if (irq >= NR_IRQS) -+ return -EINVAL; -+ if (!handler) -+ return -EINVAL; -+ -+ action = (struct irqaction *) -+ kmalloc(sizeof(struct irqaction), GFP_KERNEL); -+ if (!action) -+ return -ENOMEM; -+ -+ action->handler = handler; -+ action->flags = irqflags; -+ action->mask = 0; -+ action->name = devname; -+ action->next = NULL; -+ action->dev_id = dev_id; -+ -+ retval = setup_irq(irq, action); -+ if (retval) -+ kfree(action); -+ return retval; -+} -+ -+int um_request_irq(unsigned int irq, int fd, int type, -+ void (*handler)(int, void *, struct pt_regs *), -+ unsigned long irqflags, const char * devname, -+ void *dev_id) -+{ -+ int err; -+ -+ err = request_irq(irq, handler, irqflags, devname, dev_id); -+ if(err) -+ return(err); -+ -+ if(fd != -1) -+ err = activate_fd(irq, fd, type, dev_id); -+ return(err); -+} -+ -+/* this was setup_x86_irq but it seems pretty generic */ -+int setup_irq(unsigned int irq, struct irqaction * new) -+{ -+ int shared = 0; -+ unsigned long flags; -+ struct irqaction *old, **p; -+ irq_desc_t *desc = irq_desc + irq; -+ -+ /* -+ * Some drivers like serial.c use request_irq() heavily, -+ * so we have to be careful not to interfere with a -+ * running system. -+ */ -+ if (new->flags & SA_SAMPLE_RANDOM) { -+ /* -+ * This function might sleep, we want to call it first, -+ * outside of the atomic block. -+ * Yes, this might clear the entropy pool if the wrong -+ * driver is attempted to be loaded, without actually -+ * installing a new handler, but is this really a problem, -+ * only the sysadmin is able to do this. -+ */ -+ rand_initialize_irq(irq); -+ } -+ -+ /* -+ * The following block of code has to be executed atomically -+ */ -+ spin_lock_irqsave(&desc->lock,flags); -+ p = &desc->action; -+ old = *p; -+ if (old != NULL) { -+ /* Can't share interrupts unless both agree to */ -+ if (!(old->flags & new->flags & SA_SHIRQ)) { -+ spin_unlock_irqrestore(&desc->lock,flags); -+ return -EBUSY; -+ } -+ -+ /* add new interrupt at end of irq queue */ -+ do { -+ p = &old->next; -+ old = *p; -+ } while (old); -+ shared = 1; -+ } -+ -+ *p = new; -+ -+ if (!shared) { -+ desc->depth = 0; -+ desc->status &= ~IRQ_DISABLED; -+ desc->handler->startup(irq); -+ } -+ spin_unlock_irqrestore(&desc->lock,flags); -+ -+ register_irq_proc(irq); -+ return 0; -+} -+ -+/** -+ * free_irq - free an interrupt -+ * @irq: Interrupt line to free -+ * @dev_id: Device identity to free -+ * -+ * Remove an interrupt handler. The handler is removed and if the -+ * interrupt line is no longer in use by any driver it is disabled. -+ * On a shared IRQ the caller must ensure the interrupt is disabled -+ * on the card it drives before calling this function. The function -+ * does not return until any executing interrupts for this IRQ -+ * have completed. -+ * -+ * This function may be called from interrupt context. -+ * -+ * Bugs: Attempting to free an irq in a handler for the same irq hangs -+ * the machine. -+ */ -+ -+void free_irq(unsigned int irq, void *dev_id) -+{ -+ irq_desc_t *desc; -+ struct irqaction **p; -+ unsigned long flags; -+ -+ if (irq >= NR_IRQS) -+ return; -+ -+ desc = irq_desc + irq; -+ spin_lock_irqsave(&desc->lock,flags); -+ p = &desc->action; -+ for (;;) { -+ struct irqaction * action = *p; -+ if (action) { -+ struct irqaction **pp = p; -+ p = &action->next; -+ if (action->dev_id != dev_id) -+ continue; -+ -+ /* Found it - now remove it from the list of entries */ -+ *pp = action->next; -+ if (!desc->action) { -+ desc->status |= IRQ_DISABLED; -+ desc->handler->shutdown(irq); -+ } -+ free_irq_by_irq_and_dev(irq, dev_id); -+ spin_unlock_irqrestore(&desc->lock,flags); -+ -+#ifdef CONFIG_SMP -+ /* Wait to make sure it's not being used on another CPU */ -+ while (desc->status & IRQ_INPROGRESS) -+ barrier(); -+#endif -+ kfree(action); -+ return; -+ } -+ printk(KERN_ERR "Trying to free free IRQ%d\n",irq); -+ spin_unlock_irqrestore(&desc->lock,flags); -+ return; -+ } -+} -+ -+/* These are initialized by sysctl_init, which is called from init/main.c */ -+static struct proc_dir_entry * root_irq_dir; -+static struct proc_dir_entry * irq_dir [NR_IRQS]; -+static struct proc_dir_entry * smp_affinity_entry [NR_IRQS]; -+ -+/* These are read and written as longs, so a read won't see a partial write -+ * even during a race. -+ */ -+static unsigned long irq_affinity [NR_IRQS] = { [0 ... NR_IRQS-1] = ~0UL }; -+ -+#define HEX_DIGITS 8 -+ -+static int irq_affinity_read_proc (char *page, char **start, off_t off, -+ int count, int *eof, void *data) -+{ -+ if (count < HEX_DIGITS+1) -+ return -EINVAL; -+ return sprintf (page, "%08lx\n", irq_affinity[(long)data]); -+} -+ -+static unsigned int parse_hex_value (const char *buffer, -+ unsigned long count, unsigned long *ret) -+{ -+ unsigned char hexnum [HEX_DIGITS]; -+ unsigned long value; -+ int i; -+ -+ if (!count) -+ return -EINVAL; -+ if (count > HEX_DIGITS) -+ count = HEX_DIGITS; -+ if (copy_from_user(hexnum, buffer, count)) -+ return -EFAULT; -+ -+ /* -+ * Parse the first HEX_DIGITS characters as a hex string, any non-hex -+ * char is end-of-string. '00e1', 'e1', '00E1', 'E1' are all the same. -+ */ -+ value = 0; -+ -+ for (i = 0; i < count; i++) { -+ unsigned int c = hexnum[i]; -+ -+ switch (c) { -+ case '0' ... '9': c -= '0'; break; -+ case 'a' ... 'f': c -= 'a'-10; break; -+ case 'A' ... 'F': c -= 'A'-10; break; -+ default: -+ goto out; -+ } -+ value = (value << 4) | c; -+ } -+out: -+ *ret = value; -+ return 0; -+} -+ -+static int irq_affinity_write_proc (struct file *file, const char *buffer, -+ unsigned long count, void *data) -+{ -+ int irq = (long) data, full_count = count, err; -+ unsigned long new_value; -+ -+ if (!irq_desc[irq].handler->set_affinity) -+ return -EIO; -+ -+ err = parse_hex_value(buffer, count, &new_value); -+ -+#if CONFIG_SMP -+ /* -+ * Do not allow disabling IRQs completely - it's a too easy -+ * way to make the system unusable accidentally :-) At least -+ * one online CPU still has to be targeted. -+ */ -+ if (!(new_value & cpu_online_map)) -+ return -EINVAL; -+#endif -+ -+ irq_affinity[irq] = new_value; -+ irq_desc[irq].handler->set_affinity(irq, new_value); -+ -+ return full_count; -+} -+ -+static int prof_cpu_mask_read_proc (char *page, char **start, off_t off, -+ int count, int *eof, void *data) -+{ -+ unsigned long *mask = (unsigned long *) data; -+ if (count < HEX_DIGITS+1) -+ return -EINVAL; -+ return sprintf (page, "%08lx\n", *mask); -+} -+ -+static int prof_cpu_mask_write_proc (struct file *file, const char *buffer, -+ unsigned long count, void *data) -+{ -+ unsigned long *mask = (unsigned long *) data, full_count = count, err; -+ unsigned long new_value; -+ -+ err = parse_hex_value(buffer, count, &new_value); -+ if (err) -+ return err; -+ -+ *mask = new_value; -+ return full_count; -+} -+ -+#define MAX_NAMELEN 10 -+ -+static void register_irq_proc (unsigned int irq) -+{ -+ struct proc_dir_entry *entry; -+ char name [MAX_NAMELEN]; -+ -+ if (!root_irq_dir || (irq_desc[irq].handler == &no_irq_type) || -+ irq_dir[irq]) -+ return; -+ -+ memset(name, 0, MAX_NAMELEN); -+ sprintf(name, "%d", irq); -+ -+ /* create /proc/irq/1234 */ -+ irq_dir[irq] = proc_mkdir(name, root_irq_dir); -+ -+ /* create /proc/irq/1234/smp_affinity */ -+ entry = create_proc_entry("smp_affinity", 0600, irq_dir[irq]); -+ -+ entry->nlink = 1; -+ entry->data = (void *)(long)irq; -+ entry->read_proc = irq_affinity_read_proc; -+ entry->write_proc = irq_affinity_write_proc; -+ -+ smp_affinity_entry[irq] = entry; -+} -+ -+/* Read and written as a long */ -+unsigned long prof_cpu_mask = -1; -+ -+void __init init_irq_proc (void) -+{ -+ struct proc_dir_entry *entry; -+ int i; -+ -+ /* create /proc/irq */ -+ root_irq_dir = proc_mkdir("irq", 0); -+ -+ /* create /proc/irq/prof_cpu_mask */ -+ entry = create_proc_entry("prof_cpu_mask", 0600, root_irq_dir); -+ -+ entry->nlink = 1; -+ entry->data = (void *)&prof_cpu_mask; -+ entry->read_proc = prof_cpu_mask_read_proc; -+ entry->write_proc = prof_cpu_mask_write_proc; -+ -+ /* -+ * Create entries for all existing IRQs. -+ */ -+ for (i = 0; i < NR_IRQS; i++) -+ register_irq_proc(i); -+} -+ -+static spinlock_t irq_spinlock = SPIN_LOCK_UNLOCKED; -+ -+unsigned long irq_lock(void) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&irq_spinlock, flags); -+ return(flags); -+} -+ -+void irq_unlock(unsigned long flags) -+{ -+ spin_unlock_irqrestore(&irq_spinlock, flags); -+} -+ -+unsigned long probe_irq_on(void) -+{ -+ return(0); -+} -+ -+int probe_irq_off(unsigned long val) -+{ -+ return(0); -+} -+ -+static unsigned int startup_SIGIO_irq(unsigned int irq) -+{ -+ return(0); -+} -+ -+static void shutdown_SIGIO_irq(unsigned int irq) -+{ -+} -+ -+static void enable_SIGIO_irq(unsigned int irq) -+{ -+} -+ -+static void disable_SIGIO_irq(unsigned int irq) -+{ -+} -+ -+static void mask_and_ack_SIGIO(unsigned int irq) -+{ -+} -+ -+static void end_SIGIO_irq(unsigned int irq) -+{ -+} -+ -+static unsigned int startup_SIGVTALRM_irq(unsigned int irq) -+{ -+ return(0); -+} -+ -+static void shutdown_SIGVTALRM_irq(unsigned int irq) -+{ -+} -+ -+static void enable_SIGVTALRM_irq(unsigned int irq) -+{ -+} -+ -+static void disable_SIGVTALRM_irq(unsigned int irq) -+{ -+} -+ -+static void mask_and_ack_SIGVTALRM(unsigned int irq) -+{ -+} -+ -+static void end_SIGVTALRM_irq(unsigned int irq) -+{ -+} -+ -+static struct hw_interrupt_type SIGIO_irq_type = { -+ "SIGIO", -+ startup_SIGIO_irq, -+ shutdown_SIGIO_irq, -+ enable_SIGIO_irq, -+ disable_SIGIO_irq, -+ mask_and_ack_SIGIO, -+ end_SIGIO_irq, -+ NULL -+}; -+ -+static struct hw_interrupt_type SIGVTALRM_irq_type = { -+ "SIGVTALRM", -+ startup_SIGVTALRM_irq, -+ shutdown_SIGVTALRM_irq, -+ enable_SIGVTALRM_irq, -+ disable_SIGVTALRM_irq, -+ mask_and_ack_SIGVTALRM, -+ end_SIGVTALRM_irq, -+ NULL -+}; -+ -+void __init init_IRQ(void) -+{ -+ int i; -+ -+ irq_desc[TIMER_IRQ].status = IRQ_DISABLED; -+ irq_desc[TIMER_IRQ].action = 0; -+ irq_desc[TIMER_IRQ].depth = 1; -+ irq_desc[TIMER_IRQ].handler = &SIGVTALRM_irq_type; -+ enable_irq(TIMER_IRQ); -+ for(i=1;i<NR_IRQS;i++){ -+ irq_desc[i].status = IRQ_DISABLED; -+ irq_desc[i].action = 0; -+ irq_desc[i].depth = 1; -+ irq_desc[i].handler = &SIGIO_irq_type; -+ enable_irq(i); -+ } -+ init_irq_signals(0); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/irq_user.c um/arch/um/kernel/irq_user.c ---- orig/arch/um/kernel/irq_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/irq_user.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,424 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <stdlib.h> -+#include <unistd.h> -+#include <errno.h> -+#include <signal.h> -+#include <string.h> -+#include <sys/poll.h> -+#include <sys/types.h> -+#include <sys/time.h> -+#include "user_util.h" -+#include "kern_util.h" -+#include "user.h" -+#include "process.h" -+#include "signal_user.h" -+#include "sigio.h" -+#include "irq_user.h" -+#include "os.h" -+ -+struct irq_fd { -+ struct irq_fd *next; -+ void *id; -+ int fd; -+ int type; -+ int irq; -+ int pid; -+ int events; -+ int current_events; -+ int freed; -+}; -+ -+static struct irq_fd *active_fds = NULL; -+static struct irq_fd **last_irq_ptr = &active_fds; -+ -+static struct pollfd *pollfds = NULL; -+static int pollfds_num = 0; -+static int pollfds_size = 0; -+ -+extern int io_count, intr_count; -+ -+void sigio_handler(int sig, union uml_pt_regs *regs) -+{ -+ struct irq_fd *irq_fd, *next; -+ int i, n; -+ -+ if(smp_sigio_handler()) return; -+ while(1){ -+ n = poll(pollfds, pollfds_num, 0); -+ if(n < 0){ -+ if(errno == EINTR) continue; -+ printk("sigio_handler : poll returned %d, " -+ "errno = %d\n", n, errno); -+ break; -+ } -+ if(n == 0) break; -+ -+ irq_fd = active_fds; -+ for(i = 0; i < pollfds_num; i++){ -+ if(pollfds[i].revents != 0){ -+ irq_fd->current_events = pollfds[i].revents; -+ pollfds[i].fd = -1; -+ } -+ irq_fd = irq_fd->next; -+ } -+ -+ for(irq_fd = active_fds; irq_fd != NULL; irq_fd = next){ -+ next = irq_fd->next; -+ if(irq_fd->current_events != 0){ -+ irq_fd->current_events = 0; -+ do_IRQ(irq_fd->irq, regs); -+ -+ /* This is here because the next irq may be -+ * freed in the handler. If a console goes -+ * away, both the read and write irqs will be -+ * freed. After do_IRQ, ->next will point to -+ * a good IRQ. -+ * Irqs can't be freed inside their handlers, -+ * so the next best thing is to have them -+ * marked as needing freeing, so that they -+ * can be freed here. -+ */ -+ next = irq_fd->next; -+ if(irq_fd->freed) -+ free_irq(irq_fd->irq, irq_fd->id); -+ } -+ } -+ } -+} -+ -+int activate_ipi(int fd, int pid) -+{ -+ return(os_set_fd_async(fd, pid)); -+} -+ -+static void maybe_sigio_broken(int fd, int type) -+{ -+ if(isatty(fd)){ -+ if((type == IRQ_WRITE) && !pty_output_sigio){ -+ write_sigio_workaround(); -+ add_sigio_fd(fd, 0); -+ } -+ else if((type == IRQ_READ) && !pty_close_sigio){ -+ write_sigio_workaround(); -+ add_sigio_fd(fd, 1); -+ } -+ } -+} -+ -+int activate_fd(int irq, int fd, int type, void *dev_id) -+{ -+ struct pollfd *tmp_pfd; -+ struct irq_fd *new_fd, *irq_fd; -+ unsigned long flags; -+ int pid, events, err, n, size; -+ -+ pid = os_getpid(); -+ err = os_set_fd_async(fd, pid); -+ if(err < 0) -+ goto out; -+ -+ new_fd = um_kmalloc(sizeof(*new_fd)); -+ err = -ENOMEM; -+ if(new_fd == NULL) -+ goto out; -+ -+ if(type == IRQ_READ) events = POLLIN | POLLPRI; -+ else events = POLLOUT; -+ *new_fd = ((struct irq_fd) { .next = NULL, -+ .id = dev_id, -+ .fd = fd, -+ .type = type, -+ .irq = irq, -+ .pid = pid, -+ .events = events, -+ .current_events = 0, -+ .freed = 0 } ); -+ -+ /* Critical section - locked by a spinlock because this stuff can -+ * be changed from interrupt handlers. The stuff above is done -+ * outside the lock because it allocates memory. -+ */ -+ -+ /* Actually, it only looks like it can be called from interrupt -+ * context. The culprit is reactivate_fd, which calls -+ * maybe_sigio_broken, which calls write_sigio_workaround, -+ * which calls activate_fd. However, write_sigio_workaround should -+ * only be called once, at boot time. That would make it clear that -+ * this is called only from process context, and can be locked with -+ * a semaphore. -+ */ -+ flags = irq_lock(); -+ for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){ -+ if((irq_fd->fd == fd) && (irq_fd->type == type)){ -+ printk("Registering fd %d twice\n", fd); -+ printk("Irqs : %d, %d\n", irq_fd->irq, irq); -+ printk("Ids : 0x%x, 0x%x\n", irq_fd->id, dev_id); -+ goto out_unlock; -+ } -+ } -+ -+ n = pollfds_num; -+ if(n == pollfds_size){ -+ while(1){ -+ /* Here we have to drop the lock in order to call -+ * kmalloc, which might sleep. If something else -+ * came in and changed the pollfds array, we free -+ * the buffer and try again. -+ */ -+ irq_unlock(flags); -+ size = (pollfds_num + 1) * sizeof(pollfds[0]); -+ tmp_pfd = um_kmalloc(size); -+ flags = irq_lock(); -+ if(tmp_pfd == NULL) -+ goto out_unlock; -+ if(n == pollfds_size) -+ break; -+ kfree(tmp_pfd); -+ } -+ if(pollfds != NULL){ -+ memcpy(tmp_pfd, pollfds, -+ sizeof(pollfds[0]) * pollfds_size); -+ kfree(pollfds); -+ } -+ pollfds = tmp_pfd; -+ pollfds_size++; -+ } -+ -+ if(type == IRQ_WRITE) -+ fd = -1; -+ -+ pollfds[pollfds_num] = ((struct pollfd) { .fd = fd, -+ .events = events, -+ .revents = 0 }); -+ pollfds_num++; -+ -+ *last_irq_ptr = new_fd; -+ last_irq_ptr = &new_fd->next; -+ -+ irq_unlock(flags); -+ -+ /* This calls activate_fd, so it has to be outside the critical -+ * section. -+ */ -+ maybe_sigio_broken(fd, type); -+ -+ return(0); -+ -+ out_unlock: -+ irq_unlock(flags); -+ kfree(new_fd); -+ out: -+ return(err); -+} -+ -+static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg) -+{ -+ struct irq_fd **prev; -+ unsigned long flags; -+ int i = 0; -+ -+ flags = irq_lock(); -+ prev = &active_fds; -+ while(*prev != NULL){ -+ if((*test)(*prev, arg)){ -+ struct irq_fd *old_fd = *prev; -+ if((pollfds[i].fd != -1) && -+ (pollfds[i].fd != (*prev)->fd)){ -+ printk("free_irq_by_cb - mismatch between " -+ "active_fds and pollfds, fd %d vs %d\n", -+ (*prev)->fd, pollfds[i].fd); -+ goto out; -+ } -+ memcpy(&pollfds[i], &pollfds[i + 1], -+ (pollfds_num - i - 1) * sizeof(pollfds[0])); -+ pollfds_num--; -+ if(last_irq_ptr == &old_fd->next) -+ last_irq_ptr = prev; -+ *prev = (*prev)->next; -+ if(old_fd->type == IRQ_WRITE) -+ ignore_sigio_fd(old_fd->fd); -+ kfree(old_fd); -+ continue; -+ } -+ prev = &(*prev)->next; -+ i++; -+ } -+ out: -+ irq_unlock(flags); -+} -+ -+struct irq_and_dev { -+ int irq; -+ void *dev; -+}; -+ -+static int same_irq_and_dev(struct irq_fd *irq, void *d) -+{ -+ struct irq_and_dev *data = d; -+ -+ return((irq->irq == data->irq) && (irq->id == data->dev)); -+} -+ -+void free_irq_by_irq_and_dev(int irq, void *dev) -+{ -+ struct irq_and_dev data = ((struct irq_and_dev) { .irq = irq, -+ .dev = dev }); -+ -+ free_irq_by_cb(same_irq_and_dev, &data); -+} -+ -+static int same_fd(struct irq_fd *irq, void *fd) -+{ -+ return(irq->fd == *((int *) fd)); -+} -+ -+void free_irq_by_fd(int fd) -+{ -+ free_irq_by_cb(same_fd, &fd); -+} -+ -+static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out) -+{ -+ struct irq_fd *irq; -+ int i = 0; -+ -+ for(irq=active_fds; irq != NULL; irq = irq->next){ -+ if((irq->fd == fd) && (irq->irq == irqnum)) break; -+ i++; -+ } -+ if(irq == NULL){ -+ printk("find_irq_by_fd doesn't have descriptor %d\n", fd); -+ goto out; -+ } -+ if((pollfds[i].fd != -1) && (pollfds[i].fd != fd)){ -+ printk("find_irq_by_fd - mismatch between active_fds and " -+ "pollfds, fd %d vs %d, need %d\n", irq->fd, -+ pollfds[i].fd, fd); -+ irq = NULL; -+ goto out; -+ } -+ *index_out = i; -+ out: -+ return(irq); -+} -+ -+void free_irq_later(int irq, void *dev_id) -+{ -+ struct irq_fd *irq_fd; -+ unsigned long flags; -+ -+ flags = irq_lock(); -+ for(irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next){ -+ if((irq_fd->irq == irq) && (irq_fd->id == dev_id)) -+ break; -+ } -+ if(irq_fd == NULL){ -+ printk("free_irq_later found no irq, irq = %d, " -+ "dev_id = 0x%p\n", irq, dev_id); -+ goto out; -+ } -+ irq_fd->freed = 1; -+ out: -+ irq_unlock(flags); -+} -+ -+void reactivate_fd(int fd, int irqnum) -+{ -+ struct irq_fd *irq; -+ unsigned long flags; -+ int i; -+ -+ flags = irq_lock(); -+ irq = find_irq_by_fd(fd, irqnum, &i); -+ if(irq == NULL){ -+ irq_unlock(flags); -+ return; -+ } -+ -+ pollfds[i].fd = irq->fd; -+ -+ irq_unlock(flags); -+ -+ /* This calls activate_fd, so it has to be outside the critical -+ * section. -+ */ -+ maybe_sigio_broken(fd, irq->type); -+} -+ -+void deactivate_fd(int fd, int irqnum) -+{ -+ struct irq_fd *irq; -+ unsigned long flags; -+ int i; -+ -+ flags = irq_lock(); -+ irq = find_irq_by_fd(fd, irqnum, &i); -+ if(irq == NULL) -+ goto out; -+ pollfds[i].fd = -1; -+ out: -+ irq_unlock(flags); -+} -+ -+void forward_ipi(int fd, int pid) -+{ -+ int err; -+ -+ err = os_set_owner(fd, pid); -+ if(err < 0) -+ printk("forward_ipi: set_owner failed, fd = %d, me = %d, " -+ "target = %d, err = %d\n", fd, os_getpid(), pid, -err); -+} -+ -+void forward_interrupts(int pid) -+{ -+ struct irq_fd *irq; -+ unsigned long flags; -+ int err; -+ -+ flags = irq_lock(); -+ for(irq=active_fds;irq != NULL;irq = irq->next){ -+ err = os_set_owner(irq->fd, pid); -+ if(err < 0){ -+ /* XXX Just remove the irq rather than -+ * print out an infinite stream of these -+ */ -+ printk("Failed to forward %d to pid %d, err = %d\n", -+ irq->fd, pid, -err); -+ } -+ -+ irq->pid = pid; -+ } -+ irq_unlock(flags); -+} -+ -+void init_irq_signals(int on_sigstack) -+{ -+ __sighandler_t h; -+ int flags; -+ -+ flags = on_sigstack ? SA_ONSTACK : 0; -+ if(timer_irq_inited) h = (__sighandler_t) alarm_handler; -+ else h = boot_timer_handler; -+ -+ set_handler(SIGVTALRM, h, flags | SA_RESTART, -+ SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1); -+ set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART, -+ SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); -+ signal(SIGWINCH, SIG_IGN); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/ksyms.c um/arch/um/kernel/ksyms.c ---- orig/arch/um/kernel/ksyms.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/ksyms.c 2004-01-23 00:44:09.000000000 -0500 -@@ -0,0 +1,120 @@ -+/* -+ * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/config.h" -+#include "linux/module.h" -+#include "linux/string.h" -+#include "linux/smp_lock.h" -+#include "linux/spinlock.h" -+#include "asm/current.h" -+#include "asm/delay.h" -+#include "asm/processor.h" -+#include "asm/unistd.h" -+#include "asm/pgalloc.h" -+#include "asm/pgtable.h" -+#include "asm/page.h" -+#include "kern_util.h" -+#include "user_util.h" -+#include "os.h" -+#include "helper.h" -+ -+EXPORT_SYMBOL(stop); -+EXPORT_SYMBOL(strtok); -+EXPORT_SYMBOL(uml_physmem); -+EXPORT_SYMBOL(set_signals); -+EXPORT_SYMBOL(get_signals); -+EXPORT_SYMBOL(kernel_thread); -+EXPORT_SYMBOL(__const_udelay); -+EXPORT_SYMBOL(__udelay); -+EXPORT_SYMBOL(sys_waitpid); -+EXPORT_SYMBOL(task_size); -+EXPORT_SYMBOL(flush_tlb_range); -+EXPORT_SYMBOL(host_task_size); -+EXPORT_SYMBOL(arch_validate); -+EXPORT_SYMBOL(get_kmem_end); -+ -+EXPORT_SYMBOL(high_physmem); -+EXPORT_SYMBOL(empty_zero_page); -+EXPORT_SYMBOL(um_virt_to_phys); -+EXPORT_SYMBOL(__virt_to_page); -+EXPORT_SYMBOL(to_phys); -+EXPORT_SYMBOL(to_virt); -+EXPORT_SYMBOL(mode_tt); -+EXPORT_SYMBOL(handle_page_fault); -+ -+#ifdef CONFIG_MODE_TT -+EXPORT_SYMBOL(copy_from_user_tt); -+EXPORT_SYMBOL(copy_to_user_tt); -+#endif -+ -+#ifdef CONFIG_MODE_SKAS -+EXPORT_SYMBOL(copy_to_user_skas); -+EXPORT_SYMBOL(copy_from_user_skas); -+#endif -+ -+EXPORT_SYMBOL(os_stat_fd); -+EXPORT_SYMBOL(os_stat_file); -+EXPORT_SYMBOL(os_access); -+EXPORT_SYMBOL(os_print_error); -+EXPORT_SYMBOL(os_get_exec_close); -+EXPORT_SYMBOL(os_set_exec_close); -+EXPORT_SYMBOL(os_getpid); -+EXPORT_SYMBOL(os_open_file); -+EXPORT_SYMBOL(os_read_file); -+EXPORT_SYMBOL(os_write_file); -+EXPORT_SYMBOL(os_seek_file); -+EXPORT_SYMBOL(os_lock_file); -+EXPORT_SYMBOL(os_pipe); -+EXPORT_SYMBOL(os_file_type); -+EXPORT_SYMBOL(os_file_mode); -+EXPORT_SYMBOL(os_file_size); -+EXPORT_SYMBOL(os_flush_stdout); -+EXPORT_SYMBOL(os_close_file); -+EXPORT_SYMBOL(os_set_fd_async); -+EXPORT_SYMBOL(os_set_fd_block); -+EXPORT_SYMBOL(helper_wait); -+EXPORT_SYMBOL(os_shutdown_socket); -+EXPORT_SYMBOL(os_create_unix_socket); -+EXPORT_SYMBOL(os_connect_socket); -+EXPORT_SYMBOL(os_accept_connection); -+EXPORT_SYMBOL(os_ioctl_generic); -+EXPORT_SYMBOL(os_rcv_fd); -+EXPORT_SYMBOL(run_helper); -+EXPORT_SYMBOL(start_thread); -+EXPORT_SYMBOL(dump_thread); -+ -+/* This is here because UML expands open to sys_open, not to a system -+ * call instruction. -+ */ -+EXPORT_SYMBOL(sys_open); -+EXPORT_SYMBOL(sys_lseek); -+EXPORT_SYMBOL(sys_read); -+EXPORT_SYMBOL(sys_wait4); -+ -+#ifdef CONFIG_SMP -+ -+/* required for SMP */ -+ -+extern void FASTCALL( __write_lock_failed(rwlock_t *rw)); -+EXPORT_SYMBOL_NOVERS(__write_lock_failed); -+ -+extern void FASTCALL( __read_lock_failed(rwlock_t *rw)); -+EXPORT_SYMBOL_NOVERS(__read_lock_failed); -+ -+EXPORT_SYMBOL(kernel_flag_cacheline); -+EXPORT_SYMBOL(smp_num_cpus); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/Makefile um/arch/um/kernel/Makefile ---- orig/arch/um/kernel/Makefile 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/Makefile 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,73 @@ -+# -+# Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+# Licensed under the GPL -+# -+ -+O_TARGET = built-in.o -+ -+obj-y = config.o checksum.o exec_kern.o exitcode.o frame_kern.o frame.o \ -+ helper.o init_task.o irq.o irq_user.o ksyms.o mem.o mem_user.o \ -+ physmem.o process.o process_kern.o ptrace.o reboot.o resource.o \ -+ sigio_user.o sigio_kern.o signal_kern.o signal_user.o smp.o \ -+ syscall_kern.o syscall_user.o sysrq.o sys_call_table.o tempfile.o \ -+ time.o time_kern.o tlb.o trap_kern.o trap_user.o uaccess_user.o \ -+ um_arch.o umid.o user_syms.o user_util.o -+ -+obj-$(CONFIG_BLK_DEV_INITRD) += initrd_kern.o initrd_user.o -+obj-$(CONFIG_GPROF) += gprof_syms.o -+obj-$(CONFIG_GCOV) += gmon_syms.o -+obj-$(CONFIG_TTY_LOG) += tty_log.o -+ -+subdir-$(CONFIG_MODE_TT) += tt -+subdir-$(CONFIG_MODE_SKAS) += skas -+ -+user-objs-$(CONFIG_TTY_LOG) += tty_log.o -+ -+obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o)) -+ -+# user_syms.o not included here because Rules.make has its own ideas about -+# building anything in export-objs -+ -+USER_OBJS = $(filter %_user.o,$(obj-y)) $(user-objs-y) config.o helper.o \ -+ process.o tempfile.o time.o umid.o user_util.o -+ -+DMODULES-$(CONFIG_MODULES) = -D__CONFIG_MODULES__ -+DMODVERSIONS-$(CONFIG_MODVERSIONS) = -D__CONFIG_MODVERSIONS__ -+ -+export-objs-$(CONFIG_GPROF) += gprof_syms.o -+export-objs-$(CONFIG_GCOV) += gmon_syms.o -+ -+export-objs = ksyms.o process_kern.o signal_kern.o user_syms.o $(export-objs-y) -+ -+CFLAGS_user_syms.o = -D__AUTOCONF_INCLUDED__ $(DMODULES-y) $(DMODVERSIONS-y) \ -+ -I/usr/include -I../include -+ -+CFLAGS_frame.o := $(patsubst -fomit-frame-pointer,,$(USER_CFLAGS)) -+ -+include $(TOPDIR)/Rules.make -+ -+$(USER_OBJS) : %.o: %.c -+ $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $< -+ -+# This has to be separate because it needs be compiled with frame pointers -+# regardless of how the rest of the kernel is built. -+ -+frame.o: frame.c -+ $(CC) $(CFLAGS_$@) -c -o $@ $< -+ -+QUOTE = 'my $$config=`cat $(TOPDIR)/.config`; $$config =~ s/"/\\"/g ; $$config =~ s/\n/\\n"\n"/g ; while(<STDIN>) { $$_ =~ s/CONFIG/$$config/; print $$_ }' -+ -+config.c : config.c.in $(TOPDIR)/.config -+ $(PERL) -e $(QUOTE) < config.c.in > $@ -+ -+clean: -+ $(RM) config.c -+ for dir in $(subdir-y) ; do $(MAKE) -C $$dir clean; done -+ -+modules: -+ -+fastdep: -+ -+dep: -+ -+archmrproper: clean -diff -Naur -X ../exclude-files orig/arch/um/kernel/mem.c um/arch/um/kernel/mem.c ---- orig/arch/um/kernel/mem.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/mem.c 2003-12-22 01:25:00.000000000 -0500 -@@ -0,0 +1,336 @@ -+/* -+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/stddef.h" -+#include "linux/kernel.h" -+#include "linux/mm.h" -+#include "linux/bootmem.h" -+#include "linux/highmem.h" -+#include "asm/page.h" -+#include "asm/fixmap.h" -+#include "asm/pgalloc.h" -+#include "user_util.h" -+#include "kern_util.h" -+#include "kern.h" -+#include "mem_user.h" -+#include "uml_uaccess.h" -+#include "os.h" -+ -+extern char __binary_start; -+ -+/* Changed during early boot */ -+unsigned long *empty_zero_page = NULL; -+unsigned long *empty_bad_page = NULL; -+pgd_t swapper_pg_dir[1024]; -+unsigned long highmem; -+int kmalloc_ok = 0; -+ -+static unsigned long brk_end; -+static unsigned long totalram_pages = 0; -+ -+void unmap_physmem(void) -+{ -+ os_unmap_memory((void *) brk_end, uml_reserved - brk_end); -+} -+ -+static void map_cb(void *unused) -+{ -+ map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, 0); -+} -+ -+#ifdef CONFIG_HIGHMEM -+static void setup_highmem(unsigned long highmem_start, -+ unsigned long highmem_len) -+{ -+ struct page *page; -+ unsigned long highmem_pfn; -+ int i; -+ -+ highmem_start_page = virt_to_page(highmem_start); -+ -+ highmem_pfn = __pa(highmem_start) >> PAGE_SHIFT; -+ for(i = 0; i < highmem_len >> PAGE_SHIFT; i++){ -+ page = &mem_map[highmem_pfn + i]; -+ ClearPageReserved(page); -+ set_bit(PG_highmem, &page->flags); -+ atomic_set(&page->count, 1); -+ __free_page(page); -+ } -+} -+#endif -+ -+void mem_init(void) -+{ -+ unsigned long start; -+ -+ /* clear the zero-page */ -+ memset((void *) empty_zero_page, 0, PAGE_SIZE); -+ -+ /* Map in the area just after the brk now that kmalloc is about -+ * to be turned on. -+ */ -+ brk_end = (unsigned long) UML_ROUND_UP(sbrk(0)); -+ map_cb(NULL); -+ initial_thread_cb(map_cb, NULL); -+ free_bootmem(__pa(brk_end), uml_reserved - brk_end); -+ uml_reserved = brk_end; -+ -+ /* Fill in any hole at the start of the binary */ -+ start = (unsigned long) &__binary_start; -+ if(uml_physmem != start){ -+ map_memory(uml_physmem, __pa(uml_physmem), start - uml_physmem, -+ 1, 1, 0); -+ } -+ -+ /* this will put all low memory onto the freelists */ -+ totalram_pages = free_all_bootmem(); -+ totalram_pages += highmem >> PAGE_SHIFT; -+ num_physpages = totalram_pages; -+ printk(KERN_INFO "Memory: %luk available\n", -+ (unsigned long) nr_free_pages() << (PAGE_SHIFT-10)); -+ kmalloc_ok = 1; -+ -+#ifdef CONFIG_HIGHMEM -+ setup_highmem(end_iomem, highmem); -+#endif -+} -+ -+static void __init fixrange_init(unsigned long start, unsigned long end, -+ pgd_t *pgd_base) -+{ -+ pgd_t *pgd; -+ pmd_t *pmd; -+ pte_t *pte; -+ int i, j; -+ unsigned long vaddr; -+ -+ vaddr = start; -+ i = __pgd_offset(vaddr); -+ j = __pmd_offset(vaddr); -+ pgd = pgd_base + i; -+ -+ for ( ; (i < PTRS_PER_PGD) && (vaddr < end); pgd++, i++) { -+ pmd = (pmd_t *)pgd; -+ for (; (j < PTRS_PER_PMD) && (vaddr != end); pmd++, j++) { -+ if (pmd_none(*pmd)) { -+ pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); -+ set_pmd(pmd, __pmd(_KERNPG_TABLE + -+ (unsigned long) __pa(pte))); -+ if (pte != pte_offset(pmd, 0)) -+ BUG(); -+ } -+ vaddr += PMD_SIZE; -+ } -+ j = 0; -+ } -+} -+ -+#ifdef CONFIG_HIGHMEM -+pte_t *kmap_pte; -+pgprot_t kmap_prot; -+ -+#define kmap_get_fixmap_pte(vaddr) \ -+ pte_offset(pmd_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)) -+ -+void __init kmap_init(void) -+{ -+ unsigned long kmap_vstart; -+ -+ /* cache the first kmap pte */ -+ kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN); -+ kmap_pte = kmap_get_fixmap_pte(kmap_vstart); -+ -+ kmap_prot = PAGE_KERNEL; -+} -+ -+static void init_highmem(void) -+{ -+ pgd_t *pgd; -+ pmd_t *pmd; -+ pte_t *pte; -+ unsigned long vaddr; -+ -+ /* -+ * Permanent kmaps: -+ */ -+ vaddr = PKMAP_BASE; -+ fixrange_init(vaddr, vaddr + PAGE_SIZE*LAST_PKMAP, swapper_pg_dir); -+ -+ pgd = swapper_pg_dir + __pgd_offset(vaddr); -+ pmd = pmd_offset(pgd, vaddr); -+ pte = pte_offset(pmd, vaddr); -+ pkmap_page_table = pte; -+ -+ kmap_init(); -+} -+ -+#endif /* CONFIG_HIGHMEM */ -+ -+void paging_init(void) -+{ -+ unsigned long zones_size[MAX_NR_ZONES], vaddr; -+ int i; -+ -+ empty_zero_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE); -+ empty_bad_page = (unsigned long *) alloc_bootmem_low_pages(PAGE_SIZE); -+ for(i=0;i<sizeof(zones_size)/sizeof(zones_size[0]);i++) -+ zones_size[i] = 0; -+ zones_size[0] = (end_iomem >> PAGE_SHIFT) - (uml_physmem >> PAGE_SHIFT); -+ zones_size[2] = highmem >> PAGE_SHIFT; -+ free_area_init(zones_size); -+ -+ /* -+ * Fixed mappings, only the page table structure has to be -+ * created - mappings will be set by set_fixmap(): -+ */ -+ vaddr = __fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK; -+ fixrange_init(vaddr, FIXADDR_TOP, swapper_pg_dir); -+ -+#if CONFIG_HIGHMEM -+ init_highmem(); -+#endif -+} -+ -+struct page *arch_validate(struct page *page, int mask, int order) -+{ -+ unsigned long addr, zero = 0; -+ int i; -+ -+ again: -+ if(page == NULL) return(page); -+ if(PageHighMem(page)) return(page); -+ -+ addr = (unsigned long) page_address(page); -+ for(i = 0; i < (1 << order); i++){ -+ current->thread.fault_addr = (void *) addr; -+ if(__do_copy_to_user((void *) addr, &zero, -+ sizeof(zero), -+ ¤t->thread.fault_addr, -+ ¤t->thread.fault_catcher)){ -+ if(!(mask & __GFP_WAIT)) return(NULL); -+ else break; -+ } -+ addr += PAGE_SIZE; -+ } -+ if(i == (1 << order)) return(page); -+ page = _alloc_pages(mask, order); -+ goto again; -+} -+ -+/* This can't do anything because nothing in the kernel image can be freed -+ * since it's not in kernel physical memory. -+ */ -+ -+void free_initmem(void) -+{ -+} -+ -+#ifdef CONFIG_BLK_DEV_INITRD -+ -+void free_initrd_mem(unsigned long start, unsigned long end) -+{ -+ if (start < end) -+ printk ("Freeing initrd memory: %ldk freed\n", -+ (end - start) >> 10); -+ for (; start < end; start += PAGE_SIZE) { -+ ClearPageReserved(virt_to_page(start)); -+ set_page_count(virt_to_page(start), 1); -+ free_page(start); -+ totalram_pages++; -+ } -+} -+ -+#endif -+ -+int do_check_pgt_cache(int low, int high) -+{ -+ int freed = 0; -+ if(pgtable_cache_size > high) { -+ do { -+ if (pgd_quicklist) { -+ free_pgd_slow(get_pgd_fast()); -+ freed++; -+ } -+ if (pmd_quicklist) { -+ pmd_free_slow(pmd_alloc_one_fast(NULL, 0)); -+ freed++; -+ } -+ if (pte_quicklist) { -+ pte_free_slow(pte_alloc_one_fast(NULL, 0)); -+ freed++; -+ } -+ } while(pgtable_cache_size > low); -+ } -+ return freed; -+} -+ -+void show_mem(void) -+{ -+ int i, total = 0, reserved = 0; -+ int shared = 0, cached = 0; -+ int highmem = 0; -+ -+ printk("Mem-info:\n"); -+ show_free_areas(); -+ printk("Free swap: %6dkB\n", nr_swap_pages<<(PAGE_SHIFT-10)); -+ i = max_mapnr; -+ while(i-- > 0) { -+ total++; -+ if(PageHighMem(mem_map + i)) -+ highmem++; -+ if(PageReserved(mem_map + i)) -+ reserved++; -+ else if(PageSwapCache(mem_map + i)) -+ cached++; -+ else if(page_count(mem_map + i)) -+ shared += page_count(mem_map + i) - 1; -+ } -+ printk("%d pages of RAM\n", total); -+ printk("%d pages of HIGHMEM\n", highmem); -+ printk("%d reserved pages\n", reserved); -+ printk("%d pages shared\n", shared); -+ printk("%d pages swap cached\n", cached); -+ printk("%ld pages in page table cache\n", pgtable_cache_size); -+ show_buffers(); -+} -+ -+/* Changed by meminfo_compat, which is a setup */ -+static int meminfo_22 = 0; -+ -+static int meminfo_compat(char *str) -+{ -+ meminfo_22 = 1; -+ return(1); -+} -+ -+__setup("22_meminfo", meminfo_compat); -+ -+void si_meminfo(struct sysinfo *val) -+{ -+ val->totalram = totalram_pages; -+ val->sharedram = 0; -+ val->freeram = nr_free_pages(); -+ val->bufferram = atomic_read(&buffermem_pages); -+ val->totalhigh = highmem >> PAGE_SHIFT; -+ val->freehigh = nr_free_highpages(); -+ val->mem_unit = PAGE_SIZE; -+ if(meminfo_22){ -+ val->freeram <<= PAGE_SHIFT; -+ val->bufferram <<= PAGE_SHIFT; -+ val->totalram <<= PAGE_SHIFT; -+ val->sharedram <<= PAGE_SHIFT; -+ } -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/mem_user.c um/arch/um/kernel/mem_user.c ---- orig/arch/um/kernel/mem_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/mem_user.c 2004-01-10 00:19:09.000000000 -0500 -@@ -0,0 +1,216 @@ -+/* -+ * arch/um/kernel/mem_user.c -+ * -+ * BRIEF MODULE DESCRIPTION -+ * user side memory routines for supporting IO memory inside user mode linux -+ * -+ * Copyright (C) 2001 RidgeRun, Inc. -+ * Author: RidgeRun, Inc. -+ * Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com -+ * -+ * This program is free software; you can redistribute it and/or modify it -+ * under the terms of the GNU General Public License as published by the -+ * Free Software Foundation; either version 2 of the License, or (at your -+ * option) any later version. -+ * -+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED -+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN -+ * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, -+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 675 Mass Ave, Cambridge, MA 02139, USA. -+ */ -+ -+#include <stdio.h> -+#include <stdlib.h> -+#include <stddef.h> -+#include <stdarg.h> -+#include <unistd.h> -+#include <errno.h> -+#include <string.h> -+#include <fcntl.h> -+#include <sys/types.h> -+#include <sys/mman.h> -+#include "kern_util.h" -+#include "user.h" -+#include "user_util.h" -+#include "mem_user.h" -+#include "init.h" -+#include "os.h" -+#include "tempfile.h" -+#include "kern_constants.h" -+ -+extern struct mem_region physmem_region; -+ -+#define TEMPNAME_TEMPLATE "vm_file-XXXXXX" -+ -+static int create_tmp_file(unsigned long len) -+{ -+ int fd, err; -+ char zero; -+ -+ fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1); -+ if(fd < 0) { -+ os_print_error(fd, "make_tempfile"); -+ exit(1); -+ } -+ -+ err = os_mode_fd(fd, 0777); -+ if(err < 0){ -+ os_print_error(err, "os_mode_fd"); -+ exit(1); -+ } -+ err = os_seek_file(fd, len); -+ if(err < 0){ -+ os_print_error(err, "os_seek_file"); -+ exit(1); -+ } -+ zero = 0; -+ err = os_write_file(fd, &zero, 1); -+ if(err != 1){ -+ os_print_error(err, "os_write_file"); -+ exit(1); -+ } -+ -+ return(fd); -+} -+ -+static int have_devanon(void) -+{ -+ int fd; -+ -+ printk("Checking for /dev/anon on the host..."); -+ fd = open("/dev/anon", O_RDWR); -+ if(fd < 0){ -+ printk("Not available (open failed with errno %d)\n", errno); -+ return(0); -+ } -+ -+ printk("OK\n"); -+ return(1); -+} -+ -+static int create_anon_file(unsigned long len) -+{ -+ void *addr; -+ int fd; -+ -+ fd = open("/dev/anon", O_RDWR); -+ if(fd < 0) { -+ os_print_error(fd, "opening /dev/anon"); -+ exit(1); -+ } -+ -+ addr = mmap(NULL, len, PROT_READ | PROT_WRITE , MAP_PRIVATE, fd, 0); -+ if(addr == MAP_FAILED){ -+ os_print_error((int) addr, "mapping physmem file"); -+ exit(1); -+ } -+ munmap(addr, len); -+ -+ return(fd); -+} -+ -+int create_mem_file(unsigned long len) -+{ -+ int err, fd; -+ -+ if(have_devanon()) -+ fd = create_anon_file(len); -+ else fd = create_tmp_file(len); -+ -+ err = os_set_exec_close(fd, 1); -+ if(err < 0) -+ os_print_error(err, "exec_close"); -+ return(fd); -+} -+ -+struct iomem_region *iomem_regions = NULL; -+int iomem_size = 0; -+ -+static int __init parse_iomem(char *str, int *add) -+{ -+ struct iomem_region *new; -+ struct uml_stat buf; -+ char *file, *driver; -+ int fd, err; -+ -+ driver = str; -+ file = strchr(str,','); -+ if(file == NULL){ -+ printf("parse_iomem : failed to parse iomem\n"); -+ goto out; -+ } -+ *file = '\0'; -+ file++; -+ fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0); -+ if(fd < 0){ -+ os_print_error(fd, "parse_iomem - Couldn't open io file"); -+ goto out; -+ } -+ -+ err = os_stat_fd(fd, &buf); -+ if(err < 0){ -+ os_print_error(err, "parse_iomem - cannot stat_fd file"); -+ goto out_close; -+ } -+ -+ new = malloc(sizeof(*new)); -+ if(new == NULL){ -+ perror("Couldn't allocate iomem_region struct"); -+ goto out_close; -+ } -+ -+ *new = ((struct iomem_region) { .next = iomem_regions, -+ .driver = driver, -+ .fd = fd, -+ .size = buf.ust_size, -+ .phys = 0, -+ .virt = 0 }); -+ iomem_regions = new; -+ iomem_size += new->size + UM_KERN_PAGE_SIZE; -+ -+ return(0); -+ out_close: -+ os_close_file(fd); -+ out: -+ return(1); -+} -+ -+__uml_setup("iomem=", parse_iomem, -+"iomem=<name>,<file>\n" -+" Configure <file> as an IO memory region named <name>.\n\n" -+); -+ -+int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x, -+ int must_succeed) -+{ -+ int err; -+ -+ err = os_protect_memory((void *) addr, len, r, w, x); -+ if(err < 0){ -+ if(must_succeed) -+ panic("protect failed, err = %d", -err); -+ else return(err); -+ } -+ return(0); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/mprot.h um/arch/um/kernel/mprot.h ---- orig/arch/um/kernel/mprot.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/mprot.h 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __MPROT_H__ -+#define __MPROT_H__ -+ -+extern void no_access(unsigned long addr, unsigned int len); -+ -+#endif -diff -Naur -X ../exclude-files orig/arch/um/kernel/physmem.c um/arch/um/kernel/physmem.c ---- orig/arch/um/kernel/physmem.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/physmem.c 2004-01-16 23:38:02.000000000 -0500 -@@ -0,0 +1,446 @@ -+/* -+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/mm.h" -+#include "linux/ghash.h" -+#include "linux/slab.h" -+#include "linux/vmalloc.h" -+#include "linux/bootmem.h" -+#include "asm/types.h" -+#include "asm/pgtable.h" -+#include "kern_util.h" -+#include "user_util.h" -+#include "mode_kern.h" -+#include "mem.h" -+#include "mem_user.h" -+#include "os.h" -+#include "kern.h" -+#include "init.h" -+ -+#define PHYS_HASHSIZE (8192) -+ -+struct phys_desc; -+ -+DEF_HASH_STRUCTS(virtmem, PHYS_HASHSIZE, struct phys_desc); -+ -+struct phys_desc { -+ struct virtmem_ptrs virt_ptrs; -+ int fd; -+ __u64 offset; -+ void *virt; -+ unsigned long phys; -+ struct list_head list; -+}; -+ -+struct virtmem_table virtmem_hash; -+ -+static int virt_cmp(void *virt1, void *virt2) -+{ -+ return(virt1 != virt2); -+} -+ -+static int virt_hash(void *virt) -+{ -+ unsigned long addr = ((unsigned long) virt) >> PAGE_SHIFT; -+ return(addr % PHYS_HASHSIZE); -+} -+ -+DEF_HASH(static, virtmem, struct phys_desc, virt_ptrs, void *, virt, virt_cmp, -+ virt_hash); -+ -+LIST_HEAD(descriptor_mappings); -+ -+struct desc_mapping { -+ int fd; -+ struct list_head list; -+ struct list_head pages; -+}; -+ -+static struct desc_mapping *find_mapping(int fd) -+{ -+ struct desc_mapping *desc; -+ struct list_head *ele; -+ -+ list_for_each(ele, &descriptor_mappings){ -+ desc = list_entry(ele, struct desc_mapping, list); -+ if(desc->fd == fd) -+ return(desc); -+ } -+ -+ return(NULL); -+} -+ -+static struct desc_mapping *descriptor_mapping(int fd) -+{ -+ struct desc_mapping *desc; -+ -+ desc = find_mapping(fd); -+ if(desc != NULL) -+ return(desc); -+ -+ desc = kmalloc(sizeof(*desc), GFP_ATOMIC); -+ if(desc == NULL) -+ return(NULL); -+ -+ *desc = ((struct desc_mapping) -+ { .fd = fd, -+ .list = LIST_HEAD_INIT(desc->list), -+ .pages = LIST_HEAD_INIT(desc->pages) }); -+ list_add(&desc->list, &descriptor_mappings); -+ -+ return(desc); -+} -+ -+int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w) -+{ -+ struct desc_mapping *fd_maps; -+ struct phys_desc *desc; -+ unsigned long phys; -+ int err; -+ -+ fd_maps = descriptor_mapping(fd); -+ if(fd_maps == NULL) -+ return(-ENOMEM); -+ -+ phys = __pa(virt); -+ if(find_virtmem_hash(&virtmem_hash, virt) != NULL) -+ panic("Address 0x%p is already substituted\n", virt); -+ -+ err = -ENOMEM; -+ desc = kmalloc(sizeof(*desc), GFP_ATOMIC); -+ if(desc == NULL) -+ goto out; -+ -+ *desc = ((struct phys_desc) -+ { .virt_ptrs = { NULL, NULL }, -+ .fd = fd, -+ .offset = offset, -+ .virt = virt, -+ .phys = __pa(virt), -+ .list = LIST_HEAD_INIT(desc->list) }); -+ insert_virtmem_hash(&virtmem_hash, desc); -+ -+ list_add(&desc->list, &fd_maps->pages); -+ -+ virt = (void *) ((unsigned long) virt & PAGE_MASK); -+ err = os_map_memory(virt, fd, offset, PAGE_SIZE, 1, w, 0); -+ if(!err) -+ goto out; -+ -+ remove_virtmem_hash(&virtmem_hash, desc); -+ kfree(desc); -+ out: -+ return(err); -+} -+ -+static int physmem_fd = -1; -+ -+static void remove_mapping(struct phys_desc *desc) -+{ -+ void *virt = desc->virt; -+ int err; -+ -+ remove_virtmem_hash(&virtmem_hash, desc); -+ list_del(&desc->list); -+ kfree(desc); -+ -+ err = os_map_memory(virt, physmem_fd, __pa(virt), PAGE_SIZE, 1, 1, 0); -+ if(err) -+ panic("Failed to unmap block device page from physical memory, " -+ "errno = %d", -err); -+} -+ -+int physmem_remove_mapping(void *virt) -+{ -+ struct phys_desc *desc; -+ -+ virt = (void *) ((unsigned long) virt & PAGE_MASK); -+ desc = find_virtmem_hash(&virtmem_hash, virt); -+ if(desc == NULL) -+ return(0); -+ -+ remove_mapping(desc); -+ return(1); -+} -+ -+void physmem_forget_descriptor(int fd) -+{ -+ struct desc_mapping *desc; -+ struct phys_desc *page; -+ struct list_head *ele, *next; -+ __u64 offset; -+ void *addr; -+ int err; -+ -+ desc = find_mapping(fd); -+ if(desc == NULL) -+ return; -+ -+ list_for_each_safe(ele, next, &desc->pages){ -+ page = list_entry(ele, struct phys_desc, list); -+ offset = page->offset; -+ addr = page->virt; -+ remove_mapping(page); -+ err = os_seek_file(fd, offset); -+ if(err) -+ panic("physmem_forget_descriptor - failed to seek " -+ "to %lld in fd %d, error = %d\n", -+ offset, fd, -err); -+ err = os_read_file(fd, addr, PAGE_SIZE); -+ if(err < 0) -+ panic("physmem_forget_descriptor - failed to read " -+ "from fd %d to 0x%p, error = %d\n", -+ fd, addr, -err); -+ } -+ -+ list_del(&desc->list); -+ kfree(desc); -+} -+ -+void arch_free_page(struct page *page, int order) -+{ -+ void *virt; -+ int i; -+ -+ for(i = 0; i < (1 << order); i++){ -+ virt = __va(page_to_phys(page + i)); -+ physmem_remove_mapping(virt); -+ } -+} -+ -+int is_remapped(void *virt) -+{ -+ return(find_virtmem_hash(&virtmem_hash, virt) != NULL); -+} -+ -+/* Changed during early boot */ -+unsigned long high_physmem; -+ -+extern unsigned long physmem_size; -+ -+void *to_virt(unsigned long phys) -+{ -+ return((void *) uml_physmem + phys); -+} -+ -+unsigned long to_phys(void *virt) -+{ -+ return(((unsigned long) virt) - uml_physmem); -+} -+ -+int init_maps(unsigned long physmem, unsigned long iomem, unsigned long highmem) -+{ -+ struct page *p, *map; -+ unsigned long phys_len, phys_pages, highmem_len, highmem_pages; -+ unsigned long iomem_len, iomem_pages, total_len, total_pages; -+ int i; -+ -+ phys_pages = physmem >> PAGE_SHIFT; -+ phys_len = phys_pages * sizeof(struct page); -+ -+ iomem_pages = iomem >> PAGE_SHIFT; -+ iomem_len = iomem_pages * sizeof(struct page); -+ -+ highmem_pages = highmem >> PAGE_SHIFT; -+ highmem_len = highmem_pages * sizeof(struct page); -+ -+ total_pages = phys_pages + iomem_pages + highmem_pages; -+ total_len = phys_len + iomem_pages + highmem_len; -+ -+ if(kmalloc_ok){ -+ map = kmalloc(total_len, GFP_KERNEL); -+ if(map == NULL) -+ map = vmalloc(total_len); -+ } -+ else map = alloc_bootmem_low_pages(total_len); -+ -+ if(map == NULL) -+ return(-ENOMEM); -+ -+ for(i = 0; i < total_pages; i++){ -+ p = &map[i]; -+ set_page_count(p, 0); -+ SetPageReserved(p); -+ INIT_LIST_HEAD(&p->list); -+ } -+ -+ mem_map = map; -+ max_mapnr = total_pages; -+ return(0); -+} -+ -+struct page *phys_to_page(const unsigned long phys) -+{ -+ return(&mem_map[phys >> PAGE_SHIFT]); -+} -+ -+struct page *__virt_to_page(const unsigned long virt) -+{ -+ return(&mem_map[__pa(virt) >> PAGE_SHIFT]); -+} -+ -+unsigned long page_to_phys(struct page *page) -+{ -+ return((page - mem_map) << PAGE_SHIFT); -+} -+ -+pte_t mk_pte(struct page *page, pgprot_t pgprot) -+{ -+ pte_t pte; -+ -+ pte_val(pte) = page_to_phys(page) + pgprot_val(pgprot); -+ if(pte_present(pte)) pte_mknewprot(pte_mknewpage(pte)); -+ return(pte); -+} -+ -+/* Changed during early boot */ -+static unsigned long kmem_top = 0; -+ -+unsigned long get_kmem_end(void) -+{ -+ if(kmem_top == 0) -+ kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas); -+ return(kmem_top); -+} -+ -+void map_memory(unsigned long virt, unsigned long phys, unsigned long len, -+ int r, int w, int x) -+{ -+ __u64 offset; -+ int fd, err; -+ -+ fd = phys_mapping(phys, &offset); -+ err = os_map_memory((void *) virt, fd, offset, len, r, w, x); -+ if(err) -+ panic("map_memory(0x%lx, %d, 0x%llx, %ld, %d, %d, %d) failed, " -+ "err = %d\n", virt, fd, offset, len, r, w, x, err); -+} -+ -+#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT) -+ -+void setup_physmem(unsigned long start, unsigned long reserve_end, -+ unsigned long len, unsigned long highmem) -+{ -+ unsigned long reserve = reserve_end - start; -+ int pfn = PFN_UP(__pa(reserve_end)); -+ int delta = (len - reserve) >> PAGE_SHIFT; -+ int err, offset, bootmap_size; -+ -+ physmem_fd = create_mem_file(len + highmem); -+ -+ offset = uml_reserved - uml_physmem; -+ err = os_map_memory((void *) uml_reserved, physmem_fd, offset, -+ len - offset, 1, 1, 0); -+ if(err < 0){ -+ os_print_error(err, "Mapping memory"); -+ exit(1); -+ } -+ -+ bootmap_size = init_bootmem(pfn, pfn + delta); -+ free_bootmem(__pa(reserve_end) + bootmap_size, -+ len - bootmap_size - reserve); -+} -+ -+int phys_mapping(unsigned long phys, __u64 *offset_out) -+{ -+ struct phys_desc *desc = find_virtmem_hash(&virtmem_hash, -+ __va(phys & PAGE_MASK)); -+ int fd = -1; -+ -+ if(desc != NULL){ -+ fd = desc->fd; -+ *offset_out = desc->offset; -+ } -+ else if(phys < physmem_size){ -+ fd = physmem_fd; -+ *offset_out = phys; -+ } -+ else if(phys < __pa(end_iomem)){ -+ struct iomem_region *region = iomem_regions; -+ -+ while(region != NULL){ -+ if((phys >= region->phys) && -+ (phys < region->phys + region->size)){ -+ fd = region->fd; -+ *offset_out = phys - region->phys; -+ break; -+ } -+ region = region->next; -+ } -+ } -+ else if(phys < __pa(end_iomem) + highmem){ -+ fd = physmem_fd; -+ *offset_out = phys - iomem_size; -+ } -+ -+ return(fd); -+} -+ -+static int __init uml_mem_setup(char *line, int *add) -+{ -+ char *retptr; -+ physmem_size = memparse(line,&retptr); -+ return 0; -+} -+__uml_setup("mem=", uml_mem_setup, -+"mem=<Amount of desired ram>\n" -+" This controls how much \"physical\" memory the kernel allocates\n" -+" for the system. The size is specified as a number followed by\n" -+" one of 'k', 'K', 'm', 'M', which have the obvious meanings.\n" -+" This is not related to the amount of memory in the host. It can\n" -+" be more, and the excess, if it's ever used, will just be swapped out.\n" -+" Example: mem=64M\n\n" -+); -+ -+unsigned long find_iomem(char *driver, unsigned long *len_out) -+{ -+ struct iomem_region *region = iomem_regions; -+ -+ while(region != NULL){ -+ if(!strcmp(region->driver, driver)){ -+ *len_out = region->size; -+ return(region->virt); -+ } -+ } -+ -+ return(0); -+} -+ -+int setup_iomem(void) -+{ -+ struct iomem_region *region = iomem_regions; -+ unsigned long iomem_start = high_physmem + PAGE_SIZE; -+ int err; -+ -+ while(region != NULL){ -+ err = os_map_memory((void *) iomem_start, region->fd, 0, -+ region->size, 1, 1, 0); -+ if(err) -+ printk("Mapping iomem region for driver '%s' failed, " -+ "errno = %d\n", region->driver, -err); -+ else { -+ region->virt = iomem_start; -+ region->phys = __pa(region->virt); -+ } -+ -+ iomem_start += region->size + PAGE_SIZE; -+ region = region->next; -+ } -+ -+ return(0); -+} -+ -+__initcall(setup_iomem); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/process.c um/arch/um/kernel/process.c ---- orig/arch/um/kernel/process.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/process.c 2004-01-31 02:47:57.000000000 -0500 -@@ -0,0 +1,289 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <stdio.h> -+#include <unistd.h> -+#include <signal.h> -+#include <sched.h> -+#include <errno.h> -+#include <stdarg.h> -+#include <stdlib.h> -+#include <setjmp.h> -+#include <sys/time.h> -+#include <sys/ptrace.h> -+#include <sys/wait.h> -+#include <sys/mman.h> -+#include <asm/ptrace.h> -+#include <asm/sigcontext.h> -+#include <asm/unistd.h> -+#include <asm/page.h> -+#include "user_util.h" -+#include "kern_util.h" -+#include "user.h" -+#include "process.h" -+#include "signal_kern.h" -+#include "signal_user.h" -+#include "sysdep/ptrace.h" -+#include "sysdep/sigcontext.h" -+#include "irq_user.h" -+#include "ptrace_user.h" -+#include "time_user.h" -+#include "init.h" -+#include "os.h" -+#include "uml-config.h" -+#include "choose-mode.h" -+#include "mode.h" -+#ifdef UML_CONFIG_MODE_SKAS -+#include "skas.h" -+#include "skas_ptrace.h" -+#endif -+ -+void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int)) -+{ -+ int flags = 0, pages; -+ -+ if(sig_stack != NULL){ -+ pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2; -+ set_sigstack(sig_stack, pages * page_size()); -+ flags = SA_ONSTACK; -+ } -+ if(usr1_handler) set_handler(SIGUSR1, usr1_handler, flags, -1); -+} -+ -+void init_new_thread_signals(int altstack) -+{ -+ int flags = altstack ? SA_ONSTACK : 0; -+ -+ /* NODEFER is set here because SEGV isn't turned back on when the -+ * handler is ready to receive signals. This causes any segfault -+ * during a copy_user to kill the process because the fault is blocked. -+ */ -+ set_handler(SIGSEGV, (__sighandler_t) sig_handler, flags | SA_NODEFER, -+ SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); -+ set_handler(SIGTRAP, (__sighandler_t) sig_handler, flags, -+ SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); -+ set_handler(SIGFPE, (__sighandler_t) sig_handler, flags, -+ SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); -+ set_handler(SIGILL, (__sighandler_t) sig_handler, flags, -+ SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); -+ set_handler(SIGBUS, (__sighandler_t) sig_handler, flags, -+ SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); -+ set_handler(SIGWINCH, (__sighandler_t) sig_handler, flags, -+ SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); -+ set_handler(SIGUSR2, (__sighandler_t) sig_handler, -+ SA_NOMASK | flags, -1); -+ signal(SIGHUP, SIG_IGN); -+ -+ init_irq_signals(altstack); -+} -+ -+struct tramp { -+ int (*tramp)(void *); -+ void *tramp_data; -+ unsigned long temp_stack; -+ int flags; -+ int pid; -+}; -+ -+/* See above for why sigkill is here */ -+ -+int sigkill = SIGKILL; -+ -+int outer_tramp(void *arg) -+{ -+ struct tramp *t; -+ int sig = sigkill; -+ -+ t = arg; -+ t->pid = clone(t->tramp, (void *) t->temp_stack + page_size()/2, -+ t->flags, t->tramp_data); -+ if(t->pid > 0) wait_for_stop(t->pid, SIGSTOP, PTRACE_CONT, NULL); -+ kill(os_getpid(), sig); -+ _exit(0); -+} -+ -+int start_fork_tramp(void *thread_arg, unsigned long temp_stack, -+ int clone_flags, int (*tramp)(void *)) -+{ -+ struct tramp arg; -+ unsigned long sp; -+ int new_pid, status, err; -+ -+ /* The trampoline will run on the temporary stack */ -+ sp = stack_sp(temp_stack); -+ -+ clone_flags |= CLONE_FILES | SIGCHLD; -+ -+ arg.tramp = tramp; -+ arg.tramp_data = thread_arg; -+ arg.temp_stack = temp_stack; -+ arg.flags = clone_flags; -+ -+ /* Start the process and wait for it to kill itself */ -+ new_pid = clone(outer_tramp, (void *) sp, clone_flags, &arg); -+ if(new_pid < 0) return(-errno); -+ while(((err = waitpid(new_pid, &status, 0)) < 0) && (errno == EINTR)) ; -+ if(err < 0) panic("Waiting for outer trampoline failed - errno = %d", -+ errno); -+ if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL)) -+ panic("outer trampoline didn't exit with SIGKILL, " -+ "status = %d", status); -+ -+ return(arg.pid); -+} -+ -+void suspend_new_thread(int fd) -+{ -+ char c; -+ -+ os_stop_process(os_getpid()); -+ -+ if(os_read_file(fd, &c, sizeof(c)) != sizeof(c)) -+ panic("read failed in suspend_new_thread"); -+} -+ -+static int ptrace_child(void *arg) -+{ -+ int pid = os_getpid(); -+ -+ if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){ -+ perror("ptrace"); -+ os_kill_process(pid, 0); -+ } -+ os_stop_process(pid); -+ _exit(os_getpid() == pid); -+} -+ -+static int start_ptraced_child(void **stack_out) -+{ -+ void *stack; -+ unsigned long sp; -+ int pid, n, status; -+ -+ stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, -+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); -+ if(stack == MAP_FAILED) -+ panic("check_ptrace : mmap failed, errno = %d", errno); -+ sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *); -+ pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL); -+ if(pid < 0) -+ panic("check_ptrace : clone failed, errno = %d", errno); -+ n = waitpid(pid, &status, WUNTRACED); -+ if(n < 0) -+ panic("check_ptrace : wait failed, errno = %d", errno); -+ if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) -+ panic("check_ptrace : expected SIGSTOP, got status = %d", -+ status); -+ -+ *stack_out = stack; -+ return(pid); -+} -+ -+static void stop_ptraced_child(int pid, void *stack, int exitcode) -+{ -+ int status, n; -+ -+ if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) -+ panic("check_ptrace : ptrace failed, errno = %d", errno); -+ n = waitpid(pid, &status, 0); -+ if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) -+ panic("check_ptrace : child exited with status 0x%x", status); -+ -+ if(munmap(stack, PAGE_SIZE) < 0) -+ panic("check_ptrace : munmap failed, errno = %d", errno); -+} -+ -+void __init check_ptrace(void) -+{ -+ void *stack; -+ int pid, syscall, n, status; -+ -+ printk("Checking that ptrace can change system call numbers..."); -+ pid = start_ptraced_child(&stack); -+ -+ while(1){ -+ if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) -+ panic("check_ptrace : ptrace failed, errno = %d", -+ errno); -+ n = waitpid(pid, &status, WUNTRACED); -+ if(n < 0) -+ panic("check_ptrace : wait failed, errno = %d", errno); -+ if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) -+ panic("check_ptrace : expected SIGTRAP, " -+ "got status = %d", status); -+ -+ syscall = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_NR_OFFSET, -+ 0); -+ if(syscall == __NR_getpid){ -+ n = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, -+ __NR_getppid); -+ if(n < 0) -+ panic("check_ptrace : failed to modify system " -+ "call, errno = %d", errno); -+ break; -+ } -+ } -+ stop_ptraced_child(pid, stack, 0); -+ printk("OK\n"); -+} -+ -+int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) -+{ -+ sigjmp_buf buf; -+ int n; -+ -+ *jmp_ptr = &buf; -+ n = sigsetjmp(buf, 1); -+ if(n != 0) -+ return(n); -+ (*fn)(arg); -+ return(0); -+} -+ -+int can_do_skas(void) -+{ -+#ifdef UML_CONFIG_MODE_SKAS -+ struct ptrace_faultinfo fi; -+ void *stack; -+ int pid, n, ret = 1; -+ -+ printf("Checking for the skas3 patch in the host..."); -+ pid = start_ptraced_child(&stack); -+ -+ n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); -+ if(n < 0){ -+ if(errno == EIO) -+ printf("not found\n"); -+ else printf("No (unexpected errno - %d)\n", errno); -+ ret = 0; -+ } -+ else printf("found\n"); -+ -+ init_registers(pid); -+ stop_ptraced_child(pid, stack, 1); -+ -+ printf("Checking for /proc/mm..."); -+ if(os_access("/proc/mm", OS_ACC_W_OK) < 0){ -+ printf("not found\n"); -+ ret = 0; -+ } -+ else printf("found\n"); -+ -+ return(ret); -+#else -+ return(0); -+#endif -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/process_kern.c um/arch/um/kernel/process_kern.c ---- orig/arch/um/kernel/process_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/process_kern.c 2003-11-08 08:37:04.000000000 -0500 -@@ -0,0 +1,396 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/config.h" -+#include "linux/kernel.h" -+#include "linux/sched.h" -+#include "linux/interrupt.h" -+#include "linux/mm.h" -+#include "linux/slab.h" -+#include "linux/utsname.h" -+#include "linux/fs.h" -+#include "linux/utime.h" -+#include "linux/smp_lock.h" -+#include "linux/module.h" -+#include "linux/init.h" -+#include "linux/capability.h" -+#include "asm/unistd.h" -+#include "asm/mman.h" -+#include "asm/segment.h" -+#include "asm/stat.h" -+#include "asm/pgtable.h" -+#include "asm/processor.h" -+#include "asm/pgalloc.h" -+#include "asm/spinlock.h" -+#include "asm/uaccess.h" -+#include "asm/user.h" -+#include "user_util.h" -+#include "kern_util.h" -+#include "kern.h" -+#include "signal_kern.h" -+#include "signal_user.h" -+#include "init.h" -+#include "irq_user.h" -+#include "mem_user.h" -+#include "time_user.h" -+#include "tlb.h" -+#include "frame_kern.h" -+#include "sigcontext.h" -+#include "2_5compat.h" -+#include "os.h" -+#include "mode.h" -+#include "mode_kern.h" -+#include "choose-mode.h" -+ -+/* This is a per-cpu array. A processor only modifies its entry and it only -+ * cares about its entry, so it's OK if another processor is modifying its -+ * entry. -+ */ -+struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } }; -+ -+struct task_struct *get_task(int pid, int require) -+{ -+ struct task_struct *ret; -+ -+ read_lock(&tasklist_lock); -+ ret = find_task_by_pid(pid); -+ read_unlock(&tasklist_lock); -+ -+ if(require && (ret == NULL)) panic("get_task couldn't find a task\n"); -+ return(ret); -+} -+ -+int external_pid(void *t) -+{ -+ struct task_struct *task = t ? t : current; -+ -+ return(CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task)); -+} -+ -+int pid_to_processor_id(int pid) -+{ -+ int i; -+ -+ for(i = 0; i < smp_num_cpus; i++){ -+ if(cpu_tasks[i].pid == pid) return(i); -+ } -+ return(-1); -+} -+ -+void free_stack(unsigned long stack, int order) -+{ -+ free_pages(stack, order); -+} -+ -+unsigned long alloc_stack(int order, int atomic) -+{ -+ unsigned long page; -+ int flags = GFP_KERNEL; -+ -+ if(atomic) flags |= GFP_ATOMIC; -+ page = __get_free_pages(flags, order); -+ if(page == 0) -+ return(0); -+ stack_protections(page); -+ return(page); -+} -+ -+int arch_kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) -+{ -+ int pid; -+ -+ current->thread.request.u.thread.proc = fn; -+ current->thread.request.u.thread.arg = arg; -+ pid = do_fork(CLONE_VM | flags, 0, NULL, 0); -+#if 0 /* CLONE_UNTRACED for 2.6 */ -+ pid = do_fork(CLONE_VM | CLONE_UNTRACED | flags, 0, NULL, 0); -+#endif -+ if(pid < 0) -+ panic("do_fork failed in kernel_thread, errno = %d", pid); -+ return(pid); -+} -+ -+void switch_mm(struct mm_struct *prev, struct mm_struct *next, -+ struct task_struct *tsk, unsigned cpu) -+{ -+ if (prev != next) -+ clear_bit(cpu, &prev->cpu_vm_mask); -+ set_bit(cpu, &next->cpu_vm_mask); -+} -+ -+void set_current(void *t) -+{ -+ struct task_struct *task = t; -+ -+ cpu_tasks[task->processor] = ((struct cpu_task) -+ { external_pid(task), task }); -+} -+ -+void *_switch_to(void *prev, void *next) -+{ -+ return(CHOOSE_MODE(_switch_to_tt(prev, next), -+ _switch_to_skas(prev, next))); -+} -+ -+void interrupt_end(void) -+{ -+ if(current->need_resched) schedule(); -+ if(current->sigpending != 0) do_signal(0); -+} -+ -+void release_thread(struct task_struct *task) -+{ -+ CHOOSE_MODE(release_thread_tt(task), release_thread_skas(task)); -+} -+ -+void exit_thread(void) -+{ -+ CHOOSE_MODE(exit_thread_tt(), exit_thread_skas()); -+ unprotect_stack((unsigned long) current); -+} -+ -+void *get_current(void) -+{ -+ return(current); -+} -+ -+int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, -+ unsigned long stack_top, struct task_struct * p, -+ struct pt_regs *regs) -+{ -+ p->thread = (struct thread_struct) INIT_THREAD; -+ p->thread.kernel_stack = (unsigned long) p + 2 * PAGE_SIZE; -+ -+ return(CHOOSE_MODE_PROC(copy_thread_tt, copy_thread_skas, nr, -+ clone_flags, sp, stack_top, p, regs)); -+} -+ -+void initial_thread_cb(void (*proc)(void *), void *arg) -+{ -+ int save_kmalloc_ok = kmalloc_ok; -+ -+ kmalloc_ok = 0; -+ CHOOSE_MODE_PROC(initial_thread_cb_tt, initial_thread_cb_skas, proc, -+ arg); -+ kmalloc_ok = save_kmalloc_ok; -+} -+ -+unsigned long stack_sp(unsigned long page) -+{ -+ return(page + PAGE_SIZE - sizeof(void *)); -+} -+ -+int current_pid(void) -+{ -+ return(current->pid); -+} -+ -+void cpu_idle(void) -+{ -+ CHOOSE_MODE(init_idle_tt(), init_idle_skas()); -+ -+ atomic_inc(&init_mm.mm_count); -+ current->mm = &init_mm; -+ current->active_mm = &init_mm; -+ -+ while(1){ -+ /* endless idle loop with no priority at all */ -+ SET_PRI(current); -+ -+ /* -+ * although we are an idle CPU, we do not want to -+ * get into the scheduler unnecessarily. -+ */ -+ if (current->need_resched) { -+ schedule(); -+ check_pgt_cache(); -+ } -+ idle_sleep(10); -+ } -+} -+ -+int page_size(void) -+{ -+ return(PAGE_SIZE); -+} -+ -+int page_mask(void) -+{ -+ return(PAGE_MASK); -+} -+ -+void *um_virt_to_phys(struct task_struct *task, unsigned long addr, -+ pte_t *pte_out) -+{ -+ pgd_t *pgd; -+ pmd_t *pmd; -+ pte_t *pte; -+ -+ if(task->mm == NULL) -+ return(ERR_PTR(-EINVAL)); -+ pgd = pgd_offset(task->mm, addr); -+ pmd = pmd_offset(pgd, addr); -+ if(!pmd_present(*pmd)) -+ return(ERR_PTR(-EINVAL)); -+ pte = pte_offset(pmd, addr); -+ if(!pte_present(*pte)) -+ return(ERR_PTR(-EINVAL)); -+ if(pte_out != NULL) -+ *pte_out = *pte; -+ return((void *) (pte_val(*pte) & PAGE_MASK) + (addr & ~PAGE_MASK)); -+} -+ -+char *current_cmd(void) -+{ -+#if defined(CONFIG_SMP) || defined(CONFIG_HIGHMEM) -+ return("(Unknown)"); -+#else -+ void *addr = um_virt_to_phys(current, current->mm->arg_start, NULL); -+ return IS_ERR(addr) ? "(Unknown)": __va((unsigned long) addr); -+#endif -+} -+ -+void force_sigbus(void) -+{ -+ printk(KERN_ERR "Killing pid %d because of a lack of memory\n", -+ current->pid); -+ lock_kernel(); -+ sigaddset(¤t->pending.signal, SIGBUS); -+ recalc_sigpending(current); -+ current->flags |= PF_SIGNALED; -+ do_exit(SIGBUS | 0x80); -+} -+ -+void dump_thread(struct pt_regs *regs, struct user *u) -+{ -+} -+ -+void enable_hlt(void) -+{ -+ panic("enable_hlt"); -+} -+ -+void disable_hlt(void) -+{ -+ panic("disable_hlt"); -+} -+ -+extern int signal_frame_size; -+ -+void *um_kmalloc(int size) -+{ -+ return(kmalloc(size, GFP_KERNEL)); -+} -+ -+void *um_kmalloc_atomic(int size) -+{ -+ return(kmalloc(size, GFP_ATOMIC)); -+} -+ -+unsigned long get_fault_addr(void) -+{ -+ return((unsigned long) current->thread.fault_addr); -+} -+ -+EXPORT_SYMBOL(get_fault_addr); -+ -+void not_implemented(void) -+{ -+ printk(KERN_DEBUG "Something isn't implemented in here\n"); -+} -+ -+EXPORT_SYMBOL(not_implemented); -+ -+int user_context(unsigned long sp) -+{ -+ unsigned long stack; -+ -+ stack = sp & (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER); -+ stack += 2 * PAGE_SIZE; -+ return(stack != current->thread.kernel_stack); -+} -+ -+extern void remove_umid_dir(void); -+ -+__uml_exitcall(remove_umid_dir); -+ -+extern exitcall_t __uml_exitcall_begin, __uml_exitcall_end; -+ -+void do_uml_exitcalls(void) -+{ -+ exitcall_t *call; -+ -+ call = &__uml_exitcall_end; -+ while (--call >= &__uml_exitcall_begin) -+ (*call)(); -+} -+ -+char *uml_strdup(char *string) -+{ -+ char *new; -+ -+ new = kmalloc(strlen(string) + 1, GFP_KERNEL); -+ if(new == NULL) return(NULL); -+ strcpy(new, string); -+ return(new); -+} -+ -+void *get_init_task(void) -+{ -+ return(&init_task_union.task); -+} -+ -+int copy_to_user_proc(void *to, void *from, int size) -+{ -+ return(copy_to_user(to, from, size)); -+} -+ -+int copy_from_user_proc(void *to, void *from, int size) -+{ -+ return(copy_from_user(to, from, size)); -+} -+ -+int clear_user_proc(void *buf, int size) -+{ -+ return(clear_user(buf, size)); -+} -+ -+int strlen_user_proc(char *str) -+{ -+ return(strlen_user(str)); -+} -+ -+int smp_sigio_handler(void) -+{ -+#ifdef CONFIG_SMP -+ int cpu = current->processor; -+ -+ IPI_handler(cpu); -+ if(cpu != 0) -+ return(1); -+#endif -+ return(0); -+} -+ -+int um_in_interrupt(void) -+{ -+ return(in_interrupt()); -+} -+ -+int cpu(void) -+{ -+ return(current->processor); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/ptrace.c um/arch/um/kernel/ptrace.c ---- orig/arch/um/kernel/ptrace.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/ptrace.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,325 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/sched.h" -+#include "linux/mm.h" -+#include "linux/errno.h" -+#include "linux/smp_lock.h" -+#ifdef CONFIG_PROC_MM -+#include "linux/proc_mm.h" -+#endif -+#include "asm/ptrace.h" -+#include "asm/uaccess.h" -+#include "kern_util.h" -+#include "ptrace_user.h" -+ -+/* -+ * Called by kernel/ptrace.c when detaching.. -+ */ -+void ptrace_disable(struct task_struct *child) -+{ -+} -+ -+extern long do_mmap2(struct task_struct *task, unsigned long addr, -+ unsigned long len, unsigned long prot, -+ unsigned long flags, unsigned long fd, -+ unsigned long pgoff); -+ -+int sys_ptrace(long request, long pid, long addr, long data) -+{ -+ struct task_struct *child; -+ int i, ret; -+ -+ lock_kernel(); -+ ret = -EPERM; -+ if (request == PTRACE_TRACEME) { -+ /* are we already being traced? */ -+ if (current->ptrace & PT_PTRACED) -+ goto out; -+ /* set the ptrace bit in the process flags. */ -+ current->ptrace |= PT_PTRACED; -+ ret = 0; -+ goto out; -+ } -+ ret = -ESRCH; -+ read_lock(&tasklist_lock); -+ child = find_task_by_pid(pid); -+ if (child) -+ get_task_struct(child); -+ read_unlock(&tasklist_lock); -+ if (!child) -+ goto out; -+ -+ ret = -EPERM; -+ if (pid == 1) /* you may not mess with init */ -+ goto out_tsk; -+ -+ if (request == PTRACE_ATTACH) { -+ ret = ptrace_attach(child); -+ goto out_tsk; -+ } -+ -+ ret = ptrace_check_attach(child, request == PTRACE_KILL); -+ if (ret < 0) -+ goto out_tsk; -+ -+ switch (request) { -+ /* when I and D space are separate, these will need to be fixed. */ -+ case PTRACE_PEEKTEXT: /* read word at location addr. */ -+ case PTRACE_PEEKDATA: { -+ unsigned long tmp; -+ int copied; -+ -+ ret = -EIO; -+ copied = access_process_vm(child, addr, &tmp, sizeof(tmp), 0); -+ if (copied != sizeof(tmp)) -+ break; -+ ret = put_user(tmp,(unsigned long *) data); -+ break; -+ } -+ -+ /* read the word at location addr in the USER area. */ -+ case PTRACE_PEEKUSR: { -+ unsigned long tmp; -+ -+ ret = -EIO; -+ if ((addr & 3) || addr < 0) -+ break; -+ -+ tmp = 0; /* Default return condition */ -+ if(addr < FRAME_SIZE_OFFSET){ -+ tmp = getreg(child, addr); -+ } -+ else if((addr >= offsetof(struct user, u_debugreg[0])) && -+ (addr <= offsetof(struct user, u_debugreg[7]))){ -+ addr -= offsetof(struct user, u_debugreg[0]); -+ addr = addr >> 2; -+ tmp = child->thread.arch.debugregs[addr]; -+ } -+ ret = put_user(tmp, (unsigned long *) data); -+ break; -+ } -+ -+ /* when I and D space are separate, this will have to be fixed. */ -+ case PTRACE_POKETEXT: /* write the word at location addr. */ -+ case PTRACE_POKEDATA: -+ ret = -EIO; -+ if (access_process_vm(child, addr, &data, sizeof(data), -+ 1) != sizeof(data)) -+ break; -+ ret = 0; -+ break; -+ -+ case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ -+ ret = -EIO; -+ if ((addr & 3) || addr < 0) -+ break; -+ -+ if (addr < FRAME_SIZE_OFFSET) { -+ ret = putreg(child, addr, data); -+ break; -+ } -+ else if((addr >= offsetof(struct user, u_debugreg[0])) && -+ (addr <= offsetof(struct user, u_debugreg[7]))){ -+ addr -= offsetof(struct user, u_debugreg[0]); -+ addr = addr >> 2; -+ if((addr == 4) || (addr == 5)) break; -+ child->thread.arch.debugregs[addr] = data; -+ ret = 0; -+ } -+ -+ break; -+ -+ case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ -+ case PTRACE_CONT: { /* restart after signal. */ -+ ret = -EIO; -+ if ((unsigned long) data > _NSIG) -+ break; -+ if (request == PTRACE_SYSCALL) -+ child->ptrace |= PT_TRACESYS; -+ else -+ child->ptrace &= ~PT_TRACESYS; -+ child->exit_code = data; -+ wake_up_process(child); -+ ret = 0; -+ break; -+ } -+ -+/* -+ * make the child exit. Best I can do is send it a sigkill. -+ * perhaps it should be put in the status that it wants to -+ * exit. -+ */ -+ case PTRACE_KILL: { -+ ret = 0; -+ if (child->state == TASK_ZOMBIE) /* already dead */ -+ break; -+ child->exit_code = SIGKILL; -+ wake_up_process(child); -+ break; -+ } -+ -+ case PTRACE_SINGLESTEP: { /* set the trap flag. */ -+ ret = -EIO; -+ if ((unsigned long) data > _NSIG) -+ break; -+ child->ptrace &= ~PT_TRACESYS; -+ child->ptrace |= PT_DTRACE; -+ child->exit_code = data; -+ /* give it a chance to run. */ -+ wake_up_process(child); -+ ret = 0; -+ break; -+ } -+ -+ case PTRACE_DETACH: -+ /* detach a process that was attached. */ -+ ret = ptrace_detach(child, data); -+ break; -+ -+#ifdef PTRACE_GETREGS -+ case PTRACE_GETREGS: { /* Get all gp regs from the child. */ -+ if (!access_ok(VERIFY_WRITE, (unsigned long *)data, -+ FRAME_SIZE_OFFSET)) { -+ ret = -EIO; -+ break; -+ } -+ for ( i = 0; i < FRAME_SIZE_OFFSET; i += sizeof(long) ) { -+ __put_user(getreg(child, i), (unsigned long *) data); -+ data += sizeof(long); -+ } -+ ret = 0; -+ break; -+ } -+#endif -+#ifdef PTRACE_SETREGS -+ case PTRACE_SETREGS: { /* Set all gp regs in the child. */ -+ unsigned long tmp = 0; -+ if (!access_ok(VERIFY_READ, (unsigned *)data, -+ FRAME_SIZE_OFFSET)) { -+ ret = -EIO; -+ break; -+ } -+ for ( i = 0; i < FRAME_SIZE_OFFSET; i += sizeof(long) ) { -+ __get_user(tmp, (unsigned long *) data); -+ putreg(child, i, tmp); -+ data += sizeof(long); -+ } -+ ret = 0; -+ break; -+ } -+#endif -+#ifdef PTRACE_GETFPREGS -+ case PTRACE_GETFPREGS: /* Get the child FPU state. */ -+ ret = get_fpregs(data, child); -+ break; -+#endif -+#ifdef PTRACE_SETFPREGS -+ case PTRACE_SETFPREGS: /* Set the child FPU state. */ -+ ret = set_fpregs(data, child); -+ break; -+#endif -+#ifdef PTRACE_GETFPXREGS -+ case PTRACE_GETFPXREGS: /* Get the child FPU state. */ -+ ret = get_fpxregs(data, child); -+ break; -+#endif -+#ifdef PTRACE_SETFPXREGS -+ case PTRACE_SETFPXREGS: /* Set the child FPU state. */ -+ ret = set_fpxregs(data, child); -+ break; -+#endif -+ case PTRACE_FAULTINFO: { -+ struct ptrace_faultinfo fault; -+ -+ fault = ((struct ptrace_faultinfo) -+ { .is_write = child->thread.err, -+ .addr = child->thread.cr2 }); -+ ret = copy_to_user((unsigned long *) data, &fault, -+ sizeof(fault)); -+ if(ret) -+ break; -+ break; -+ } -+ case PTRACE_SIGPENDING: -+ ret = copy_to_user((unsigned long *) data, -+ &child->pending.signal, -+ sizeof(child->pending.signal)); -+ break; -+ -+ case PTRACE_LDT: { -+ struct ptrace_ldt ldt; -+ -+ if(copy_from_user(&ldt, (unsigned long *) data, -+ sizeof(ldt))){ -+ ret = -EIO; -+ break; -+ } -+ -+ /* This one is confusing, so just punt and return -EIO for -+ * now -+ */ -+ ret = -EIO; -+ break; -+ } -+#ifdef CONFIG_PROC_MM -+ case PTRACE_SWITCH_MM: { -+ struct mm_struct *old = child->mm; -+ struct mm_struct *new = proc_mm_get_mm(data); -+ -+ if(IS_ERR(new)){ -+ ret = PTR_ERR(new); -+ break; -+ } -+ -+ atomic_inc(&new->mm_users); -+ child->mm = new; -+ child->active_mm = new; -+ mmput(old); -+ ret = 0; -+ break; -+ } -+#endif -+ default: -+ ret = -EIO; -+ break; -+ } -+ out_tsk: -+ free_task_struct(child); -+ out: -+ unlock_kernel(); -+ return ret; -+} -+ -+void syscall_trace(void) -+{ -+ if ((current->ptrace & (PT_PTRACED|PT_TRACESYS)) -+ != (PT_PTRACED|PT_TRACESYS)) -+ return; -+ current->exit_code = SIGTRAP; -+ current->state = TASK_STOPPED; -+ notify_parent(current, SIGCHLD); -+ schedule(); -+ /* -+ * this isn't the same as continuing with a signal, but it will do -+ * for normal use. strace only continues with a signal if the -+ * stopping signal is not SIGTRAP. -brl -+ */ -+ if (current->exit_code) { -+ send_sig(current->exit_code, current, 1); -+ current->exit_code = 0; -+ } -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/reboot.c um/arch/um/kernel/reboot.c ---- orig/arch/um/kernel/reboot.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/reboot.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,73 @@ -+/* -+ * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/sched.h" -+#include "user_util.h" -+#include "kern_util.h" -+#include "kern.h" -+#include "os.h" -+#include "mode.h" -+#include "choose-mode.h" -+ -+#ifdef CONFIG_SMP -+static void kill_idlers(int me) -+{ -+#ifdef CONFIG_MODE_TT -+ struct task_struct *p; -+ int i; -+ -+ for(i = 0; i < sizeof(init_tasks)/sizeof(init_tasks[0]); i++){ -+ p = init_tasks[i]; -+ if((p != NULL) && (p->thread.mode.tt.extern_pid != me) && -+ (p->thread.mode.tt.extern_pid != -1)) -+ os_kill_process(p->thread.mode.tt.extern_pid, 0); -+ } -+#endif -+} -+#endif -+ -+static void kill_off_processes(void) -+{ -+ CHOOSE_MODE(kill_off_processes_tt(), kill_off_processes_skas()); -+#ifdef CONFIG_SMP -+ kill_idlers(os_getpid()); -+#endif -+} -+ -+void uml_cleanup(void) -+{ -+ kill_off_processes(); -+ do_uml_exitcalls(); -+} -+ -+void machine_restart(char * __unused) -+{ -+ do_uml_exitcalls(); -+ kill_off_processes(); -+ CHOOSE_MODE(reboot_tt(), reboot_skas()); -+} -+ -+void machine_power_off(void) -+{ -+ do_uml_exitcalls(); -+ kill_off_processes(); -+ CHOOSE_MODE(halt_tt(), halt_skas()); -+} -+ -+void machine_halt(void) -+{ -+ machine_power_off(); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/resource.c um/arch/um/kernel/resource.c ---- orig/arch/um/kernel/resource.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/resource.c 2003-10-21 03:26:06.000000000 -0400 -@@ -0,0 +1,23 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/pci.h" -+ -+unsigned long resource_fixup(struct pci_dev * dev, struct resource * res, -+ unsigned long start, unsigned long size) -+{ -+ return start; -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/sigio_kern.c um/arch/um/kernel/sigio_kern.c ---- orig/arch/um/kernel/sigio_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/sigio_kern.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,57 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/kernel.h" -+#include "linux/list.h" -+#include "linux/slab.h" -+#include "asm/irq.h" -+#include "init.h" -+#include "sigio.h" -+#include "irq_user.h" -+#include "irq_kern.h" -+ -+/* Protected by sigio_lock() called from write_sigio_workaround */ -+static int sigio_irq_fd = -1; -+ -+void sigio_interrupt(int irq, void *data, struct pt_regs *unused) -+{ -+ read_sigio_fd(sigio_irq_fd); -+ reactivate_fd(sigio_irq_fd, SIGIO_WRITE_IRQ); -+} -+ -+int write_sigio_irq(int fd) -+{ -+ if(um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt, -+ SA_INTERRUPT | SA_SAMPLE_RANDOM, "write sigio", -+ NULL)){ -+ printk("write_sigio_irq : um_request_irq failed\n"); -+ return(-1); -+ } -+ sigio_irq_fd = fd; -+ return(0); -+} -+ -+static spinlock_t sigio_spinlock = SPIN_LOCK_UNLOCKED; -+ -+void sigio_lock(void) -+{ -+ spin_lock(&sigio_spinlock); -+} -+ -+void sigio_unlock(void) -+{ -+ spin_unlock(&sigio_spinlock); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/sigio_user.c um/arch/um/kernel/sigio_user.c ---- orig/arch/um/kernel/sigio_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/sigio_user.c 2003-11-07 01:41:13.000000000 -0500 -@@ -0,0 +1,438 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <unistd.h> -+#include <stdlib.h> -+#include <termios.h> -+#include <pty.h> -+#include <signal.h> -+#include <errno.h> -+#include <string.h> -+#include <sched.h> -+#include <sys/socket.h> -+#include <sys/poll.h> -+#include "init.h" -+#include "user.h" -+#include "kern_util.h" -+#include "sigio.h" -+#include "helper.h" -+#include "os.h" -+ -+/* Changed during early boot */ -+int pty_output_sigio = 0; -+int pty_close_sigio = 0; -+ -+/* Used as a flag during SIGIO testing early in boot */ -+static volatile int got_sigio = 0; -+ -+void __init handler(int sig) -+{ -+ got_sigio = 1; -+} -+ -+struct openpty_arg { -+ int master; -+ int slave; -+ int err; -+}; -+ -+static void openpty_cb(void *arg) -+{ -+ struct openpty_arg *info = arg; -+ -+ info->err = 0; -+ if(openpty(&info->master, &info->slave, NULL, NULL, NULL)) -+ info->err = -errno; -+} -+ -+void __init check_one_sigio(void (*proc)(int, int)) -+{ -+ struct sigaction old, new; -+ struct termios tt; -+ struct openpty_arg pty = { .master = -1, .slave = -1 }; -+ int master, slave, err; -+ -+ initial_thread_cb(openpty_cb, &pty); -+ if(pty.err){ -+ printk("openpty failed, errno = %d\n", -pty.err); -+ return; -+ } -+ -+ master = pty.master; -+ slave = pty.slave; -+ -+ if((master == -1) || (slave == -1)){ -+ printk("openpty failed to allocate a pty\n"); -+ return; -+ } -+ -+ /* XXX These can fail with EINTR */ -+ if(tcgetattr(master, &tt) < 0) -+ panic("check_sigio : tcgetattr failed, errno = %d\n", errno); -+ cfmakeraw(&tt); -+ if(tcsetattr(master, TCSADRAIN, &tt) < 0) -+ panic("check_sigio : tcsetattr failed, errno = %d\n", errno); -+ -+ err = os_sigio_async(master, slave); -+ if(err < 0) -+ panic("tty_fds : sigio_async failed, err = %d\n", -err); -+ -+ if(sigaction(SIGIO, NULL, &old) < 0) -+ panic("check_sigio : sigaction 1 failed, errno = %d\n", errno); -+ new = old; -+ new.sa_handler = handler; -+ if(sigaction(SIGIO, &new, NULL) < 0) -+ panic("check_sigio : sigaction 2 failed, errno = %d\n", errno); -+ -+ got_sigio = 0; -+ (*proc)(master, slave); -+ -+ os_close_file(master); -+ os_close_file(slave); -+ -+ if(sigaction(SIGIO, &old, NULL) < 0) -+ panic("check_sigio : sigaction 3 failed, errno = %d\n", errno); -+} -+ -+static void tty_output(int master, int slave) -+{ -+ int n; -+ char buf[512]; -+ -+ printk("Checking that host ptys support output SIGIO..."); -+ -+ memset(buf, 0, sizeof(buf)); -+ -+ while(os_write_file(master, buf, sizeof(buf)) > 0) ; -+ if(errno != EAGAIN) -+ panic("check_sigio : write failed, errno = %d\n", errno); -+ while(((n = os_read_file(slave, buf, sizeof(buf))) > 0) && !got_sigio) ; -+ -+ if(got_sigio){ -+ printk("Yes\n"); -+ pty_output_sigio = 1; -+ } -+ else if(n == -EAGAIN) printk("No, enabling workaround\n"); -+ else panic("check_sigio : read failed, err = %d\n", n); -+} -+ -+static void tty_close(int master, int slave) -+{ -+ printk("Checking that host ptys support SIGIO on close..."); -+ -+ os_close_file(slave); -+ if(got_sigio){ -+ printk("Yes\n"); -+ pty_close_sigio = 1; -+ } -+ else printk("No, enabling workaround\n"); -+} -+ -+void __init check_sigio(void) -+{ -+ if((os_access("/dev/ptmx", OS_ACC_R_OK) < 0) && -+ (os_access("/dev/ptyp0", OS_ACC_R_OK) < 0)){ -+ printk("No pseudo-terminals available - skipping pty SIGIO " -+ "check\n"); -+ return; -+ } -+ check_one_sigio(tty_output); -+ check_one_sigio(tty_close); -+} -+ -+/* Protected by sigio_lock(), also used by sigio_cleanup, which is an -+ * exitcall. -+ */ -+static int write_sigio_pid = -1; -+ -+/* These arrays are initialized before the sigio thread is started, and -+ * the descriptors closed after it is killed. So, it can't see them change. -+ * On the UML side, they are changed under the sigio_lock. -+ */ -+static int write_sigio_fds[2] = { -1, -1 }; -+static int sigio_private[2] = { -1, -1 }; -+ -+struct pollfds { -+ struct pollfd *poll; -+ int size; -+ int used; -+}; -+ -+/* Protected by sigio_lock(). Used by the sigio thread, but the UML thread -+ * synchronizes with it. -+ */ -+struct pollfds current_poll = { -+ .poll = NULL, -+ .size = 0, -+ .used = 0 -+}; -+ -+struct pollfds next_poll = { -+ .poll = NULL, -+ .size = 0, -+ .used = 0 -+}; -+ -+static int write_sigio_thread(void *unused) -+{ -+ struct pollfds *fds, tmp; -+ struct pollfd *p; -+ int i, n, respond_fd; -+ char c; -+ -+ fds = ¤t_poll; -+ while(1){ -+ n = poll(fds->poll, fds->used, -1); -+ if(n < 0){ -+ if(errno == EINTR) continue; -+ printk("write_sigio_thread : poll returned %d, " -+ "errno = %d\n", n, errno); -+ } -+ for(i = 0; i < fds->used; i++){ -+ p = &fds->poll[i]; -+ if(p->revents == 0) continue; -+ if(p->fd == sigio_private[1]){ -+ n = os_read_file(sigio_private[1], &c, sizeof(c)); -+ if(n != sizeof(c)) -+ printk("write_sigio_thread : " -+ "read failed, err = %d\n", -n); -+ tmp = current_poll; -+ current_poll = next_poll; -+ next_poll = tmp; -+ respond_fd = sigio_private[1]; -+ } -+ else { -+ respond_fd = write_sigio_fds[1]; -+ fds->used--; -+ memmove(&fds->poll[i], &fds->poll[i + 1], -+ (fds->used - i) * sizeof(*fds->poll)); -+ } -+ -+ n = os_write_file(respond_fd, &c, sizeof(c)); -+ if(n != sizeof(c)) -+ printk("write_sigio_thread : write failed, " -+ "err = %d\n", -n); -+ } -+ } -+} -+ -+static int need_poll(int n) -+{ -+ if(n <= next_poll.size){ -+ next_poll.used = n; -+ return(0); -+ } -+ if(next_poll.poll != NULL) kfree(next_poll.poll); -+ next_poll.poll = um_kmalloc_atomic(n * sizeof(struct pollfd)); -+ if(next_poll.poll == NULL){ -+ printk("need_poll : failed to allocate new pollfds\n"); -+ next_poll.size = 0; -+ next_poll.used = 0; -+ return(-1); -+ } -+ next_poll.size = n; -+ next_poll.used = n; -+ return(0); -+} -+ -+static void update_thread(void) -+{ -+ unsigned long flags; -+ int n; -+ char c; -+ -+ flags = set_signals(0); -+ n = os_write_file(sigio_private[0], &c, sizeof(c)); -+ if(n != sizeof(c)){ -+ printk("update_thread : write failed, err = %d\n", -n); -+ goto fail; -+ } -+ -+ n = os_read_file(sigio_private[0], &c, sizeof(c)); -+ if(n != sizeof(c)){ -+ printk("update_thread : read failed, err = %d\n", -n); -+ goto fail; -+ } -+ -+ set_signals(flags); -+ return; -+ fail: -+ sigio_lock(); -+ if(write_sigio_pid != -1) -+ os_kill_process(write_sigio_pid, 1); -+ write_sigio_pid = -1; -+ os_close_file(sigio_private[0]); -+ os_close_file(sigio_private[1]); -+ os_close_file(write_sigio_fds[0]); -+ os_close_file(write_sigio_fds[1]); -+ sigio_unlock(); -+ set_signals(flags); -+} -+ -+int add_sigio_fd(int fd, int read) -+{ -+ int err = 0, i, n, events; -+ -+ sigio_lock(); -+ for(i = 0; i < current_poll.used; i++){ -+ if(current_poll.poll[i].fd == fd) -+ goto out; -+ } -+ -+ n = current_poll.used + 1; -+ err = need_poll(n); -+ if(err) -+ goto out; -+ -+ for(i = 0; i < current_poll.used; i++) -+ next_poll.poll[i] = current_poll.poll[i]; -+ -+ if(read) events = POLLIN; -+ else events = POLLOUT; -+ -+ next_poll.poll[n - 1] = ((struct pollfd) { .fd = fd, -+ .events = events, -+ .revents = 0 }); -+ update_thread(); -+ out: -+ sigio_unlock(); -+ return(err); -+} -+ -+int ignore_sigio_fd(int fd) -+{ -+ struct pollfd *p; -+ int err = 0, i, n = 0; -+ -+ sigio_lock(); -+ for(i = 0; i < current_poll.used; i++){ -+ if(current_poll.poll[i].fd == fd) break; -+ } -+ if(i == current_poll.used) -+ goto out; -+ -+ err = need_poll(current_poll.used - 1); -+ if(err) -+ goto out; -+ -+ for(i = 0; i < current_poll.used; i++){ -+ p = ¤t_poll.poll[i]; -+ if(p->fd != fd) next_poll.poll[n++] = current_poll.poll[i]; -+ } -+ if(n == i){ -+ printk("ignore_sigio_fd : fd %d not found\n", fd); -+ err = -1; -+ goto out; -+ } -+ -+ update_thread(); -+ out: -+ sigio_unlock(); -+ return(err); -+} -+ -+static int setup_initial_poll(int fd) -+{ -+ struct pollfd *p; -+ -+ p = um_kmalloc(sizeof(struct pollfd)); -+ if(p == NULL){ -+ printk("setup_initial_poll : failed to allocate poll\n"); -+ return(-1); -+ } -+ *p = ((struct pollfd) { .fd = fd, -+ .events = POLLIN, -+ .revents = 0 }); -+ current_poll = ((struct pollfds) { .poll = p, -+ .used = 1, -+ .size = 1 }); -+ return(0); -+} -+ -+void write_sigio_workaround(void) -+{ -+ unsigned long stack; -+ int err; -+ -+ sigio_lock(); -+ if(write_sigio_pid != -1) -+ goto out; -+ -+ err = os_pipe(write_sigio_fds, 1, 1); -+ if(err < 0){ -+ printk("write_sigio_workaround - os_pipe 1 failed, " -+ "err = %d\n", -err); -+ goto out; -+ } -+ err = os_pipe(sigio_private, 1, 1); -+ if(err < 0){ -+ printk("write_sigio_workaround - os_pipe 2 failed, " -+ "err = %d\n", -err); -+ goto out_close1; -+ } -+ if(setup_initial_poll(sigio_private[1])) -+ goto out_close2; -+ -+ write_sigio_pid = run_helper_thread(write_sigio_thread, NULL, -+ CLONE_FILES | CLONE_VM, &stack, 0); -+ -+ if(write_sigio_pid < 0) goto out_close2; -+ -+ if(write_sigio_irq(write_sigio_fds[0])) -+ goto out_kill; -+ -+ out: -+ sigio_unlock(); -+ return; -+ -+ out_kill: -+ os_kill_process(write_sigio_pid, 1); -+ write_sigio_pid = -1; -+ out_close2: -+ os_close_file(sigio_private[0]); -+ os_close_file(sigio_private[1]); -+ out_close1: -+ os_close_file(write_sigio_fds[0]); -+ os_close_file(write_sigio_fds[1]); -+ sigio_unlock(); -+} -+ -+int read_sigio_fd(int fd) -+{ -+ int n; -+ char c; -+ -+ n = os_read_file(fd, &c, sizeof(c)); -+ if(n != sizeof(c)){ -+ if(n < 0) { -+ printk("read_sigio_fd - read failed, err = %d\n", -n); -+ return(n); -+ } -+ else { -+ printk("read_sigio_fd - short read, bytes = %d\n", n); -+ return(-EIO); -+ } -+ } -+ return(n); -+} -+ -+static void sigio_cleanup(void) -+{ -+ if(write_sigio_pid != -1) -+ os_kill_process(write_sigio_pid, 1); -+} -+ -+__uml_exitcall(sigio_cleanup); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/signal_kern.c um/arch/um/kernel/signal_kern.c ---- orig/arch/um/kernel/signal_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/signal_kern.c 2003-11-19 03:50:58.000000000 -0500 -@@ -0,0 +1,369 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/config.h" -+#include "linux/stddef.h" -+#include "linux/sys.h" -+#include "linux/sched.h" -+#include "linux/wait.h" -+#include "linux/kernel.h" -+#include "linux/smp_lock.h" -+#include "linux/module.h" -+#include "linux/slab.h" -+#include "asm/signal.h" -+#include "asm/uaccess.h" -+#include "asm/ucontext.h" -+#include "user_util.h" -+#include "kern_util.h" -+#include "signal_kern.h" -+#include "signal_user.h" -+#include "kern.h" -+#include "frame_kern.h" -+#include "sigcontext.h" -+#include "mode.h" -+ -+EXPORT_SYMBOL(block_signals); -+EXPORT_SYMBOL(unblock_signals); -+ -+static void force_segv(int sig) -+{ -+ if(sig == SIGSEGV){ -+ struct k_sigaction *ka; -+ -+ ka = ¤t->sig->action[SIGSEGV - 1]; -+ ka->sa.sa_handler = SIG_DFL; -+ } -+ force_sig(SIGSEGV, current); -+} -+ -+#define _S(nr) (1<<((nr)-1)) -+ -+#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP))) -+ -+/* -+ * OK, we're invoking a handler -+ */ -+static int handle_signal(struct pt_regs *regs, unsigned long signr, -+ struct k_sigaction *ka, siginfo_t *info, -+ sigset_t *oldset, int error) -+{ -+ __sighandler_t handler; -+ void (*restorer)(void); -+ unsigned long sp; -+ sigset_t save; -+ int err, ret; -+ -+ ret = 0; -+ switch(error){ -+ case -ERESTARTNOHAND: -+ ret = -EINTR; -+ break; -+ -+ case -ERESTARTSYS: -+ if (!(ka->sa.sa_flags & SA_RESTART)) { -+ ret = -EINTR; -+ break; -+ } -+ /* fallthrough */ -+ case -ERESTARTNOINTR: -+ PT_REGS_RESTART_SYSCALL(regs); -+ PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs); -+ -+ /* This is because of the UM_SET_SYSCALL_RETURN and the fact -+ * that on i386 the system call number and return value are -+ * in the same register. When the system call restarts, %eax -+ * had better have the system call number in it. Since the -+ * return value doesn't matter (except that it shouldn't be -+ * -ERESTART*), we'll stick the system call number there. -+ */ -+ ret = PT_REGS_SYSCALL_NR(regs); -+ break; -+ } -+ -+ handler = ka->sa.sa_handler; -+ save = *oldset; -+ -+ if (ka->sa.sa_flags & SA_ONESHOT) -+ ka->sa.sa_handler = SIG_DFL; -+ -+ if (!(ka->sa.sa_flags & SA_NODEFER)) { -+ spin_lock_irq(¤t->sigmask_lock); -+ sigorsets(¤t->blocked, ¤t->blocked, -+ &ka->sa.sa_mask); -+ sigaddset(¤t->blocked, signr); -+ recalc_sigpending(current); -+ spin_unlock_irq(¤t->sigmask_lock); -+ } -+ -+ sp = PT_REGS_SP(regs); -+ -+ if((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0)) -+ sp = current->sas_ss_sp + current->sas_ss_size; -+ -+ if(error != 0) PT_REGS_SET_SYSCALL_RETURN(regs, ret); -+ -+ if (ka->sa.sa_flags & SA_RESTORER) restorer = ka->sa.sa_restorer; -+ else restorer = NULL; -+ -+ if(ka->sa.sa_flags & SA_SIGINFO) -+ err = setup_signal_stack_si(sp, signr, (unsigned long) handler, -+ restorer, regs, info, &save); -+ else -+ err = setup_signal_stack_sc(sp, signr, (unsigned long) handler, -+ restorer, regs, &save); -+ if(err) goto segv; -+ -+ return(0); -+ segv: -+ force_segv(signr); -+ return(1); -+} -+ -+/* -+ * Note that 'init' is a special process: it doesn't get signals it doesn't -+ * want to handle. Thus you cannot kill init even with a SIGKILL even by -+ * mistake. -+ */ -+ -+static int kern_do_signal(struct pt_regs *regs, sigset_t *oldset, int error) -+{ -+ siginfo_t info; -+ struct k_sigaction *ka; -+ int err; -+ -+ if (!oldset) -+ oldset = ¤t->blocked; -+ -+ for (;;) { -+ unsigned long signr; -+ -+ spin_lock_irq(¤t->sigmask_lock); -+ signr = dequeue_signal(¤t->blocked, &info); -+ spin_unlock_irq(¤t->sigmask_lock); -+ -+ if (!signr) -+ break; -+ -+ if ((current->ptrace & PT_PTRACED) && signr != SIGKILL) { -+ /* Let the debugger run. */ -+ current->exit_code = signr; -+ current->state = TASK_STOPPED; -+ notify_parent(current, SIGCHLD); -+ schedule(); -+ -+ /* We're back. Did the debugger cancel the sig? */ -+ signr = current->exit_code; -+ if (!signr) -+ continue; -+ current->exit_code = 0; -+ -+ /* The debugger continued. Ignore SIGSTOP. */ -+ if (signr == SIGSTOP) -+ continue; -+ -+ /* Update the siginfo structure. Is this good? */ -+ if (signr != info.si_signo) { -+ info.si_signo = signr; -+ info.si_errno = 0; -+ info.si_code = SI_USER; -+ info.si_pid = current->p_pptr->pid; -+ info.si_uid = current->p_pptr->uid; -+ } -+ -+ /* If the (new) signal is now blocked, requeue it. */ -+ if (sigismember(¤t->blocked, signr)) { -+ send_sig_info(signr, &info, current); -+ continue; -+ } -+ } -+ -+ ka = ¤t->sig->action[signr-1]; -+ if (ka->sa.sa_handler == SIG_IGN) { -+ if (signr != SIGCHLD) -+ continue; -+ /* Check for SIGCHLD: it's special. */ -+ while (sys_wait4(-1, NULL, WNOHANG, NULL) > 0) -+ /* nothing */; -+ continue; -+ } -+ -+ if (ka->sa.sa_handler == SIG_DFL) { -+ int exit_code = signr; -+ -+ /* Init gets no signals it doesn't want. */ -+ if (current->pid == 1) -+ continue; -+ -+ switch (signr) { -+ case SIGCONT: case SIGCHLD: case SIGWINCH: case SIGURG: -+ continue; -+ -+ case SIGTSTP: case SIGTTIN: case SIGTTOU: -+ if (is_orphaned_pgrp(current->pgrp)) -+ continue; -+ /* FALLTHRU */ -+ -+ case SIGSTOP: { -+ struct signal_struct *sig; -+ current->state = TASK_STOPPED; -+ current->exit_code = signr; -+ sig = current->p_pptr->sig; -+ if (sig && !(sig->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDSTOP)) -+ notify_parent(current, SIGCHLD); -+ schedule(); -+ continue; -+ } -+ case SIGQUIT: case SIGILL: case SIGTRAP: -+ case SIGABRT: case SIGFPE: case SIGSEGV: -+ case SIGBUS: case SIGSYS: case SIGXCPU: case SIGXFSZ: -+ if (do_coredump(signr, ¤t->thread.regs)) -+ exit_code |= 0x80; -+ /* FALLTHRU */ -+ -+ default: -+ sig_exit(signr, exit_code, &info); -+ /* NOTREACHED */ -+ } -+ } -+ -+ /* Whee! Actually deliver the signal. */ -+ err = handle_signal(regs, signr, ka, &info, oldset, error); -+ if(!err) return(1); -+ } -+ -+ /* Did we come from a system call? */ -+ if(PT_REGS_SYSCALL_NR(regs) >= 0){ -+ /* Restart the system call - no handlers present */ -+ if(PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOHAND || -+ PT_REGS_SYSCALL_RET(regs) == -ERESTARTSYS || -+ PT_REGS_SYSCALL_RET(regs) == -ERESTARTNOINTR){ -+ PT_REGS_ORIG_SYSCALL(regs) = PT_REGS_SYSCALL_NR(regs); -+ PT_REGS_RESTART_SYSCALL(regs); -+ } -+ } -+ -+ /* This closes a way to execute a system call on the host. If -+ * you set a breakpoint on a system call instruction and singlestep -+ * from it, the tracing thread used to PTRACE_SINGLESTEP the process -+ * rather than PTRACE_SYSCALL it, allowing the system call to execute -+ * on the host. The tracing thread will check this flag and -+ * PTRACE_SYSCALL if necessary. -+ */ -+ if((current->ptrace & PT_DTRACE) && -+ is_syscall(PT_REGS_IP(¤t->thread.regs))) -+ (void) CHOOSE_MODE(current->thread.mode.tt.singlestep_syscall = 1, 0); -+ -+ return(0); -+} -+ -+int do_signal(int error) -+{ -+ return(kern_do_signal(¤t->thread.regs, NULL, error)); -+} -+ -+/* -+ * Atomically swap in the new signal mask, and wait for a signal. -+ */ -+int sys_sigsuspend(int history0, int history1, old_sigset_t mask) -+{ -+ sigset_t saveset; -+ -+ mask &= _BLOCKABLE; -+ spin_lock_irq(¤t->sigmask_lock); -+ saveset = current->blocked; -+ siginitset(¤t->blocked, mask); -+ recalc_sigpending(current); -+ spin_unlock_irq(¤t->sigmask_lock); -+ -+ while (1) { -+ current->state = TASK_INTERRUPTIBLE; -+ schedule(); -+ if(kern_do_signal(¤t->thread.regs, &saveset, -EINTR)) -+ return(-EINTR); -+ } -+} -+ -+int sys_rt_sigsuspend(sigset_t *unewset, size_t sigsetsize) -+{ -+ sigset_t saveset, newset; -+ -+ /* XXX: Don't preclude handling different sized sigset_t's. */ -+ if (sigsetsize != sizeof(sigset_t)) -+ return -EINVAL; -+ -+ if (copy_from_user(&newset, unewset, sizeof(newset))) -+ return -EFAULT; -+ sigdelsetmask(&newset, ~_BLOCKABLE); -+ -+ spin_lock_irq(¤t->sigmask_lock); -+ saveset = current->blocked; -+ current->blocked = newset; -+ recalc_sigpending(current); -+ spin_unlock_irq(¤t->sigmask_lock); -+ -+ while (1) { -+ current->state = TASK_INTERRUPTIBLE; -+ schedule(); -+ if (kern_do_signal(¤t->thread.regs, &saveset, -EINTR)) -+ return(-EINTR); -+ } -+} -+ -+extern int userspace_pid[]; -+ -+static int copy_sc_from_user(struct pt_regs *to, void *from, -+ struct arch_frame_data *arch) -+{ -+ int ret; -+ -+ ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from, arch), -+ copy_sc_from_user_skas(userspace_pid[0], -+ &to->regs, from)); -+ return(ret); -+} -+ -+int sys_sigreturn(struct pt_regs regs) -+{ -+ void *sc = sp_to_sc(PT_REGS_SP(¤t->thread.regs)); -+ void *mask = sp_to_mask(PT_REGS_SP(¤t->thread.regs)); -+ int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long); -+ -+ spin_lock_irq(¤t->sigmask_lock); -+ copy_from_user(¤t->blocked.sig[0], sc_sigmask(sc), -+ sizeof(current->blocked.sig[0])); -+ copy_from_user(¤t->blocked.sig[1], mask, sig_size); -+ sigdelsetmask(¤t->blocked, ~_BLOCKABLE); -+ recalc_sigpending(current); -+ spin_unlock_irq(¤t->sigmask_lock); -+ copy_sc_from_user(¤t->thread.regs, sc, -+ &signal_frame_sc.common.arch); -+ return(PT_REGS_SYSCALL_RET(¤t->thread.regs)); -+} -+ -+int sys_rt_sigreturn(struct pt_regs regs) -+{ -+ struct ucontext *uc = sp_to_uc(PT_REGS_SP(¤t->thread.regs)); -+ int sig_size = _NSIG_WORDS * sizeof(unsigned long); -+ -+ spin_lock_irq(¤t->sigmask_lock); -+ copy_from_user(¤t->blocked, &uc->uc_sigmask, sig_size); -+ sigdelsetmask(¤t->blocked, ~_BLOCKABLE); -+ recalc_sigpending(current); -+ spin_unlock_irq(¤t->sigmask_lock); -+ copy_sc_from_user(¤t->thread.regs, &uc->uc_mcontext, -+ &signal_frame_si.common.arch); -+ return(PT_REGS_SYSCALL_RET(¤t->thread.regs)); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/signal_user.c um/arch/um/kernel/signal_user.c ---- orig/arch/um/kernel/signal_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/signal_user.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,142 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <stdio.h> -+#include <unistd.h> -+#include <stdlib.h> -+#include <signal.h> -+#include <errno.h> -+#include <stdarg.h> -+#include <string.h> -+#include <sys/mman.h> -+#include "user_util.h" -+#include "kern_util.h" -+#include "user.h" -+#include "signal_user.h" -+#include "signal_kern.h" -+#include "sysdep/sigcontext.h" -+#include "sigcontext.h" -+ -+void set_sigstack(void *sig_stack, int size) -+{ -+ stack_t stack = ((stack_t) { .ss_flags = 0, -+ .ss_sp = (__ptr_t) sig_stack, -+ .ss_size = size - sizeof(void *) }); -+ -+ if(sigaltstack(&stack, NULL) != 0) -+ panic("enabling signal stack failed, errno = %d\n", errno); -+} -+ -+void set_handler(int sig, void (*handler)(int), int flags, ...) -+{ -+ struct sigaction action; -+ va_list ap; -+ int mask; -+ -+ va_start(ap, flags); -+ action.sa_handler = handler; -+ sigemptyset(&action.sa_mask); -+ while((mask = va_arg(ap, int)) != -1){ -+ sigaddset(&action.sa_mask, mask); -+ } -+ action.sa_flags = flags; -+ action.sa_restorer = NULL; -+ if(sigaction(sig, &action, NULL) < 0) -+ panic("sigaction failed"); -+} -+ -+int change_sig(int signal, int on) -+{ -+ sigset_t sigset, old; -+ -+ sigemptyset(&sigset); -+ sigaddset(&sigset, signal); -+ sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old); -+ return(!sigismember(&old, signal)); -+} -+ -+static void change_signals(int type) -+{ -+ sigset_t mask; -+ -+ sigemptyset(&mask); -+ sigaddset(&mask, SIGVTALRM); -+ sigaddset(&mask, SIGALRM); -+ sigaddset(&mask, SIGIO); -+ sigaddset(&mask, SIGPROF); -+ if(sigprocmask(type, &mask, NULL) < 0) -+ panic("Failed to change signal mask - errno = %d", errno); -+} -+ -+void block_signals(void) -+{ -+ change_signals(SIG_BLOCK); -+} -+ -+void unblock_signals(void) -+{ -+ change_signals(SIG_UNBLOCK); -+} -+ -+#define SIGIO_BIT 0 -+#define SIGVTALRM_BIT 1 -+ -+static int enable_mask(sigset_t *mask) -+{ -+ int sigs; -+ -+ sigs = sigismember(mask, SIGIO) ? 0 : 1 << SIGIO_BIT; -+ sigs |= sigismember(mask, SIGVTALRM) ? 0 : 1 << SIGVTALRM_BIT; -+ sigs |= sigismember(mask, SIGALRM) ? 0 : 1 << SIGVTALRM_BIT; -+ return(sigs); -+} -+ -+int get_signals(void) -+{ -+ sigset_t mask; -+ -+ if(sigprocmask(SIG_SETMASK, NULL, &mask) < 0) -+ panic("Failed to get signal mask"); -+ return(enable_mask(&mask)); -+} -+ -+int set_signals(int enable) -+{ -+ sigset_t mask; -+ int ret; -+ -+ sigemptyset(&mask); -+ if(enable & (1 << SIGIO_BIT)) -+ sigaddset(&mask, SIGIO); -+ if(enable & (1 << SIGVTALRM_BIT)){ -+ sigaddset(&mask, SIGVTALRM); -+ sigaddset(&mask, SIGALRM); -+ } -+ if(sigprocmask(SIG_UNBLOCK, &mask, &mask) < 0) -+ panic("Failed to enable signals"); -+ ret = enable_mask(&mask); -+ sigemptyset(&mask); -+ if((enable & (1 << SIGIO_BIT)) == 0) -+ sigaddset(&mask, SIGIO); -+ if((enable & (1 << SIGVTALRM_BIT)) == 0){ -+ sigaddset(&mask, SIGVTALRM); -+ sigaddset(&mask, SIGALRM); -+ } -+ if(sigprocmask(SIG_BLOCK, &mask, NULL) < 0) -+ panic("Failed to block signals"); -+ -+ return(ret); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/exec_kern.c um/arch/um/kernel/skas/exec_kern.c ---- orig/arch/um/kernel/skas/exec_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/skas/exec_kern.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,41 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/kernel.h" -+#include "asm/current.h" -+#include "asm/page.h" -+#include "asm/signal.h" -+#include "asm/ptrace.h" -+#include "asm/uaccess.h" -+#include "asm/mmu_context.h" -+#include "tlb.h" -+#include "skas.h" -+#include "mmu.h" -+#include "os.h" -+ -+void flush_thread_skas(void) -+{ -+ force_flush_all(); -+ switch_mm_skas(current->mm->context.skas.mm_fd); -+} -+ -+void start_thread_skas(struct pt_regs *regs, unsigned long eip, -+ unsigned long esp) -+{ -+ set_fs(USER_DS); -+ PT_REGS_IP(regs) = eip; -+ PT_REGS_SP(regs) = esp; -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/exec_user.c um/arch/um/kernel/skas/exec_user.c ---- orig/arch/um/kernel/skas/exec_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/skas/exec_user.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,61 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <stdlib.h> -+#include <errno.h> -+#include <signal.h> -+#include <sched.h> -+#include <sys/wait.h> -+#include <sys/ptrace.h> -+#include "user.h" -+#include "kern_util.h" -+#include "os.h" -+#include "time_user.h" -+ -+static int user_thread_tramp(void *arg) -+{ -+ if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) -+ panic("user_thread_tramp - PTRACE_TRACEME failed, " -+ "errno = %d\n", errno); -+ enable_timer(); -+ os_stop_process(os_getpid()); -+ return(0); -+} -+ -+int user_thread(unsigned long stack, int flags) -+{ -+ int pid, status; -+ -+ pid = clone(user_thread_tramp, (void *) stack_sp(stack), -+ flags | CLONE_FILES | SIGCHLD, NULL); -+ if(pid < 0){ -+ printk("user_thread - clone failed, errno = %d\n", errno); -+ return(pid); -+ } -+ -+ if(waitpid(pid, &status, WUNTRACED) < 0){ -+ printk("user_thread - waitpid failed, errno = %d\n", errno); -+ return(-errno); -+ } -+ -+ if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)){ -+ printk("user_thread - trampoline didn't stop, status = %d\n", -+ status); -+ return(-EINVAL); -+ } -+ -+ return(pid); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/mmu.h um/arch/um/kernel/skas/include/mmu.h ---- orig/arch/um/kernel/skas/include/mmu.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/skas/include/mmu.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,27 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __SKAS_MMU_H -+#define __SKAS_MMU_H -+ -+#include "linux/list.h" -+#include "linux/spinlock.h" -+ -+struct mmu_context_skas { -+ int mm_fd; -+}; -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/mode.h um/arch/um/kernel/skas/include/mode.h ---- orig/arch/um/kernel/skas/include/mode.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/skas/include/mode.h 2003-11-19 03:27:36.000000000 -0500 -@@ -0,0 +1,37 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __MODE_SKAS_H__ -+#define __MODE_SKAS_H__ -+ -+extern unsigned long exec_regs[]; -+extern unsigned long exec_fp_regs[]; -+extern unsigned long exec_fpx_regs[]; -+extern int have_fpx_regs; -+ -+extern void user_time_init_skas(void); -+extern int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs, -+ void *from_ptr); -+extern int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp, -+ union uml_pt_regs *regs, -+ unsigned long fault_addr, int fault_type); -+extern void sig_handler_common_skas(int sig, void *sc_ptr); -+extern void halt_skas(void); -+extern void reboot_skas(void); -+extern void kill_off_processes_skas(void); -+extern int is_skas_winch(int pid, int fd, void *data); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/mode_kern.h um/arch/um/kernel/skas/include/mode_kern.h ---- orig/arch/um/kernel/skas/include/mode_kern.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/skas/include/mode_kern.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,51 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __SKAS_MODE_KERN_H__ -+#define __SKAS_MODE_KERN_H__ -+ -+#include "linux/sched.h" -+#include "asm/page.h" -+#include "asm/ptrace.h" -+ -+extern void flush_thread_skas(void); -+extern void *_switch_to_skas(void *prev, void *next); -+extern void start_thread_skas(struct pt_regs *regs, unsigned long eip, -+ unsigned long esp); -+extern int copy_thread_skas(int nr, unsigned long clone_flags, -+ unsigned long sp, unsigned long stack_top, -+ struct task_struct *p, struct pt_regs *regs); -+extern void release_thread_skas(struct task_struct *task); -+extern void exit_thread_skas(void); -+extern void initial_thread_cb_skas(void (*proc)(void *), void *arg); -+extern void init_idle_skas(void); -+extern void flush_tlb_kernel_vm_skas(void); -+extern void __flush_tlb_one_skas(unsigned long addr); -+extern void flush_tlb_range_skas(struct mm_struct *mm, unsigned long start, -+ unsigned long end); -+extern void flush_tlb_mm_skas(struct mm_struct *mm); -+extern void force_flush_all_skas(void); -+extern long execute_syscall_skas(void *r); -+extern void before_mem_skas(unsigned long unused); -+extern unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out, -+ unsigned long *task_size_out); -+extern int start_uml_skas(void); -+extern int external_pid_skas(struct task_struct *task); -+extern int thread_pid_skas(struct thread_struct *thread); -+ -+#define kmem_end_skas (host_task_size - 1024 * 1024) -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/proc_mm.h um/arch/um/kernel/skas/include/proc_mm.h ---- orig/arch/um/kernel/skas/include/proc_mm.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/skas/include/proc_mm.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,55 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __SKAS_PROC_MM_H -+#define __SKAS_PROC_MM_H -+ -+#define MM_MMAP 54 -+#define MM_MUNMAP 55 -+#define MM_MPROTECT 56 -+#define MM_COPY_SEGMENTS 57 -+ -+struct mm_mmap { -+ unsigned long addr; -+ unsigned long len; -+ unsigned long prot; -+ unsigned long flags; -+ unsigned long fd; -+ unsigned long offset; -+}; -+ -+struct mm_munmap { -+ unsigned long addr; -+ unsigned long len; -+}; -+ -+struct mm_mprotect { -+ unsigned long addr; -+ unsigned long len; -+ unsigned int prot; -+}; -+ -+struct proc_mm_op { -+ int op; -+ union { -+ struct mm_mmap mmap; -+ struct mm_munmap munmap; -+ struct mm_mprotect mprotect; -+ int copy_segments; -+ } u; -+}; -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/ptrace-skas.h um/arch/um/kernel/skas/include/ptrace-skas.h ---- orig/arch/um/kernel/skas/include/ptrace-skas.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/skas/include/ptrace-skas.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,57 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __PTRACE_SKAS_H -+#define __PTRACE_SKAS_H -+ -+#include "uml-config.h" -+ -+#ifdef UML_CONFIG_MODE_SKAS -+ -+#include "skas_ptregs.h" -+ -+#define HOST_FRAME_SIZE 17 -+ -+#define REGS_IP(r) ((r)[HOST_IP]) -+#define REGS_SP(r) ((r)[HOST_SP]) -+#define REGS_EFLAGS(r) ((r)[HOST_EFLAGS]) -+#define REGS_EAX(r) ((r)[HOST_EAX]) -+#define REGS_EBX(r) ((r)[HOST_EBX]) -+#define REGS_ECX(r) ((r)[HOST_ECX]) -+#define REGS_EDX(r) ((r)[HOST_EDX]) -+#define REGS_ESI(r) ((r)[HOST_ESI]) -+#define REGS_EDI(r) ((r)[HOST_EDI]) -+#define REGS_EBP(r) ((r)[HOST_EBP]) -+#define REGS_CS(r) ((r)[HOST_CS]) -+#define REGS_SS(r) ((r)[HOST_SS]) -+#define REGS_DS(r) ((r)[HOST_DS]) -+#define REGS_ES(r) ((r)[HOST_ES]) -+#define REGS_FS(r) ((r)[HOST_FS]) -+#define REGS_GS(r) ((r)[HOST_GS]) -+ -+#define REGS_SET_SYSCALL_RETURN(r, res) REGS_EAX(r) = (res) -+ -+#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r)) -+ -+#define REGS_SEGV_IS_FIXABLE(r) SEGV_IS_FIXABLE((r)->trap_type) -+ -+#define REGS_FAULT_ADDR(r) ((r)->fault_addr) -+ -+#define REGS_FAULT_WRITE(r) FAULT_WRITE((r)->fault_type) -+ -+#endif -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/skas.h um/arch/um/kernel/skas/include/skas.h ---- orig/arch/um/kernel/skas/include/skas.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/skas/include/skas.h 2003-11-19 03:00:51.000000000 -0500 -@@ -0,0 +1,49 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __SKAS_H -+#define __SKAS_H -+ -+#include "sysdep/ptrace.h" -+ -+extern int userspace_pid[]; -+ -+extern void switch_threads(void *me, void *next); -+extern void thread_wait(void *sw, void *fb); -+extern void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, -+ void (*handler)(int)); -+extern int start_idle_thread(void *stack, void *switch_buf_ptr, -+ void **fork_buf_ptr); -+extern int user_thread(unsigned long stack, int flags); -+extern void userspace(union uml_pt_regs *regs); -+extern void new_thread_proc(void *stack, void (*handler)(int sig)); -+extern void remove_sigstack(void); -+extern void new_thread_handler(int sig); -+extern void handle_syscall(union uml_pt_regs *regs); -+extern void map(int fd, unsigned long virt, unsigned long phys, -+ unsigned long len, int r, int w, int x); -+extern int unmap(int fd, void *addr, int len); -+extern int protect(int fd, unsigned long addr, unsigned long len, -+ int r, int w, int x, int must_succeed); -+extern void user_signal(int sig, union uml_pt_regs *regs); -+extern int singlestepping_skas(void); -+extern int new_mm(int from); -+extern void save_registers(union uml_pt_regs *regs); -+extern void restore_registers(union uml_pt_regs *regs); -+extern void start_userspace(int cpu); -+extern void init_registers(int pid); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/include/uaccess.h um/arch/um/kernel/skas/include/uaccess.h ---- orig/arch/um/kernel/skas/include/uaccess.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/skas/include/uaccess.h 2004-01-17 06:35:41.000000000 -0500 -@@ -0,0 +1,40 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __SKAS_UACCESS_H -+#define __SKAS_UACCESS_H -+ -+#include "asm/errno.h" -+ -+#define access_ok_skas(type, addr, size) \ -+ ((segment_eq(get_fs(), KERNEL_DS)) || \ -+ (((unsigned long) (addr) < TASK_SIZE) && \ -+ ((unsigned long) (addr) + (size) <= TASK_SIZE))) -+ -+static inline int verify_area_skas(int type, const void * addr, -+ unsigned long size) -+{ -+ return(access_ok_skas(type, addr, size) ? 0 : -EFAULT); -+} -+ -+extern int copy_from_user_skas(void *to, const void *from, int n); -+extern int copy_to_user_skas(void *to, const void *from, int n); -+extern int strncpy_from_user_skas(char *dst, const char *src, int count); -+extern int __clear_user_skas(void *mem, int len); -+extern int clear_user_skas(void *mem, int len); -+extern int strnlen_user_skas(const void *str, int len); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/Makefile um/arch/um/kernel/skas/Makefile ---- orig/arch/um/kernel/skas/Makefile 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/skas/Makefile 2003-11-11 06:36:12.000000000 -0500 -@@ -0,0 +1,31 @@ -+# -+# Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+# Licensed under the GPL -+# -+ -+O_TARGET = skas.o -+ -+obj-y = exec_kern.o exec_user.o mem.o mem_user.o mmu.o process.o \ -+ process_kern.o syscall_kern.o syscall_user.o time.o tlb.o trap_user.o \ -+ uaccess.o -+ -+subdir-y = sys-$(SUBARCH) -+ -+obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o)) -+ -+USER_OBJS = $(filter %_user.o,$(obj-y)) process.o time.o -+ -+include $(TOPDIR)/Rules.make -+ -+include/skas_ptregs.h : util/mk_ptregs -+ util/mk_ptregs > $@ -+ -+util/mk_ptregs : -+ $(MAKE) -C util -+ -+$(USER_OBJS) : %.o: %.c -+ $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $< -+ -+clean : -+ $(MAKE) -C util clean -+ $(RM) -f include/skas_ptregs.h -diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/mem.c um/arch/um/kernel/skas/mem.c ---- orig/arch/um/kernel/skas/mem.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/skas/mem.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,30 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/config.h" -+#include "linux/mm.h" -+#include "mem_user.h" -+ -+unsigned long set_task_sizes_skas(int arg, unsigned long *host_size_out, -+ unsigned long *task_size_out) -+{ -+ /* Round up to the nearest 4M */ -+ unsigned long top = ROUND_4M((unsigned long) &arg); -+ -+ *host_size_out = top; -+ *task_size_out = top; -+ return(((unsigned long) set_task_sizes_skas) & ~0xffffff); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/mem_user.c um/arch/um/kernel/skas/mem_user.c ---- orig/arch/um/kernel/skas/mem_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/skas/mem_user.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,105 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <errno.h> -+#include <sys/mman.h> -+#include <sys/ptrace.h> -+#include "mem_user.h" -+#include "mem.h" -+#include "user.h" -+#include "os.h" -+#include "proc_mm.h" -+ -+void map(int fd, unsigned long virt, unsigned long phys, unsigned long len, -+ int r, int w, int x) -+{ -+ struct proc_mm_op map; -+ __u64 offset; -+ int prot, n, phys_fd; -+ -+ prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | -+ (x ? PROT_EXEC : 0); -+ phys_fd = phys_mapping(phys, &offset); -+ -+ map = ((struct proc_mm_op) { .op = MM_MMAP, -+ .u = -+ { .mmap = -+ { .addr = virt, -+ .len = len, -+ .prot = prot, -+ .flags = MAP_SHARED | -+ MAP_FIXED, -+ .fd = phys_fd, -+ .offset = offset -+ } } } ); -+ n = os_write_file(fd, &map, sizeof(map)); -+ if(n != sizeof(map)) -+ printk("map : /proc/mm map failed, err = %d\n", -n); -+} -+ -+int unmap(int fd, void *addr, int len) -+{ -+ struct proc_mm_op unmap; -+ int n; -+ -+ unmap = ((struct proc_mm_op) { .op = MM_MUNMAP, -+ .u = -+ { .munmap = -+ { .addr = (unsigned long) addr, -+ .len = len } } } ); -+ n = os_write_file(fd, &unmap, sizeof(unmap)); -+ if(n != sizeof(unmap)) { -+ if(n < 0) -+ return(n); -+ else if(n > 0) -+ return(-EIO); -+ } -+ -+ return(0); -+} -+ -+int protect(int fd, unsigned long addr, unsigned long len, int r, int w, -+ int x, int must_succeed) -+{ -+ struct proc_mm_op protect; -+ int prot, n; -+ -+ prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | -+ (x ? PROT_EXEC : 0); -+ -+ protect = ((struct proc_mm_op) { .op = MM_MPROTECT, -+ .u = -+ { .mprotect = -+ { .addr = (unsigned long) addr, -+ .len = len, -+ .prot = prot } } } ); -+ -+ n = os_write_file(fd, &protect, sizeof(protect)); -+ if(n != sizeof(protect)) { -+ if(n == 0) return(0); -+ -+ if(must_succeed) -+ panic("protect failed, err = %d", -n); -+ -+ return(-EIO); -+ } -+ -+ return(0); -+} -+ -+void before_mem_skas(unsigned long unused) -+{ -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/mmu.c um/arch/um/kernel/skas/mmu.c ---- orig/arch/um/kernel/skas/mmu.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/skas/mmu.c 2003-11-15 22:25:20.000000000 -0500 -@@ -0,0 +1,46 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/list.h" -+#include "linux/spinlock.h" -+#include "linux/slab.h" -+#include "asm/segment.h" -+#include "asm/mmu.h" -+#include "os.h" -+#include "skas.h" -+ -+int init_new_context_skas(struct task_struct *task, struct mm_struct *mm) -+{ -+ int from; -+ -+ if((current->mm != NULL) && (current->mm != &init_mm)) -+ from = current->mm->context.skas.mm_fd; -+ else from = -1; -+ -+ mm->context.skas.mm_fd = new_mm(from); -+ if(mm->context.skas.mm_fd < 0){ -+ printk("init_new_context_skas - new_mm failed, errno = %d\n", -+ mm->context.skas.mm_fd); -+ return(mm->context.skas.mm_fd); -+ } -+ -+ return(0); -+} -+ -+void destroy_context_skas(struct mm_struct *mm) -+{ -+ os_close_file(mm->context.skas.mm_fd); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/process.c um/arch/um/kernel/skas/process.c ---- orig/arch/um/kernel/skas/process.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/skas/process.c 2004-01-31 02:49:36.000000000 -0500 -@@ -0,0 +1,417 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <stdlib.h> -+#include <unistd.h> -+#include <errno.h> -+#include <signal.h> -+#include <setjmp.h> -+#include <sched.h> -+#include <sys/wait.h> -+#include <sys/ptrace.h> -+#include <sys/mman.h> -+#include <sys/user.h> -+#include <asm/unistd.h> -+#include "user.h" -+#include "ptrace_user.h" -+#include "time_user.h" -+#include "sysdep/ptrace.h" -+#include "user_util.h" -+#include "kern_util.h" -+#include "skas.h" -+#include "sysdep/sigcontext.h" -+#include "os.h" -+#include "proc_mm.h" -+#include "skas_ptrace.h" -+#include "chan_user.h" -+ -+int is_skas_winch(int pid, int fd, void *data) -+{ -+ if(pid != getpid()) -+ return(0); -+ -+ register_winch_irq(-1, fd, -1, data); -+ return(1); -+} -+ -+/* These are set once at boot time and not changed thereafter */ -+ -+unsigned long exec_regs[FRAME_SIZE]; -+unsigned long exec_fp_regs[HOST_FP_SIZE]; -+unsigned long exec_fpx_regs[HOST_XFP_SIZE]; -+int have_fpx_regs = 1; -+ -+static void handle_segv(int pid) -+{ -+ struct ptrace_faultinfo fault; -+ int err; -+ -+ err = ptrace(PTRACE_FAULTINFO, pid, 0, &fault); -+ if(err) -+ panic("handle_segv - PTRACE_FAULTINFO failed, errno = %d\n", -+ errno); -+ -+ segv(fault.addr, 0, FAULT_WRITE(fault.is_write), 1, NULL); -+} -+ -+static void handle_trap(int pid, union uml_pt_regs *regs) -+{ -+ int err, syscall_nr, status; -+ -+ syscall_nr = PT_SYSCALL_NR(regs->skas.regs); -+ UPT_SYSCALL_NR(regs) = syscall_nr; -+ if(syscall_nr < 1){ -+ relay_signal(SIGTRAP, regs); -+ return; -+ } -+ -+ err = ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_getpid); -+ if(err < 0) -+ panic("handle_trap - nullifying syscall failed errno = %d\n", -+ errno); -+ -+ err = ptrace(PTRACE_SYSCALL, pid, 0, 0); -+ if(err < 0) -+ panic("handle_trap - continuing to end of syscall failed, " -+ "errno = %d\n", errno); -+ -+ err = waitpid(pid, &status, WUNTRACED); -+ if((err < 0) || !WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) -+ panic("handle_trap - failed to wait at end of syscall, " -+ "errno = %d, status = %d\n", errno, status); -+ -+ handle_syscall(regs); -+} -+ -+static int userspace_tramp(void *arg) -+{ -+ init_new_thread_signals(0); -+ enable_timer(); -+ ptrace(PTRACE_TRACEME, 0, 0, 0); -+ os_stop_process(os_getpid()); -+ return(0); -+} -+ -+/* Each element set once, and only accessed by a single processor anyway */ -+#define NR_CPUS 1 -+int userspace_pid[NR_CPUS]; -+ -+void start_userspace(int cpu) -+{ -+ void *stack; -+ unsigned long sp; -+ int pid, status, n; -+ -+ stack = mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC, -+ MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); -+ if(stack == MAP_FAILED) -+ panic("start_userspace : mmap failed, errno = %d", errno); -+ sp = (unsigned long) stack + PAGE_SIZE - sizeof(void *); -+ -+ pid = clone(userspace_tramp, (void *) sp, -+ CLONE_FILES | CLONE_VM | SIGCHLD, NULL); -+ if(pid < 0) -+ panic("start_userspace : clone failed, errno = %d", errno); -+ -+ do { -+ n = waitpid(pid, &status, WUNTRACED); -+ if(n < 0) -+ panic("start_userspace : wait failed, errno = %d", -+ errno); -+ } while(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM)); -+ -+ if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) -+ panic("start_userspace : expected SIGSTOP, got status = %d", -+ status); -+ -+ if(munmap(stack, PAGE_SIZE) < 0) -+ panic("start_userspace : munmap failed, errno = %d\n", errno); -+ -+ userspace_pid[cpu] = pid; -+} -+ -+void userspace(union uml_pt_regs *regs) -+{ -+ int err, status, op, pid = userspace_pid[0]; -+ -+ restore_registers(regs); -+ -+ err = ptrace(PTRACE_SYSCALL, pid, 0, 0); -+ if(err) -+ panic("userspace - PTRACE_SYSCALL failed, errno = %d\n", -+ errno); -+ while(1){ -+ err = waitpid(pid, &status, WUNTRACED); -+ if(err < 0) -+ panic("userspace - waitpid failed, errno = %d\n", -+ errno); -+ -+ regs->skas.is_user = 1; -+ save_registers(regs); -+ -+ if(WIFSTOPPED(status)){ -+ switch(WSTOPSIG(status)){ -+ case SIGSEGV: -+ handle_segv(pid); -+ break; -+ case SIGTRAP: -+ handle_trap(pid, regs); -+ break; -+ case SIGIO: -+ case SIGVTALRM: -+ case SIGILL: -+ case SIGBUS: -+ case SIGFPE: -+ case SIGWINCH: -+ user_signal(WSTOPSIG(status), regs); -+ break; -+ default: -+ printk("userspace - child stopped with signal " -+ "%d\n", WSTOPSIG(status)); -+ } -+ interrupt_end(); -+ } -+ -+ restore_registers(regs); -+ -+ op = singlestepping_skas() ? PTRACE_SINGLESTEP : -+ PTRACE_SYSCALL; -+ err = ptrace(op, pid, 0, 0); -+ if(err) -+ panic("userspace - PTRACE_SYSCALL failed, " -+ "errno = %d\n", errno); -+ } -+} -+ -+void new_thread(void *stack, void **switch_buf_ptr, void **fork_buf_ptr, -+ void (*handler)(int)) -+{ -+ sigjmp_buf switch_buf, fork_buf; -+ -+ *switch_buf_ptr = &switch_buf; -+ *fork_buf_ptr = &fork_buf; -+ -+ if(sigsetjmp(fork_buf, 1) == 0) -+ new_thread_proc(stack, handler); -+ -+ remove_sigstack(); -+} -+ -+void thread_wait(void *sw, void *fb) -+{ -+ sigjmp_buf buf, **switch_buf = sw, *fork_buf; -+ -+ *switch_buf = &buf; -+ fork_buf = fb; -+ if(sigsetjmp(buf, 1) == 0) -+ siglongjmp(*fork_buf, 1); -+} -+ -+static int move_registers(int pid, int int_op, int fp_op, -+ union uml_pt_regs *regs, unsigned long *fp_regs) -+{ -+ if(ptrace(int_op, pid, 0, regs->skas.regs) < 0) -+ return(-errno); -+ if(ptrace(fp_op, pid, 0, fp_regs) < 0) -+ return(-errno); -+ return(0); -+} -+ -+void save_registers(union uml_pt_regs *regs) -+{ -+ unsigned long *fp_regs; -+ int err, fp_op; -+ -+ if(have_fpx_regs){ -+ fp_op = PTRACE_GETFPXREGS; -+ fp_regs = regs->skas.xfp; -+ } -+ else { -+ fp_op = PTRACE_GETFPREGS; -+ fp_regs = regs->skas.fp; -+ } -+ -+ err = move_registers(userspace_pid[0], PTRACE_GETREGS, fp_op, regs, -+ fp_regs); -+ if(err) -+ panic("save_registers - saving registers failed, errno = %d\n", -+ -err); -+} -+ -+void restore_registers(union uml_pt_regs *regs) -+{ -+ unsigned long *fp_regs; -+ int err, fp_op; -+ -+ if(have_fpx_regs){ -+ fp_op = PTRACE_SETFPXREGS; -+ fp_regs = regs->skas.xfp; -+ } -+ else { -+ fp_op = PTRACE_SETFPREGS; -+ fp_regs = regs->skas.fp; -+ } -+ -+ err = move_registers(userspace_pid[0], PTRACE_SETREGS, fp_op, regs, -+ fp_regs); -+ if(err) -+ panic("restore_registers - saving registers failed, " -+ "errno = %d\n", -err); -+} -+ -+void switch_threads(void *me, void *next) -+{ -+ sigjmp_buf my_buf, **me_ptr = me, *next_buf = next; -+ -+ *me_ptr = &my_buf; -+ if(sigsetjmp(my_buf, 1) == 0) -+ siglongjmp(*next_buf, 1); -+} -+ -+static sigjmp_buf initial_jmpbuf; -+ -+/* XXX Make these percpu */ -+static void (*cb_proc)(void *arg); -+static void *cb_arg; -+static sigjmp_buf *cb_back; -+ -+int start_idle_thread(void *stack, void *switch_buf_ptr, void **fork_buf_ptr) -+{ -+ sigjmp_buf **switch_buf = switch_buf_ptr; -+ int n; -+ -+ *fork_buf_ptr = &initial_jmpbuf; -+ n = sigsetjmp(initial_jmpbuf, 1); -+ if(n == 0) -+ new_thread_proc((void *) stack, new_thread_handler); -+ else if(n == 1) -+ remove_sigstack(); -+ else if(n == 2){ -+ (*cb_proc)(cb_arg); -+ siglongjmp(*cb_back, 1); -+ } -+ else if(n == 3){ -+ kmalloc_ok = 0; -+ return(0); -+ } -+ else if(n == 4){ -+ kmalloc_ok = 0; -+ return(1); -+ } -+ siglongjmp(**switch_buf, 1); -+} -+ -+void remove_sigstack(void) -+{ -+ stack_t stack = ((stack_t) { .ss_flags = SS_DISABLE, -+ .ss_sp = NULL, -+ .ss_size = 0 }); -+ -+ if(sigaltstack(&stack, NULL) != 0) -+ panic("disabling signal stack failed, errno = %d\n", errno); -+} -+ -+void initial_thread_cb_skas(void (*proc)(void *), void *arg) -+{ -+ sigjmp_buf here; -+ -+ cb_proc = proc; -+ cb_arg = arg; -+ cb_back = &here; -+ -+ block_signals(); -+ if(sigsetjmp(here, 1) == 0) -+ siglongjmp(initial_jmpbuf, 2); -+ unblock_signals(); -+ -+ cb_proc = NULL; -+ cb_arg = NULL; -+ cb_back = NULL; -+} -+ -+void halt_skas(void) -+{ -+ block_signals(); -+ siglongjmp(initial_jmpbuf, 3); -+} -+ -+void reboot_skas(void) -+{ -+ block_signals(); -+ siglongjmp(initial_jmpbuf, 4); -+} -+ -+int new_mm(int from) -+{ -+ struct proc_mm_op copy; -+ int n, fd = os_open_file("/proc/mm", -+ of_cloexec(of_write(OPENFLAGS())), 0); -+ -+ if(fd < 0) -+ return(fd); -+ -+ if(from != -1){ -+ copy = ((struct proc_mm_op) { .op = MM_COPY_SEGMENTS, -+ .u = -+ { .copy_segments = from } } ); -+ n = os_write_file(fd, ©, sizeof(copy)); -+ if(n != sizeof(copy)) -+ printk("new_mm : /proc/mm copy_segments failed, " -+ "err = %d\n", -n); -+ } -+ -+ return(fd); -+} -+ -+void switch_mm_skas(int mm_fd) -+{ -+ int err; -+ -+#warning need cpu pid in switch_mm_skas -+ err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, mm_fd); -+ if(err) -+ panic("switch_mm_skas - PTRACE_SWITCH_MM failed, errno = %d\n", -+ errno); -+} -+ -+void kill_off_processes_skas(void) -+{ -+#warning need to loop over userspace_pids in kill_off_processes_skas -+ os_kill_process(userspace_pid[0], 1); -+} -+ -+void init_registers(int pid) -+{ -+ int err; -+ -+ if(ptrace(PTRACE_GETREGS, pid, 0, exec_regs) < 0) -+ panic("check_ptrace : PTRACE_GETREGS failed, errno = %d", -+ errno); -+ -+ err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs); -+ if(!err) -+ return; -+ -+ have_fpx_regs = 0; -+ if(errno != EIO) -+ panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d", -+ errno); -+ -+ err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs); -+ if(err) -+ panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d", -+ errno); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/process_kern.c um/arch/um/kernel/skas/process_kern.c ---- orig/arch/um/kernel/skas/process_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/skas/process_kern.c 2003-11-19 03:18:25.000000000 -0500 -@@ -0,0 +1,196 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/sched.h" -+#include "linux/slab.h" -+#include "kern_util.h" -+#include "time_user.h" -+#include "signal_user.h" -+#include "skas.h" -+#include "os.h" -+#include "user_util.h" -+#include "tlb.h" -+#include "frame.h" -+#include "kern.h" -+#include "mode.h" -+ -+int singlestepping_skas(void) -+{ -+ int ret = current->ptrace & PT_DTRACE; -+ -+ current->ptrace &= ~PT_DTRACE; -+ return(ret); -+} -+ -+void *_switch_to_skas(void *prev, void *next) -+{ -+ struct task_struct *from, *to; -+ -+ from = prev; -+ to = next; -+ -+ /* XXX need to check runqueues[cpu].idle */ -+ if(current->pid == 0) -+ switch_timers(0); -+ -+ to->thread.prev_sched = from; -+ set_current(to); -+ -+ switch_threads(&from->thread.mode.skas.switch_buf, -+ to->thread.mode.skas.switch_buf); -+ -+ if(current->pid == 0) -+ switch_timers(1); -+ -+ return(current->thread.prev_sched); -+} -+ -+extern void schedule_tail(struct task_struct *prev); -+ -+void new_thread_handler(int sig) -+{ -+ int (*fn)(void *), n; -+ void *arg; -+ -+ fn = current->thread.request.u.thread.proc; -+ arg = current->thread.request.u.thread.arg; -+ change_sig(SIGUSR1, 1); -+ thread_wait(¤t->thread.mode.skas.switch_buf, -+ current->thread.mode.skas.fork_buf); -+ -+ if(current->thread.prev_sched != NULL) -+ schedule_tail(current->thread.prev_sched); -+ current->thread.prev_sched = NULL; -+ -+ /* The return value is 1 if the kernel thread execs a process, -+ * 0 if it just exits -+ */ -+ n = run_kernel_thread(fn, arg, ¤t->thread.exec_buf); -+ if(n == 1) -+ userspace(¤t->thread.regs.regs); -+ else do_exit(0); -+} -+ -+void new_thread_proc(void *stack, void (*handler)(int sig)) -+{ -+ init_new_thread_stack(stack, handler); -+ os_usr1_process(os_getpid()); -+} -+ -+void release_thread_skas(struct task_struct *task) -+{ -+} -+ -+void exit_thread_skas(void) -+{ -+} -+ -+void fork_handler(int sig) -+{ -+ change_sig(SIGUSR1, 1); -+ thread_wait(¤t->thread.mode.skas.switch_buf, -+ current->thread.mode.skas.fork_buf); -+ -+ force_flush_all(); -+ if(current->thread.prev_sched != NULL) -+ schedule_tail(current->thread.prev_sched); -+ current->thread.prev_sched = NULL; -+ unblock_signals(); -+ -+ userspace(¤t->thread.regs.regs); -+} -+ -+int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp, -+ unsigned long stack_top, struct task_struct * p, -+ struct pt_regs *regs) -+{ -+ void (*handler)(int); -+ -+ if(current->thread.forking){ -+ memcpy(&p->thread.regs.regs.skas, -+ ¤t->thread.regs.regs.skas, -+ sizeof(p->thread.regs.regs.skas)); -+ REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.skas.regs, 0); -+ if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp; -+ -+ handler = fork_handler; -+ } -+ else { -+ memcpy(p->thread.regs.regs.skas.regs, exec_regs, -+ sizeof(p->thread.regs.regs.skas.regs)); -+ memcpy(p->thread.regs.regs.skas.fp, exec_fp_regs, -+ sizeof(p->thread.regs.regs.skas.fp)); -+ memcpy(p->thread.regs.regs.skas.xfp, exec_fpx_regs, -+ sizeof(p->thread.regs.regs.skas.xfp)); -+ p->thread.request.u.thread = current->thread.request.u.thread; -+ handler = new_thread_handler; -+ } -+ -+ new_thread((void *) p->thread.kernel_stack, -+ &p->thread.mode.skas.switch_buf, -+ &p->thread.mode.skas.fork_buf, handler); -+ return(0); -+} -+ -+void init_idle_skas(void) -+{ -+ cpu_tasks[current->processor].pid = os_getpid(); -+} -+ -+extern void start_kernel(void); -+ -+static int start_kernel_proc(void *unused) -+{ -+ int pid; -+ -+ block_signals(); -+ pid = os_getpid(); -+ -+ cpu_tasks[0].pid = pid; -+ cpu_tasks[0].task = current; -+#ifdef CONFIG_SMP -+ cpu_online_map = 1; -+#endif -+ start_kernel(); -+ return(0); -+} -+ -+int start_uml_skas(void) -+{ -+ start_userspace(0); -+ capture_signal_stack(); -+ idle_timer(); -+ -+ init_new_thread_signals(1); -+ -+ init_task.thread.request.u.thread.proc = start_kernel_proc; -+ init_task.thread.request.u.thread.arg = NULL; -+ return(start_idle_thread((void *) init_task.thread.kernel_stack, -+ &init_task.thread.mode.skas.switch_buf, -+ &init_task.thread.mode.skas.fork_buf)); -+} -+ -+int external_pid_skas(struct task_struct *task) -+{ -+#warning Need to look up userspace_pid by cpu -+ return(userspace_pid[0]); -+} -+ -+int thread_pid_skas(struct thread_struct *thread) -+{ -+#warning Need to look up userspace_pid by cpu -+ return(userspace_pid[0]); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/syscall_kern.c um/arch/um/kernel/skas/syscall_kern.c ---- orig/arch/um/kernel/skas/syscall_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/skas/syscall_kern.c 2004-01-04 08:20:29.000000000 -0500 -@@ -0,0 +1,42 @@ -+/* -+ * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/sys.h" -+#include "asm/errno.h" -+#include "asm/unistd.h" -+#include "asm/ptrace.h" -+#include "asm/current.h" -+#include "sysdep/syscalls.h" -+#include "kern_util.h" -+ -+extern syscall_handler_t *sys_call_table[]; -+ -+long execute_syscall_skas(void *r) -+{ -+ struct pt_regs *regs = r; -+ long res; -+ int syscall; -+ -+ current->thread.nsyscalls++; -+ nsyscalls++; -+ syscall = UPT_SYSCALL_NR(®s->regs); -+ -+ if((syscall >= NR_syscalls) || (syscall < 1)) -+ res = -ENOSYS; -+ else res = EXECUTE_SYSCALL(syscall, regs); -+ -+ return(res); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/syscall_user.c um/arch/um/kernel/skas/syscall_user.c ---- orig/arch/um/kernel/skas/syscall_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/skas/syscall_user.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,46 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <stdlib.h> -+#include <signal.h> -+#include "kern_util.h" -+#include "syscall_user.h" -+#include "sysdep/ptrace.h" -+#include "sysdep/sigcontext.h" -+ -+/* XXX Bogus */ -+#define ERESTARTSYS 512 -+#define ERESTARTNOINTR 513 -+#define ERESTARTNOHAND 514 -+ -+void handle_syscall(union uml_pt_regs *regs) -+{ -+ long result; -+ int index; -+ -+ index = record_syscall_start(UPT_SYSCALL_NR(regs)); -+ -+ syscall_trace(); -+ result = execute_syscall(regs); -+ -+ REGS_SET_SYSCALL_RETURN(regs->skas.regs, result); -+ if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) || -+ (result == -ERESTARTNOINTR)) -+ do_signal(result); -+ -+ syscall_trace(); -+ record_syscall_end(index, result); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/sys-i386/Makefile um/arch/um/kernel/skas/sys-i386/Makefile ---- orig/arch/um/kernel/skas/sys-i386/Makefile 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/skas/sys-i386/Makefile 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,17 @@ -+# -+# Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+# Licensed under the GPL -+# -+ -+O_TARGET = sys-i386.o -+ -+obj-y = sigcontext.o -+ -+USER_OBJS = sigcontext.o -+ -+include $(TOPDIR)/Rules.make -+ -+$(USER_OBJS) : %.o: %.c -+ $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $< -+ -+clean : -diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/sys-i386/sigcontext.c um/arch/um/kernel/skas/sys-i386/sigcontext.c ---- orig/arch/um/kernel/skas/sys-i386/sigcontext.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/skas/sys-i386/sigcontext.c 2003-11-19 03:27:43.000000000 -0500 -@@ -0,0 +1,114 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <errno.h> -+#include <asm/sigcontext.h> -+#include <sys/ptrace.h> -+#include <linux/ptrace.h> -+#include "sysdep/ptrace.h" -+#include "sysdep/ptrace_user.h" -+#include "kern_util.h" -+#include "user.h" -+#include "sigcontext.h" -+#include "mode.h" -+ -+int copy_sc_from_user_skas(int pid, union uml_pt_regs *regs, void *from_ptr) -+{ -+ struct sigcontext sc, *from = from_ptr; -+ unsigned long fpregs[FP_FRAME_SIZE]; -+ int err; -+ -+ err = copy_from_user_proc(&sc, from, sizeof(sc)); -+ err |= copy_from_user_proc(fpregs, sc.fpstate, sizeof(fpregs)); -+ if(err) -+ return(err); -+ -+ regs->skas.regs[GS] = sc.gs; -+ regs->skas.regs[FS] = sc.fs; -+ regs->skas.regs[ES] = sc.es; -+ regs->skas.regs[DS] = sc.ds; -+ regs->skas.regs[EDI] = sc.edi; -+ regs->skas.regs[ESI] = sc.esi; -+ regs->skas.regs[EBP] = sc.ebp; -+ regs->skas.regs[UESP] = sc.esp; -+ regs->skas.regs[EBX] = sc.ebx; -+ regs->skas.regs[EDX] = sc.edx; -+ regs->skas.regs[ECX] = sc.ecx; -+ regs->skas.regs[EAX] = sc.eax; -+ regs->skas.regs[EIP] = sc.eip; -+ regs->skas.regs[CS] = sc.cs; -+ regs->skas.regs[EFL] = sc.eflags; -+ regs->skas.regs[SS] = sc.ss; -+ regs->skas.fault_addr = sc.cr2; -+ regs->skas.fault_type = FAULT_WRITE(sc.err); -+ regs->skas.trap_type = sc.trapno; -+ -+ err = ptrace(PTRACE_SETFPREGS, pid, 0, fpregs); -+ if(err < 0){ -+ printk("copy_sc_to_user - PTRACE_SETFPREGS failed, " -+ "errno = %d\n", errno); -+ return(1); -+ } -+ -+ return(0); -+} -+ -+int copy_sc_to_user_skas(int pid, void *to_ptr, void *fp, -+ union uml_pt_regs *regs, unsigned long fault_addr, -+ int fault_type) -+{ -+ struct sigcontext sc, *to = to_ptr; -+ struct _fpstate *to_fp; -+ unsigned long fpregs[FP_FRAME_SIZE]; -+ int err; -+ -+ sc.gs = regs->skas.regs[GS]; -+ sc.fs = regs->skas.regs[FS]; -+ sc.es = regs->skas.regs[ES]; -+ sc.ds = regs->skas.regs[DS]; -+ sc.edi = regs->skas.regs[EDI]; -+ sc.esi = regs->skas.regs[ESI]; -+ sc.ebp = regs->skas.regs[EBP]; -+ sc.esp = regs->skas.regs[UESP]; -+ sc.ebx = regs->skas.regs[EBX]; -+ sc.edx = regs->skas.regs[EDX]; -+ sc.ecx = regs->skas.regs[ECX]; -+ sc.eax = regs->skas.regs[EAX]; -+ sc.eip = regs->skas.regs[EIP]; -+ sc.cs = regs->skas.regs[CS]; -+ sc.eflags = regs->skas.regs[EFL]; -+ sc.esp_at_signal = regs->skas.regs[UESP]; -+ sc.ss = regs->skas.regs[SS]; -+ sc.cr2 = fault_addr; -+ sc.err = TO_SC_ERR(fault_type); -+ sc.trapno = regs->skas.trap_type; -+ -+ err = ptrace(PTRACE_GETFPREGS, pid, 0, fpregs); -+ if(err < 0){ -+ printk("copy_sc_to_user - PTRACE_GETFPREGS failed, " -+ "errno = %d\n", errno); -+ return(1); -+ } -+ to_fp = (struct _fpstate *) -+ (fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to))); -+ sc.fpstate = to_fp; -+ -+ if(err) -+ return(err); -+ -+ return(copy_to_user_proc(to, &sc, sizeof(sc)) || -+ copy_to_user_proc(to_fp, fpregs, sizeof(fpregs))); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/time.c um/arch/um/kernel/skas/time.c ---- orig/arch/um/kernel/skas/time.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/skas/time.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,30 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <sys/signal.h> -+#include <sys/time.h> -+#include "time_user.h" -+#include "process.h" -+#include "user.h" -+ -+void user_time_init_skas(void) -+{ -+ if(signal(SIGALRM, (__sighandler_t) alarm_handler) == SIG_ERR) -+ panic("Couldn't set SIGALRM handler"); -+ if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR) -+ panic("Couldn't set SIGVTALRM handler"); -+ set_interval(ITIMER_VIRTUAL); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/tlb.c um/arch/um/kernel/skas/tlb.c ---- orig/arch/um/kernel/skas/tlb.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/skas/tlb.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,153 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/stddef.h" -+#include "linux/sched.h" -+#include "asm/page.h" -+#include "asm/pgtable.h" -+#include "asm/mmu.h" -+#include "user_util.h" -+#include "mem_user.h" -+#include "skas.h" -+#include "os.h" -+ -+static void fix_range(struct mm_struct *mm, unsigned long start_addr, -+ unsigned long end_addr, int force) -+{ -+ pgd_t *npgd; -+ pmd_t *npmd; -+ pte_t *npte; -+ unsigned long addr; -+ int r, w, x, err, fd; -+ -+ if(mm == NULL) return; -+ fd = mm->context.skas.mm_fd; -+ for(addr = start_addr; addr < end_addr;){ -+ npgd = pgd_offset(mm, addr); -+ npmd = pmd_offset(npgd, addr); -+ if(pmd_present(*npmd)){ -+ npte = pte_offset(npmd, addr); -+ r = pte_read(*npte); -+ w = pte_write(*npte); -+ x = pte_exec(*npte); -+ if(!pte_dirty(*npte)) w = 0; -+ if(!pte_young(*npte)){ -+ r = 0; -+ w = 0; -+ } -+ if(force || pte_newpage(*npte)){ -+ err = unmap(fd, (void *) addr, PAGE_SIZE); -+ if(err < 0) -+ panic("munmap failed, errno = %d\n", -+ -err); -+ if(pte_present(*npte)) -+ map(fd, addr, -+ pte_val(*npte) & PAGE_MASK, -+ PAGE_SIZE, r, w, x); -+ } -+ else if(pte_newprot(*npte)){ -+ protect(fd, addr, PAGE_SIZE, r, w, x, 1); -+ } -+ *npte = pte_mkuptodate(*npte); -+ addr += PAGE_SIZE; -+ } -+ else { -+ if(force || pmd_newpage(*npmd)){ -+ err = unmap(fd, (void *) addr, PMD_SIZE); -+ if(err < 0) -+ panic("munmap failed, errno = %d\n", -+ -err); -+ pmd_mkuptodate(*npmd); -+ } -+ addr += PMD_SIZE; -+ } -+ } -+} -+ -+static void flush_kernel_vm_range(unsigned long start, unsigned long end) -+{ -+ struct mm_struct *mm; -+ pgd_t *pgd; -+ pmd_t *pmd; -+ pte_t *pte; -+ unsigned long addr; -+ int updated = 0, err; -+ -+ mm = &init_mm; -+ for(addr = start_vm; addr < end_vm;){ -+ pgd = pgd_offset(mm, addr); -+ pmd = pmd_offset(pgd, addr); -+ if(pmd_present(*pmd)){ -+ pte = pte_offset(pmd, addr); -+ if(!pte_present(*pte) || pte_newpage(*pte)){ -+ updated = 1; -+ err = os_unmap_memory((void *) addr, -+ PAGE_SIZE); -+ if(err < 0) -+ panic("munmap failed, errno = %d\n", -+ -err); -+ if(pte_present(*pte)) -+ map_memory(addr, -+ pte_val(*pte) & PAGE_MASK, -+ PAGE_SIZE, 1, 1, 1); -+ } -+ else if(pte_newprot(*pte)){ -+ updated = 1; -+ protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1); -+ } -+ addr += PAGE_SIZE; -+ } -+ else { -+ if(pmd_newpage(*pmd)){ -+ updated = 1; -+ err = os_unmap_memory((void *) addr, PMD_SIZE); -+ if(err < 0) -+ panic("munmap failed, errno = %d\n", -+ -err); -+ } -+ addr += PMD_SIZE; -+ } -+ } -+} -+ -+void flush_tlb_kernel_vm_skas(void) -+{ -+ flush_kernel_vm_range(start_vm, end_vm); -+} -+ -+void __flush_tlb_one_skas(unsigned long addr) -+{ -+ flush_kernel_vm_range(addr, addr + PAGE_SIZE); -+} -+ -+void flush_tlb_range_skas(struct mm_struct *mm, unsigned long start, -+ unsigned long end) -+{ -+ if(mm == NULL) -+ flush_kernel_vm_range(start, end); -+ else fix_range(mm, start, end, 0); -+} -+ -+void flush_tlb_mm_skas(struct mm_struct *mm) -+{ -+ flush_tlb_kernel_vm_skas(); -+ fix_range(mm, 0, host_task_size, 0); -+} -+ -+void force_flush_all_skas(void) -+{ -+ fix_range(current->mm, 0, host_task_size, 1); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/trap_user.c um/arch/um/kernel/skas/trap_user.c ---- orig/arch/um/kernel/skas/trap_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/skas/trap_user.c 2004-01-21 01:17:05.000000000 -0500 -@@ -0,0 +1,66 @@ -+/* -+ * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com) -+ * Licensed under the GPL -+ */ -+ -+#include <signal.h> -+#include <errno.h> -+#include <asm/sigcontext.h> -+#include "sysdep/ptrace.h" -+#include "signal_user.h" -+#include "user_util.h" -+#include "kern_util.h" -+#include "task.h" -+#include "sigcontext.h" -+ -+void sig_handler_common_skas(int sig, void *sc_ptr) -+{ -+ struct sigcontext *sc = sc_ptr; -+ struct skas_regs *r; -+ struct signal_info *info; -+ int save_errno = errno; -+ int save_user; -+ -+ r = &TASK_REGS(get_current())->skas; -+ save_user = r->is_user; -+ r->is_user = 0; -+ r->fault_addr = SC_FAULT_ADDR(sc); -+ r->fault_type = SC_FAULT_TYPE(sc); -+ r->trap_type = SC_TRAP_TYPE(sc); -+ -+ change_sig(SIGUSR1, 1); -+ info = &sig_info[sig]; -+ if(!info->is_irq) unblock_signals(); -+ -+ (*info->handler)(sig, (union uml_pt_regs *) r); -+ -+ errno = save_errno; -+ r->is_user = save_user; -+} -+ -+extern int missed_ticks[]; -+ -+void user_signal(int sig, union uml_pt_regs *regs) -+{ -+ struct signal_info *info; -+ -+ regs->skas.is_user = 1; -+ regs->skas.fault_addr = 0; -+ regs->skas.fault_type = 0; -+ regs->skas.trap_type = 0; -+ info = &sig_info[sig]; -+ (*info->handler)(sig, regs); -+ -+ unblock_signals(); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/uaccess.c um/arch/um/kernel/skas/uaccess.c ---- orig/arch/um/kernel/skas/uaccess.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/skas/uaccess.c 2003-12-22 01:30:09.000000000 -0500 -@@ -0,0 +1,217 @@ -+/* -+ * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/stddef.h" -+#include "linux/kernel.h" -+#include "linux/string.h" -+#include "linux/fs.h" -+#include "linux/highmem.h" -+#include "asm/page.h" -+#include "asm/pgtable.h" -+#include "asm/uaccess.h" -+#include "kern_util.h" -+ -+extern void *um_virt_to_phys(struct task_struct *task, unsigned long addr, -+ pte_t *pte_out); -+ -+static unsigned long maybe_map(unsigned long virt, int is_write) -+{ -+ pte_t pte; -+ -+ void *phys = um_virt_to_phys(current, virt, &pte); -+ int dummy_code; -+ -+ if(IS_ERR(phys) || (is_write && !pte_write(pte))){ -+ if(!handle_page_fault(virt, 0, is_write, 0, &dummy_code)) -+ return(0); -+ phys = um_virt_to_phys(current, virt, NULL); -+ } -+ return((unsigned long) phys); -+} -+ -+static int do_op(unsigned long addr, int len, int is_write, -+ int (*op)(unsigned long addr, int len, void *arg), void *arg) -+{ -+ struct page *page; -+ int n; -+ -+ addr = maybe_map(addr, is_write); -+ if(addr == -1) -+ return(-1); -+ -+ page = phys_to_page(addr); -+ addr = (unsigned long) kmap(page) + (addr & ~PAGE_MASK); -+ n = (*op)(addr, len, arg); -+ kunmap(page); -+ -+ return(n); -+} -+ -+static int buffer_op(unsigned long addr, int len, int is_write, -+ int (*op)(unsigned long addr, int len, void *arg), -+ void *arg) -+{ -+ int size = min(PAGE_ALIGN(addr) - addr, (unsigned long) len); -+ int remain = len, n; -+ -+ n = do_op(addr, size, is_write, op, arg); -+ if(n != 0) -+ return(n < 0 ? remain : 0); -+ -+ addr += size; -+ remain -= size; -+ if(remain == 0) -+ return(0); -+ -+ while(addr < ((addr + remain) & PAGE_MASK)){ -+ n = do_op(addr, PAGE_SIZE, is_write, op, arg); -+ if(n != 0) -+ return(n < 0 ? remain : 0); -+ -+ addr += PAGE_SIZE; -+ remain -= PAGE_SIZE; -+ } -+ if(remain == 0) -+ return(0); -+ -+ n = do_op(addr, remain, is_write, op, arg); -+ if(n != 0) -+ return(n < 0 ? remain : 0); -+ return(0); -+} -+ -+static int copy_chunk_from_user(unsigned long from, int len, void *arg) -+{ -+ unsigned long *to_ptr = arg, to = *to_ptr; -+ -+ memcpy((void *) to, (void *) from, len); -+ *to_ptr += len; -+ return(0); -+} -+ -+int copy_from_user_skas(void *to, const void *from, int n) -+{ -+ if(segment_eq(get_fs(), KERNEL_DS)){ -+ memcpy(to, from, n); -+ return(0); -+ } -+ -+ return(access_ok_skas(VERIFY_READ, from, n) ? -+ buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to): -+ n); -+} -+ -+static int copy_chunk_to_user(unsigned long to, int len, void *arg) -+{ -+ unsigned long *from_ptr = arg, from = *from_ptr; -+ -+ memcpy((void *) to, (void *) from, len); -+ *from_ptr += len; -+ return(0); -+} -+ -+int copy_to_user_skas(void *to, const void *from, int n) -+{ -+ if(segment_eq(get_fs(), KERNEL_DS)){ -+ memcpy(to, from, n); -+ return(0); -+ } -+ -+ return(access_ok_skas(VERIFY_WRITE, to, n) ? -+ buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) : -+ n); -+} -+ -+static int strncpy_chunk_from_user(unsigned long from, int len, void *arg) -+{ -+ char **to_ptr = arg, *to = *to_ptr; -+ int n; -+ -+ strncpy(to, (void *) from, len); -+ n = strnlen(to, len); -+ *to_ptr += n; -+ -+ if(n < len) -+ return(1); -+ return(0); -+} -+ -+int strncpy_from_user_skas(char *dst, const char *src, int count) -+{ -+ int n; -+ char *ptr = dst; -+ -+ if(segment_eq(get_fs(), KERNEL_DS)){ -+ strncpy(dst, src, count); -+ return(strnlen(dst, count)); -+ } -+ -+ if(!access_ok_skas(VERIFY_READ, src, 1)) -+ return(-EFAULT); -+ -+ n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user, -+ &ptr); -+ if(n != 0) -+ return(-EFAULT); -+ return(strnlen(dst, count)); -+} -+ -+static int clear_chunk(unsigned long addr, int len, void *unused) -+{ -+ memset((void *) addr, 0, len); -+ return(0); -+} -+ -+int __clear_user_skas(void *mem, int len) -+{ -+ return(buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL)); -+} -+ -+int clear_user_skas(void *mem, int len) -+{ -+ if(segment_eq(get_fs(), KERNEL_DS)){ -+ memset(mem, 0, len); -+ return(0); -+ } -+ -+ return(access_ok_skas(VERIFY_WRITE, mem, len) ? -+ buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len); -+} -+ -+static int strnlen_chunk(unsigned long str, int len, void *arg) -+{ -+ int *len_ptr = arg, n; -+ -+ n = strnlen((void *) str, len); -+ *len_ptr += n; -+ -+ if(n < len) -+ return(1); -+ return(0); -+} -+ -+int strnlen_user_skas(const void *str, int len) -+{ -+ int count = 0, n; -+ -+ if(segment_eq(get_fs(), KERNEL_DS)) -+ return(strnlen(str, len) + 1); -+ -+ n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count); -+ if(n == 0) -+ return(count + 1); -+ return(-EFAULT); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/util/Makefile um/arch/um/kernel/skas/util/Makefile ---- orig/arch/um/kernel/skas/util/Makefile 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/skas/util/Makefile 2003-11-08 02:52:22.000000000 -0500 -@@ -0,0 +1,10 @@ -+all: mk_ptregs -+ -+mk_ptregs : mk_ptregs.o -+ $(HOSTCC) -o mk_ptregs mk_ptregs.o -+ -+mk_ptregs.o : mk_ptregs.c -+ $(HOSTCC) -c $< -+ -+clean : -+ $(RM) -f mk_ptregs *.o *~ -diff -Naur -X ../exclude-files orig/arch/um/kernel/skas/util/mk_ptregs.c um/arch/um/kernel/skas/util/mk_ptregs.c ---- orig/arch/um/kernel/skas/util/mk_ptregs.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/skas/util/mk_ptregs.c 2003-12-22 01:31:11.000000000 -0500 -@@ -0,0 +1,51 @@ -+#include <stdio.h> -+#include <asm/ptrace.h> -+#include <asm/user.h> -+ -+#define PRINT_REG(name, val) printf("#define HOST_%s %d\n", (name), (val)) -+ -+int main(int argc, char **argv) -+{ -+ printf("/* Automatically generated by " -+ "arch/um/kernel/skas/util/mk_ptregs */\n"); -+ printf("\n"); -+ printf("#ifndef __SKAS_PT_REGS_\n"); -+ printf("#define __SKAS_PT_REGS_\n"); -+ printf("\n"); -+ printf("#define HOST_FRAME_SIZE %d\n", FRAME_SIZE); -+ printf("#define HOST_FP_SIZE %d\n", -+ sizeof(struct user_i387_struct) / sizeof(unsigned long)); -+ printf("#define HOST_XFP_SIZE %d\n", -+ sizeof(struct user_fxsr_struct) / sizeof(unsigned long)); -+ -+ PRINT_REG("IP", EIP); -+ PRINT_REG("SP", UESP); -+ PRINT_REG("EFLAGS", EFL); -+ PRINT_REG("EAX", EAX); -+ PRINT_REG("EBX", EBX); -+ PRINT_REG("ECX", ECX); -+ PRINT_REG("EDX", EDX); -+ PRINT_REG("ESI", ESI); -+ PRINT_REG("EDI", EDI); -+ PRINT_REG("EBP", EBP); -+ PRINT_REG("CS", CS); -+ PRINT_REG("SS", SS); -+ PRINT_REG("DS", DS); -+ PRINT_REG("FS", FS); -+ PRINT_REG("ES", ES); -+ PRINT_REG("GS", GS); -+ printf("\n"); -+ printf("#endif\n"); -+ return(0); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/smp.c um/arch/um/kernel/smp.c ---- orig/arch/um/kernel/smp.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/smp.c 2003-11-15 02:59:25.000000000 -0500 -@@ -0,0 +1,328 @@ -+/* -+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/config.h" -+ -+#ifdef CONFIG_SMP -+ -+#include "linux/sched.h" -+#include "linux/threads.h" -+#include "linux/interrupt.h" -+#include "asm/smp.h" -+#include "asm/processor.h" -+#include "asm/spinlock.h" -+#include "asm/softirq.h" -+#include "asm/hardirq.h" -+#include "asm/tlb.h" -+#include "user_util.h" -+#include "kern_util.h" -+#include "irq_user.h" -+#include "kern.h" -+#include "os.h" -+ -+/* Total count of live CPUs, set by smp_boot_cpus */ -+int smp_num_cpus = 1; -+ -+/* The 'big kernel lock' */ -+spinlock_cacheline_t kernel_flag_cacheline = {SPIN_LOCK_UNLOCKED}; -+ -+/* Per CPU bogomips and other parameters */ -+ -+/* The only piece used here is the ipi pipe, which is set before SMP is -+ * started and never changed. -+ */ -+struct cpuinfo_um cpu_data[NR_CPUS]; -+ -+/* CPU online map, set by smp_boot_cpus */ -+unsigned long cpu_online_map; -+ -+atomic_t global_bh_count; -+ -+/* Set when the idlers are all forked */ -+int smp_threads_ready = 0; -+ -+/* Not used by UML */ -+unsigned char global_irq_holder = 0; -+unsigned volatile long global_irq_lock; -+ -+/* A statistic, can be a little off */ -+static int num_reschedules_sent = 0; -+ -+mmu_gather_t mmu_gathers[NR_CPUS]; -+ -+void smp_send_reschedule(int cpu) -+{ -+ os_write_file(cpu_data[cpu].ipi_pipe[1], "R", 1); -+ num_reschedules_sent++; -+} -+ -+static void show(char * str) -+{ -+ int cpu = smp_processor_id(); -+ -+ printk(KERN_INFO "\n%s, CPU %d:\n", str, cpu); -+} -+ -+#define MAXCOUNT 100000000 -+ -+static inline void wait_on_bh(void) -+{ -+ int count = MAXCOUNT; -+ do { -+ if (!--count) { -+ show("wait_on_bh"); -+ count = ~0; -+ } -+ /* nothing .. wait for the other bh's to go away */ -+ } while (atomic_read(&global_bh_count) != 0); -+} -+ -+/* -+ * This is called when we want to synchronize with -+ * bottom half handlers. We need to wait until -+ * no other CPU is executing any bottom half handler. -+ * -+ * Don't wait if we're already running in an interrupt -+ * context or are inside a bh handler. -+ */ -+void synchronize_bh(void) -+{ -+ if (atomic_read(&global_bh_count) && !in_interrupt()) -+ wait_on_bh(); -+} -+ -+void smp_send_stop(void) -+{ -+ int i; -+ -+ printk(KERN_INFO "Stopping all CPUs..."); -+ for(i = 0; i < ncpus; i++){ -+ if(i == current->processor) -+ continue; -+ os_write_file(cpu_data[i].ipi_pipe[1], "S", 1); -+ } -+ printk("done\n"); -+} -+ -+ -+static atomic_t smp_commenced = ATOMIC_INIT(0); -+static volatile unsigned long smp_callin_map = 0; -+ -+void smp_commence(void) -+{ -+ printk("All CPUs are go!\n"); -+ -+ wmb(); -+ atomic_set(&smp_commenced, 1); -+} -+ -+static int idle_proc(void *unused) -+{ -+ int cpu, err; -+ -+ set_current(current); -+ del_from_runqueue(current); -+ unhash_process(current); -+ -+ cpu = current->processor; -+ err = os_pipe(cpu_data[cpu].ipi_pipe, 1, 1); -+ if(err < 0) -+ panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err); -+ -+ activate_ipi(cpu_data[cpu].ipi_pipe[0], -+ current->thread.mode.tt.extern_pid); -+ -+ wmb(); -+ if (test_and_set_bit(current->processor, &smp_callin_map)) { -+ printk("huh, CPU#%d already present??\n", current->processor); -+ BUG(); -+ } -+ -+ while (!atomic_read(&smp_commenced)) -+ cpu_relax(); -+ -+ init_idle(); -+ cpu_idle(); -+ return(0); -+} -+ -+static int idle_thread(int (*fn)(void *), int cpu) -+{ -+ struct task_struct *new_task; -+ int pid; -+ unsigned char c; -+ -+ current->thread.request.u.thread.proc = fn; -+ current->thread.request.u.thread.arg = NULL; -+ pid = do_fork(CLONE_VM | CLONE_PID, 0, NULL, 0); -+ if(pid < 0) -+ panic("do_fork failed in idle_thread"); -+ new_task = get_task(pid, 1); -+ -+ cpu_tasks[cpu] = ((struct cpu_task) -+ { .pid = new_task->thread.mode.tt.extern_pid, -+ .task = new_task } ); -+ init_tasks[cpu] = new_task; -+ new_task->processor = cpu; -+ new_task->cpus_allowed = 1 << cpu; -+ new_task->cpus_runnable = new_task->cpus_allowed; -+ CHOOSE_MODE(os_write_file(new_task->thread.mode.tt.switch_pipe[1], &c, -+ sizeof(c)), -+ ({ panic("skas mode doesn't support SMP"); })); -+ return(new_task->thread.mode.tt.extern_pid); -+} -+ -+void smp_boot_cpus(void) -+{ -+ int err; -+ -+ set_bit(0, &cpu_online_map); -+ set_bit(0, &smp_callin_map); -+ -+ err = os_pipe(cpu_data[0].ipi_pipe, 1, 1); -+ if(err < 0) -+ panic("CPU#0 failed to create IPI pipe, err = %d", -err); -+ -+ activate_ipi(cpu_data[0].ipi_pipe[0], -+ current->thread.mode.tt.extern_pid); -+ -+ if(ncpus < 1){ -+ printk(KERN_INFO "ncpus set to 1\n"); -+ ncpus = 1; -+ } -+ else if(ncpus > NR_CPUS){ -+ printk(KERN_INFO -+ "ncpus can't be greater than NR_CPUS, set to %d\n", -+ NR_CPUS); -+ ncpus = NR_CPUS; -+ } -+ -+ if(ncpus > 1){ -+ int i, pid; -+ -+ printk(KERN_INFO "Starting up other processors:\n"); -+ for(i=1;i<ncpus;i++){ -+ int waittime; -+ -+ /* Do this early, for hard_smp_processor_id() */ -+ cpu_tasks[i].pid = -1; -+ set_bit(i, &cpu_online_map); -+ smp_num_cpus++; -+ -+ pid = idle_thread(idle_proc, i); -+ printk(KERN_INFO "\t#%d - idle thread pid = %d.. ", -+ i, pid); -+ -+ waittime = 200000000; -+ while (waittime-- && !test_bit(i, &smp_callin_map)) -+ cpu_relax(); -+ -+ if (test_bit(i, &smp_callin_map)) -+ printk("online\n"); -+ else { -+ printk("failed\n"); -+ clear_bit(i, &cpu_online_map); -+ } -+ } -+ } -+} -+ -+int setup_profiling_timer(unsigned int multiplier) -+{ -+ printk(KERN_INFO "setup_profiling_timer\n"); -+ return(0); -+} -+ -+void smp_call_function_slave(int cpu); -+ -+void IPI_handler(int cpu) -+{ -+ unsigned char c; -+ int fd; -+ -+ fd = cpu_data[cpu].ipi_pipe[0]; -+ while (os_read_file(fd, &c, 1) == 1) { -+ switch (c) { -+ case 'C': -+ smp_call_function_slave(cpu); -+ break; -+ -+ case 'R': -+ current->need_resched = 1; -+ break; -+ -+ case 'S': -+ printk("CPU#%d stopping\n", cpu); -+ while(1) -+ pause(); -+ break; -+ -+ default: -+ printk("CPU#%d received unknown IPI [%c]!\n", cpu, c); -+ break; -+ } -+ } -+} -+ -+int hard_smp_processor_id(void) -+{ -+ return(pid_to_processor_id(os_getpid())); -+} -+ -+static spinlock_t call_lock = SPIN_LOCK_UNLOCKED; -+static atomic_t scf_started; -+static atomic_t scf_finished; -+static void (*func)(void *info); -+static void *info; -+ -+void smp_call_function_slave(int cpu) -+{ -+ atomic_inc(&scf_started); -+ (*func)(info); -+ atomic_inc(&scf_finished); -+} -+ -+int smp_call_function(void (*_func)(void *info), void *_info, int nonatomic, -+ int wait) -+{ -+ int cpus = smp_num_cpus - 1; -+ int i; -+ -+ if (!cpus) -+ return 0; -+ -+ spin_lock_bh(&call_lock); -+ atomic_set(&scf_started, 0); -+ atomic_set(&scf_finished, 0); -+ func = _func; -+ info = _info; -+ -+ for (i=0;i<NR_CPUS;i++) -+ if (i != current->processor && test_bit(i, &cpu_online_map)) -+ os_write_file(cpu_data[i].ipi_pipe[1], "C", 1); -+ -+ while (atomic_read(&scf_started) != cpus) -+ barrier(); -+ -+ if (wait) -+ while (atomic_read(&scf_finished) != cpus) -+ barrier(); -+ -+ spin_unlock_bh(&call_lock); -+ return 0; -+} -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/syscall_kern.c um/arch/um/kernel/syscall_kern.c ---- orig/arch/um/kernel/syscall_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/syscall_kern.c 2004-01-10 06:37:46.000000000 -0500 -@@ -0,0 +1,343 @@ -+/* -+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/sched.h" -+#include "linux/file.h" -+#include "linux/smp_lock.h" -+#include "linux/mm.h" -+#include "linux/utsname.h" -+#include "linux/msg.h" -+#include "linux/shm.h" -+#include "linux/sys.h" -+#include "linux/unistd.h" -+#include "linux/slab.h" -+#include "linux/utime.h" -+#include "asm/mman.h" -+#include "asm/uaccess.h" -+#include "asm/ipc.h" -+#include "kern_util.h" -+#include "user_util.h" -+#include "sysdep/syscalls.h" -+#include "mode_kern.h" -+#include "choose-mode.h" -+ -+/* Unlocked, I don't care if this is a bit off */ -+int nsyscalls = 0; -+ -+long um_mount(char * dev_name, char * dir_name, char * type, -+ unsigned long new_flags, void * data) -+{ -+ if(type == NULL) type = ""; -+ return(sys_mount(dev_name, dir_name, type, new_flags, data)); -+} -+ -+long sys_fork(void) -+{ -+ long ret; -+ -+ current->thread.forking = 1; -+ ret = do_fork(SIGCHLD, 0, NULL, 0); -+ current->thread.forking = 0; -+ return(ret); -+} -+ -+long sys_clone(unsigned long clone_flags, unsigned long newsp) -+{ -+ long ret; -+ -+ current->thread.forking = 1; -+ ret = do_fork(clone_flags, newsp, NULL, 0); -+ current->thread.forking = 0; -+ return(ret); -+} -+ -+long sys_vfork(void) -+{ -+ long ret; -+ -+ current->thread.forking = 1; -+ ret = do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, 0, NULL, 0); -+ current->thread.forking = 0; -+ return(ret); -+} -+ -+/* common code for old and new mmaps */ -+long do_mmap2(struct mm_struct *mm, unsigned long addr, unsigned long len, -+ unsigned long prot, unsigned long flags, unsigned long fd, -+ unsigned long pgoff) -+{ -+ int error = -EBADF; -+ struct file * file = NULL; -+ -+ flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE); -+ if (!(flags & MAP_ANONYMOUS)) { -+ file = fget(fd); -+ if (!file) -+ goto out; -+ } -+ -+ down_write(&mm->mmap_sem); -+ error = do_mmap_pgoff(mm, file, addr, len, prot, flags, pgoff); -+ up_write(&mm->mmap_sem); -+ -+ if (file) -+ fput(file); -+ out: -+ return error; -+} -+ -+long sys_mmap2(unsigned long addr, unsigned long len, -+ unsigned long prot, unsigned long flags, -+ unsigned long fd, unsigned long pgoff) -+{ -+ return do_mmap2(current->mm, addr, len, prot, flags, fd, pgoff); -+} -+ -+/* -+ * Perform the select(nd, in, out, ex, tv) and mmap() system -+ * calls. Linux/i386 didn't use to be able to handle more than -+ * 4 system call parameters, so these system calls used a memory -+ * block for parameter passing.. -+ */ -+ -+struct mmap_arg_struct { -+ unsigned long addr; -+ unsigned long len; -+ unsigned long prot; -+ unsigned long flags; -+ unsigned long fd; -+ unsigned long offset; -+}; -+ -+int old_mmap(unsigned long addr, unsigned long len, -+ unsigned long prot, unsigned long flags, -+ unsigned long fd, unsigned long offset) -+{ -+ int err = -EINVAL; -+ if (offset & ~PAGE_MASK) -+ goto out; -+ -+ err = do_mmap2(current->mm, addr, len, prot, flags, fd, -+ offset >> PAGE_SHIFT); -+ out: -+ return err; -+} -+/* -+ * sys_pipe() is the normal C calling standard for creating -+ * a pipe. It's not the way unix traditionally does this, though. -+ */ -+int sys_pipe(unsigned long * fildes) -+{ -+ int fd[2]; -+ int error; -+ -+ error = do_pipe(fd); -+ if (!error) { -+ if (copy_to_user(fildes, fd, sizeof(fd))) -+ error = -EFAULT; -+ } -+ return error; -+} -+ -+int sys_pause(void) -+{ -+ current->state = TASK_INTERRUPTIBLE; -+ schedule(); -+ return -ERESTARTNOHAND; -+} -+ -+int sys_sigaction(int sig, const struct old_sigaction *act, -+ struct old_sigaction *oact) -+{ -+ struct k_sigaction new_ka, old_ka; -+ int ret; -+ -+ if (act) { -+ old_sigset_t mask; -+ if (verify_area(VERIFY_READ, act, sizeof(*act)) || -+ __get_user(new_ka.sa.sa_handler, &act->sa_handler) || -+ __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) -+ return -EFAULT; -+ __get_user(new_ka.sa.sa_flags, &act->sa_flags); -+ __get_user(mask, &act->sa_mask); -+ siginitset(&new_ka.sa.sa_mask, mask); -+ } -+ -+ ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); -+ -+ if (!ret && oact) { -+ if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) || -+ __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || -+ __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) -+ return -EFAULT; -+ __put_user(old_ka.sa.sa_flags, &oact->sa_flags); -+ __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); -+ } -+ -+ return ret; -+} -+ -+/* -+ * sys_ipc() is the de-multiplexer for the SysV IPC calls.. -+ * -+ * This is really horribly ugly. -+ */ -+int sys_ipc (uint call, int first, int second, -+ int third, void *ptr, long fifth) -+{ -+ int version, ret; -+ -+ version = call >> 16; /* hack for backward compatibility */ -+ call &= 0xffff; -+ -+ switch (call) { -+ case SEMOP: -+ return sys_semop (first, (struct sembuf *)ptr, second); -+ case SEMGET: -+ return sys_semget (first, second, third); -+ case SEMCTL: { -+ union semun fourth; -+ if (!ptr) -+ return -EINVAL; -+ if (get_user(fourth.__pad, (void **) ptr)) -+ return -EFAULT; -+ return sys_semctl (first, second, third, fourth); -+ } -+ -+ case MSGSND: -+ return sys_msgsnd (first, (struct msgbuf *) ptr, -+ second, third); -+ case MSGRCV: -+ switch (version) { -+ case 0: { -+ struct ipc_kludge tmp; -+ if (!ptr) -+ return -EINVAL; -+ -+ if (copy_from_user(&tmp, -+ (struct ipc_kludge *) ptr, -+ sizeof (tmp))) -+ return -EFAULT; -+ return sys_msgrcv (first, tmp.msgp, second, -+ tmp.msgtyp, third); -+ } -+ default: -+ panic("msgrcv with version != 0"); -+ return sys_msgrcv (first, -+ (struct msgbuf *) ptr, -+ second, fifth, third); -+ } -+ case MSGGET: -+ return sys_msgget ((key_t) first, second); -+ case MSGCTL: -+ return sys_msgctl (first, second, (struct msqid_ds *) ptr); -+ -+ case SHMAT: -+ switch (version) { -+ default: { -+ ulong raddr; -+ ret = sys_shmat (first, (char *) ptr, second, &raddr); -+ if (ret) -+ return ret; -+ return put_user (raddr, (ulong *) third); -+ } -+ case 1: /* iBCS2 emulator entry point */ -+ if (!segment_eq(get_fs(), get_ds())) -+ return -EINVAL; -+ return sys_shmat (first, (char *) ptr, second, (ulong *) third); -+ } -+ case SHMDT: -+ return sys_shmdt ((char *)ptr); -+ case SHMGET: -+ return sys_shmget (first, second, third); -+ case SHMCTL: -+ return sys_shmctl (first, second, -+ (struct shmid_ds *) ptr); -+ default: -+ return -EINVAL; -+ } -+} -+ -+int sys_uname(struct old_utsname * name) -+{ -+ int err; -+ if (!name) -+ return -EFAULT; -+ down_read(&uts_sem); -+ err=copy_to_user(name, &system_utsname, sizeof (*name)); -+ up_read(&uts_sem); -+ return err?-EFAULT:0; -+} -+ -+int sys_olduname(struct oldold_utsname * name) -+{ -+ int error; -+ -+ if (!name) -+ return -EFAULT; -+ if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) -+ return -EFAULT; -+ -+ down_read(&uts_sem); -+ -+ error = __copy_to_user(&name->sysname,&system_utsname.sysname, -+ __OLD_UTS_LEN); -+ error |= __put_user(0,name->sysname+__OLD_UTS_LEN); -+ error |= __copy_to_user(&name->nodename,&system_utsname.nodename, -+ __OLD_UTS_LEN); -+ error |= __put_user(0,name->nodename+__OLD_UTS_LEN); -+ error |= __copy_to_user(&name->release,&system_utsname.release, -+ __OLD_UTS_LEN); -+ error |= __put_user(0,name->release+__OLD_UTS_LEN); -+ error |= __copy_to_user(&name->version,&system_utsname.version, -+ __OLD_UTS_LEN); -+ error |= __put_user(0,name->version+__OLD_UTS_LEN); -+ error |= __copy_to_user(&name->machine,&system_utsname.machine, -+ __OLD_UTS_LEN); -+ error |= __put_user(0,name->machine+__OLD_UTS_LEN); -+ -+ up_read(&uts_sem); -+ -+ error = error ? -EFAULT : 0; -+ -+ return error; -+} -+ -+int sys_sigaltstack(const stack_t *uss, stack_t *uoss) -+{ -+ return(do_sigaltstack(uss, uoss, PT_REGS_SP(¤t->thread.regs))); -+} -+ -+long execute_syscall(void *r) -+{ -+ return(CHOOSE_MODE_PROC(execute_syscall_tt, execute_syscall_skas, r)); -+} -+ -+spinlock_t syscall_lock = SPIN_LOCK_UNLOCKED; -+ -+static int syscall_index = 0; -+ -+int next_syscall_index(int limit) -+{ -+ int ret; -+ -+ spin_lock(&syscall_lock); -+ ret = syscall_index; -+ if(++syscall_index == limit) -+ syscall_index = 0; -+ spin_unlock(&syscall_lock); -+ return(ret); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/sys_call_table.c um/arch/um/kernel/sys_call_table.c ---- orig/arch/um/kernel/sys_call_table.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/sys_call_table.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,496 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/unistd.h" -+#include "linux/version.h" -+#include "linux/sys.h" -+#include "asm/signal.h" -+#include "sysdep/syscalls.h" -+#include "kern_util.h" -+ -+extern syscall_handler_t sys_ni_syscall; -+extern syscall_handler_t sys_exit; -+extern syscall_handler_t sys_fork; -+extern syscall_handler_t sys_creat; -+extern syscall_handler_t sys_link; -+extern syscall_handler_t sys_unlink; -+extern syscall_handler_t sys_chdir; -+extern syscall_handler_t sys_mknod; -+extern syscall_handler_t sys_chmod; -+extern syscall_handler_t sys_lchown16; -+extern syscall_handler_t sys_ni_syscall; -+extern syscall_handler_t sys_stat; -+extern syscall_handler_t sys_getpid; -+extern syscall_handler_t sys_oldumount; -+extern syscall_handler_t sys_setuid16; -+extern syscall_handler_t sys_getuid16; -+extern syscall_handler_t sys_ptrace; -+extern syscall_handler_t sys_alarm; -+extern syscall_handler_t sys_fstat; -+extern syscall_handler_t sys_pause; -+extern syscall_handler_t sys_utime; -+extern syscall_handler_t sys_ni_syscall; -+extern syscall_handler_t sys_ni_syscall; -+extern syscall_handler_t sys_access; -+extern syscall_handler_t sys_nice; -+extern syscall_handler_t sys_ni_syscall; -+extern syscall_handler_t sys_sync; -+extern syscall_handler_t sys_kill; -+extern syscall_handler_t sys_rename; -+extern syscall_handler_t sys_mkdir; -+extern syscall_handler_t sys_rmdir; -+extern syscall_handler_t sys_pipe; -+extern syscall_handler_t sys_times; -+extern syscall_handler_t sys_ni_syscall; -+extern syscall_handler_t sys_brk; -+extern syscall_handler_t sys_setgid16; -+extern syscall_handler_t sys_getgid16; -+extern syscall_handler_t sys_signal; -+extern syscall_handler_t sys_geteuid16; -+extern syscall_handler_t sys_getegid16; -+extern syscall_handler_t sys_acct; -+extern syscall_handler_t sys_umount; -+extern syscall_handler_t sys_ni_syscall; -+extern syscall_handler_t sys_ioctl; -+extern syscall_handler_t sys_fcntl; -+extern syscall_handler_t sys_ni_syscall; -+extern syscall_handler_t sys_setpgid; -+extern syscall_handler_t sys_ni_syscall; -+extern syscall_handler_t sys_olduname; -+extern syscall_handler_t sys_umask; -+extern syscall_handler_t sys_chroot; -+extern syscall_handler_t sys_ustat; -+extern syscall_handler_t sys_dup2; -+extern syscall_handler_t sys_getppid; -+extern syscall_handler_t sys_getpgrp; -+extern syscall_handler_t sys_sigaction; -+extern syscall_handler_t sys_sgetmask; -+extern syscall_handler_t sys_ssetmask; -+extern syscall_handler_t sys_setreuid16; -+extern syscall_handler_t sys_setregid16; -+extern syscall_handler_t sys_sigsuspend; -+extern syscall_handler_t sys_sigpending; -+extern syscall_handler_t sys_sethostname; -+extern syscall_handler_t sys_setrlimit; -+extern syscall_handler_t sys_old_getrlimit; -+extern syscall_handler_t sys_getrusage; -+extern syscall_handler_t sys_gettimeofday; -+extern syscall_handler_t sys_settimeofday; -+extern syscall_handler_t sys_getgroups16; -+extern syscall_handler_t sys_setgroups16; -+extern syscall_handler_t sys_symlink; -+extern syscall_handler_t sys_lstat; -+extern syscall_handler_t sys_readlink; -+extern syscall_handler_t sys_uselib; -+extern syscall_handler_t sys_swapon; -+extern syscall_handler_t sys_reboot; -+extern syscall_handler_t old_readdir; -+extern syscall_handler_t sys_munmap; -+extern syscall_handler_t sys_truncate; -+extern syscall_handler_t sys_ftruncate; -+extern syscall_handler_t sys_fchmod; -+extern syscall_handler_t sys_fchown16; -+extern syscall_handler_t sys_getpriority; -+extern syscall_handler_t sys_setpriority; -+extern syscall_handler_t sys_ni_syscall; -+extern syscall_handler_t sys_statfs; -+extern syscall_handler_t sys_fstatfs; -+extern syscall_handler_t sys_ni_syscall; -+extern syscall_handler_t sys_socketcall; -+extern syscall_handler_t sys_syslog; -+extern syscall_handler_t sys_setitimer; -+extern syscall_handler_t sys_getitimer; -+extern syscall_handler_t sys_newstat; -+extern syscall_handler_t sys_newlstat; -+extern syscall_handler_t sys_newfstat; -+extern syscall_handler_t sys_uname; -+extern syscall_handler_t sys_ni_syscall; -+extern syscall_handler_t sys_vhangup; -+extern syscall_handler_t sys_ni_syscall; -+extern syscall_handler_t sys_ni_syscall; -+extern syscall_handler_t sys_swapoff; -+extern syscall_handler_t sys_sysinfo; -+extern syscall_handler_t sys_ipc; -+extern syscall_handler_t sys_fsync; -+extern syscall_handler_t sys_sigreturn; -+extern syscall_handler_t sys_rt_sigreturn; -+extern syscall_handler_t sys_clone; -+extern syscall_handler_t sys_setdomainname; -+extern syscall_handler_t sys_newuname; -+extern syscall_handler_t sys_ni_syscall; -+extern syscall_handler_t sys_adjtimex; -+extern syscall_handler_t sys_mprotect; -+extern syscall_handler_t sys_sigprocmask; -+extern syscall_handler_t sys_create_module; -+extern syscall_handler_t sys_init_module; -+extern syscall_handler_t sys_delete_module; -+extern syscall_handler_t sys_get_kernel_syms; -+extern syscall_handler_t sys_quotactl; -+extern syscall_handler_t sys_getpgid; -+extern syscall_handler_t sys_fchdir; -+extern syscall_handler_t sys_bdflush; -+extern syscall_handler_t sys_sysfs; -+extern syscall_handler_t sys_personality; -+extern syscall_handler_t sys_ni_syscall; -+extern syscall_handler_t sys_setfsuid16; -+extern syscall_handler_t sys_setfsgid16; -+extern syscall_handler_t sys_llseek; -+extern syscall_handler_t sys_getdents; -+extern syscall_handler_t sys_flock; -+extern syscall_handler_t sys_msync; -+extern syscall_handler_t sys_readv; -+extern syscall_handler_t sys_writev; -+extern syscall_handler_t sys_getsid; -+extern syscall_handler_t sys_fdatasync; -+extern syscall_handler_t sys_sysctl; -+extern syscall_handler_t sys_mlock; -+extern syscall_handler_t sys_munlock; -+extern syscall_handler_t sys_mlockall; -+extern syscall_handler_t sys_munlockall; -+extern syscall_handler_t sys_sched_setparam; -+extern syscall_handler_t sys_sched_getparam; -+extern syscall_handler_t sys_sched_setscheduler; -+extern syscall_handler_t sys_sched_getscheduler; -+extern syscall_handler_t sys_sched_get_priority_max; -+extern syscall_handler_t sys_sched_get_priority_min; -+extern syscall_handler_t sys_sched_rr_get_interval; -+extern syscall_handler_t sys_nanosleep; -+extern syscall_handler_t sys_mremap; -+extern syscall_handler_t sys_setresuid16; -+extern syscall_handler_t sys_getresuid16; -+extern syscall_handler_t sys_ni_syscall; -+extern syscall_handler_t sys_query_module; -+extern syscall_handler_t sys_poll; -+extern syscall_handler_t sys_nfsservctl; -+extern syscall_handler_t sys_setresgid16; -+extern syscall_handler_t sys_getresgid16; -+extern syscall_handler_t sys_prctl; -+extern syscall_handler_t sys_ni_syscall; -+extern syscall_handler_t sys_rt_sigaction; -+extern syscall_handler_t sys_rt_sigprocmask; -+extern syscall_handler_t sys_rt_sigpending; -+extern syscall_handler_t sys_rt_sigtimedwait; -+extern syscall_handler_t sys_rt_sigqueueinfo; -+extern syscall_handler_t sys_rt_sigsuspend; -+extern syscall_handler_t sys_pread; -+extern syscall_handler_t sys_pwrite; -+extern syscall_handler_t sys_chown16; -+extern syscall_handler_t sys_getcwd; -+extern syscall_handler_t sys_capget; -+extern syscall_handler_t sys_capset; -+extern syscall_handler_t sys_sigaltstack; -+extern syscall_handler_t sys_sendfile; -+extern syscall_handler_t sys_ni_syscall; -+extern syscall_handler_t sys_ni_syscall; -+extern syscall_handler_t sys_vfork; -+extern syscall_handler_t sys_getrlimit; -+extern syscall_handler_t sys_mmap2; -+extern syscall_handler_t sys_truncate64; -+extern syscall_handler_t sys_ftruncate64; -+extern syscall_handler_t sys_stat64; -+extern syscall_handler_t sys_lstat64; -+extern syscall_handler_t sys_fstat64; -+extern syscall_handler_t sys_lchown; -+extern syscall_handler_t sys_getuid; -+extern syscall_handler_t sys_getgid; -+extern syscall_handler_t sys_geteuid; -+extern syscall_handler_t sys_getegid; -+extern syscall_handler_t sys_setreuid; -+extern syscall_handler_t sys_setregid; -+extern syscall_handler_t sys_getgroups; -+extern syscall_handler_t sys_setgroups; -+extern syscall_handler_t sys_fchown; -+extern syscall_handler_t sys_setresuid; -+extern syscall_handler_t sys_getresuid; -+extern syscall_handler_t sys_setresgid; -+extern syscall_handler_t sys_getresgid; -+extern syscall_handler_t sys_chown; -+extern syscall_handler_t sys_setuid; -+extern syscall_handler_t sys_setgid; -+extern syscall_handler_t sys_setfsuid; -+extern syscall_handler_t sys_setfsgid; -+extern syscall_handler_t sys_pivot_root; -+extern syscall_handler_t sys_mincore; -+extern syscall_handler_t sys_madvise; -+extern syscall_handler_t sys_fcntl64; -+extern syscall_handler_t sys_getdents64; -+extern syscall_handler_t sys_gettid; -+extern syscall_handler_t sys_readahead; -+extern syscall_handler_t sys_tkill; -+extern syscall_handler_t sys_setxattr; -+extern syscall_handler_t sys_lsetxattr; -+extern syscall_handler_t sys_fsetxattr; -+extern syscall_handler_t sys_getxattr; -+extern syscall_handler_t sys_lgetxattr; -+extern syscall_handler_t sys_fgetxattr; -+extern syscall_handler_t sys_listxattr; -+extern syscall_handler_t sys_llistxattr; -+extern syscall_handler_t sys_flistxattr; -+extern syscall_handler_t sys_removexattr; -+extern syscall_handler_t sys_lremovexattr; -+extern syscall_handler_t sys_fremovexattr; -+extern syscall_handler_t sys_sendfile64; -+ -+extern syscall_handler_t um_mount; -+extern syscall_handler_t um_time; -+extern syscall_handler_t um_stime; -+ -+#define LAST_GENERIC_SYSCALL __NR_exit_group -+ -+#if LAST_GENERIC_SYSCALL > LAST_ARCH_SYSCALL -+#define LAST_SYSCALL LAST_GENERIC_SYSCALL -+#else -+#define LAST_SYSCALL LAST_ARCH_SYSCALL -+#endif -+ -+syscall_handler_t *sys_call_table[] = { -+ [ 0 ] = sys_ni_syscall, -+ [ __NR_exit ] = sys_exit, -+ [ __NR_fork ] = sys_fork, -+ [ __NR_read ] = (syscall_handler_t *) sys_read, -+ [ __NR_write ] = (syscall_handler_t *) sys_write, -+ -+ /* These three are declared differently in asm/unistd.h */ -+ [ __NR_open ] = (syscall_handler_t *) sys_open, -+ [ __NR_close ] = (syscall_handler_t *) sys_close, -+ [ __NR_waitpid ] = (syscall_handler_t *) sys_waitpid, -+ [ __NR_creat ] = sys_creat, -+ [ __NR_link ] = sys_link, -+ [ __NR_unlink ] = sys_unlink, -+ -+ /* declared differently in kern_util.h */ -+ [ __NR_execve ] = (syscall_handler_t *) sys_execve, -+ [ __NR_chdir ] = sys_chdir, -+ [ __NR_time ] = um_time, -+ [ __NR_mknod ] = sys_mknod, -+ [ __NR_chmod ] = sys_chmod, -+ [ __NR_lchown ] = sys_lchown16, -+ [ __NR_break ] = sys_ni_syscall, -+ [ __NR_oldstat ] = sys_stat, -+ [ __NR_lseek ] = (syscall_handler_t *) sys_lseek, -+ [ __NR_getpid ] = sys_getpid, -+ [ __NR_mount ] = um_mount, -+ [ __NR_umount ] = sys_oldumount, -+ [ __NR_setuid ] = sys_setuid16, -+ [ __NR_getuid ] = sys_getuid16, -+ [ __NR_stime ] = um_stime, -+ [ __NR_ptrace ] = sys_ptrace, -+ [ __NR_alarm ] = sys_alarm, -+ [ __NR_oldfstat ] = sys_fstat, -+ [ __NR_pause ] = sys_pause, -+ [ __NR_utime ] = sys_utime, -+ [ __NR_stty ] = sys_ni_syscall, -+ [ __NR_gtty ] = sys_ni_syscall, -+ [ __NR_access ] = sys_access, -+ [ __NR_nice ] = sys_nice, -+ [ __NR_ftime ] = sys_ni_syscall, -+ [ __NR_sync ] = sys_sync, -+ [ __NR_kill ] = sys_kill, -+ [ __NR_rename ] = sys_rename, -+ [ __NR_mkdir ] = sys_mkdir, -+ [ __NR_rmdir ] = sys_rmdir, -+ -+ /* Declared differently in asm/unistd.h */ -+ [ __NR_dup ] = (syscall_handler_t *) sys_dup, -+ [ __NR_pipe ] = sys_pipe, -+ [ __NR_times ] = sys_times, -+ [ __NR_prof ] = sys_ni_syscall, -+ [ __NR_brk ] = sys_brk, -+ [ __NR_setgid ] = sys_setgid16, -+ [ __NR_getgid ] = sys_getgid16, -+ [ __NR_signal ] = sys_signal, -+ [ __NR_geteuid ] = sys_geteuid16, -+ [ __NR_getegid ] = sys_getegid16, -+ [ __NR_acct ] = sys_acct, -+ [ __NR_umount2 ] = sys_umount, -+ [ __NR_lock ] = sys_ni_syscall, -+ [ __NR_ioctl ] = sys_ioctl, -+ [ __NR_fcntl ] = sys_fcntl, -+ [ __NR_mpx ] = sys_ni_syscall, -+ [ __NR_setpgid ] = sys_setpgid, -+ [ __NR_ulimit ] = sys_ni_syscall, -+ [ __NR_oldolduname ] = sys_olduname, -+ [ __NR_umask ] = sys_umask, -+ [ __NR_chroot ] = sys_chroot, -+ [ __NR_ustat ] = sys_ustat, -+ [ __NR_dup2 ] = sys_dup2, -+ [ __NR_getppid ] = sys_getppid, -+ [ __NR_getpgrp ] = sys_getpgrp, -+ [ __NR_setsid ] = (syscall_handler_t *) sys_setsid, -+ [ __NR_sigaction ] = sys_sigaction, -+ [ __NR_sgetmask ] = sys_sgetmask, -+ [ __NR_ssetmask ] = sys_ssetmask, -+ [ __NR_setreuid ] = sys_setreuid16, -+ [ __NR_setregid ] = sys_setregid16, -+ [ __NR_sigsuspend ] = sys_sigsuspend, -+ [ __NR_sigpending ] = sys_sigpending, -+ [ __NR_sethostname ] = sys_sethostname, -+ [ __NR_setrlimit ] = sys_setrlimit, -+ [ __NR_getrlimit ] = sys_old_getrlimit, -+ [ __NR_getrusage ] = sys_getrusage, -+ [ __NR_gettimeofday ] = sys_gettimeofday, -+ [ __NR_settimeofday ] = sys_settimeofday, -+ [ __NR_getgroups ] = sys_getgroups16, -+ [ __NR_setgroups ] = sys_setgroups16, -+ [ __NR_symlink ] = sys_symlink, -+ [ __NR_oldlstat ] = sys_lstat, -+ [ __NR_readlink ] = sys_readlink, -+ [ __NR_uselib ] = sys_uselib, -+ [ __NR_swapon ] = sys_swapon, -+ [ __NR_reboot ] = sys_reboot, -+ [ __NR_readdir ] = old_readdir, -+ [ __NR_munmap ] = sys_munmap, -+ [ __NR_truncate ] = sys_truncate, -+ [ __NR_ftruncate ] = sys_ftruncate, -+ [ __NR_fchmod ] = sys_fchmod, -+ [ __NR_fchown ] = sys_fchown16, -+ [ __NR_getpriority ] = sys_getpriority, -+ [ __NR_setpriority ] = sys_setpriority, -+ [ __NR_profil ] = sys_ni_syscall, -+ [ __NR_statfs ] = sys_statfs, -+ [ __NR_fstatfs ] = sys_fstatfs, -+ [ __NR_ioperm ] = sys_ni_syscall, -+ [ __NR_socketcall ] = sys_socketcall, -+ [ __NR_syslog ] = sys_syslog, -+ [ __NR_setitimer ] = sys_setitimer, -+ [ __NR_getitimer ] = sys_getitimer, -+ [ __NR_stat ] = sys_newstat, -+ [ __NR_lstat ] = sys_newlstat, -+ [ __NR_fstat ] = sys_newfstat, -+ [ __NR_olduname ] = sys_uname, -+ [ __NR_iopl ] = sys_ni_syscall, -+ [ __NR_vhangup ] = sys_vhangup, -+ [ __NR_idle ] = sys_ni_syscall, -+ [ __NR_wait4 ] = (syscall_handler_t *) sys_wait4, -+ [ __NR_swapoff ] = sys_swapoff, -+ [ __NR_sysinfo ] = sys_sysinfo, -+ [ __NR_ipc ] = sys_ipc, -+ [ __NR_fsync ] = sys_fsync, -+ [ __NR_sigreturn ] = sys_sigreturn, -+ [ __NR_clone ] = sys_clone, -+ [ __NR_setdomainname ] = sys_setdomainname, -+ [ __NR_uname ] = sys_newuname, -+ [ __NR_adjtimex ] = sys_adjtimex, -+ [ __NR_mprotect ] = sys_mprotect, -+ [ __NR_sigprocmask ] = sys_sigprocmask, -+ [ __NR_create_module ] = sys_create_module, -+ [ __NR_init_module ] = sys_init_module, -+ [ __NR_delete_module ] = sys_delete_module, -+ [ __NR_get_kernel_syms ] = sys_get_kernel_syms, -+ [ __NR_quotactl ] = sys_quotactl, -+ [ __NR_getpgid ] = sys_getpgid, -+ [ __NR_fchdir ] = sys_fchdir, -+ [ __NR_bdflush ] = sys_bdflush, -+ [ __NR_sysfs ] = sys_sysfs, -+ [ __NR_personality ] = sys_personality, -+ [ __NR_afs_syscall ] = sys_ni_syscall, -+ [ __NR_setfsuid ] = sys_setfsuid16, -+ [ __NR_setfsgid ] = sys_setfsgid16, -+ [ __NR__llseek ] = sys_llseek, -+ [ __NR_getdents ] = sys_getdents, -+ [ __NR__newselect ] = (syscall_handler_t *) sys_select, -+ [ __NR_flock ] = sys_flock, -+ [ __NR_msync ] = sys_msync, -+ [ __NR_readv ] = sys_readv, -+ [ __NR_writev ] = sys_writev, -+ [ __NR_getsid ] = sys_getsid, -+ [ __NR_fdatasync ] = sys_fdatasync, -+ [ __NR__sysctl ] = sys_sysctl, -+ [ __NR_mlock ] = sys_mlock, -+ [ __NR_munlock ] = sys_munlock, -+ [ __NR_mlockall ] = sys_mlockall, -+ [ __NR_munlockall ] = sys_munlockall, -+ [ __NR_sched_setparam ] = sys_sched_setparam, -+ [ __NR_sched_getparam ] = sys_sched_getparam, -+ [ __NR_sched_setscheduler ] = sys_sched_setscheduler, -+ [ __NR_sched_getscheduler ] = sys_sched_getscheduler, -+ [ __NR_sched_yield ] = (syscall_handler_t *) yield, -+ [ __NR_sched_get_priority_max ] = sys_sched_get_priority_max, -+ [ __NR_sched_get_priority_min ] = sys_sched_get_priority_min, -+ [ __NR_sched_rr_get_interval ] = sys_sched_rr_get_interval, -+ [ __NR_nanosleep ] = sys_nanosleep, -+ [ __NR_mremap ] = sys_mremap, -+ [ __NR_setresuid ] = sys_setresuid16, -+ [ __NR_getresuid ] = sys_getresuid16, -+ [ __NR_vm86 ] = sys_ni_syscall, -+ [ __NR_query_module ] = sys_query_module, -+ [ __NR_poll ] = sys_poll, -+ [ __NR_nfsservctl ] = sys_nfsservctl, -+ [ __NR_setresgid ] = sys_setresgid16, -+ [ __NR_getresgid ] = sys_getresgid16, -+ [ __NR_prctl ] = sys_prctl, -+ [ __NR_rt_sigreturn ] = sys_rt_sigreturn, -+ [ __NR_rt_sigaction ] = sys_rt_sigaction, -+ [ __NR_rt_sigprocmask ] = sys_rt_sigprocmask, -+ [ __NR_rt_sigpending ] = sys_rt_sigpending, -+ [ __NR_rt_sigtimedwait ] = sys_rt_sigtimedwait, -+ [ __NR_rt_sigqueueinfo ] = sys_rt_sigqueueinfo, -+ [ __NR_rt_sigsuspend ] = sys_rt_sigsuspend, -+ [ __NR_pread ] = sys_pread, -+ [ __NR_pwrite ] = sys_pwrite, -+ [ __NR_chown ] = sys_chown16, -+ [ __NR_getcwd ] = sys_getcwd, -+ [ __NR_capget ] = sys_capget, -+ [ __NR_capset ] = sys_capset, -+ [ __NR_sigaltstack ] = sys_sigaltstack, -+ [ __NR_sendfile ] = sys_sendfile, -+ [ __NR_getpmsg ] = sys_ni_syscall, -+ [ __NR_putpmsg ] = sys_ni_syscall, -+ [ __NR_vfork ] = sys_vfork, -+ [ __NR_ugetrlimit ] = sys_getrlimit, -+ [ __NR_mmap2 ] = sys_mmap2, -+ [ __NR_truncate64 ] = sys_truncate64, -+ [ __NR_ftruncate64 ] = sys_ftruncate64, -+ [ __NR_stat64 ] = sys_stat64, -+ [ __NR_lstat64 ] = sys_lstat64, -+ [ __NR_fstat64 ] = sys_fstat64, -+ [ __NR_fcntl64 ] = sys_fcntl64, -+ [ __NR_getdents64 ] = sys_getdents64, -+ [ __NR_security ] = sys_ni_syscall, -+ [ __NR_gettid ] = sys_gettid, -+ [ __NR_readahead ] = sys_readahead, -+ [ __NR_setxattr ] = sys_setxattr, -+ [ __NR_lsetxattr ] = sys_lsetxattr, -+ [ __NR_fsetxattr ] = sys_fsetxattr, -+ [ __NR_getxattr ] = sys_getxattr, -+ [ __NR_lgetxattr ] = sys_lgetxattr, -+ [ __NR_fgetxattr ] = sys_fgetxattr, -+ [ __NR_listxattr ] = sys_listxattr, -+ [ __NR_llistxattr ] = sys_llistxattr, -+ [ __NR_flistxattr ] = sys_flistxattr, -+ [ __NR_removexattr ] = sys_removexattr, -+ [ __NR_lremovexattr ] = sys_lremovexattr, -+ [ __NR_fremovexattr ] = sys_fremovexattr, -+ [ __NR_tkill ] = sys_tkill, -+ [ __NR_sendfile64 ] = sys_sendfile64, -+ [ __NR_futex ] = sys_ni_syscall, -+ [ __NR_sched_setaffinity ] = sys_ni_syscall, -+ [ __NR_sched_getaffinity ] = sys_ni_syscall, -+ [ __NR_set_thread_area ] = sys_ni_syscall, -+ [ __NR_get_thread_area ] = sys_ni_syscall, -+ [ __NR_io_setup ] = sys_ni_syscall, -+ [ __NR_io_destroy ] = sys_ni_syscall, -+ [ __NR_io_getevents ] = sys_ni_syscall, -+ [ __NR_io_submit ] = sys_ni_syscall, -+ [ __NR_io_cancel ] = sys_ni_syscall, -+ [ __NR_alloc_hugepages ] = sys_ni_syscall, -+ [ __NR_free_hugepages ] = sys_ni_syscall, -+ [ __NR_exit_group ] = sys_ni_syscall, -+ -+ ARCH_SYSCALLS -+ [ LAST_SYSCALL + 1 ... NR_syscalls ] = -+ (syscall_handler_t *) sys_ni_syscall -+}; -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/syscall_user.c um/arch/um/kernel/syscall_user.c ---- orig/arch/um/kernel/syscall_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/syscall_user.c 2003-12-22 01:32:48.000000000 -0500 -@@ -0,0 +1,48 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <stdlib.h> -+#include <sys/time.h> -+#include "kern_util.h" -+#include "syscall_user.h" -+ -+struct { -+ int syscall; -+ int pid; -+ int result; -+ struct timeval start; -+ struct timeval end; -+} syscall_record[1024]; -+ -+int record_syscall_start(int syscall) -+{ -+ int max, index; -+ -+ max = sizeof(syscall_record)/sizeof(syscall_record[0]); -+ index = next_syscall_index(max); -+ -+ syscall_record[index].syscall = syscall; -+ syscall_record[index].pid = current_pid(); -+ syscall_record[index].result = 0xdeadbeef; -+ gettimeofday(&syscall_record[index].start, NULL); -+ return(index); -+} -+ -+void record_syscall_end(int index, int result) -+{ -+ syscall_record[index].result = result; -+ gettimeofday(&syscall_record[index].end, NULL); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/sysrq.c um/arch/um/kernel/sysrq.c ---- orig/arch/um/kernel/sysrq.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/sysrq.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,98 @@ -+/* -+ * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/sched.h" -+#include "linux/kernel.h" -+#include "linux/module.h" -+#include "asm/page.h" -+#include "asm/processor.h" -+#include "sysrq.h" -+#include "user_util.h" -+ -+ /* -+ * If the address is either in the .text section of the -+ * kernel, or in the vmalloc'ed module regions, it *may* -+ * be the address of a calling routine -+ */ -+ -+#ifdef CONFIG_MODULES -+ -+extern struct module *module_list; -+extern struct module kernel_module; -+ -+static inline int kernel_text_address(unsigned long addr) -+{ -+ int retval = 0; -+ struct module *mod; -+ -+ if (addr >= (unsigned long) &_stext && -+ addr <= (unsigned long) &_etext) -+ return 1; -+ -+ for (mod = module_list; mod != &kernel_module; mod = mod->next) { -+ /* mod_bound tests for addr being inside the vmalloc'ed -+ * module area. Of course it'd be better to test only -+ * for the .text subset... */ -+ if (mod_bound(addr, 0, mod)) { -+ retval = 1; -+ break; -+ } -+ } -+ -+ return retval; -+} -+ -+#else -+ -+static inline int kernel_text_address(unsigned long addr) -+{ -+ return (addr >= (unsigned long) &_stext && -+ addr <= (unsigned long) &_etext); -+} -+ -+#endif -+ -+void show_trace(unsigned long * stack) -+{ -+ int i; -+ unsigned long addr; -+ -+ if (!stack) -+ stack = (unsigned long*) &stack; -+ -+ printk("Call Trace: "); -+ i = 1; -+ while (((long) stack & (THREAD_SIZE-1)) != 0) { -+ addr = *stack++; -+ if (kernel_text_address(addr)) { -+ if (i && ((i % 6) == 0)) -+ printk("\n "); -+ printk("[<%08lx>] ", addr); -+ i++; -+ } -+ } -+ printk("\n"); -+} -+ -+void show_trace_task(struct task_struct *tsk) -+{ -+ unsigned long esp = PT_REGS_SP(&tsk->thread.regs); -+ -+ /* User space on another CPU? */ -+ if ((esp ^ (unsigned long)tsk) & (PAGE_MASK<<1)) -+ return; -+ show_trace((unsigned long *)esp); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tempfile.c um/arch/um/kernel/tempfile.c ---- orig/arch/um/kernel/tempfile.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tempfile.c 2003-12-22 01:33:38.000000000 -0500 -@@ -0,0 +1,82 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <stdio.h> -+#include <stdlib.h> -+#include <unistd.h> -+#include <string.h> -+#include <errno.h> -+#include <sys/param.h> -+#include "init.h" -+ -+/* Modified from create_mem_file and start_debugger */ -+static char *tempdir = NULL; -+ -+static void __init find_tempdir(void) -+{ -+ char *dirs[] = { "TMP", "TEMP", "TMPDIR", NULL }; -+ int i; -+ char *dir = NULL; -+ -+ if(tempdir != NULL) return; /* We've already been called */ -+ for(i = 0; dirs[i]; i++){ -+ dir = getenv(dirs[i]); -+ if((dir != NULL) && (*dir != '\0')) -+ break; -+ } -+ if((dir == NULL) || (*dir == '\0')) -+ dir = "/tmp"; -+ -+ tempdir = malloc(strlen(dir) + 2); -+ if(tempdir == NULL){ -+ fprintf(stderr, "Failed to malloc tempdir, " -+ "errno = %d\n", errno); -+ return; -+ } -+ strcpy(tempdir, dir); -+ strcat(tempdir, "/"); -+} -+ -+int make_tempfile(const char *template, char **out_tempname, int do_unlink) -+{ -+ char tempname[MAXPATHLEN]; -+ int fd; -+ -+ find_tempdir(); -+ if (*template != '/') -+ strcpy(tempname, tempdir); -+ else -+ *tempname = 0; -+ strcat(tempname, template); -+ fd = mkstemp(tempname); -+ if(fd < 0){ -+ fprintf(stderr, "open - cannot create %s: %s\n", tempname, -+ strerror(errno)); -+ return -1; -+ } -+ if(do_unlink && (unlink(tempname) < 0)){ -+ perror("unlink"); -+ return -1; -+ } -+ if(out_tempname){ -+ *out_tempname = strdup(tempname); -+ if(*out_tempname == NULL){ -+ perror("strdup"); -+ return -1; -+ } -+ } -+ return(fd); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/time.c um/arch/um/kernel/time.c ---- orig/arch/um/kernel/time.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/time.c 2004-02-12 07:09:48.000000000 -0500 -@@ -0,0 +1,172 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <stdio.h> -+#include <stdlib.h> -+#include <unistd.h> -+#include <time.h> -+#include <sys/time.h> -+#include <signal.h> -+#include <errno.h> -+#include "user_util.h" -+#include "kern_util.h" -+#include "user.h" -+#include "process.h" -+#include "signal_user.h" -+#include "time_user.h" -+ -+extern struct timeval xtime; -+ -+struct timeval local_offset = { 0, 0 }; -+ -+void timer(void) -+{ -+ gettimeofday(&xtime, NULL); -+ timeradd(&xtime, &local_offset, &xtime); -+} -+ -+void set_interval(int timer_type) -+{ -+ int usec = 1000000/hz(); -+ struct itimerval interval = ((struct itimerval) { { 0, usec }, -+ { 0, usec } }); -+ -+ if(setitimer(timer_type, &interval, NULL) == -1) -+ panic("setitimer failed - errno = %d\n", errno); -+} -+ -+void enable_timer(void) -+{ -+ int usec = 1000000/hz(); -+ struct itimerval enable = ((struct itimerval) { { 0, usec }, -+ { 0, usec }}); -+ if(setitimer(ITIMER_VIRTUAL, &enable, NULL)) -+ printk("enable_timer - setitimer failed, errno = %d\n", -+ errno); -+} -+ -+void switch_timers(int to_real) -+{ -+ struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }}); -+ struct itimerval enable = ((struct itimerval) { { 0, 1000000/hz() }, -+ { 0, 1000000/hz() }}); -+ int old, new; -+ -+ if(to_real){ -+ old = ITIMER_VIRTUAL; -+ new = ITIMER_REAL; -+ } -+ else { -+ old = ITIMER_REAL; -+ new = ITIMER_VIRTUAL; -+ } -+ -+ if((setitimer(old, &disable, NULL) < 0) || -+ (setitimer(new, &enable, NULL))) -+ printk("switch_timers - setitimer failed, errno = %d\n", -+ errno); -+} -+ -+void idle_timer(void) -+{ -+ if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR) -+ panic("Couldn't unset SIGVTALRM handler"); -+ -+ set_handler(SIGALRM, (__sighandler_t) alarm_handler, -+ SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1); -+ set_interval(ITIMER_REAL); -+} -+ -+static unsigned long long get_host_hz(void) -+{ -+ char mhzline[16], *end; -+ unsigned long long mhz; -+ int ret, mult, rest, len; -+ -+ ret = cpu_feature("cpu MHz", mhzline, -+ sizeof(mhzline) / sizeof(mhzline[0])); -+ if(!ret) -+ panic ("Could not get host MHZ"); -+ -+ mhz = strtoul(mhzline, &end, 10); -+ -+ /* This business is to parse a floating point number without using -+ * floating types. -+ */ -+ -+ rest = 0; -+ mult = 0; -+ if(*end == '.'){ -+ end++; -+ len = strlen(end); -+ if(len < 6) -+ mult = 6 - len; -+ else if(len > 6) -+ end[6] = '\0'; -+ rest = strtoul(end, NULL, 10); -+ while(mult-- > 0) -+ rest *= 10; -+ } -+ -+ return(1000000 * mhz + rest); -+} -+ -+unsigned long long host_hz = 0; -+ -+void time_init(void) -+{ -+ /* XXX This is to fill xtime with something real - otherwise by the -+ * time /proc is mounted, no timers have fired, and xtime is still 0, -+ * meaning it shows times of Jan 1 1970. The real fix is to figure -+ * out why no timers have happened by then. -+ */ -+ timer(); -+ -+ host_hz = get_host_hz(); -+ if(signal(SIGVTALRM, boot_timer_handler) == SIG_ERR) -+ panic("Couldn't set SIGVTALRM handler"); -+ set_interval(ITIMER_VIRTUAL); -+} -+ -+void do_gettimeofday(struct timeval *tv) -+{ -+ unsigned long flags; -+ -+ flags = time_lock(); -+ gettimeofday(tv, NULL); -+ timeradd(tv, &local_offset, tv); -+ time_unlock(flags); -+} -+ -+void do_settimeofday(struct timeval *tv) -+{ -+ struct timeval now; -+ unsigned long flags; -+ -+ flags = time_lock(); -+ gettimeofday(&now, NULL); -+ timersub(tv, &now, &local_offset); -+ time_unlock(flags); -+} -+ -+void idle_sleep(int secs) -+{ -+ struct timespec ts; -+ -+ ts.tv_sec = secs; -+ ts.tv_nsec = 0; -+ nanosleep(&ts, NULL); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/time_kern.c um/arch/um/kernel/time_kern.c ---- orig/arch/um/kernel/time_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/time_kern.c 2004-02-14 06:51:31.000000000 -0500 -@@ -0,0 +1,205 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/kernel.h" -+#include "linux/unistd.h" -+#include "linux/stddef.h" -+#include "linux/spinlock.h" -+#include "linux/sched.h" -+#include "linux/interrupt.h" -+#include "linux/init.h" -+#include "linux/delay.h" -+#include "asm/irq.h" -+#include "asm/param.h" -+#include "asm/current.h" -+#include "kern_util.h" -+#include "user_util.h" -+#include "time_user.h" -+#include "mode.h" -+ -+extern rwlock_t xtime_lock; -+ -+int hz(void) -+{ -+ return(HZ); -+} -+ -+/* Changed at early boot */ -+int timer_irq_inited = 0; -+ -+/* missed_ticks will be modified after kernel memory has been -+ * write-protected, so this puts it in a section which will be left -+ * write-enabled. -+ */ -+int __attribute__ ((__section__ (".unprotected"))) missed_ticks[NR_CPUS]; -+ -+static int first_tick; -+static unsigned long long prev_tsc; -+static long long delta; /* Deviation per interval */ -+ -+extern unsigned long long host_hz; -+ -+void timer_irq(union uml_pt_regs *regs) -+{ -+ unsigned long long ticks = 0; -+ -+ if(!timer_irq_inited){ -+ /* This is to ensure that ticks don't pile up when -+ * the timer handler is suspended */ -+ first_tick = 0; -+ return; -+ } -+ -+ if(first_tick){ -+#if defined(CONFIG_UML_REAL_TIME_CLOCK) -+ unsigned long long tsc; -+ /* We've had 1 tick */ -+ tsc = time_stamp(); -+ -+ delta += tsc - prev_tsc; -+ prev_tsc = tsc; -+ -+ ticks += (delta * HZ) / host_hz; -+ delta -= (ticks * host_hz) / HZ; -+#else -+ ticks = 1; -+#endif -+ } -+ else { -+ prev_tsc = time_stamp(); -+ first_tick = 1; -+ } -+ -+ while(ticks > 0){ -+ do_IRQ(TIMER_IRQ, regs); -+ ticks--; -+ } -+} -+ -+void boot_timer_handler(int sig) -+{ -+ struct pt_regs regs; -+ -+ CHOOSE_MODE((void) -+ (UPT_SC(®s.regs) = (struct sigcontext *) (&sig + 1)), -+ (void) (regs.regs.skas.is_user = 0)); -+ do_timer(®s); -+} -+ -+void um_timer(int irq, void *dev, struct pt_regs *regs) -+{ -+ do_timer(regs); -+ write_lock(&xtime_lock); -+ vxtime_lock(); -+ timer(); -+ vxtime_unlock(); -+ write_unlock(&xtime_lock); -+} -+ -+long um_time(int * tloc) -+{ -+ struct timeval now; -+ -+ do_gettimeofday(&now); -+ if (tloc) { -+ if (put_user(now.tv_sec,tloc)) -+ now.tv_sec = -EFAULT; -+ } -+ return now.tv_sec; -+} -+ -+long um_stime(int * tptr) -+{ -+ int value; -+ struct timeval new; -+ -+ if (get_user(value, tptr)) -+ return -EFAULT; -+ new.tv_sec = value; -+ new.tv_usec = 0; -+ do_settimeofday(&new); -+ return 0; -+} -+ -+/* XXX Needs to be moved under sys-i386 */ -+void __delay(um_udelay_t time) -+{ -+ /* Stolen from the i386 __loop_delay */ -+ int d0; -+ __asm__ __volatile__( -+ "\tjmp 1f\n" -+ ".align 16\n" -+ "1:\tjmp 2f\n" -+ ".align 16\n" -+ "2:\tdecl %0\n\tjns 2b" -+ :"=&a" (d0) -+ :"0" (time)); -+} -+ -+void __udelay(um_udelay_t usecs) -+{ -+ int i, n; -+ -+ n = (loops_per_jiffy * HZ * usecs) / 1000000; -+ for(i=0;i<n;i++) ; -+} -+ -+void __const_udelay(um_udelay_t usecs) -+{ -+ int i, n; -+ -+ n = (loops_per_jiffy * HZ * usecs) / 1000000; -+ for(i=0;i<n;i++) ; -+} -+ -+void timer_handler(int sig, union uml_pt_regs *regs) -+{ -+#ifdef CONFIG_SMP -+ update_process_times(user_context(UPT_SP(regs))); -+#endif -+ if(current->processor == 0) -+ timer_irq(regs); -+} -+ -+static spinlock_t timer_spinlock = SPIN_LOCK_UNLOCKED; -+ -+unsigned long time_lock(void) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&timer_spinlock, flags); -+ return(flags); -+} -+ -+void time_unlock(unsigned long flags) -+{ -+ spin_unlock_irqrestore(&timer_spinlock, flags); -+} -+ -+int __init timer_init(void) -+{ -+ int err; -+ -+ CHOOSE_MODE(user_time_init_tt(), user_time_init_skas()); -+ err = request_irq(TIMER_IRQ, um_timer, SA_INTERRUPT, "timer", NULL); -+ if(err != 0) -+ printk(KERN_ERR "timer_init : request_irq failed - " -+ "errno = %d\n", -err); -+ timer_irq_inited = 1; -+ return(0); -+} -+ -+__initcall(timer_init); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tlb.c um/arch/um/kernel/tlb.c ---- orig/arch/um/kernel/tlb.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tlb.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,80 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/mm.h" -+#include "asm/page.h" -+#include "asm/pgalloc.h" -+#include "choose-mode.h" -+#include "mode_kern.h" -+ -+void flush_tlb_page(struct vm_area_struct *vma, unsigned long address) -+{ -+ address &= PAGE_MASK; -+ flush_tlb_range(vma->vm_mm, address, address + PAGE_SIZE); -+} -+ -+void flush_tlb_all(void) -+{ -+ flush_tlb_mm(current->mm); -+} -+ -+void flush_tlb_kernel_vm(void) -+{ -+ CHOOSE_MODE(flush_tlb_kernel_vm_tt(), flush_tlb_kernel_vm_skas()); -+} -+ -+void __flush_tlb_one(unsigned long addr) -+{ -+ CHOOSE_MODE_PROC(__flush_tlb_one_tt, __flush_tlb_one_skas, addr); -+} -+ -+void flush_tlb_range(struct mm_struct *mm, unsigned long start, -+ unsigned long end) -+{ -+ CHOOSE_MODE_PROC(flush_tlb_range_tt, flush_tlb_range_skas, mm, start, -+ end); -+} -+ -+void flush_tlb_mm(struct mm_struct *mm) -+{ -+ CHOOSE_MODE_PROC(flush_tlb_mm_tt, flush_tlb_mm_skas, mm); -+} -+ -+void force_flush_all(void) -+{ -+ CHOOSE_MODE(force_flush_all_tt(), force_flush_all_skas()); -+} -+ -+ -+pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address) -+{ -+ return(pgd_offset(mm, address)); -+} -+ -+pmd_t *pmd_offset_proc(pgd_t *pgd, unsigned long address) -+{ -+ return(pmd_offset(pgd, address)); -+} -+ -+pte_t *pte_offset_proc(pmd_t *pmd, unsigned long address) -+{ -+ return(pte_offset(pmd, address)); -+} -+ -+pte_t *addr_pte(struct task_struct *task, unsigned long addr) -+{ -+ return(pte_offset(pmd_offset(pgd_offset(task->mm, addr), addr), addr)); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/trap_kern.c um/arch/um/kernel/trap_kern.c ---- orig/arch/um/kernel/trap_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/trap_kern.c 2003-12-22 22:48:41.000000000 -0500 -@@ -0,0 +1,220 @@ -+/* -+ * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/kernel.h" -+#include "linux/sched.h" -+#include "linux/mm.h" -+#include "linux/spinlock.h" -+#include "linux/config.h" -+#include "linux/init.h" -+#include "asm/semaphore.h" -+#include "asm/pgtable.h" -+#include "asm/pgalloc.h" -+#include "asm/a.out.h" -+#include "asm/current.h" -+#include "asm/irq.h" -+#include "user_util.h" -+#include "kern_util.h" -+#include "kern.h" -+#include "chan_kern.h" -+#include "mconsole_kern.h" -+#include "2_5compat.h" -+#include "mem.h" -+#include "mem_kern.h" -+ -+unsigned long handle_page_fault(unsigned long address, unsigned long ip, -+ int is_write, int is_user, int *code_out) -+{ -+ struct mm_struct *mm = current->mm; -+ struct vm_area_struct *vma; -+ pgd_t *pgd; -+ pmd_t *pmd; -+ pte_t *pte; -+ unsigned long page; -+ int handled = 0; -+ -+ *code_out = SEGV_MAPERR; -+ down_read(&mm->mmap_sem); -+ vma = find_vma(mm, address); -+ if(!vma) -+ goto out; -+ else if(vma->vm_start <= address) -+ goto good_area; -+ else if(!(vma->vm_flags & VM_GROWSDOWN)) -+ goto out; -+ else if(expand_stack(vma, address)) -+ goto out; -+ -+ good_area: -+ *code_out = SEGV_ACCERR; -+ if(is_write && !(vma->vm_flags & VM_WRITE)) -+ goto out; -+ page = address & PAGE_MASK; -+ if(page == (unsigned long) current + PAGE_SIZE) -+ panic("Kernel stack overflow"); -+ pgd = pgd_offset(mm, page); -+ pmd = pmd_offset(pgd, page); -+ do { -+ survive: -+ switch (handle_mm_fault(mm, vma, address, is_write)) { -+ case 1: -+ current->min_flt++; -+ break; -+ case 2: -+ current->maj_flt++; -+ break; -+ default: -+ if (current->pid == 1) { -+ up_read(&mm->mmap_sem); -+ yield(); -+ down_read(&mm->mmap_sem); -+ goto survive; -+ } -+ /* Fall through to bad area case */ -+ case 0: -+ goto out; -+ } -+ pte = pte_offset(pmd, page); -+ } while(!pte_present(*pte)); -+ handled = 1; -+ *pte = pte_mkyoung(*pte); -+ if(pte_write(*pte)) *pte = pte_mkdirty(*pte); -+ flush_tlb_page(vma, page); -+ out: -+ up_read(&mm->mmap_sem); -+ return(handled); -+} -+ -+LIST_HEAD(physmem_remappers); -+ -+void register_remapper(struct remapper *info) -+{ -+ list_add(&info->list, &physmem_remappers); -+} -+ -+static int check_remapped_addr(unsigned long address, int is_write) -+{ -+ struct remapper *remapper; -+ struct list_head *ele; -+ __u64 offset; -+ int fd; -+ -+ fd = phys_mapping(__pa(address), &offset); -+ if(fd == -1) -+ return(0); -+ -+ list_for_each(ele, &physmem_remappers){ -+ remapper = list_entry(ele, struct remapper, list); -+ if((*remapper->proc)(fd, address, is_write, offset)) -+ return(1); -+ } -+ -+ return(0); -+} -+ -+unsigned long segv(unsigned long address, unsigned long ip, int is_write, -+ int is_user, void *sc) -+{ -+ struct siginfo si; -+ void *catcher; -+ int handled; -+ -+ if(!is_user && (address >= start_vm) && (address < end_vm)){ -+ flush_tlb_kernel_vm(); -+ return(0); -+ } -+ else if(check_remapped_addr(address & PAGE_MASK, is_write)) -+ return(0); -+ else if(current->mm == NULL) -+ panic("Segfault with no mm"); -+ -+ handled = handle_page_fault(address, ip, is_write, is_user, -+ &si.si_code); -+ -+ catcher = current->thread.fault_catcher; -+ if(handled) -+ return(0); -+ else if(catcher != NULL){ -+ current->thread.fault_addr = (void *) address; -+ do_longjmp(catcher, 1); -+ } -+ else if(current->thread.fault_addr != NULL) -+ panic("fault_addr set but no fault catcher"); -+ else if(arch_fixup(ip, sc)) -+ return(0); -+ -+ if(!is_user) -+ panic("Kernel mode fault at addr 0x%lx, ip 0x%lx", -+ address, ip); -+ si.si_signo = SIGSEGV; -+ si.si_addr = (void *) address; -+ current->thread.cr2 = address; -+ current->thread.err = is_write; -+ force_sig_info(SIGSEGV, &si, current); -+ return(0); -+} -+ -+void bad_segv(unsigned long address, unsigned long ip, int is_write) -+{ -+ struct siginfo si; -+ -+ si.si_signo = SIGSEGV; -+ si.si_code = SEGV_ACCERR; -+ si.si_addr = (void *) address; -+ current->thread.cr2 = address; -+ current->thread.err = is_write; -+ force_sig_info(SIGSEGV, &si, current); -+} -+ -+void relay_signal(int sig, union uml_pt_regs *regs) -+{ -+ if(arch_handle_signal(sig, regs)) return; -+ if(!UPT_IS_USER(regs)) -+ panic("Kernel mode signal %d", sig); -+ force_sig(sig, current); -+} -+ -+void bus_handler(int sig, union uml_pt_regs *regs) -+{ -+ if(current->thread.fault_catcher != NULL) -+ do_longjmp(current->thread.fault_catcher, 1); -+ else relay_signal(sig, regs); -+} -+ -+void winch(int sig, union uml_pt_regs *regs) -+{ -+ do_IRQ(WINCH_IRQ, regs); -+} -+ -+void trap_init(void) -+{ -+} -+ -+spinlock_t trap_lock = SPIN_LOCK_UNLOCKED; -+ -+static int trap_index = 0; -+ -+int next_trap_index(int limit) -+{ -+ int ret; -+ -+ spin_lock(&trap_lock); -+ ret = trap_index; -+ if(++trap_index == limit) -+ trap_index = 0; -+ spin_unlock(&trap_lock); -+ return(ret); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/trap_user.c um/arch/um/kernel/trap_user.c ---- orig/arch/um/kernel/trap_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/trap_user.c 2004-01-31 02:47:39.000000000 -0500 -@@ -0,0 +1,138 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <stdlib.h> -+#include <errno.h> -+#include <setjmp.h> -+#include <signal.h> -+#include <sys/time.h> -+#include <sys/ptrace.h> -+#include <sys/wait.h> -+#include <asm/page.h> -+#include <asm/unistd.h> -+#include <asm/ptrace.h> -+#include "init.h" -+#include "sysdep/ptrace.h" -+#include "sigcontext.h" -+#include "sysdep/sigcontext.h" -+#include "irq_user.h" -+#include "frame_user.h" -+#include "signal_user.h" -+#include "time_user.h" -+#include "task.h" -+#include "mode.h" -+#include "choose-mode.h" -+#include "kern_util.h" -+#include "user_util.h" -+#include "os.h" -+ -+void kill_child_dead(int pid) -+{ -+ kill(pid, SIGKILL); -+ kill(pid, SIGCONT); -+ while(waitpid(pid, NULL, 0) > 0) kill(pid, SIGCONT); -+} -+ -+/* Unlocked - don't care if this is a bit off */ -+int nsegfaults = 0; -+ -+struct { -+ unsigned long address; -+ int is_write; -+ int pid; -+ unsigned long sp; -+ int is_user; -+} segfault_record[1024]; -+ -+void segv_handler(int sig, union uml_pt_regs *regs) -+{ -+ int index, max; -+ -+ if(UPT_IS_USER(regs) && !UPT_SEGV_IS_FIXABLE(regs)){ -+ bad_segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), -+ UPT_FAULT_WRITE(regs)); -+ return; -+ } -+ max = sizeof(segfault_record)/sizeof(segfault_record[0]); -+ index = next_trap_index(max); -+ -+ nsegfaults++; -+ segfault_record[index].address = UPT_FAULT_ADDR(regs); -+ segfault_record[index].pid = os_getpid(); -+ segfault_record[index].is_write = UPT_FAULT_WRITE(regs); -+ segfault_record[index].sp = UPT_SP(regs); -+ segfault_record[index].is_user = UPT_IS_USER(regs); -+ segv(UPT_FAULT_ADDR(regs), UPT_IP(regs), UPT_FAULT_WRITE(regs), -+ UPT_IS_USER(regs), regs); -+} -+ -+void usr2_handler(int sig, union uml_pt_regs *regs) -+{ -+ CHOOSE_MODE(syscall_handler_tt(sig, regs), (void) 0); -+} -+ -+struct signal_info sig_info[] = { -+ [ SIGTRAP ] { .handler = relay_signal, -+ .is_irq = 0 }, -+ [ SIGFPE ] { .handler = relay_signal, -+ .is_irq = 0 }, -+ [ SIGILL ] { .handler = relay_signal, -+ .is_irq = 0 }, -+ [ SIGWINCH ] { .handler = winch, -+ .is_irq = 1 }, -+ [ SIGBUS ] { .handler = bus_handler, -+ .is_irq = 0 }, -+ [ SIGSEGV] { .handler = segv_handler, -+ .is_irq = 0 }, -+ [ SIGIO ] { .handler = sigio_handler, -+ .is_irq = 1 }, -+ [ SIGVTALRM ] { .handler = timer_handler, -+ .is_irq = 1 }, -+ [ SIGALRM ] { .handler = timer_handler, -+ .is_irq = 1 }, -+ [ SIGUSR2 ] { .handler = usr2_handler, -+ .is_irq = 0 }, -+}; -+ -+void sig_handler(int sig, struct sigcontext sc) -+{ -+ CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas, -+ sig, &sc); -+} -+ -+extern int timer_irq_inited, missed_ticks[]; -+ -+void alarm_handler(int sig, struct sigcontext sc) -+{ -+ if(!timer_irq_inited) return; -+ missed_ticks[cpu()]++; -+ -+ if(sig == SIGALRM) -+ switch_timers(0); -+ -+ CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas, -+ sig, &sc); -+ -+ if(sig == SIGALRM) -+ switch_timers(1); -+} -+ -+void do_longjmp(void *b, int val) -+{ -+ sigjmp_buf *buf = b; -+ -+ siglongjmp(*buf, val); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/exec_kern.c um/arch/um/kernel/tt/exec_kern.c ---- orig/arch/um/kernel/tt/exec_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/exec_kern.c 2003-11-07 02:23:10.000000000 -0500 -@@ -0,0 +1,84 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/kernel.h" -+#include "linux/mm.h" -+#include "asm/signal.h" -+#include "asm/ptrace.h" -+#include "asm/uaccess.h" -+#include "asm/pgalloc.h" -+#include "user_util.h" -+#include "kern_util.h" -+#include "irq_user.h" -+#include "time_user.h" -+#include "mem_user.h" -+#include "os.h" -+#include "tlb.h" -+#include "mode.h" -+ -+static int exec_tramp(void *sig_stack) -+{ -+ init_new_thread_stack(sig_stack, NULL); -+ init_new_thread_signals(1); -+ os_stop_process(os_getpid()); -+ return(0); -+} -+ -+void flush_thread_tt(void) -+{ -+ unsigned long stack; -+ int new_pid; -+ -+ stack = alloc_stack(0, 0); -+ if(stack == 0){ -+ printk(KERN_ERR -+ "flush_thread : failed to allocate temporary stack\n"); -+ do_exit(SIGKILL); -+ } -+ -+ new_pid = start_fork_tramp((void *) current->thread.kernel_stack, -+ stack, 0, exec_tramp); -+ if(new_pid < 0){ -+ printk(KERN_ERR -+ "flush_thread : new thread failed, errno = %d\n", -+ -new_pid); -+ do_exit(SIGKILL); -+ } -+ -+ if(current->processor == 0) -+ forward_interrupts(new_pid); -+ current->thread.request.op = OP_EXEC; -+ current->thread.request.u.exec.pid = new_pid; -+ unprotect_stack((unsigned long) current); -+ os_usr1_process(os_getpid()); -+ -+ enable_timer(); -+ free_page(stack); -+ protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1); -+ task_protections((unsigned long) current); -+ force_flush_all(); -+ unblock_signals(); -+} -+ -+void start_thread_tt(struct pt_regs *regs, unsigned long eip, -+ unsigned long esp) -+{ -+ set_fs(USER_DS); -+ flush_tlb_mm(current->mm); -+ PT_REGS_IP(regs) = eip; -+ PT_REGS_SP(regs) = esp; -+ PT_FIX_EXEC_STACK(esp); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/exec_user.c um/arch/um/kernel/tt/exec_user.c ---- orig/arch/um/kernel/tt/exec_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/exec_user.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,49 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <stdio.h> -+#include <unistd.h> -+#include <stdlib.h> -+#include <sched.h> -+#include <errno.h> -+#include <sys/wait.h> -+#include <sys/ptrace.h> -+#include <signal.h> -+#include "user_util.h" -+#include "kern_util.h" -+#include "user.h" -+#include "ptrace_user.h" -+ -+void do_exec(int old_pid, int new_pid) -+{ -+ unsigned long regs[FRAME_SIZE]; -+ -+ if((ptrace(PTRACE_ATTACH, new_pid, 0, 0) < 0) || -+ (ptrace(PTRACE_CONT, new_pid, 0, 0) < 0) || -+ (waitpid(new_pid, 0, WUNTRACED) < 0)) -+ tracer_panic("do_exec failed to attach proc - errno = %d", -+ errno); -+ -+ if(ptrace_getregs(old_pid, regs) < 0) -+ tracer_panic("do_exec failed to get registers - errno = %d", -+ errno); -+ -+ kill(old_pid, SIGKILL); -+ -+ if(ptrace_setregs(new_pid, regs) < 0) -+ tracer_panic("do_exec failed to start new proc - errno = %d", -+ errno); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/gdb.c um/arch/um/kernel/tt/gdb.c ---- orig/arch/um/kernel/tt/gdb.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/gdb.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,278 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <stdio.h> -+#include <stdlib.h> -+#include <errno.h> -+#include <string.h> -+#include <signal.h> -+#include <sys/ptrace.h> -+#include <sys/types.h> -+#include "uml-config.h" -+#include "kern_constants.h" -+#include "chan_user.h" -+#include "init.h" -+#include "user.h" -+#include "debug.h" -+#include "kern_util.h" -+#include "user_util.h" -+#include "tt.h" -+#include "sysdep/thread.h" -+ -+extern int debugger_pid; -+extern int debugger_fd; -+extern int debugger_parent; -+ -+int detach(int pid, int sig) -+{ -+ return(ptrace(PTRACE_DETACH, pid, 0, sig)); -+} -+ -+int attach(int pid) -+{ -+ int err; -+ -+ err = ptrace(PTRACE_ATTACH, pid, 0, 0); -+ if(err < 0) return(-errno); -+ else return(err); -+} -+ -+int cont(int pid) -+{ -+ return(ptrace(PTRACE_CONT, pid, 0, 0)); -+} -+ -+#ifdef UML_CONFIG_PT_PROXY -+ -+int debugger_signal(int status, pid_t pid) -+{ -+ return(debugger_proxy(status, pid)); -+} -+ -+void child_signal(pid_t pid, int status) -+{ -+ child_proxy(pid, status); -+} -+ -+static void gdb_announce(char *dev_name, int dev) -+{ -+ printf("gdb assigned device '%s'\n", dev_name); -+} -+ -+static struct chan_opts opts = { -+ .announce = gdb_announce, -+ .xterm_title = "UML kernel debugger", -+ .raw = 0, -+ .tramp_stack = 0, -+ .in_kernel = 0, -+}; -+ -+/* Accessed by the tracing thread, which automatically serializes access */ -+static void *xterm_data; -+static int xterm_fd; -+ -+extern void *xterm_init(char *, int, struct chan_opts *); -+extern int xterm_open(int, int, int, void *, char **); -+extern void xterm_close(int, void *); -+ -+int open_gdb_chan(void) -+{ -+ char stack[UM_KERN_PAGE_SIZE], *dummy; -+ -+ opts.tramp_stack = (unsigned long) stack; -+ xterm_data = xterm_init("", 0, &opts); -+ xterm_fd = xterm_open(1, 1, 1, xterm_data, &dummy); -+ return(xterm_fd); -+} -+ -+static void exit_debugger_cb(void *unused) -+{ -+ if(debugger_pid != -1){ -+ if(gdb_pid != -1){ -+ fake_child_exit(); -+ gdb_pid = -1; -+ } -+ else kill_child_dead(debugger_pid); -+ debugger_pid = -1; -+ if(debugger_parent != -1) -+ detach(debugger_parent, SIGINT); -+ } -+ if(xterm_data != NULL) xterm_close(xterm_fd, xterm_data); -+} -+ -+static void exit_debugger(void) -+{ -+ initial_thread_cb(exit_debugger_cb, NULL); -+} -+ -+__uml_exitcall(exit_debugger); -+ -+struct gdb_data { -+ char *str; -+ int err; -+}; -+ -+static void config_gdb_cb(void *arg) -+{ -+ struct gdb_data *data = arg; -+ void *task; -+ int pid; -+ -+ data->err = -1; -+ if(debugger_pid != -1) exit_debugger_cb(NULL); -+ if(!strncmp(data->str, "pid,", strlen("pid,"))){ -+ data->str += strlen("pid,"); -+ pid = strtoul(data->str, NULL, 0); -+ task = cpu_tasks[0].task; -+ debugger_pid = attach_debugger(TASK_EXTERN_PID(task), pid, 0); -+ if(debugger_pid != -1){ -+ data->err = 0; -+ gdb_pid = pid; -+ } -+ return; -+ } -+ data->err = 0; -+ debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd); -+ init_proxy(debugger_pid, 0, 0); -+} -+ -+int gdb_config(char *str) -+{ -+ struct gdb_data data; -+ -+ if(*str++ != '=') return(-1); -+ data.str = str; -+ initial_thread_cb(config_gdb_cb, &data); -+ return(data.err); -+} -+ -+void remove_gdb_cb(void *unused) -+{ -+ exit_debugger_cb(NULL); -+} -+ -+int gdb_remove(char *unused) -+{ -+ initial_thread_cb(remove_gdb_cb, NULL); -+ return(0); -+} -+ -+void signal_usr1(int sig) -+{ -+ if(debugger_pid != -1){ -+ printk(UM_KERN_ERR "The debugger is already running\n"); -+ return; -+ } -+ debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd); -+ init_proxy(debugger_pid, 0, 0); -+} -+ -+int init_ptrace_proxy(int idle_pid, int startup, int stop) -+{ -+ int pid, status; -+ -+ pid = start_debugger(linux_prog, startup, stop, &debugger_fd); -+ status = wait_for_stop(idle_pid, SIGSTOP, PTRACE_CONT, NULL); -+ if(pid < 0){ -+ cont(idle_pid); -+ return(-1); -+ } -+ init_proxy(pid, 1, status); -+ return(pid); -+} -+ -+int attach_debugger(int idle_pid, int pid, int stop) -+{ -+ int status = 0, err; -+ -+ err = attach(pid); -+ if(err < 0){ -+ printf("Failed to attach pid %d, errno = %d\n", pid, -err); -+ return(-1); -+ } -+ if(stop) status = wait_for_stop(idle_pid, SIGSTOP, PTRACE_CONT, NULL); -+ init_proxy(pid, 1, status); -+ return(pid); -+} -+ -+#ifdef notdef /* Put this back in when it does something useful */ -+static int __init uml_gdb_init_setup(char *line, int *add) -+{ -+ gdb_init = uml_strdup(line); -+ return 0; -+} -+ -+__uml_setup("gdb=", uml_gdb_init_setup, -+"gdb=<channel description>\n\n" -+); -+#endif -+ -+static int __init uml_gdb_pid_setup(char *line, int *add) -+{ -+ gdb_pid = strtoul(line, NULL, 0); -+ *add = 0; -+ return 0; -+} -+ -+__uml_setup("gdb-pid=", uml_gdb_pid_setup, -+"gdb-pid=<pid>\n" -+" gdb-pid is used to attach an external debugger to UML. This may be\n" -+" an already-running gdb or a debugger-like process like strace.\n\n" -+); -+ -+#else -+ -+int debugger_signal(int status, pid_t pid){ return(0); } -+void child_signal(pid_t pid, int status){ } -+int init_ptrace_proxy(int idle_pid, int startup, int stop) -+{ -+ printk(UM_KERN_ERR "debug requested when CONFIG_PT_PROXY is off\n"); -+ kill_child_dead(idle_pid); -+ exit(1); -+} -+ -+void signal_usr1(int sig) -+{ -+ printk(UM_KERN_ERR "debug requested when CONFIG_PT_PROXY is off\n"); -+} -+ -+int attach_debugger(int idle_pid, int pid, int stop) -+{ -+ printk(UM_KERN_ERR "attach_debugger called when CONFIG_PT_PROXY " -+ "is off\n"); -+ return(-1); -+} -+ -+int config_gdb(char *str) -+{ -+ return(-1); -+} -+ -+int remove_gdb(void) -+{ -+ return(-1); -+} -+ -+int init_parent_proxy(int pid) -+{ -+ return(-1); -+} -+ -+void debugger_parent_signal(int status, int pid) -+{ -+} -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/gdb_kern.c um/arch/um/kernel/tt/gdb_kern.c ---- orig/arch/um/kernel/tt/gdb_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/gdb_kern.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,40 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/init.h" -+#include "linux/config.h" -+#include "mconsole_kern.h" -+ -+#ifdef CONFIG_MCONSOLE -+ -+extern int gdb_config(char *str); -+extern int gdb_remove(char *unused); -+ -+static struct mc_device gdb_mc = { -+ .name = "gdb", -+ .config = gdb_config, -+ .remove = gdb_remove, -+}; -+ -+int gdb_mc_init(void) -+{ -+ mconsole_register_dev(&gdb_mc); -+ return(0); -+} -+ -+__initcall(gdb_mc_init); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/debug.h um/arch/um/kernel/tt/include/debug.h ---- orig/arch/um/kernel/tt/include/debug.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/include/debug.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,29 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) and -+ * Lars Brinkhoff. -+ * Licensed under the GPL -+ */ -+ -+#ifndef __DEBUG_H -+#define __DEBUG_H -+ -+extern int debugger_proxy(int status, pid_t pid); -+extern void child_proxy(pid_t pid, int status); -+extern void init_proxy (pid_t pid, int waiting, int status); -+extern int start_debugger(char *prog, int startup, int stop, int *debugger_fd); -+extern void fake_child_exit(void); -+extern int gdb_config(char *str); -+extern int gdb_remove(char *unused); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/mmu.h um/arch/um/kernel/tt/include/mmu.h ---- orig/arch/um/kernel/tt/include/mmu.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/include/mmu.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,23 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __TT_MMU_H -+#define __TT_MMU_H -+ -+struct mmu_context_tt { -+}; -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/mode.h um/arch/um/kernel/tt/include/mode.h ---- orig/arch/um/kernel/tt/include/mode.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/include/mode.h 2003-11-07 01:42:09.000000000 -0500 -@@ -0,0 +1,38 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __MODE_TT_H__ -+#define __MODE_TT_H__ -+ -+#include "sysdep/ptrace.h" -+ -+enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB }; -+ -+extern int tracing_pid; -+ -+extern int tracer(int (*init_proc)(void *), void *sp); -+extern void user_time_init_tt(void); -+extern int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data); -+extern int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr, -+ void *data); -+extern void sig_handler_common_tt(int sig, void *sc); -+extern void syscall_handler_tt(int sig, union uml_pt_regs *regs); -+extern void reboot_tt(void); -+extern void halt_tt(void); -+extern int is_tracer_winch(int pid, int fd, void *data); -+extern void kill_off_processes_tt(void); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/mode_kern.h um/arch/um/kernel/tt/include/mode_kern.h ---- orig/arch/um/kernel/tt/include/mode_kern.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/include/mode_kern.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,52 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __TT_MODE_KERN_H__ -+#define __TT_MODE_KERN_H__ -+ -+#include "linux/sched.h" -+#include "asm/page.h" -+#include "asm/ptrace.h" -+#include "asm/uaccess.h" -+ -+extern void *_switch_to_tt(void *prev, void *next); -+extern void flush_thread_tt(void); -+extern void start_thread_tt(struct pt_regs *regs, unsigned long eip, -+ unsigned long esp); -+extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp, -+ unsigned long stack_top, struct task_struct *p, -+ struct pt_regs *regs); -+extern void release_thread_tt(struct task_struct *task); -+extern void exit_thread_tt(void); -+extern void initial_thread_cb_tt(void (*proc)(void *), void *arg); -+extern void init_idle_tt(void); -+extern void flush_tlb_kernel_vm_tt(void); -+extern void __flush_tlb_one_tt(unsigned long addr); -+extern void flush_tlb_range_tt(struct mm_struct *mm, unsigned long start, -+ unsigned long end); -+extern void flush_tlb_mm_tt(struct mm_struct *mm); -+extern void force_flush_all_tt(void); -+extern long execute_syscall_tt(void *r); -+extern void before_mem_tt(unsigned long brk_start); -+extern unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, -+ unsigned long *task_size_out); -+extern int start_uml_tt(void); -+extern int external_pid_tt(struct task_struct *task); -+extern int thread_pid_tt(struct thread_struct *thread); -+ -+#define kmem_end_tt (host_task_size - ABOVE_KMEM) -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/ptrace-tt.h um/arch/um/kernel/tt/include/ptrace-tt.h ---- orig/arch/um/kernel/tt/include/ptrace-tt.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/include/ptrace-tt.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,26 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __PTRACE_TT_H -+#define __PTRACE_TT_H -+ -+#include "uml-config.h" -+ -+#ifdef UML_CONFIG_MODE_TT -+#include "sysdep/sc.h" -+#endif -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/tt.h um/arch/um/kernel/tt/include/tt.h ---- orig/arch/um/kernel/tt/include/tt.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/include/tt.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,46 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __TT_H__ -+#define __TT_H__ -+ -+#include "sysdep/ptrace.h" -+ -+extern int gdb_pid; -+extern int debug; -+extern int debug_stop; -+extern int debug_trace; -+ -+extern int honeypot; -+ -+extern int fork_tramp(void *sig_stack); -+extern int do_proc_op(void *t, int proc_id); -+extern int tracer(int (*init_proc)(void *), void *sp); -+extern void attach_process(int pid); -+extern void tracer_panic(char *format, ...); -+extern void set_init_pid(int pid); -+extern int set_user_mode(void *task); -+extern void set_tracing(void *t, int tracing); -+extern int is_tracing(void *task); -+extern int singlestepping_tt(void *t); -+extern void clear_singlestep(void *t); -+extern void syscall_handler(int sig, union uml_pt_regs *regs); -+extern void exit_kernel(int pid, void *task); -+extern int do_syscall(void *task, int pid); -+extern int is_valid_pid(int pid); -+extern void remap_data(void *segment_start, void *segment_end, int w); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/include/uaccess.h um/arch/um/kernel/tt/include/uaccess.h ---- orig/arch/um/kernel/tt/include/uaccess.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/include/uaccess.h 2003-11-12 08:37:20.000000000 -0500 -@@ -0,0 +1,71 @@ -+/* -+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __TT_UACCESS_H -+#define __TT_UACCESS_H -+ -+#include "linux/string.h" -+#include "linux/sched.h" -+#include "asm/processor.h" -+#include "asm/errno.h" -+#include "asm/current.h" -+#include "asm/a.out.h" -+#include "uml_uaccess.h" -+ -+#define ABOVE_KMEM (16 * 1024 * 1024) -+ -+extern unsigned long end_vm; -+extern unsigned long uml_physmem; -+ -+#define under_task_size(addr, size) \ -+ (((unsigned long) (addr) < TASK_SIZE) && \ -+ (((unsigned long) (addr) + (size)) < TASK_SIZE)) -+ -+#define is_stack(addr, size) \ -+ (((unsigned long) (addr) < STACK_TOP) && \ -+ ((unsigned long) (addr) >= STACK_TOP - ABOVE_KMEM) && \ -+ (((unsigned long) (addr) + (size)) <= STACK_TOP)) -+ -+#define access_ok_tt(type, addr, size) \ -+ ((type == VERIFY_READ) || (segment_eq(get_fs(), KERNEL_DS)) || \ -+ (((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) && \ -+ (under_task_size(addr, size) || is_stack(addr, size)))) -+ -+static inline int verify_area_tt(int type, const void * addr, -+ unsigned long size) -+{ -+ return(access_ok_tt(type, addr, size) ? 0 : -EFAULT); -+} -+ -+extern unsigned long get_fault_addr(void); -+ -+extern int __do_copy_from_user(void *to, const void *from, int n, -+ void **fault_addr, void **fault_catcher); -+extern int __do_strncpy_from_user(char *dst, const char *src, size_t n, -+ void **fault_addr, void **fault_catcher); -+extern int __do_clear_user(void *mem, size_t len, void **fault_addr, -+ void **fault_catcher); -+extern int __do_strnlen_user(const char *str, unsigned long n, -+ void **fault_addr, void **fault_catcher); -+ -+extern int copy_from_user_tt(void *to, const void *from, int n); -+extern int copy_to_user_tt(void *to, const void *from, int n); -+extern int strncpy_from_user_tt(char *dst, const char *src, int count); -+extern int __clear_user_tt(void *mem, int len); -+extern int clear_user_tt(void *mem, int len); -+extern int strnlen_user_tt(const void *str, int len); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ksyms.c um/arch/um/kernel/tt/ksyms.c ---- orig/arch/um/kernel/tt/ksyms.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/ksyms.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,28 @@ -+/* -+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/module.h" -+#include "asm/uaccess.h" -+#include "mode.h" -+ -+EXPORT_SYMBOL(__do_copy_from_user); -+EXPORT_SYMBOL(__do_copy_to_user); -+EXPORT_SYMBOL(__do_strncpy_from_user); -+EXPORT_SYMBOL(__do_strnlen_user); -+EXPORT_SYMBOL(__do_clear_user); -+ -+EXPORT_SYMBOL(tracing_pid); -+EXPORT_SYMBOL(honeypot); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/Makefile um/arch/um/kernel/tt/Makefile ---- orig/arch/um/kernel/tt/Makefile 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/Makefile 2003-11-12 08:34:27.000000000 -0500 -@@ -0,0 +1,39 @@ -+# -+# Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com) -+# Licensed under the GPL -+# -+ -+O_TARGET = tt.o -+ -+obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \ -+ syscall_kern.o syscall_user.o time.o tlb.o tracer.o trap_user.o \ -+ uaccess.o uaccess_user.o -+ -+obj-$(CONFIG_PT_PROXY) += gdb_kern.o -+ -+subdir-y = sys-$(SUBARCH) -+subdir-$(CONFIG_PT_PROXY) += ptproxy -+ -+obj-y += $(join $(subdir-y),$(subdir-y:%=/%.o)) -+ -+export-objs = ksyms.o -+ -+USER_OBJS = $(filter %_user.o,$(obj-y)) gdb.o time.o tracer.o -+ -+UNMAP_CFLAGS := $(patsubst -pg -DPROFILING,,$(USER_CFLAGS)) -+UNMAP_CFLAGS := $(patsubst -fprofile-arcs -ftest-coverage,,$(UNMAP_CFLAGS)) -+ -+include $(TOPDIR)/Rules.make -+ -+$(USER_OBJS) : %.o: %.c -+ $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $< -+ -+$(O_TARGET) : unmap_fin.o -+ -+unmap.o: unmap.c -+ $(CC) $(UNMAP_CFLAGS) -c -o $@ $< -+ -+unmap_fin.o : unmap.o -+ ld -r -o $@ $< -lc -L/usr/lib -+ -+clean : -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/mem.c um/arch/um/kernel/tt/mem.c ---- orig/arch/um/kernel/tt/mem.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/mem.c 2004-01-31 02:38:28.000000000 -0500 -@@ -0,0 +1,51 @@ -+/* -+ * Copyright (C) 2002 - 2004 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/stddef.h" -+#include "linux/config.h" -+#include "linux/mm.h" -+#include "asm/uaccess.h" -+#include "mem_user.h" -+#include "kern_util.h" -+#include "user_util.h" -+#include "kern.h" -+#include "tt.h" -+ -+void before_mem_tt(unsigned long brk_start) -+{ -+ if(!jail || debug) -+ remap_data(UML_ROUND_DOWN(&_stext), UML_ROUND_UP(&_etext), 1); -+ remap_data(UML_ROUND_DOWN(&_sdata), UML_ROUND_UP(&_edata), 1); -+ remap_data(UML_ROUND_DOWN(&__bss_start), UML_ROUND_UP(&_end), 1); -+} -+ -+#ifdef CONFIG_HOST_2G_2G -+#define TOP 0x80000000 -+#else -+#define TOP 0xc0000000 -+#endif -+ -+#define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000) -+#define START (TOP - SIZE) -+ -+unsigned long set_task_sizes_tt(int arg, unsigned long *host_size_out, -+ unsigned long *task_size_out) -+{ -+ /* Round up to the nearest 4M */ -+ *host_size_out = ROUND_4M((unsigned long) &arg); -+ *task_size_out = START; -+ return(START); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/mem_user.c um/arch/um/kernel/tt/mem_user.c ---- orig/arch/um/kernel/tt/mem_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/mem_user.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,49 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <stdlib.h> -+#include <stdio.h> -+#include <unistd.h> -+#include <string.h> -+#include <errno.h> -+#include <sys/mman.h> -+#include "tt.h" -+#include "mem_user.h" -+#include "user_util.h" -+ -+void remap_data(void *segment_start, void *segment_end, int w) -+{ -+ void *addr; -+ unsigned long size; -+ int data, prot; -+ -+ if(w) prot = PROT_WRITE; -+ else prot = 0; -+ prot |= PROT_READ | PROT_EXEC; -+ size = (unsigned long) segment_end - -+ (unsigned long) segment_start; -+ data = create_mem_file(size); -+ addr = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, data, 0); -+ if(addr == MAP_FAILED){ -+ perror("mapping new data segment"); -+ exit(1); -+ } -+ memcpy(addr, segment_start, size); -+ if(switcheroo(data, prot, addr, segment_start, size) < 0){ -+ printf("switcheroo failed\n"); -+ exit(1); -+ } -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/process_kern.c um/arch/um/kernel/tt/process_kern.c ---- orig/arch/um/kernel/tt/process_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/process_kern.c 2004-01-31 02:39:08.000000000 -0500 -@@ -0,0 +1,535 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/sched.h" -+#include "linux/signal.h" -+#include "linux/kernel.h" -+#include "asm/system.h" -+#include "asm/pgalloc.h" -+#include "asm/ptrace.h" -+#include "irq_user.h" -+#include "signal_user.h" -+#include "kern_util.h" -+#include "user_util.h" -+#include "os.h" -+#include "kern.h" -+#include "sigcontext.h" -+#include "time_user.h" -+#include "mem_user.h" -+#include "tlb.h" -+#include "mode.h" -+#include "init.h" -+#include "tt.h" -+ -+void *_switch_to_tt(void *prev, void *next) -+{ -+ struct task_struct *from, *to; -+ unsigned long flags; -+ int err, vtalrm, alrm, prof, cpu; -+ char c; -+ /* jailing and SMP are incompatible, so this doesn't need to be -+ * made per-cpu -+ */ -+ static int reading; -+ -+ from = prev; -+ to = next; -+ -+ to->thread.prev_sched = from; -+ -+ cpu = from->processor; -+ if(cpu == 0) -+ forward_interrupts(to->thread.mode.tt.extern_pid); -+#ifdef CONFIG_SMP -+ forward_ipi(cpu_data[cpu].ipi_pipe[0], to->thread.mode.tt.extern_pid); -+#endif -+ local_irq_save(flags); -+ -+ vtalrm = change_sig(SIGVTALRM, 0); -+ alrm = change_sig(SIGALRM, 0); -+ prof = change_sig(SIGPROF, 0); -+ -+ c = 0; -+ set_current(to); -+ -+ reading = 0; -+ err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c)); -+ if(err != sizeof(c)) -+ panic("write of switch_pipe failed, err = %d", -err); -+ -+ reading = 1; -+ if(from->state == TASK_ZOMBIE) -+ os_kill_process(os_getpid(), 0); -+ -+ err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c, sizeof(c)); -+ if(err != sizeof(c)) -+ panic("read of switch_pipe failed, errno = %d", -err); -+ -+ /* This works around a nasty race with 'jail'. If we are switching -+ * between two threads of a threaded app and the incoming process -+ * runs before the outgoing process reaches the read, and it makes -+ * it all the way out to userspace, then it will have write-protected -+ * the outgoing process stack. Then, when the outgoing process -+ * returns from the write, it will segfault because it can no longer -+ * write its own stack. So, in order to avoid that, the incoming -+ * thread sits in a loop yielding until 'reading' is set. This -+ * isn't entirely safe, since there may be a reschedule from a timer -+ * happening between setting 'reading' and sleeping in read. But, -+ * it should get a whole quantum in which to reach the read and sleep, -+ * which should be enough. -+ */ -+ -+ if(jail){ -+ while(!reading) sched_yield(); -+ } -+ -+ change_sig(SIGVTALRM, vtalrm); -+ change_sig(SIGALRM, alrm); -+ change_sig(SIGPROF, prof); -+ -+ arch_switch(); -+ -+ flush_tlb_all(); -+ local_irq_restore(flags); -+ -+ return(current->thread.prev_sched); -+} -+ -+void release_thread_tt(struct task_struct *task) -+{ -+ os_kill_process(task->thread.mode.tt.extern_pid, 0); -+} -+ -+void exit_thread_tt(void) -+{ -+ os_close_file(current->thread.mode.tt.switch_pipe[0]); -+ os_close_file(current->thread.mode.tt.switch_pipe[1]); -+} -+ -+extern void schedule_tail(struct task_struct *prev); -+ -+static void new_thread_handler(int sig) -+{ -+ unsigned long disable; -+ int (*fn)(void *); -+ void *arg; -+ -+ fn = current->thread.request.u.thread.proc; -+ arg = current->thread.request.u.thread.arg; -+ -+ UPT_SC(¤t->thread.regs.regs) = (void *) (&sig + 1); -+ disable = (1 << (SIGVTALRM - 1)) | (1 << (SIGALRM - 1)) | -+ (1 << (SIGIO - 1)) | (1 << (SIGPROF - 1)); -+ SC_SIGMASK(UPT_SC(¤t->thread.regs.regs)) &= ~disable; -+ -+ suspend_new_thread(current->thread.mode.tt.switch_pipe[0]); -+ -+ init_new_thread_signals(1); -+ enable_timer(); -+ free_page(current->thread.temp_stack); -+ set_cmdline("(kernel thread)"); -+ force_flush_all(); -+ -+ if(current->thread.prev_sched != NULL) -+ schedule_tail(current->thread.prev_sched); -+ current->thread.prev_sched = NULL; -+ -+ change_sig(SIGUSR1, 1); -+ change_sig(SIGVTALRM, 1); -+ change_sig(SIGPROF, 1); -+ sti(); -+ if(!run_kernel_thread(fn, arg, ¤t->thread.exec_buf)) -+ do_exit(0); -+} -+ -+static int new_thread_proc(void *stack) -+{ -+ /* cli is needed to block out signals until this thread is properly -+ * scheduled. Otherwise, the tracing thread will get mighty upset -+ * about any signals that arrive before that. -+ * This has the complication that it sets the saved signal mask in -+ * the sigcontext to block signals. This gets restored when this -+ * thread (or a descendant, since they get a copy of this sigcontext) -+ * returns to userspace. -+ * So, this is compensated for elsewhere. -+ * XXX There is still a small window until cli() actually finishes -+ * where signals are possible - shouldn't be a problem in practice -+ * since SIGIO hasn't been forwarded here yet, and the cli should -+ * finish before a SIGVTALRM has time to be delivered. -+ */ -+ cli(); -+ init_new_thread_stack(stack, new_thread_handler); -+ os_usr1_process(os_getpid()); -+ return(0); -+} -+ -+/* Signal masking - signals are blocked at the start of fork_tramp. They -+ * are re-enabled when finish_fork_handler is entered by fork_tramp hitting -+ * itself with a SIGUSR1. set_user_mode has to be run with SIGUSR1 off, -+ * so it is blocked before it's called. They are re-enabled on sigreturn -+ * despite the fact that they were blocked when the SIGUSR1 was issued because -+ * copy_thread copies the parent's sigcontext, including the signal mask -+ * onto the signal frame. -+ */ -+ -+static void finish_fork_handler(int sig) -+{ -+ UPT_SC(¤t->thread.regs.regs) = (void *) (&sig + 1); -+ suspend_new_thread(current->thread.mode.tt.switch_pipe[0]); -+ -+ init_new_thread_signals(1); -+ enable_timer(); -+ sti(); -+ force_flush_all(); -+ if(current->mm != current->p_pptr->mm) -+ protect_memory(uml_reserved, high_physmem - uml_reserved, 1, -+ 1, 0, 1); -+ task_protections((unsigned long) current); -+ -+ if(current->thread.prev_sched != NULL) -+ schedule_tail(current->thread.prev_sched); -+ current->thread.prev_sched = NULL; -+ -+ free_page(current->thread.temp_stack); -+ cli(); -+ change_sig(SIGUSR1, 0); -+ set_user_mode(current); -+} -+ -+int fork_tramp(void *stack) -+{ -+ cli(); -+ arch_init_thread(); -+ init_new_thread_stack(stack, finish_fork_handler); -+ os_usr1_process(os_getpid()); -+ return(0); -+} -+ -+int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp, -+ unsigned long stack_top, struct task_struct * p, -+ struct pt_regs *regs) -+{ -+ int (*tramp)(void *); -+ int new_pid, err; -+ unsigned long stack; -+ -+ if(current->thread.forking) -+ tramp = fork_tramp; -+ else { -+ tramp = new_thread_proc; -+ p->thread.request.u.thread = current->thread.request.u.thread; -+ } -+ -+ err = os_pipe(p->thread.mode.tt.switch_pipe, 1, 1); -+ if(err < 0){ -+ printk("copy_thread : pipe failed, err = %d\n", -err); -+ return(err); -+ } -+ -+ stack = alloc_stack(0, 0); -+ if(stack == 0){ -+ printk(KERN_ERR "copy_thread : failed to allocate " -+ "temporary stack\n"); -+ return(-ENOMEM); -+ } -+ -+ clone_flags &= CLONE_VM; -+ p->thread.temp_stack = stack; -+ new_pid = start_fork_tramp((void *) p->thread.kernel_stack, stack, -+ clone_flags, tramp); -+ if(new_pid < 0){ -+ printk(KERN_ERR "copy_thread : clone failed - errno = %d\n", -+ -new_pid); -+ return(new_pid); -+ } -+ -+ if(current->thread.forking){ -+ sc_to_sc(UPT_SC(&p->thread.regs.regs), -+ UPT_SC(¤t->thread.regs.regs)); -+ SC_SET_SYSCALL_RETURN(UPT_SC(&p->thread.regs.regs), 0); -+ if(sp != 0) SC_SP(UPT_SC(&p->thread.regs.regs)) = sp; -+ } -+ p->thread.mode.tt.extern_pid = new_pid; -+ -+ current->thread.request.op = OP_FORK; -+ current->thread.request.u.fork.pid = new_pid; -+ os_usr1_process(os_getpid()); -+ return(0); -+} -+ -+void reboot_tt(void) -+{ -+ current->thread.request.op = OP_REBOOT; -+ os_usr1_process(os_getpid()); -+} -+ -+void halt_tt(void) -+{ -+ current->thread.request.op = OP_HALT; -+ os_usr1_process(os_getpid()); -+} -+ -+void kill_off_processes_tt(void) -+{ -+ struct task_struct *p; -+ int me; -+ -+ me = os_getpid(); -+ for_each_task(p){ -+ int pid = p->thread.mode.tt.extern_pid; -+ if((pid != me) && (pid != -1)) -+ os_kill_process(p->thread.mode.tt.extern_pid, 0); -+ } -+ if((init_task.thread.mode.tt.extern_pid != me) && -+ (init_task.thread.mode.tt.extern_pid != -1)) -+ os_kill_process(init_task.thread.mode.tt.extern_pid, 0); -+} -+ -+void initial_thread_cb_tt(void (*proc)(void *), void *arg) -+{ -+ if(os_getpid() == tracing_pid){ -+ (*proc)(arg); -+ } -+ else { -+ current->thread.request.op = OP_CB; -+ current->thread.request.u.cb.proc = proc; -+ current->thread.request.u.cb.arg = arg; -+ os_usr1_process(os_getpid()); -+ } -+} -+ -+int do_proc_op(void *t, int proc_id) -+{ -+ struct task_struct *task; -+ struct thread_struct *thread; -+ int op, pid; -+ -+ task = t; -+ thread = &task->thread; -+ op = thread->request.op; -+ switch(op){ -+ case OP_NONE: -+ case OP_TRACE_ON: -+ break; -+ case OP_EXEC: -+ pid = thread->request.u.exec.pid; -+ do_exec(thread->mode.tt.extern_pid, pid); -+ thread->mode.tt.extern_pid = pid; -+ cpu_tasks[task->processor].pid = pid; -+ break; -+ case OP_FORK: -+ attach_process(thread->request.u.fork.pid); -+ break; -+ case OP_CB: -+ (*thread->request.u.cb.proc)(thread->request.u.cb.arg); -+ break; -+ case OP_REBOOT: -+ case OP_HALT: -+ break; -+ default: -+ tracer_panic("Bad op in do_proc_op"); -+ break; -+ } -+ thread->request.op = OP_NONE; -+ return(op); -+} -+ -+void init_idle_tt(void) -+{ -+ idle_timer(); -+} -+ -+/* Changed by jail_setup, which is a setup */ -+int jail = 0; -+ -+int __init jail_setup(char *line, int *add) -+{ -+ int ok = 1; -+ -+ if(jail) return(0); -+#ifdef CONFIG_SMP -+ printf("'jail' may not used used in a kernel with CONFIG_SMP " -+ "enabled\n"); -+ ok = 0; -+#endif -+#ifdef CONFIG_HOSTFS -+ printf("'jail' may not used used in a kernel with CONFIG_HOSTFS " -+ "enabled\n"); -+ ok = 0; -+#endif -+#ifdef CONFIG_MODULES -+ printf("'jail' may not used used in a kernel with CONFIG_MODULES " -+ "enabled\n"); -+ ok = 0; -+#endif -+ if(!ok) exit(1); -+ -+ /* CAP_SYS_RAWIO controls the ability to open /dev/mem and /dev/kmem. -+ * Removing it from the bounding set eliminates the ability of anything -+ * to acquire it, and thus read or write kernel memory. -+ */ -+ cap_lower(cap_bset, CAP_SYS_RAWIO); -+ jail = 1; -+ return(0); -+} -+ -+__uml_setup("jail", jail_setup, -+"jail\n" -+" Enables the protection of kernel memory from processes.\n\n" -+); -+ -+static void mprotect_kernel_mem(int w) -+{ -+ unsigned long start, end; -+ int pages; -+ -+ if(!jail || (current == &init_task)) return; -+ -+ pages = (1 << CONFIG_KERNEL_STACK_ORDER); -+ -+ start = (unsigned long) current + PAGE_SIZE; -+ end = (unsigned long) current + PAGE_SIZE * pages; -+ protect_memory(uml_reserved, start - uml_reserved, 1, w, 1, 1); -+ protect_memory(end, high_physmem - end, 1, w, 1, 1); -+ -+ start = (unsigned long) UML_ROUND_DOWN(&_stext); -+ end = (unsigned long) UML_ROUND_UP(&_etext); -+ protect_memory(start, end - start, 1, w, 1, 1); -+ -+ start = (unsigned long) UML_ROUND_DOWN(&_unprotected_end); -+ end = (unsigned long) UML_ROUND_UP(&_edata); -+ protect_memory(start, end - start, 1, w, 1, 1); -+ -+ start = (unsigned long) UML_ROUND_DOWN(&__bss_start); -+ end = (unsigned long) UML_ROUND_UP(&_end); -+ protect_memory(start, end - start, 1, w, 1, 1); -+ -+ mprotect_kernel_vm(w); -+} -+ -+void unprotect_kernel_mem(void) -+{ -+ mprotect_kernel_mem(1); -+} -+ -+void protect_kernel_mem(void) -+{ -+ mprotect_kernel_mem(0); -+} -+ -+extern void start_kernel(void); -+ -+static int start_kernel_proc(void *unused) -+{ -+ int pid; -+ -+ block_signals(); -+ pid = os_getpid(); -+ -+ cpu_tasks[0].pid = pid; -+ cpu_tasks[0].task = current; -+#ifdef CONFIG_SMP -+ cpu_online_map = 1; -+#endif -+ if(debug) os_stop_process(pid); -+ start_kernel(); -+ return(0); -+} -+ -+void set_tracing(void *task, int tracing) -+{ -+ ((struct task_struct *) task)->thread.mode.tt.tracing = tracing; -+} -+ -+int is_tracing(void *t) -+{ -+ return (((struct task_struct *) t)->thread.mode.tt.tracing); -+} -+ -+int set_user_mode(void *t) -+{ -+ struct task_struct *task; -+ -+ task = t ? t : current; -+ if(task->thread.mode.tt.tracing) -+ return(1); -+ task->thread.request.op = OP_TRACE_ON; -+ os_usr1_process(os_getpid()); -+ return(0); -+} -+ -+void set_init_pid(int pid) -+{ -+ int err; -+ -+ init_task.thread.mode.tt.extern_pid = pid; -+ err = os_pipe(init_task.thread.mode.tt.switch_pipe, 1, 1); -+ if(err) -+ panic("Can't create switch pipe for init_task, errno = %d", -+ -err); -+} -+ -+int singlestepping_tt(void *t) -+{ -+ struct task_struct *task = t; -+ -+ if(task->thread.mode.tt.singlestep_syscall) -+ return(0); -+ return(task->ptrace & PT_DTRACE); -+} -+ -+void clear_singlestep(void *t) -+{ -+ struct task_struct *task = t; -+ -+ task->ptrace &= ~PT_DTRACE; -+} -+ -+int start_uml_tt(void) -+{ -+ void *sp; -+ int pages; -+ -+ pages = (1 << CONFIG_KERNEL_STACK_ORDER) - 2; -+ sp = (void *) init_task.thread.kernel_stack + pages * PAGE_SIZE - -+ sizeof(unsigned long); -+ return(tracer(start_kernel_proc, sp)); -+} -+ -+int external_pid_tt(struct task_struct *task) -+{ -+ return(task->thread.mode.tt.extern_pid); -+} -+ -+int thread_pid_tt(struct thread_struct *thread) -+{ -+ return(thread->mode.tt.extern_pid); -+} -+ -+int is_valid_pid(int pid) -+{ -+ struct task_struct *task; -+ -+ read_lock(&tasklist_lock); -+ for_each_task(task){ -+ if(task->thread.mode.tt.extern_pid == pid){ -+ read_unlock(&tasklist_lock); -+ return(1); -+ } -+ } -+ read_unlock(&tasklist_lock); -+ return(0); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/Makefile um/arch/um/kernel/tt/ptproxy/Makefile ---- orig/arch/um/kernel/tt/ptproxy/Makefile 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/ptproxy/Makefile 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,12 @@ -+O_TARGET = ptproxy.o -+ -+obj-y = proxy.o ptrace.o sysdep.o wait.o -+ -+USER_OBJS = $(obj-y) -+ -+include $(TOPDIR)/Rules.make -+ -+$(USER_OBJS) : %.o: %.c -+ $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $< -+ -+clean: -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/proxy.c um/arch/um/kernel/tt/ptproxy/proxy.c ---- orig/arch/um/kernel/tt/ptproxy/proxy.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/ptproxy/proxy.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,371 @@ -+/********************************************************************** -+proxy.c -+ -+Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing -+terms and conditions. -+ -+Jeff Dike (jdike@karaya.com) : Modified for integration into uml -+**********************************************************************/ -+ -+/* XXX This file shouldn't refer to CONFIG_* */ -+ -+#include <errno.h> -+#include <stdio.h> -+#include <stdlib.h> -+#include <unistd.h> -+#include <signal.h> -+#include <string.h> -+#include <termios.h> -+#include <sys/wait.h> -+#include <sys/types.h> -+#include <sys/ptrace.h> -+#include <sys/ioctl.h> -+#include <asm/unistd.h> -+ -+#include "ptproxy.h" -+#include "sysdep.h" -+#include "wait.h" -+ -+#include "user_util.h" -+#include "user.h" -+#include "os.h" -+#include "tempfile.h" -+ -+static int debugger_wait(debugger_state *debugger, int *status, int options, -+ int (*syscall)(debugger_state *debugger, pid_t child), -+ int (*normal_return)(debugger_state *debugger, -+ pid_t unused), -+ int (*wait_return)(debugger_state *debugger, -+ pid_t unused)) -+{ -+ if(debugger->real_wait){ -+ debugger->handle_trace = normal_return; -+ syscall_continue(debugger->pid); -+ debugger->real_wait = 0; -+ return(1); -+ } -+ debugger->wait_status_ptr = status; -+ debugger->wait_options = options; -+ if((debugger->debugee != NULL) && debugger->debugee->event){ -+ syscall_continue(debugger->pid); -+ wait_for_stop(debugger->pid, SIGTRAP, PTRACE_SYSCALL, -+ NULL); -+ (*wait_return)(debugger, -1); -+ return(0); -+ } -+ else if(debugger->wait_options & WNOHANG){ -+ syscall_cancel(debugger->pid, 0); -+ debugger->handle_trace = syscall; -+ return(0); -+ } -+ else { -+ syscall_pause(debugger->pid); -+ debugger->handle_trace = wait_return; -+ debugger->waiting = 1; -+ } -+ return(1); -+} -+ -+/* -+ * Handle debugger trap, i.e. syscall. -+ */ -+ -+int debugger_syscall(debugger_state *debugger, pid_t child) -+{ -+ long arg1, arg2, arg3, arg4, arg5, result; -+ int syscall, ret = 0; -+ -+ syscall = get_syscall(debugger->pid, &arg1, &arg2, &arg3, &arg4, -+ &arg5); -+ -+ switch(syscall){ -+ case __NR_execve: -+ /* execve never returns */ -+ debugger->handle_trace = debugger_syscall; -+ break; -+ -+ case __NR_ptrace: -+ if(debugger->debugee->pid != 0) arg2 = debugger->debugee->pid; -+ if(!debugger->debugee->in_context) -+ child = debugger->debugee->pid; -+ result = proxy_ptrace(debugger, arg1, arg2, arg3, arg4, child, -+ &ret); -+ syscall_cancel(debugger->pid, result); -+ debugger->handle_trace = debugger_syscall; -+ return(ret); -+ -+ case __NR_waitpid: -+ case __NR_wait4: -+ if(!debugger_wait(debugger, (int *) arg2, arg3, -+ debugger_syscall, debugger_normal_return, -+ proxy_wait_return)) -+ return(0); -+ break; -+ -+ case __NR_kill: -+ if(!debugger->debugee->in_context) -+ child = debugger->debugee->pid; -+ if(arg1 == debugger->debugee->pid){ -+ result = kill(child, arg2); -+ syscall_cancel(debugger->pid, result); -+ debugger->handle_trace = debugger_syscall; -+ return(0); -+ } -+ else debugger->handle_trace = debugger_normal_return; -+ break; -+ -+ default: -+ debugger->handle_trace = debugger_normal_return; -+ } -+ -+ syscall_continue(debugger->pid); -+ return(0); -+} -+ -+/* Used by the tracing thread */ -+static debugger_state parent; -+static int parent_syscall(debugger_state *debugger, int pid); -+ -+int init_parent_proxy(int pid) -+{ -+ parent = ((debugger_state) { .pid = pid, -+ .wait_options = 0, -+ .wait_status_ptr = NULL, -+ .waiting = 0, -+ .real_wait = 0, -+ .expecting_child = 0, -+ .handle_trace = parent_syscall, -+ .debugee = NULL } ); -+ return(0); -+} -+ -+int parent_normal_return(debugger_state *debugger, pid_t unused) -+{ -+ debugger->handle_trace = parent_syscall; -+ syscall_continue(debugger->pid); -+ return(0); -+} -+ -+static int parent_syscall(debugger_state *debugger, int pid) -+{ -+ long arg1, arg2, arg3, arg4, arg5; -+ int syscall; -+ -+ syscall = get_syscall(pid, &arg1, &arg2, &arg3, &arg4, &arg5); -+ -+ if((syscall == __NR_waitpid) || (syscall == __NR_wait4)){ -+ debugger_wait(&parent, (int *) arg2, arg3, parent_syscall, -+ parent_normal_return, parent_wait_return); -+ } -+ else ptrace(PTRACE_SYSCALL, pid, 0, 0); -+ return(0); -+} -+ -+int debugger_normal_return(debugger_state *debugger, pid_t unused) -+{ -+ debugger->handle_trace = debugger_syscall; -+ syscall_continue(debugger->pid); -+ return(0); -+} -+ -+void debugger_cancelled_return(debugger_state *debugger, int result) -+{ -+ debugger->handle_trace = debugger_syscall; -+ syscall_set_result(debugger->pid, result); -+ syscall_continue(debugger->pid); -+} -+ -+/* Used by the tracing thread */ -+static debugger_state debugger; -+static debugee_state debugee; -+ -+void init_proxy (pid_t debugger_pid, int stopped, int status) -+{ -+ debugger.pid = debugger_pid; -+ debugger.handle_trace = debugger_syscall; -+ debugger.debugee = &debugee; -+ debugger.waiting = 0; -+ debugger.real_wait = 0; -+ debugger.expecting_child = 0; -+ -+ debugee.pid = 0; -+ debugee.traced = 0; -+ debugee.stopped = stopped; -+ debugee.event = 0; -+ debugee.zombie = 0; -+ debugee.died = 0; -+ debugee.wait_status = status; -+ debugee.in_context = 1; -+} -+ -+int debugger_proxy(int status, int pid) -+{ -+ int ret = 0, sig; -+ -+ if(WIFSTOPPED(status)){ -+ sig = WSTOPSIG(status); -+ if (sig == SIGTRAP) -+ ret = (*debugger.handle_trace)(&debugger, pid); -+ -+ else if(sig == SIGCHLD){ -+ if(debugger.expecting_child){ -+ ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig); -+ debugger.expecting_child = 0; -+ } -+ else if(debugger.waiting) -+ real_wait_return(&debugger); -+ else { -+ ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig); -+ debugger.real_wait = 1; -+ } -+ } -+ else ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig); -+ } -+ else if(WIFEXITED(status)){ -+ tracer_panic("debugger (pid %d) exited with status %d", -+ debugger.pid, WEXITSTATUS(status)); -+ } -+ else if(WIFSIGNALED(status)){ -+ tracer_panic("debugger (pid %d) exited with signal %d", -+ debugger.pid, WTERMSIG(status)); -+ } -+ else { -+ tracer_panic("proxy got unknown status (0x%x) on debugger " -+ "(pid %d)", status, debugger.pid); -+ } -+ return(ret); -+} -+ -+void child_proxy(pid_t pid, int status) -+{ -+ debugee.event = 1; -+ debugee.wait_status = status; -+ -+ if(WIFSTOPPED(status)){ -+ debugee.stopped = 1; -+ debugger.expecting_child = 1; -+ kill(debugger.pid, SIGCHLD); -+ } -+ else if(WIFEXITED(status) || WIFSIGNALED(status)){ -+ debugee.zombie = 1; -+ debugger.expecting_child = 1; -+ kill(debugger.pid, SIGCHLD); -+ } -+ else panic("proxy got unknown status (0x%x) on child (pid %d)", -+ status, pid); -+} -+ -+void debugger_parent_signal(int status, int pid) -+{ -+ int sig; -+ -+ if(WIFSTOPPED(status)){ -+ sig = WSTOPSIG(status); -+ if(sig == SIGTRAP) (*parent.handle_trace)(&parent, pid); -+ else ptrace(PTRACE_SYSCALL, pid, 0, sig); -+ } -+} -+ -+void fake_child_exit(void) -+{ -+ int status, pid; -+ -+ child_proxy(1, W_EXITCODE(0, 0)); -+ while(debugger.waiting == 1){ -+ pid = waitpid(debugger.pid, &status, WUNTRACED); -+ if(pid != debugger.pid){ -+ printk("fake_child_exit - waitpid failed, " -+ "errno = %d\n", errno); -+ return; -+ } -+ debugger_proxy(status, debugger.pid); -+ } -+ pid = waitpid(debugger.pid, &status, WUNTRACED); -+ if(pid != debugger.pid){ -+ printk("fake_child_exit - waitpid failed, " -+ "errno = %d\n", errno); -+ return; -+ } -+ if(ptrace(PTRACE_DETACH, debugger.pid, 0, SIGCONT) < 0) -+ printk("fake_child_exit - PTRACE_DETACH failed, errno = %d\n", -+ errno); -+} -+ -+char gdb_init_string[] = -+"att 1 \n\ -+b panic \n\ -+b stop \n\ -+handle SIGWINCH nostop noprint pass \n\ -+"; -+ -+int start_debugger(char *prog, int startup, int stop, int *fd_out) -+{ -+ int slave, child; -+ -+ slave = open_gdb_chan(); -+ child = fork(); -+ if(child == 0){ -+ char *tempname = NULL; -+ int fd; -+ -+ if(setsid() < 0) perror("setsid"); -+ if((dup2(slave, 0) < 0) || (dup2(slave, 1) < 0) || -+ (dup2(slave, 2) < 0)){ -+ printk("start_debugger : dup2 failed, errno = %d\n", -+ errno); -+ exit(1); -+ } -+ if(ioctl(0, TIOCSCTTY, 0) < 0){ -+ printk("start_debugger : TIOCSCTTY failed, " -+ "errno = %d\n", errno); -+ exit(1); -+ } -+ if(tcsetpgrp (1, os_getpid()) < 0){ -+ printk("start_debugger : tcsetpgrp failed, " -+ "errno = %d\n", errno); -+#ifdef notdef -+ exit(1); -+#endif -+ } -+ fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0); -+ if(fd < 0){ -+ printk("start_debugger : make_tempfile failed," -+ "err = %d\n", -fd); -+ exit(1); -+ } -+ os_write_file(fd, gdb_init_string, sizeof(gdb_init_string) - 1); -+ if(startup){ -+ if(stop){ -+ os_write_file(fd, "b start_kernel\n", -+ strlen("b start_kernel\n")); -+ } -+ os_write_file(fd, "c\n", strlen("c\n")); -+ } -+ if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){ -+ printk("start_debugger : PTRACE_TRACEME failed, " -+ "errno = %d\n", errno); -+ exit(1); -+ } -+ execlp("gdb", "gdb", "--command", tempname, prog, NULL); -+ printk("start_debugger : exec of gdb failed, errno = %d\n", -+ errno); -+ } -+ if(child < 0){ -+ printk("start_debugger : fork for gdb failed, errno = %d\n", -+ errno); -+ return(-1); -+ } -+ *fd_out = slave; -+ return(child); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/ptproxy.h um/arch/um/kernel/tt/ptproxy/ptproxy.h ---- orig/arch/um/kernel/tt/ptproxy/ptproxy.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/ptproxy/ptproxy.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,61 @@ -+/********************************************************************** -+ptproxy.h -+ -+Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing -+terms and conditions. -+**********************************************************************/ -+ -+#ifndef __PTPROXY_H -+#define __PTPROXY_H -+ -+#include <sys/types.h> -+ -+typedef struct debugger debugger_state; -+typedef struct debugee debugee_state; -+ -+struct debugger -+{ -+ pid_t pid; -+ int wait_options; -+ int *wait_status_ptr; -+ unsigned int waiting : 1; -+ unsigned int real_wait : 1; -+ unsigned int expecting_child : 1; -+ int (*handle_trace) (debugger_state *, pid_t); -+ -+ debugee_state *debugee; -+}; -+ -+struct debugee -+{ -+ pid_t pid; -+ int wait_status; -+ unsigned int died : 1; -+ unsigned int event : 1; -+ unsigned int stopped : 1; -+ unsigned int trace_singlestep : 1; -+ unsigned int trace_syscall : 1; -+ unsigned int traced : 1; -+ unsigned int zombie : 1; -+ unsigned int in_context : 1; -+}; -+ -+extern int debugger_syscall(debugger_state *debugger, pid_t pid); -+extern int debugger_normal_return (debugger_state *debugger, pid_t unused); -+ -+extern long proxy_ptrace (struct debugger *, int, pid_t, long, long, pid_t, -+ int *strace_out); -+extern void debugger_cancelled_return(debugger_state *debugger, int result); -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/ptrace.c um/arch/um/kernel/tt/ptproxy/ptrace.c ---- orig/arch/um/kernel/tt/ptproxy/ptrace.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/ptproxy/ptrace.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,239 @@ -+/********************************************************************** -+ptrace.c -+ -+Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing -+terms and conditions. -+ -+Jeff Dike (jdike@karaya.com) : Modified for integration into uml -+**********************************************************************/ -+ -+#include <errno.h> -+#include <unistd.h> -+#include <signal.h> -+#include <sys/types.h> -+#include <sys/time.h> -+#include <sys/ptrace.h> -+#include <sys/wait.h> -+#include <asm/ptrace.h> -+ -+#include "ptproxy.h" -+#include "debug.h" -+#include "user_util.h" -+#include "kern_util.h" -+#include "ptrace_user.h" -+#include "tt.h" -+ -+long proxy_ptrace(struct debugger *debugger, int arg1, pid_t arg2, -+ long arg3, long arg4, pid_t child, int *ret) -+{ -+ sigset_t relay; -+ long result; -+ int status; -+ -+ *ret = 0; -+ if(debugger->debugee->died) return(-ESRCH); -+ -+ switch(arg1){ -+ case PTRACE_ATTACH: -+ if(debugger->debugee->traced) return(-EPERM); -+ -+ debugger->debugee->pid = arg2; -+ debugger->debugee->traced = 1; -+ -+ if(is_valid_pid(arg2) && (arg2 != child)){ -+ debugger->debugee->in_context = 0; -+ kill(arg2, SIGSTOP); -+ debugger->debugee->event = 1; -+ debugger->debugee->wait_status = W_STOPCODE(SIGSTOP); -+ } -+ else { -+ debugger->debugee->in_context = 1; -+ if(debugger->debugee->stopped) -+ child_proxy(child, W_STOPCODE(SIGSTOP)); -+ else kill(child, SIGSTOP); -+ } -+ -+ return(0); -+ -+ case PTRACE_DETACH: -+ if(!debugger->debugee->traced) return(-EPERM); -+ -+ debugger->debugee->traced = 0; -+ debugger->debugee->pid = 0; -+ if(!debugger->debugee->in_context) -+ kill(child, SIGCONT); -+ -+ return(0); -+ -+ case PTRACE_CONT: -+ if(!debugger->debugee->in_context) return(-EPERM); -+ *ret = PTRACE_CONT; -+ return(ptrace(PTRACE_CONT, child, arg3, arg4)); -+ -+#ifdef UM_HAVE_GETFPREGS -+ case PTRACE_GETFPREGS: -+ { -+ long regs[FP_FRAME_SIZE]; -+ int i, result; -+ -+ result = ptrace(PTRACE_GETFPREGS, child, 0, regs); -+ if(result == -1) return(-errno); -+ -+ for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++) -+ ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i, -+ regs[i]); -+ return(result); -+ } -+#endif -+ -+#ifdef UM_HAVE_GETFPXREGS -+ case PTRACE_GETFPXREGS: -+ { -+ long regs[FPX_FRAME_SIZE]; -+ int i, result; -+ -+ result = ptrace(PTRACE_GETFPXREGS, child, 0, regs); -+ if(result == -1) return(-errno); -+ -+ for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++) -+ ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i, -+ regs[i]); -+ return(result); -+ } -+#endif -+ -+#ifdef UM_HAVE_GETREGS -+ case PTRACE_GETREGS: -+ { -+ long regs[FRAME_SIZE]; -+ int i, result; -+ -+ result = ptrace(PTRACE_GETREGS, child, 0, regs); -+ if(result == -1) return(-errno); -+ -+ for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++) -+ ptrace (PTRACE_POKEDATA, debugger->pid, -+ arg4 + 4 * i, regs[i]); -+ return(result); -+ } -+ break; -+#endif -+ -+ case PTRACE_KILL: -+ result = ptrace(PTRACE_KILL, child, arg3, arg4); -+ if(result == -1) return(-errno); -+ -+ return(result); -+ -+ case PTRACE_PEEKDATA: -+ case PTRACE_PEEKTEXT: -+ case PTRACE_PEEKUSER: -+ /* The value being read out could be -1, so we have to -+ * check errno to see if there's an error, and zero it -+ * beforehand so we're not faked out by an old error -+ */ -+ -+ errno = 0; -+ result = ptrace(arg1, child, arg3, 0); -+ if((result == -1) && (errno != 0)) return(-errno); -+ -+ result = ptrace(PTRACE_POKEDATA, debugger->pid, arg4, result); -+ if(result == -1) return(-errno); -+ -+ return(result); -+ -+ case PTRACE_POKEDATA: -+ case PTRACE_POKETEXT: -+ case PTRACE_POKEUSER: -+ result = ptrace(arg1, child, arg3, arg4); -+ if(result == -1) return(-errno); -+ -+ if(arg1 == PTRACE_POKEUSER) ptrace_pokeuser(arg3, arg4); -+ return(result); -+ -+#ifdef UM_HAVE_SETFPREGS -+ case PTRACE_SETFPREGS: -+ { -+ long regs[FP_FRAME_SIZE]; -+ int i; -+ -+ for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++) -+ regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid, -+ arg4 + 4 * i, 0); -+ result = ptrace(PTRACE_SETFPREGS, child, 0, regs); -+ if(result == -1) return(-errno); -+ -+ return(result); -+ } -+#endif -+ -+#ifdef UM_HAVE_SETFPXREGS -+ case PTRACE_SETFPXREGS: -+ { -+ long regs[FPX_FRAME_SIZE]; -+ int i; -+ -+ for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++) -+ regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid, -+ arg4 + 4 * i, 0); -+ result = ptrace(PTRACE_SETFPXREGS, child, 0, regs); -+ if(result == -1) return(-errno); -+ -+ return(result); -+ } -+#endif -+ -+#ifdef UM_HAVE_SETREGS -+ case PTRACE_SETREGS: -+ { -+ long regs[FRAME_SIZE]; -+ int i; -+ -+ for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++) -+ regs[i] = ptrace(PTRACE_PEEKDATA, debugger->pid, -+ arg4 + 4 * i, 0); -+ result = ptrace(PTRACE_SETREGS, child, 0, regs); -+ if(result == -1) return(-errno); -+ -+ return(result); -+ } -+#endif -+ -+ case PTRACE_SINGLESTEP: -+ if(!debugger->debugee->in_context) return(-EPERM); -+ sigemptyset(&relay); -+ sigaddset(&relay, SIGSEGV); -+ sigaddset(&relay, SIGILL); -+ sigaddset(&relay, SIGBUS); -+ result = ptrace(PTRACE_SINGLESTEP, child, arg3, arg4); -+ if(result == -1) return(-errno); -+ -+ status = wait_for_stop(child, SIGTRAP, PTRACE_SINGLESTEP, -+ &relay); -+ child_proxy(child, status); -+ return(result); -+ -+ case PTRACE_SYSCALL: -+ if(!debugger->debugee->in_context) return(-EPERM); -+ result = ptrace(PTRACE_SYSCALL, child, arg3, arg4); -+ if(result == -1) return(-errno); -+ -+ *ret = PTRACE_SYSCALL; -+ return(result); -+ -+ case PTRACE_TRACEME: -+ default: -+ return(-EINVAL); -+ } -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/sysdep.c um/arch/um/kernel/tt/ptproxy/sysdep.c ---- orig/arch/um/kernel/tt/ptproxy/sysdep.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/ptproxy/sysdep.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,72 @@ -+/********************************************************************** -+sysdep.c -+ -+Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing -+terms and conditions. -+**********************************************************************/ -+ -+#include <stdio.h> -+#include <string.h> -+#include <stdlib.h> -+#include <signal.h> -+#include <errno.h> -+#include <sys/types.h> -+#include <sys/ptrace.h> -+#include <asm/ptrace.h> -+#include <linux/unistd.h> -+#include "ptrace_user.h" -+#include "user_util.h" -+#include "user.h" -+ -+int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3, long *arg4, -+ long *arg5) -+{ -+ *arg1 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG1_OFFSET, 0); -+ *arg2 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG2_OFFSET, 0); -+ *arg3 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG3_OFFSET, 0); -+ *arg4 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG4_OFFSET, 0); -+ *arg5 = ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_ARG5_OFFSET, 0); -+ return(ptrace(PTRACE_PEEKUSER, pid, PT_SYSCALL_NR_OFFSET, 0)); -+} -+ -+void syscall_cancel(pid_t pid, int result) -+{ -+ if((ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, -+ __NR_getpid) < 0) || -+ (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) || -+ (wait_for_stop(pid, SIGTRAP, PTRACE_SYSCALL, NULL) < 0) || -+ (ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, result) < 0) || -+ (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)) -+ printk("ptproxy: couldn't cancel syscall: errno = %d\n", -+ errno); -+} -+ -+void syscall_set_result(pid_t pid, long result) -+{ -+ ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_RET_OFFSET, result); -+} -+ -+void syscall_continue(pid_t pid) -+{ -+ ptrace(PTRACE_SYSCALL, pid, 0, 0); -+} -+ -+int syscall_pause(pid_t pid) -+{ -+ if(ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, __NR_pause) < 0){ -+ printk("syscall_change - ptrace failed, errno = %d\n", errno); -+ return(-1); -+ } -+ return(0); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/sysdep.h um/arch/um/kernel/tt/ptproxy/sysdep.h ---- orig/arch/um/kernel/tt/ptproxy/sysdep.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/ptproxy/sysdep.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,25 @@ -+/********************************************************************** -+sysdep.h -+ -+Copyright (C) 1999 Lars Brinkhoff. -+Copyright (C) 2001 Jeff Dike (jdike@karaya.com) -+See the file COPYING for licensing terms and conditions. -+**********************************************************************/ -+ -+extern int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3, -+ long *arg4, long *arg5); -+extern void syscall_cancel (pid_t pid, long result); -+extern void syscall_set_result (pid_t pid, long result); -+extern void syscall_continue (pid_t pid); -+extern int syscall_pause(pid_t pid); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/wait.c um/arch/um/kernel/tt/ptproxy/wait.c ---- orig/arch/um/kernel/tt/ptproxy/wait.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/ptproxy/wait.c 2004-01-17 05:27:18.000000000 -0500 -@@ -0,0 +1,88 @@ -+/********************************************************************** -+wait.c -+ -+Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing -+terms and conditions. -+ -+**********************************************************************/ -+ -+#include <errno.h> -+#include <signal.h> -+#include <sys/wait.h> -+#include <sys/ptrace.h> -+#include <asm/ptrace.h> -+ -+#include "ptproxy.h" -+#include "sysdep.h" -+#include "wait.h" -+#include "user_util.h" -+#include "sysdep/ptrace.h" -+#include "sysdep/ptrace_user.h" -+#include "sysdep/sigcontext.h" -+ -+int proxy_wait_return(struct debugger *debugger, pid_t unused) -+{ -+ debugger->waiting = 0; -+ -+ if(debugger->debugee->died || (debugger->wait_options & __WCLONE)){ -+ debugger_cancelled_return(debugger, -ECHILD); -+ return(0); -+ } -+ -+ if(debugger->debugee->zombie && debugger->debugee->event) -+ debugger->debugee->died = 1; -+ -+ if(debugger->debugee->event){ -+ debugger->debugee->event = 0; -+ ptrace(PTRACE_POKEDATA, debugger->pid, -+ debugger->wait_status_ptr, -+ debugger->debugee->wait_status); -+ /* if (wait4) -+ ptrace (PTRACE_POKEDATA, pid, rusage_ptr, ...); */ -+ debugger_cancelled_return(debugger, debugger->debugee->pid); -+ return(0); -+ } -+ -+ /* pause will return -EINTR, which happens to be right for wait */ -+ debugger_normal_return(debugger, -1); -+ return(0); -+} -+ -+int parent_wait_return(struct debugger *debugger, pid_t unused) -+{ -+ return(debugger_normal_return(debugger, -1)); -+} -+ -+int real_wait_return(struct debugger *debugger) -+{ -+ unsigned long ip; -+ int pid; -+ -+ pid = debugger->pid; -+ -+ ip = ptrace(PTRACE_PEEKUSER, pid, PT_IP_OFFSET, 0); -+ IP_RESTART_SYSCALL(ip); -+ -+ if(ptrace(PTRACE_POKEUSER, pid, PT_IP_OFFSET, ip) < 0) -+ tracer_panic("real_wait_return : Failed to restart system " -+ "call, errno = %d\n", errno); -+ -+ if((ptrace(PTRACE_SYSCALL, debugger->pid, 0, SIGCHLD) < 0) || -+ (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) || -+ (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) || -+ debugger_normal_return(debugger, -1)) -+ tracer_panic("real_wait_return : gdb failed to wait, " -+ "errno = %d\n", errno); -+ return(0); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/ptproxy/wait.h um/arch/um/kernel/tt/ptproxy/wait.h ---- orig/arch/um/kernel/tt/ptproxy/wait.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/ptproxy/wait.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,15 @@ -+/********************************************************************** -+wait.h -+ -+Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing -+terms and conditions. -+**********************************************************************/ -+ -+#ifndef __PTPROXY_WAIT_H -+#define __PTPROXY_WAIT_H -+ -+extern int proxy_wait_return(struct debugger *debugger, pid_t unused); -+extern int real_wait_return(struct debugger *debugger); -+extern int parent_wait_return(struct debugger *debugger, pid_t unused); -+ -+#endif -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/syscall_kern.c um/arch/um/kernel/tt/syscall_kern.c ---- orig/arch/um/kernel/tt/syscall_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/syscall_kern.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,142 @@ -+/* -+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/types.h" -+#include "linux/utime.h" -+#include "linux/sys.h" -+#include "asm/unistd.h" -+#include "asm/ptrace.h" -+#include "asm/uaccess.h" -+#include "sysdep/syscalls.h" -+#include "kern_util.h" -+ -+static inline int check_area(void *ptr, int size) -+{ -+ return(verify_area(VERIFY_WRITE, ptr, size)); -+} -+ -+static int check_readlink(struct pt_regs *regs) -+{ -+ return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs), -+ UPT_SYSCALL_ARG2(®s->regs))); -+} -+ -+static int check_utime(struct pt_regs *regs) -+{ -+ return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs), -+ sizeof(struct utimbuf))); -+} -+ -+static int check_oldstat(struct pt_regs *regs) -+{ -+ return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs), -+ sizeof(struct __old_kernel_stat))); -+} -+ -+static int check_stat(struct pt_regs *regs) -+{ -+ return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs), -+ sizeof(struct stat))); -+} -+ -+static int check_stat64(struct pt_regs *regs) -+{ -+ return(check_area((void *) UPT_SYSCALL_ARG1(®s->regs), -+ sizeof(struct stat64))); -+} -+ -+struct bogus { -+ int kernel_ds; -+ int (*check_params)(struct pt_regs *); -+}; -+ -+struct bogus this_is_bogus[256] = { -+ [ __NR_mknod ] = { 1, NULL }, -+ [ __NR_mkdir ] = { 1, NULL }, -+ [ __NR_rmdir ] = { 1, NULL }, -+ [ __NR_unlink ] = { 1, NULL }, -+ [ __NR_symlink ] = { 1, NULL }, -+ [ __NR_link ] = { 1, NULL }, -+ [ __NR_rename ] = { 1, NULL }, -+ [ __NR_umount ] = { 1, NULL }, -+ [ __NR_mount ] = { 1, NULL }, -+ [ __NR_pivot_root ] = { 1, NULL }, -+ [ __NR_chdir ] = { 1, NULL }, -+ [ __NR_chroot ] = { 1, NULL }, -+ [ __NR_open ] = { 1, NULL }, -+ [ __NR_quotactl ] = { 1, NULL }, -+ [ __NR_sysfs ] = { 1, NULL }, -+ [ __NR_readlink ] = { 1, check_readlink }, -+ [ __NR_acct ] = { 1, NULL }, -+ [ __NR_execve ] = { 1, NULL }, -+ [ __NR_uselib ] = { 1, NULL }, -+ [ __NR_statfs ] = { 1, NULL }, -+ [ __NR_truncate ] = { 1, NULL }, -+ [ __NR_access ] = { 1, NULL }, -+ [ __NR_chmod ] = { 1, NULL }, -+ [ __NR_chown ] = { 1, NULL }, -+ [ __NR_lchown ] = { 1, NULL }, -+ [ __NR_utime ] = { 1, check_utime }, -+ [ __NR_oldlstat ] = { 1, check_oldstat }, -+ [ __NR_oldstat ] = { 1, check_oldstat }, -+ [ __NR_stat ] = { 1, check_stat }, -+ [ __NR_lstat ] = { 1, check_stat }, -+ [ __NR_stat64 ] = { 1, check_stat64 }, -+ [ __NR_lstat64 ] = { 1, check_stat64 }, -+ [ __NR_chown32 ] = { 1, NULL }, -+}; -+ -+/* sys_utimes */ -+ -+static int check_bogosity(struct pt_regs *regs) -+{ -+ struct bogus *bogon = &this_is_bogus[UPT_SYSCALL_NR(®s->regs)]; -+ -+ if(!bogon->kernel_ds) return(0); -+ if(bogon->check_params && (*bogon->check_params)(regs)) -+ return(-EFAULT); -+ set_fs(KERNEL_DS); -+ return(0); -+} -+ -+extern syscall_handler_t *sys_call_table[]; -+ -+long execute_syscall_tt(void *r) -+{ -+ struct pt_regs *regs = r; -+ long res; -+ int syscall; -+ -+ current->thread.nsyscalls++; -+ nsyscalls++; -+ syscall = UPT_SYSCALL_NR(®s->regs); -+ -+ if((syscall >= NR_syscalls) || (syscall < 0)) -+ res = -ENOSYS; -+ else if(honeypot && check_bogosity(regs)) -+ res = -EFAULT; -+ else res = EXECUTE_SYSCALL(syscall, regs); -+ -+ set_fs(USER_DS); -+ -+ if(current->thread.mode.tt.singlestep_syscall){ -+ current->thread.mode.tt.singlestep_syscall = 0; -+ current->ptrace &= ~PT_DTRACE; -+ force_sig(SIGTRAP, current); -+ } -+ -+ return(res); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/syscall_user.c um/arch/um/kernel/tt/syscall_user.c ---- orig/arch/um/kernel/tt/syscall_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/syscall_user.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,89 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <unistd.h> -+#include <signal.h> -+#include <errno.h> -+#include <sys/ptrace.h> -+#include <asm/unistd.h> -+#include "sysdep/ptrace.h" -+#include "sigcontext.h" -+#include "ptrace_user.h" -+#include "task.h" -+#include "user_util.h" -+#include "kern_util.h" -+#include "syscall_user.h" -+#include "tt.h" -+ -+/* XXX Bogus */ -+#define ERESTARTSYS 512 -+#define ERESTARTNOINTR 513 -+#define ERESTARTNOHAND 514 -+ -+void syscall_handler_tt(int sig, union uml_pt_regs *regs) -+{ -+ void *sc; -+ long result; -+ int index, syscall; -+ -+ syscall = UPT_SYSCALL_NR(regs); -+ sc = UPT_SC(regs); -+ SC_START_SYSCALL(sc); -+ -+ index = record_syscall_start(syscall); -+ syscall_trace(); -+ result = execute_syscall(regs); -+ -+ /* regs->sc may have changed while the system call ran (there may -+ * have been an interrupt or segfault), so it needs to be refreshed. -+ */ -+ UPT_SC(regs) = sc; -+ -+ SC_SET_SYSCALL_RETURN(sc, result); -+ if((result == -ERESTARTNOHAND) || (result == -ERESTARTSYS) || -+ (result == -ERESTARTNOINTR)) -+ do_signal(result); -+ -+ syscall_trace(); -+ record_syscall_end(index, result); -+} -+ -+int do_syscall(void *task, int pid) -+{ -+ unsigned long proc_regs[FRAME_SIZE]; -+ union uml_pt_regs *regs; -+ int syscall; -+ -+ if(ptrace_getregs(pid, proc_regs) < 0) -+ tracer_panic("Couldn't read registers"); -+ syscall = PT_SYSCALL_NR(proc_regs); -+ -+ regs = TASK_REGS(task); -+ UPT_SYSCALL_NR(regs) = syscall; -+ -+ if(syscall < 1) return(0); -+ -+ if((syscall != __NR_sigreturn) && -+ ((unsigned long *) PT_IP(proc_regs) >= &_stext) && -+ ((unsigned long *) PT_IP(proc_regs) <= &_etext)) -+ tracer_panic("I'm tracing myself and I can't get out"); -+ -+ if(ptrace(PTRACE_POKEUSER, pid, PT_SYSCALL_NR_OFFSET, -+ __NR_getpid) < 0) -+ tracer_panic("do_syscall : Nullifying syscall failed, " -+ "errno = %d", errno); -+ return(1); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/sys-i386/Makefile um/arch/um/kernel/tt/sys-i386/Makefile ---- orig/arch/um/kernel/tt/sys-i386/Makefile 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/sys-i386/Makefile 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,17 @@ -+# -+# Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+# Licensed under the GPL -+# -+ -+O_TARGET = sys-i386.o -+ -+obj-y = sigcontext.o -+ -+USER_OBJS = sigcontext.o -+ -+include $(TOPDIR)/Rules.make -+ -+$(USER_OBJS) : %.o: %.c -+ $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $< -+ -+clean : -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/sys-i386/sigcontext.c um/arch/um/kernel/tt/sys-i386/sigcontext.c ---- orig/arch/um/kernel/tt/sys-i386/sigcontext.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/sys-i386/sigcontext.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,60 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <stdlib.h> -+#include <asm/sigcontext.h> -+#include "kern_util.h" -+#include "sysdep/frame.h" -+ -+int copy_sc_from_user_tt(void *to_ptr, void *from_ptr, void *data) -+{ -+ struct arch_frame_data *arch = data; -+ struct sigcontext *to = to_ptr, *from = from_ptr; -+ struct _fpstate *to_fp, *from_fp; -+ unsigned long sigs; -+ int err; -+ -+ to_fp = to->fpstate; -+ from_fp = from->fpstate; -+ sigs = to->oldmask; -+ err = copy_from_user_proc(to, from, sizeof(*to)); -+ to->oldmask = sigs; -+ if(to_fp != NULL){ -+ err |= copy_from_user_proc(&to->fpstate, &to_fp, -+ sizeof(to->fpstate)); -+ err |= copy_from_user_proc(to_fp, from_fp, arch->fpstate_size); -+ } -+ return(err); -+} -+ -+int copy_sc_to_user_tt(void *to_ptr, void *fp, void *from_ptr, void *data) -+{ -+ struct arch_frame_data *arch = data; -+ struct sigcontext *to = to_ptr, *from = from_ptr; -+ struct _fpstate *to_fp, *from_fp; -+ int err; -+ -+ to_fp = (struct _fpstate *) -+ (fp ? (unsigned long) fp : ((unsigned long) to + sizeof(*to))); -+ from_fp = from->fpstate; -+ err = copy_to_user_proc(to, from, sizeof(*to)); -+ if(from_fp != NULL){ -+ err |= copy_to_user_proc(&to->fpstate, &to_fp, -+ sizeof(to->fpstate)); -+ err |= copy_to_user_proc(to_fp, from_fp, arch->fpstate_size); -+ } -+ return(err); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/time.c um/arch/um/kernel/tt/time.c ---- orig/arch/um/kernel/tt/time.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/time.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,28 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <signal.h> -+#include <sys/time.h> -+#include <time_user.h> -+#include "process.h" -+#include "user.h" -+ -+void user_time_init_tt(void) -+{ -+ if(signal(SIGVTALRM, (__sighandler_t) alarm_handler) == SIG_ERR) -+ panic("Couldn't set SIGVTALRM handler"); -+ set_interval(ITIMER_VIRTUAL); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/tlb.c um/arch/um/kernel/tt/tlb.c ---- orig/arch/um/kernel/tt/tlb.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/tlb.c 2003-11-13 00:40:57.000000000 -0500 -@@ -0,0 +1,220 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/stddef.h" -+#include "linux/kernel.h" -+#include "linux/sched.h" -+#include "asm/page.h" -+#include "asm/pgtable.h" -+#include "asm/uaccess.h" -+#include "user_util.h" -+#include "mem_user.h" -+#include "os.h" -+ -+static void fix_range(struct mm_struct *mm, unsigned long start_addr, -+ unsigned long end_addr, int force) -+{ -+ pgd_t *npgd; -+ pmd_t *npmd; -+ pte_t *npte; -+ unsigned long addr; -+ int r, w, x, err; -+ -+ if((current->thread.mode.tt.extern_pid != -1) && -+ (current->thread.mode.tt.extern_pid != os_getpid())) -+ panic("fix_range fixing wrong address space, current = 0x%p", -+ current); -+ if(mm == NULL) return; -+ for(addr=start_addr;addr<end_addr;){ -+ if(addr == TASK_SIZE){ -+ /* Skip over kernel text, kernel data, and physical -+ * memory, which don't have ptes, plus kernel virtual -+ * memory, which is flushed separately, and remap -+ * the process stack. The only way to get here is -+ * if (end_addr == STACK_TOP) > TASK_SIZE, which is -+ * only true in the honeypot case. -+ */ -+ addr = STACK_TOP - ABOVE_KMEM; -+ continue; -+ } -+ npgd = pgd_offset(mm, addr); -+ npmd = pmd_offset(npgd, addr); -+ if(pmd_present(*npmd)){ -+ npte = pte_offset(npmd, addr); -+ r = pte_read(*npte); -+ w = pte_write(*npte); -+ x = pte_exec(*npte); -+ if(!pte_dirty(*npte)) w = 0; -+ if(!pte_young(*npte)){ -+ r = 0; -+ w = 0; -+ } -+ if(force || pte_newpage(*npte)){ -+ err = os_unmap_memory((void *) addr, -+ PAGE_SIZE); -+ if(err < 0) -+ panic("munmap failed, errno = %d\n", -+ -err); -+ if(pte_present(*npte)) -+ map_memory(addr, -+ pte_val(*npte) & PAGE_MASK, -+ PAGE_SIZE, r, w, x); -+ } -+ else if(pte_newprot(*npte)){ -+ protect_memory(addr, PAGE_SIZE, r, w, x, 1); -+ } -+ *npte = pte_mkuptodate(*npte); -+ addr += PAGE_SIZE; -+ } -+ else { -+ if(force || pmd_newpage(*npmd)){ -+ err = os_unmap_memory((void *) addr, PMD_SIZE); -+ if(err < 0) -+ panic("munmap failed, errno = %d\n", -+ -err); -+ pmd_mkuptodate(*npmd); -+ } -+ addr += PMD_SIZE; -+ } -+ } -+} -+ -+atomic_t vmchange_seq = ATOMIC_INIT(1); -+ -+static void flush_kernel_vm_range(unsigned long start, unsigned long end, -+ int update_seq) -+{ -+ struct mm_struct *mm; -+ pgd_t *pgd; -+ pmd_t *pmd; -+ pte_t *pte; -+ unsigned long addr; -+ int updated = 0, err; -+ -+ mm = &init_mm; -+ for(addr = start; addr < end;){ -+ pgd = pgd_offset(mm, addr); -+ pmd = pmd_offset(pgd, addr); -+ if(pmd_present(*pmd)){ -+ pte = pte_offset(pmd, addr); -+ if(!pte_present(*pte) || pte_newpage(*pte)){ -+ updated = 1; -+ err = os_unmap_memory((void *) addr, -+ PAGE_SIZE); -+ if(err < 0) -+ panic("munmap failed, errno = %d\n", -+ -err); -+ if(pte_present(*pte)) -+ map_memory(addr, -+ pte_val(*pte) & PAGE_MASK, -+ PAGE_SIZE, 1, 1, 1); -+ } -+ else if(pte_newprot(*pte)){ -+ updated = 1; -+ protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1); -+ } -+ addr += PAGE_SIZE; -+ } -+ else { -+ if(pmd_newpage(*pmd)){ -+ updated = 1; -+ err = os_unmap_memory((void *) addr, PMD_SIZE); -+ if(err < 0) -+ panic("munmap failed, errno = %d\n", -+ -err); -+ } -+ addr += PMD_SIZE; -+ } -+ } -+ if(updated && update_seq) atomic_inc(&vmchange_seq); -+} -+ -+static void protect_vm_page(unsigned long addr, int w, int must_succeed) -+{ -+ int err; -+ -+ err = protect_memory(addr, PAGE_SIZE, 1, w, 1, must_succeed); -+ if(err == 0) return; -+ else if((err == -EFAULT) || (err == -ENOMEM)){ -+ flush_kernel_vm_range(addr, addr + PAGE_SIZE, 1); -+ protect_vm_page(addr, w, 1); -+ } -+ else panic("protect_vm_page : protect failed, errno = %d\n", err); -+} -+ -+void mprotect_kernel_vm(int w) -+{ -+ struct mm_struct *mm; -+ pgd_t *pgd; -+ pmd_t *pmd; -+ pte_t *pte; -+ unsigned long addr; -+ -+ mm = &init_mm; -+ for(addr = start_vm; addr < end_vm;){ -+ pgd = pgd_offset(mm, addr); -+ pmd = pmd_offset(pgd, addr); -+ if(pmd_present(*pmd)){ -+ pte = pte_offset(pmd, addr); -+ if(pte_present(*pte)) protect_vm_page(addr, w, 0); -+ addr += PAGE_SIZE; -+ } -+ else addr += PMD_SIZE; -+ } -+} -+ -+void flush_tlb_kernel_vm_tt(void) -+{ -+ flush_kernel_vm_range(start_vm, end_vm, 1); -+} -+ -+void __flush_tlb_one_tt(unsigned long addr) -+{ -+ flush_kernel_vm_range(addr, addr + PAGE_SIZE, 1); -+} -+ -+void flush_tlb_range_tt(struct mm_struct *mm, unsigned long start, -+ unsigned long end) -+{ -+ if(mm != current->mm) return; -+ -+ /* Assumes that the range start ... end is entirely within -+ * either process memory or kernel vm -+ */ -+ if((start >= start_vm) && (start < end_vm)) -+ flush_kernel_vm_range(start, end, 1); -+ else fix_range(mm, start, end, 0); -+} -+ -+void flush_tlb_mm_tt(struct mm_struct *mm) -+{ -+ unsigned long seq; -+ -+ if(mm != current->mm) return; -+ -+ fix_range(mm, 0, STACK_TOP, 0); -+ -+ seq = atomic_read(&vmchange_seq); -+ if(current->thread.mode.tt.vm_seq == seq) return; -+ current->thread.mode.tt.vm_seq = seq; -+ flush_kernel_vm_range(start_vm, end_vm, 0); -+} -+ -+void force_flush_all_tt(void) -+{ -+ fix_range(current->mm, 0, STACK_TOP, 1); -+ flush_kernel_vm_range(start_vm, end_vm, 0); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/tracer.c um/arch/um/kernel/tt/tracer.c ---- orig/arch/um/kernel/tt/tracer.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/tracer.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,454 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <stdio.h> -+#include <stdlib.h> -+#include <stdarg.h> -+#include <unistd.h> -+#include <signal.h> -+#include <errno.h> -+#include <sched.h> -+#include <string.h> -+#include <sys/mman.h> -+#include <sys/ptrace.h> -+#include <sys/time.h> -+#include <sys/wait.h> -+#include "user.h" -+#include "sysdep/ptrace.h" -+#include "sigcontext.h" -+#include "sysdep/sigcontext.h" -+#include "os.h" -+#include "signal_user.h" -+#include "user_util.h" -+#include "mem_user.h" -+#include "process.h" -+#include "kern_util.h" -+#include "frame.h" -+#include "chan_user.h" -+#include "ptrace_user.h" -+#include "mode.h" -+#include "tt.h" -+ -+static int tracer_winch[2]; -+ -+int is_tracer_winch(int pid, int fd, void *data) -+{ -+ if(pid != tracing_pid) -+ return(0); -+ -+ register_winch_irq(tracer_winch[0], fd, -1, data); -+ return(1); -+} -+ -+static void tracer_winch_handler(int sig) -+{ -+ int n; -+ char c = 1; -+ -+ n = os_write_file(tracer_winch[1], &c, sizeof(c)); -+ if(n != sizeof(c)) -+ printk("tracer_winch_handler - write failed, err = %d\n", -n); -+} -+ -+/* Called only by the tracing thread during initialization */ -+ -+static void setup_tracer_winch(void) -+{ -+ int err; -+ -+ err = os_pipe(tracer_winch, 1, 1); -+ if(err < 0){ -+ printk("setup_tracer_winch : os_pipe failed, err = %d\n", -err); -+ return; -+ } -+ signal(SIGWINCH, tracer_winch_handler); -+} -+ -+void attach_process(int pid) -+{ -+ if((ptrace(PTRACE_ATTACH, pid, 0, 0) < 0) || -+ (ptrace(PTRACE_CONT, pid, 0, 0) < 0)) -+ tracer_panic("OP_FORK failed to attach pid"); -+ wait_for_stop(pid, SIGSTOP, PTRACE_CONT, NULL); -+ if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) -+ tracer_panic("OP_FORK failed to continue process"); -+} -+ -+void tracer_panic(char *format, ...) -+{ -+ va_list ap; -+ -+ va_start(ap, format); -+ vprintf(format, ap); -+ printf("\n"); -+ while(1) pause(); -+} -+ -+static void tracer_segv(int sig, struct sigcontext sc) -+{ -+ printf("Tracing thread segfault at address 0x%lx, ip 0x%lx\n", -+ SC_FAULT_ADDR(&sc), SC_IP(&sc)); -+ while(1) -+ pause(); -+} -+ -+/* Changed early in boot, and then only read */ -+int debug = 0; -+int debug_stop = 1; -+int debug_parent = 0; -+int honeypot = 0; -+ -+static int signal_tramp(void *arg) -+{ -+ int (*proc)(void *); -+ -+ if(honeypot && munmap((void *) (host_task_size - 0x10000000), -+ 0x10000000)) -+ panic("Unmapping stack failed"); -+ if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) -+ panic("ptrace PTRACE_TRACEME failed"); -+ os_stop_process(os_getpid()); -+ change_sig(SIGWINCH, 0); -+ signal(SIGUSR1, SIG_IGN); -+ change_sig(SIGCHLD, 0); -+ signal(SIGSEGV, (__sighandler_t) sig_handler); -+ set_cmdline("(idle thread)"); -+ set_init_pid(os_getpid()); -+ proc = arg; -+ return((*proc)(NULL)); -+} -+ -+static void sleeping_process_signal(int pid, int sig) -+{ -+ switch(sig){ -+ /* These two result from UML being ^Z-ed and bg-ed. PTRACE_CONT is -+ * right because the process must be in the kernel already. -+ */ -+ case SIGCONT: -+ case SIGTSTP: -+ if(ptrace(PTRACE_CONT, pid, 0, sig) < 0) -+ tracer_panic("sleeping_process_signal : Failed to " -+ "continue pid %d, signal = %d, " -+ "errno = %d\n", pid, sig, errno); -+ break; -+ -+ /* This happens when the debugger (e.g. strace) is doing system call -+ * tracing on the kernel. During a context switch, the current task -+ * will be set to the incoming process and the outgoing process will -+ * hop into write and then read. Since it's not the current process -+ * any more, the trace of those will land here. So, we need to just -+ * PTRACE_SYSCALL it. -+ */ -+ case SIGTRAP: -+ if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) -+ tracer_panic("sleeping_process_signal : Failed to " -+ "PTRACE_SYSCALL pid %d, errno = %d\n", -+ pid, errno); -+ break; -+ case SIGSTOP: -+ break; -+ default: -+ tracer_panic("sleeping process %d got unexpected " -+ "signal : %d\n", pid, sig); -+ break; -+ } -+} -+ -+/* Accessed only by the tracing thread */ -+int debugger_pid = -1; -+int debugger_parent = -1; -+int debugger_fd = -1; -+int gdb_pid = -1; -+ -+struct { -+ int pid; -+ int signal; -+ unsigned long addr; -+ struct timeval time; -+} signal_record[1024][32]; -+ -+int signal_index[32]; -+int nsignals = 0; -+int debug_trace = 0; -+extern int io_nsignals, io_count, intr_count; -+ -+extern void signal_usr1(int sig); -+ -+int tracing_pid = -1; -+ -+int tracer(int (*init_proc)(void *), void *sp) -+{ -+ void *task = NULL; -+ unsigned long eip = 0; -+ int status, pid = 0, sig = 0, cont_type, tracing = 0, op = 0; -+ int last_index, proc_id = 0, n, err, old_tracing = 0, strace = 0; -+ -+ capture_signal_stack(); -+ signal(SIGPIPE, SIG_IGN); -+ setup_tracer_winch(); -+ tracing_pid = os_getpid(); -+ printf("tracing thread pid = %d\n", tracing_pid); -+ -+ pid = clone(signal_tramp, sp, CLONE_FILES | SIGCHLD, init_proc); -+ n = waitpid(pid, &status, WUNTRACED); -+ if(n < 0){ -+ printf("waitpid on idle thread failed, errno = %d\n", errno); -+ exit(1); -+ } -+ if((ptrace(PTRACE_CONT, pid, 0, 0) < 0)){ -+ printf("Failed to continue idle thread, errno = %d\n", errno); -+ exit(1); -+ } -+ -+ signal(SIGSEGV, (sighandler_t) tracer_segv); -+ signal(SIGUSR1, signal_usr1); -+ if(debug_trace){ -+ printf("Tracing thread pausing to be attached\n"); -+ stop(); -+ } -+ if(debug){ -+ if(gdb_pid != -1) -+ debugger_pid = attach_debugger(pid, gdb_pid, 1); -+ else debugger_pid = init_ptrace_proxy(pid, 1, debug_stop); -+ if(debug_parent){ -+ debugger_parent = os_process_parent(debugger_pid); -+ init_parent_proxy(debugger_parent); -+ err = attach(debugger_parent); -+ if(err){ -+ printf("Failed to attach debugger parent %d, " -+ "errno = %d\n", debugger_parent, -err); -+ debugger_parent = -1; -+ } -+ else { -+ if(ptrace(PTRACE_SYSCALL, debugger_parent, -+ 0, 0) < 0){ -+ printf("Failed to continue debugger " -+ "parent, errno = %d\n", errno); -+ debugger_parent = -1; -+ } -+ } -+ } -+ } -+ set_cmdline("(tracing thread)"); -+ while(1){ -+ pid = waitpid(-1, &status, WUNTRACED); -+ if(pid <= 0){ -+ if(errno != ECHILD){ -+ printf("wait failed - errno = %d\n", errno); -+ } -+ continue; -+ } -+ if(pid == debugger_pid){ -+ int cont = 0; -+ -+ if(WIFEXITED(status) || WIFSIGNALED(status)) -+ debugger_pid = -1; -+ /* XXX Figure out how to deal with gdb and SMP */ -+ else cont = debugger_signal(status, cpu_tasks[0].pid); -+ if(cont == PTRACE_SYSCALL) strace = 1; -+ continue; -+ } -+ else if(pid == debugger_parent){ -+ debugger_parent_signal(status, pid); -+ continue; -+ } -+ nsignals++; -+ if(WIFEXITED(status)) ; -+#ifdef notdef -+ { -+ printf("Child %d exited with status %d\n", pid, -+ WEXITSTATUS(status)); -+ } -+#endif -+ else if(WIFSIGNALED(status)){ -+ sig = WTERMSIG(status); -+ if(sig != 9){ -+ printf("Child %d exited with signal %d\n", pid, -+ sig); -+ } -+ } -+ else if(WIFSTOPPED(status)){ -+ proc_id = pid_to_processor_id(pid); -+ sig = WSTOPSIG(status); -+ if(signal_index[proc_id] == 1024){ -+ signal_index[proc_id] = 0; -+ last_index = 1023; -+ } -+ else last_index = signal_index[proc_id] - 1; -+ if(((sig == SIGPROF) || (sig == SIGVTALRM) || -+ (sig == SIGALRM)) && -+ (signal_record[proc_id][last_index].signal == sig)&& -+ (signal_record[proc_id][last_index].pid == pid)) -+ signal_index[proc_id] = last_index; -+ signal_record[proc_id][signal_index[proc_id]].pid = pid; -+ gettimeofday(&signal_record[proc_id][signal_index[proc_id]].time, NULL); -+ eip = ptrace(PTRACE_PEEKUSER, pid, PT_IP_OFFSET, 0); -+ signal_record[proc_id][signal_index[proc_id]].addr = eip; -+ signal_record[proc_id][signal_index[proc_id]++].signal = sig; -+ -+ if(proc_id == -1){ -+ sleeping_process_signal(pid, sig); -+ continue; -+ } -+ -+ task = cpu_tasks[proc_id].task; -+ tracing = is_tracing(task); -+ old_tracing = tracing; -+ -+ switch(sig){ -+ case SIGUSR1: -+ sig = 0; -+ op = do_proc_op(task, proc_id); -+ switch(op){ -+ case OP_TRACE_ON: -+ arch_leave_kernel(task, pid); -+ tracing = 1; -+ break; -+ case OP_REBOOT: -+ case OP_HALT: -+ unmap_physmem(); -+ kmalloc_ok = 0; -+ ptrace(PTRACE_KILL, pid, 0, 0); -+ return(op == OP_REBOOT); -+ case OP_NONE: -+ printf("Detaching pid %d\n", pid); -+ detach(pid, SIGSTOP); -+ continue; -+ default: -+ break; -+ } -+ /* OP_EXEC switches host processes on us, -+ * we want to continue the new one. -+ */ -+ pid = cpu_tasks[proc_id].pid; -+ break; -+ case SIGTRAP: -+ if(!tracing && (debugger_pid != -1)){ -+ child_signal(pid, status); -+ continue; -+ } -+ tracing = 0; -+ if(do_syscall(task, pid)) sig = SIGUSR2; -+ else clear_singlestep(task); -+ break; -+ case SIGPROF: -+ if(tracing) sig = 0; -+ break; -+ case SIGCHLD: -+ case SIGHUP: -+ sig = 0; -+ break; -+ case SIGSEGV: -+ case SIGIO: -+ case SIGALRM: -+ case SIGVTALRM: -+ case SIGFPE: -+ case SIGBUS: -+ case SIGILL: -+ case SIGWINCH: -+ default: -+ tracing = 0; -+ break; -+ } -+ set_tracing(task, tracing); -+ -+ if(!tracing && old_tracing) -+ arch_enter_kernel(task, pid); -+ -+ if(!tracing && (debugger_pid != -1) && (sig != 0) && -+ (sig != SIGALRM) && (sig != SIGVTALRM) && -+ (sig != SIGSEGV) && (sig != SIGTRAP) && -+ (sig != SIGUSR2) && (sig != SIGIO) && -+ (sig != SIGFPE)){ -+ child_signal(pid, status); -+ continue; -+ } -+ -+ if(tracing){ -+ if(singlestepping_tt(task)) -+ cont_type = PTRACE_SINGLESTEP; -+ else cont_type = PTRACE_SYSCALL; -+ } -+ else cont_type = PTRACE_CONT; -+ -+ if((cont_type == PTRACE_CONT) && -+ (debugger_pid != -1) && strace) -+ cont_type = PTRACE_SYSCALL; -+ -+ if(ptrace(cont_type, pid, 0, sig) != 0){ -+ tracer_panic("ptrace failed to continue " -+ "process - errno = %d\n", -+ errno); -+ } -+ } -+ } -+ return(0); -+} -+ -+static int __init uml_debug_setup(char *line, int *add) -+{ -+ char *next; -+ -+ debug = 1; -+ *add = 0; -+ if(*line != '=') return(0); -+ line++; -+ -+ while(line != NULL){ -+ next = strchr(line, ','); -+ if(next) *next++ = '\0'; -+ -+ if(!strcmp(line, "go")) debug_stop = 0; -+ else if(!strcmp(line, "parent")) debug_parent = 1; -+ else printf("Unknown debug option : '%s'\n", line); -+ -+ line = next; -+ } -+ return(0); -+} -+ -+__uml_setup("debug", uml_debug_setup, -+"debug\n" -+" Starts up the kernel under the control of gdb. See the \n" -+" kernel debugging tutorial and the debugging session pages\n" -+" at http://user-mode-linux.sourceforge.net/ for more information.\n\n" -+); -+ -+static int __init uml_debugtrace_setup(char *line, int *add) -+{ -+ debug_trace = 1; -+ return 0; -+} -+__uml_setup("debugtrace", uml_debugtrace_setup, -+"debugtrace\n" -+" Causes the tracing thread to pause until it is attached by a\n" -+" debugger and continued. This is mostly for debugging crashes\n" -+" early during boot, and should be pretty much obsoleted by\n" -+" the debug switch.\n\n" -+); -+ -+static int __init uml_honeypot_setup(char *line, int *add) -+{ -+ jail_setup("", add); -+ honeypot = 1; -+ return 0; -+} -+__uml_setup("honeypot", uml_honeypot_setup, -+"honeypot\n" -+" This makes UML put process stacks in the same location as they are\n" -+" on the host, allowing expoits such as stack smashes to work against\n" -+" UML. This implies 'jail'.\n\n" -+); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/trap_user.c um/arch/um/kernel/tt/trap_user.c ---- orig/arch/um/kernel/tt/trap_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/trap_user.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,59 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <stdlib.h> -+#include <errno.h> -+#include <signal.h> -+#include <asm/sigcontext.h> -+#include "sysdep/ptrace.h" -+#include "signal_user.h" -+#include "user_util.h" -+#include "kern_util.h" -+#include "task.h" -+#include "tt.h" -+ -+void sig_handler_common_tt(int sig, void *sc_ptr) -+{ -+ struct sigcontext *sc = sc_ptr; -+ struct tt_regs save_regs, *r; -+ struct signal_info *info; -+ int save_errno = errno, is_user; -+ -+ unprotect_kernel_mem(); -+ -+ r = &TASK_REGS(get_current())->tt; -+ save_regs = *r; -+ is_user = user_context(SC_SP(sc)); -+ r->sc = sc; -+ if(sig != SIGUSR2) -+ r->syscall = -1; -+ -+ change_sig(SIGUSR1, 1); -+ info = &sig_info[sig]; -+ if(!info->is_irq) unblock_signals(); -+ -+ (*info->handler)(sig, (union uml_pt_regs *) r); -+ -+ if(is_user){ -+ interrupt_end(); -+ block_signals(); -+ change_sig(SIGUSR1, 0); -+ set_user_mode(NULL); -+ } -+ *r = save_regs; -+ errno = save_errno; -+ if(is_user) protect_kernel_mem(); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/uaccess.c um/arch/um/kernel/tt/uaccess.c ---- orig/arch/um/kernel/tt/uaccess.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/uaccess.c 2003-11-13 00:12:45.000000000 -0500 -@@ -0,0 +1,73 @@ -+/* -+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/sched.h" -+#include "asm/uaccess.h" -+ -+int copy_from_user_tt(void *to, const void *from, int n) -+{ -+ if(!access_ok_tt(VERIFY_READ, from, n)) -+ return(n); -+ -+ return(__do_copy_from_user(to, from, n, ¤t->thread.fault_addr, -+ ¤t->thread.fault_catcher)); -+} -+ -+int copy_to_user_tt(void *to, const void *from, int n) -+{ -+ if(!access_ok_tt(VERIFY_WRITE, to, n)) -+ return(n); -+ -+ return(__do_copy_to_user(to, from, n, ¤t->thread.fault_addr, -+ ¤t->thread.fault_catcher)); -+} -+ -+int strncpy_from_user_tt(char *dst, const char *src, int count) -+{ -+ int n; -+ -+ if(!access_ok_tt(VERIFY_READ, src, 1)) -+ return(-EFAULT); -+ -+ n = __do_strncpy_from_user(dst, src, count, -+ ¤t->thread.fault_addr, -+ ¤t->thread.fault_catcher); -+ if(n < 0) return(-EFAULT); -+ return(n); -+} -+ -+int __clear_user_tt(void *mem, int len) -+{ -+ return(__do_clear_user(mem, len, -+ ¤t->thread.fault_addr, -+ ¤t->thread.fault_catcher)); -+} -+ -+int clear_user_tt(void *mem, int len) -+{ -+ if(!access_ok_tt(VERIFY_WRITE, mem, len)) -+ return(len); -+ -+ return(__do_clear_user(mem, len, ¤t->thread.fault_addr, -+ ¤t->thread.fault_catcher)); -+} -+ -+int strnlen_user_tt(const void *str, int len) -+{ -+ return(__do_strnlen_user(str, len, -+ ¤t->thread.fault_addr, -+ ¤t->thread.fault_catcher)); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/uaccess_user.c um/arch/um/kernel/tt/uaccess_user.c ---- orig/arch/um/kernel/tt/uaccess_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/uaccess_user.c 2004-01-31 02:48:29.000000000 -0500 -@@ -0,0 +1,98 @@ -+/* -+ * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk) -+ * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <setjmp.h> -+#include <string.h> -+#include "user_util.h" -+#include "uml_uaccess.h" -+#include "task.h" -+#include "kern_util.h" -+ -+int __do_copy_from_user(void *to, const void *from, int n, -+ void **fault_addr, void **fault_catcher) -+{ -+ struct tt_regs save = TASK_REGS(get_current())->tt; -+ unsigned long fault; -+ int faulted; -+ -+ fault = __do_user_copy(to, from, n, fault_addr, fault_catcher, -+ __do_copy, &faulted); -+ TASK_REGS(get_current())->tt = save; -+ -+ if(!faulted) return(0); -+ else return(n - (fault - (unsigned long) from)); -+} -+ -+static void __do_strncpy(void *dst, const void *src, int count) -+{ -+ strncpy(dst, src, count); -+} -+ -+int __do_strncpy_from_user(char *dst, const char *src, unsigned long count, -+ void **fault_addr, void **fault_catcher) -+{ -+ struct tt_regs save = TASK_REGS(get_current())->tt; -+ unsigned long fault; -+ int faulted; -+ -+ fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher, -+ __do_strncpy, &faulted); -+ TASK_REGS(get_current())->tt = save; -+ -+ if(!faulted) return(strlen(dst)); -+ else return(-1); -+} -+ -+static void __do_clear(void *to, const void *from, int n) -+{ -+ memset(to, 0, n); -+} -+ -+int __do_clear_user(void *mem, unsigned long len, -+ void **fault_addr, void **fault_catcher) -+{ -+ struct tt_regs save = TASK_REGS(get_current())->tt; -+ unsigned long fault; -+ int faulted; -+ -+ fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher, -+ __do_clear, &faulted); -+ TASK_REGS(get_current())->tt = save; -+ -+ if(!faulted) return(0); -+ else return(len - (fault - (unsigned long) mem)); -+} -+ -+int __do_strnlen_user(const char *str, unsigned long n, -+ void **fault_addr, void **fault_catcher) -+{ -+ struct tt_regs save = TASK_REGS(get_current())->tt; -+ int ret; -+ unsigned long *faddrp = (unsigned long *)fault_addr; -+ sigjmp_buf jbuf; -+ -+ *fault_catcher = &jbuf; -+ if(sigsetjmp(jbuf, 1) == 0) -+ ret = strlen(str) + 1; -+ else ret = *faddrp - (unsigned long) str; -+ -+ *fault_addr = NULL; -+ *fault_catcher = NULL; -+ -+ TASK_REGS(get_current())->tt = save; -+ return ret; -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tt/unmap.c um/arch/um/kernel/tt/unmap.c ---- orig/arch/um/kernel/tt/unmap.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tt/unmap.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,31 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <sys/mman.h> -+ -+int switcheroo(int fd, int prot, void *from, void *to, int size) -+{ -+ if(munmap(to, size) < 0){ -+ return(-1); -+ } -+ if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) != to){ -+ return(-1); -+ } -+ if(munmap(from, size) < 0){ -+ return(-1); -+ } -+ return(0); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/tty_log.c um/arch/um/kernel/tty_log.c ---- orig/arch/um/kernel/tty_log.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/tty_log.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,228 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) and -+ * geoffrey hing <ghing@net.ohio-state.edu> -+ * Licensed under the GPL -+ */ -+ -+#include <errno.h> -+#include <string.h> -+#include <stdio.h> -+#include <stdlib.h> -+#include <unistd.h> -+#include <sys/time.h> -+#include "init.h" -+#include "user.h" -+#include "kern_util.h" -+#include "os.h" -+ -+#define TTY_LOG_DIR "./" -+ -+/* Set early in boot and then unchanged */ -+static char *tty_log_dir = TTY_LOG_DIR; -+static int tty_log_fd = -1; -+ -+#define TTY_LOG_OPEN 1 -+#define TTY_LOG_CLOSE 2 -+#define TTY_LOG_WRITE 3 -+#define TTY_LOG_EXEC 4 -+ -+#define TTY_READ 1 -+#define TTY_WRITE 2 -+ -+struct tty_log_buf { -+ int what; -+ unsigned long tty; -+ int len; -+ int direction; -+ unsigned long sec; -+ unsigned long usec; -+}; -+ -+int open_tty_log(void *tty, void *current_tty) -+{ -+ struct timeval tv; -+ struct tty_log_buf data; -+ char buf[strlen(tty_log_dir) + sizeof("01234567890-01234567\0")]; -+ int fd; -+ -+ gettimeofday(&tv, NULL); -+ if(tty_log_fd != -1){ -+ data = ((struct tty_log_buf) { .what = TTY_LOG_OPEN, -+ .tty = (unsigned long) tty, -+ .len = sizeof(current_tty), -+ .direction = 0, -+ .sec = tv.tv_sec, -+ .usec = tv.tv_usec } ); -+ os_write_file(tty_log_fd, &data, sizeof(data)); -+ os_write_file(tty_log_fd, ¤t_tty, data.len); -+ return(tty_log_fd); -+ } -+ -+ sprintf(buf, "%s/%0u-%0u", tty_log_dir, (unsigned int) tv.tv_sec, -+ (unsigned int) tv.tv_usec); -+ -+ fd = os_open_file(buf, of_append(of_create(of_rdwr(OPENFLAGS()))), -+ 0644); -+ if(fd < 0){ -+ printk("open_tty_log : couldn't open '%s', errno = %d\n", -+ buf, -fd); -+ } -+ return(fd); -+} -+ -+void close_tty_log(int fd, void *tty) -+{ -+ struct tty_log_buf data; -+ struct timeval tv; -+ -+ if(tty_log_fd != -1){ -+ gettimeofday(&tv, NULL); -+ data = ((struct tty_log_buf) { .what = TTY_LOG_CLOSE, -+ .tty = (unsigned long) tty, -+ .len = 0, -+ .direction = 0, -+ .sec = tv.tv_sec, -+ .usec = tv.tv_usec } ); -+ os_write_file(tty_log_fd, &data, sizeof(data)); -+ return; -+ } -+ os_close_file(fd); -+} -+ -+static int log_chunk(int fd, const char *buf, int len) -+{ -+ int total = 0, try, missed, n; -+ char chunk[64]; -+ -+ while(len > 0){ -+ try = (len > sizeof(chunk)) ? sizeof(chunk) : len; -+ missed = copy_from_user_proc(chunk, (char *) buf, try); -+ try -= missed; -+ n = os_write_file(fd, chunk, try); -+ if(n != try) { -+ if(n < 0) -+ return(n); -+ return(-EIO); -+ } -+ if(missed != 0) -+ return(-EFAULT); -+ -+ len -= try; -+ total += try; -+ buf += try; -+ } -+ -+ return(total); -+} -+ -+int write_tty_log(int fd, const char *buf, int len, void *tty, int is_read) -+{ -+ struct timeval tv; -+ struct tty_log_buf data; -+ int direction; -+ -+ if(fd == tty_log_fd){ -+ gettimeofday(&tv, NULL); -+ direction = is_read ? TTY_READ : TTY_WRITE; -+ data = ((struct tty_log_buf) { .what = TTY_LOG_WRITE, -+ .tty = (unsigned long) tty, -+ .len = len, -+ .direction = direction, -+ .sec = tv.tv_sec, -+ .usec = tv.tv_usec } ); -+ os_write_file(tty_log_fd, &data, sizeof(data)); -+ } -+ -+ return(log_chunk(fd, buf, len)); -+} -+ -+void log_exec(char **argv, void *tty) -+{ -+ struct timeval tv; -+ struct tty_log_buf data; -+ char **ptr,*arg; -+ int len; -+ -+ if(tty_log_fd == -1) return; -+ -+ gettimeofday(&tv, NULL); -+ -+ len = 0; -+ for(ptr = argv; ; ptr++){ -+ if(copy_from_user_proc(&arg, ptr, sizeof(arg))) -+ return; -+ if(arg == NULL) break; -+ len += strlen_user_proc(arg); -+ } -+ -+ data = ((struct tty_log_buf) { .what = TTY_LOG_EXEC, -+ .tty = (unsigned long) tty, -+ .len = len, -+ .direction = 0, -+ .sec = tv.tv_sec, -+ .usec = tv.tv_usec } ); -+ os_write_file(tty_log_fd, &data, sizeof(data)); -+ -+ for(ptr = argv; ; ptr++){ -+ if(copy_from_user_proc(&arg, ptr, sizeof(arg))) -+ return; -+ if(arg == NULL) break; -+ log_chunk(tty_log_fd, arg, strlen_user_proc(arg)); -+ } -+} -+ -+extern void register_tty_logger(int (*opener)(void *, void *), -+ int (*writer)(int, const char *, int, -+ void *, int), -+ void (*closer)(int, void *)); -+ -+static int register_logger(void) -+{ -+ register_tty_logger(open_tty_log, write_tty_log, close_tty_log); -+ return(0); -+} -+ -+__uml_initcall(register_logger); -+ -+static int __init set_tty_log_dir(char *name, int *add) -+{ -+ tty_log_dir = name; -+ return 0; -+} -+ -+__uml_setup("tty_log_dir=", set_tty_log_dir, -+"tty_log_dir=<directory>\n" -+" This is used to specify the directory where the logs of all pty\n" -+" data from this UML machine will be written.\n\n" -+); -+ -+static int __init set_tty_log_fd(char *name, int *add) -+{ -+ char *end; -+ -+ tty_log_fd = strtoul(name, &end, 0); -+ if((*end != '\0') || (end == name)){ -+ printf("set_tty_log_fd - strtoul failed on '%s'\n", name); -+ tty_log_fd = -1; -+ } -+ return 0; -+} -+ -+__uml_setup("tty_log_fd=", set_tty_log_fd, -+"tty_log_fd=<fd>\n" -+" This is used to specify a preconfigured file descriptor to which all\n" -+" tty data will be written. Preconfigure the descriptor with something\n" -+" like '10>tty_log tty_log_fd=10'.\n\n" -+); -+ -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/uaccess_user.c um/arch/um/kernel/uaccess_user.c ---- orig/arch/um/kernel/uaccess_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/uaccess_user.c 2004-01-31 02:48:08.000000000 -0500 -@@ -0,0 +1,64 @@ -+/* -+ * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk) -+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <setjmp.h> -+#include <string.h> -+ -+/* These are here rather than tt/uaccess.c because skas mode needs them in -+ * order to do SIGBUS recovery when a tmpfs mount runs out of room. -+ */ -+ -+unsigned long __do_user_copy(void *to, const void *from, int n, -+ void **fault_addr, void **fault_catcher, -+ void (*op)(void *to, const void *from, -+ int n), int *faulted_out) -+{ -+ unsigned long *faddrp = (unsigned long *) fault_addr, ret; -+ -+ sigjmp_buf jbuf; -+ *fault_catcher = &jbuf; -+ if(sigsetjmp(jbuf, 1) == 0){ -+ (*op)(to, from, n); -+ ret = 0; -+ *faulted_out = 0; -+ } -+ else { -+ ret = *faddrp; -+ *faulted_out = 1; -+ } -+ *fault_addr = NULL; -+ *fault_catcher = NULL; -+ return ret; -+} -+ -+void __do_copy(void *to, const void *from, int n) -+{ -+ memcpy(to, from, n); -+} -+ -+ -+int __do_copy_to_user(void *to, const void *from, int n, -+ void **fault_addr, void **fault_catcher) -+{ -+ unsigned long fault; -+ int faulted; -+ -+ fault = __do_user_copy(to, from, n, fault_addr, fault_catcher, -+ __do_copy, &faulted); -+ if(!faulted) return(0); -+ else return(n - (fault - (unsigned long) to)); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/um_arch.c um/arch/um/kernel/um_arch.c ---- orig/arch/um/kernel/um_arch.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/um_arch.c 2004-01-10 00:11:09.000000000 -0500 -@@ -0,0 +1,431 @@ -+/* -+ * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/config.h" -+#include "linux/kernel.h" -+#include "linux/sched.h" -+#include "linux/notifier.h" -+#include "linux/mm.h" -+#include "linux/types.h" -+#include "linux/tty.h" -+#include "linux/init.h" -+#include "linux/bootmem.h" -+#include "linux/spinlock.h" -+#include "linux/utsname.h" -+#include "linux/sysrq.h" -+#include "linux/seq_file.h" -+#include "linux/delay.h" -+#include "asm/page.h" -+#include "asm/pgtable.h" -+#include "asm/ptrace.h" -+#include "asm/elf.h" -+#include "asm/user.h" -+#include "ubd_user.h" -+#include "asm/current.h" -+#include "user_util.h" -+#include "kern_util.h" -+#include "kern.h" -+#include "mprot.h" -+#include "mem_user.h" -+#include "mem.h" -+#include "umid.h" -+#include "initrd.h" -+#include "init.h" -+#include "os.h" -+#include "choose-mode.h" -+#include "mode_kern.h" -+#include "mode.h" -+ -+#define DEFAULT_COMMAND_LINE "root=/dev/ubd0" -+ -+struct cpuinfo_um boot_cpu_data = { -+ .loops_per_jiffy = 0, -+ .pgd_quick = NULL, -+ .pmd_quick = NULL, -+ .pte_quick = NULL, -+ .pgtable_cache_sz = 0, -+ .ipi_pipe = { -1, -1 } -+}; -+ -+unsigned long thread_saved_pc(struct thread_struct *thread) -+{ -+ return(os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas, -+ thread))); -+} -+ -+static int show_cpuinfo(struct seq_file *m, void *v) -+{ -+ int index = 0; -+ -+#ifdef CONFIG_SMP -+ index = (struct cpuinfo_um *)v - cpu_data; -+ if (!(cpu_online_map & (1 << index))) -+ return 0; -+#endif -+ -+ seq_printf(m, "processor\t: %d\n", index); -+ seq_printf(m, "vendor_id\t: User Mode Linux\n"); -+ seq_printf(m, "model name\t: UML\n"); -+ seq_printf(m, "mode\t\t: %s\n", CHOOSE_MODE("tt", "skas")); -+ seq_printf(m, "host\t\t: %s\n", host_info); -+ seq_printf(m, "bogomips\t: %lu.%02lu\n\n", -+ loops_per_jiffy/(500000/HZ), -+ (loops_per_jiffy/(5000/HZ)) % 100); -+ -+ return(0); -+} -+ -+static void *c_start(struct seq_file *m, loff_t *pos) -+{ -+ return *pos < NR_CPUS ? cpu_data + *pos : NULL; -+} -+ -+static void *c_next(struct seq_file *m, void *v, loff_t *pos) -+{ -+ ++*pos; -+ return c_start(m, pos); -+} -+ -+static void c_stop(struct seq_file *m, void *v) -+{ -+} -+ -+struct seq_operations cpuinfo_op = { -+ .start = c_start, -+ .next = c_next, -+ .stop = c_stop, -+ .show = show_cpuinfo, -+}; -+ -+pte_t * __bad_pagetable(void) -+{ -+ panic("Someone should implement __bad_pagetable"); -+ return(NULL); -+} -+ -+/* Set in linux_main */ -+unsigned long host_task_size; -+unsigned long task_size; -+unsigned long uml_start; -+ -+/* Set in early boot */ -+unsigned long uml_physmem; -+unsigned long uml_reserved; -+unsigned long start_vm; -+unsigned long end_vm; -+int ncpus = 1; -+ -+#ifdef CONFIG_MODE_TT -+/* Pointer set in linux_main, the array itself is private to each thread, -+ * and changed at address space creation time so this poses no concurrency -+ * problems. -+ */ -+static char *argv1_begin = NULL; -+static char *argv1_end = NULL; -+#endif -+ -+/* Set in early boot */ -+static int have_root __initdata = 0; -+long physmem_size = 32 * 1024 * 1024; -+ -+void set_cmdline(char *cmd) -+{ -+#ifdef CONFIG_MODE_TT -+ char *umid, *ptr; -+ -+ if(CHOOSE_MODE(honeypot, 0)) return; -+ -+ umid = get_umid(1); -+ if(umid != NULL){ -+ snprintf(argv1_begin, -+ (argv1_end - argv1_begin) * sizeof(*ptr), -+ "(%s) ", umid); -+ ptr = &argv1_begin[strlen(argv1_begin)]; -+ } -+ else ptr = argv1_begin; -+ -+ snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd); -+ memset(argv1_begin + strlen(argv1_begin), '\0', -+ argv1_end - argv1_begin - strlen(argv1_begin)); -+#endif -+} -+ -+static char *usage_string = -+"User Mode Linux v%s\n" -+" available at http://user-mode-linux.sourceforge.net/\n\n"; -+ -+static int __init uml_version_setup(char *line, int *add) -+{ -+ printf("%s\n", system_utsname.release); -+ exit(0); -+} -+ -+__uml_setup("--version", uml_version_setup, -+"--version\n" -+" Prints the version number of the kernel.\n\n" -+); -+ -+static int __init uml_root_setup(char *line, int *add) -+{ -+ have_root = 1; -+ return 0; -+} -+ -+__uml_setup("root=", uml_root_setup, -+"root=<file containing the root fs>\n" -+" This is actually used by the generic kernel in exactly the same\n" -+" way as in any other kernel. If you configure a number of block\n" -+" devices and want to boot off something other than ubd0, you \n" -+" would use something like:\n" -+" root=/dev/ubd5\n\n" -+); -+ -+#ifdef CONFIG_SMP -+static int __init uml_ncpus_setup(char *line, int *add) -+{ -+ if (!sscanf(line, "%d", &ncpus)) { -+ printf("Couldn't parse [%s]\n", line); -+ return -1; -+ } -+ -+ return 0; -+} -+ -+__uml_setup("ncpus=", uml_ncpus_setup, -+"ncpus=<# of desired CPUs>\n" -+" This tells an SMP kernel how many virtual processors to start.\n\n" -+); -+#endif -+ -+int force_tt = 0; -+ -+#if defined(CONFIG_MODE_TT) && defined(CONFIG_MODE_SKAS) -+#define DEFAULT_TT 0 -+ -+static int __init mode_tt_setup(char *line, int *add) -+{ -+ force_tt = 1; -+ return(0); -+} -+ -+#else -+#ifdef CONFIG_MODE_SKAS -+ -+#define DEFAULT_TT 0 -+ -+static int __init mode_tt_setup(char *line, int *add) -+{ -+ printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n"); -+ return(0); -+} -+ -+#else -+#ifdef CONFIG_MODE_TT -+ -+#define DEFAULT_TT 1 -+ -+static int __init mode_tt_setup(char *line, int *add) -+{ -+ printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n"); -+ return(0); -+} -+ -+#else -+ -+#error Either CONFIG_MODE_TT or CONFIG_MODE_SKAS must be enabled -+ -+#endif -+#endif -+#endif -+ -+__uml_setup("mode=tt", mode_tt_setup, -+"mode=tt\n" -+" When both CONFIG_MODE_TT and CONFIG_MODE_SKAS are enabled, this option\n" -+" forces UML to run in tt (tracing thread) mode. It is not the default\n" -+" because it's slower and less secure than skas mode.\n\n" -+); -+ -+int mode_tt = DEFAULT_TT; -+ -+static int __init Usage(char *line, int *add) -+{ -+ const char **p; -+ -+ printf(usage_string, system_utsname.release); -+ p = &__uml_help_start; -+ while (p < &__uml_help_end) { -+ printf("%s", *p); -+ p++; -+ } -+ exit(0); -+} -+ -+__uml_setup("--help", Usage, -+"--help\n" -+" Prints this message.\n\n" -+); -+ -+static int __init uml_checksetup(char *line, int *add) -+{ -+ struct uml_param *p; -+ -+ p = &__uml_setup_start; -+ while(p < &__uml_setup_end) { -+ int n; -+ -+ n = strlen(p->str); -+ if(!strncmp(line, p->str, n)){ -+ if (p->setup_func(line + n, add)) return 1; -+ } -+ p++; -+ } -+ return 0; -+} -+ -+static void __init uml_postsetup(void) -+{ -+ initcall_t *p; -+ -+ p = &__uml_postsetup_start; -+ while(p < &__uml_postsetup_end){ -+ (*p)(); -+ p++; -+ } -+ return; -+} -+ -+/* Set during early boot */ -+unsigned long brk_start; -+unsigned long end_iomem; -+ -+#define MIN_VMALLOC (32 * 1024 * 1024) -+ -+int linux_main(int argc, char **argv) -+{ -+ unsigned long avail; -+ unsigned long virtmem_size, max_physmem; -+ unsigned int i, add; -+ -+ for (i = 1; i < argc; i++){ -+ if((i == 1) && (argv[i][0] == ' ')) continue; -+ add = 1; -+ uml_checksetup(argv[i], &add); -+ if(add) add_arg(saved_command_line, argv[i]); -+ } -+ if(have_root == 0) add_arg(saved_command_line, DEFAULT_COMMAND_LINE); -+ -+ mode_tt = force_tt ? 1 : !can_do_skas(); -+ uml_start = CHOOSE_MODE_PROC(set_task_sizes_tt, set_task_sizes_skas, 0, -+ &host_task_size, &task_size); -+ -+ brk_start = (unsigned long) sbrk(0); -+ CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start); -+ -+ uml_physmem = uml_start; -+ -+ /* Reserve up to 4M after the current brk */ -+ uml_reserved = ROUND_4M(brk_start) + (1 << 22); -+ -+ setup_machinename(system_utsname.machine); -+ -+#ifdef CONFIG_MODE_TT -+ argv1_begin = argv[1]; -+ argv1_end = &argv[1][strlen(argv[1])]; -+#endif -+ -+ highmem = 0; -+ iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK; -+ max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC; -+ -+ /* Zones have to begin on a 1 << MAX_ORDER page boundary, -+ * so this makes sure that's true for highmem -+ */ -+ max_physmem &= ~((1 << (PAGE_SHIFT + MAX_ORDER)) - 1); -+ if(physmem_size + iomem_size > max_physmem){ -+ highmem = physmem_size + iomem_size - max_physmem; -+ physmem_size -= highmem; -+#ifndef CONFIG_HIGHMEM -+ highmem = 0; -+ printf("CONFIG_HIGHMEM not enabled - physical memory shrunk " -+ "to %ld bytes\n", physmem_size); -+#endif -+ } -+ -+ high_physmem = uml_physmem + physmem_size; -+ end_iomem = high_physmem + iomem_size; -+ high_memory = (void *) end_iomem; -+ -+ start_vm = VMALLOC_START; -+ -+ setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem); -+ if(init_maps(physmem_size, iomem_size, highmem)){ -+ printf("Failed to allocate mem_map for %ld bytes of physical " -+ "memory and %ld bytes of highmem\n", physmem_size, -+ highmem); -+ exit(1); -+ } -+ -+ virtmem_size = physmem_size; -+ avail = get_kmem_end() - start_vm; -+ if(physmem_size > avail) virtmem_size = avail; -+ end_vm = start_vm + virtmem_size; -+ -+ if(virtmem_size < physmem_size) -+ printf("Kernel virtual memory size shrunk to %ld bytes\n", -+ virtmem_size); -+ -+ uml_postsetup(); -+ -+ init_task.thread.kernel_stack = (unsigned long) &init_task + -+ 2 * PAGE_SIZE; -+ -+ task_protections((unsigned long) &init_task); -+ os_flush_stdout(); -+ -+ return(CHOOSE_MODE(start_uml_tt(), start_uml_skas())); -+} -+ -+static int panic_exit(struct notifier_block *self, unsigned long unused1, -+ void *unused2) -+{ -+#ifdef CONFIG_SYSRQ -+ handle_sysrq('p', ¤t->thread.regs, NULL, NULL); -+#endif -+ machine_halt(); -+ return(0); -+} -+ -+static struct notifier_block panic_exit_notifier = { -+ .notifier_call = panic_exit, -+ .next = NULL, -+ .priority = 0 -+}; -+ -+void __init setup_arch(char **cmdline_p) -+{ -+ notifier_chain_register(&panic_notifier_list, &panic_exit_notifier); -+ paging_init(); -+ strcpy(command_line, saved_command_line); -+ *cmdline_p = command_line; -+ setup_hostinfo(); -+} -+ -+void __init check_bugs(void) -+{ -+ arch_check_bugs(); -+ check_ptrace(); -+ check_sigio(); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/umid.c um/arch/um/kernel/umid.c ---- orig/arch/um/kernel/umid.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/umid.c 2004-01-26 10:13:01.000000000 -0500 -@@ -0,0 +1,327 @@ -+/* -+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <stdio.h> -+#include <unistd.h> -+#include <errno.h> -+#include <string.h> -+#include <stdlib.h> -+#include <dirent.h> -+#include <signal.h> -+#include <sys/stat.h> -+#include <sys/param.h> -+#include "user.h" -+#include "umid.h" -+#include "init.h" -+#include "os.h" -+#include "user_util.h" -+#include "choose-mode.h" -+ -+#define UMID_LEN 64 -+#define UML_DIR "~/.uml/" -+ -+/* Changed by set_umid and make_umid, which are run early in boot */ -+static char umid[UMID_LEN] = { 0 }; -+ -+/* Changed by set_uml_dir and make_uml_dir, which are run early in boot */ -+static char *uml_dir = UML_DIR; -+ -+/* Changed by set_umid */ -+static int umid_is_random = 1; -+static int umid_inited = 0; -+ -+static int make_umid(int (*printer)(const char *fmt, ...)); -+ -+static int __init set_umid(char *name, int is_random, -+ int (*printer)(const char *fmt, ...)) -+{ -+ if(umid_inited){ -+ (*printer)("Unique machine name can't be set twice\n"); -+ return(-1); -+ } -+ -+ if(strlen(name) > UMID_LEN - 1) -+ (*printer)("Unique machine name is being truncated to %s " -+ "characters\n", UMID_LEN); -+ strncpy(umid, name, UMID_LEN - 1); -+ umid[UMID_LEN - 1] = '\0'; -+ -+ umid_is_random = is_random; -+ umid_inited = 1; -+ return 0; -+} -+ -+static int __init set_umid_arg(char *name, int *add) -+{ -+ return(set_umid(name, 0, printf)); -+} -+ -+__uml_setup("umid=", set_umid_arg, -+"umid=<name>\n" -+" This is used to assign a unique identity to this UML machine and\n" -+" is used for naming the pid file and management console socket.\n\n" -+); -+ -+int __init umid_file_name(char *name, char *buf, int len) -+{ -+ int n; -+ -+ if(!umid_inited && make_umid(printk)) return(-1); -+ -+ n = strlen(uml_dir) + strlen(umid) + strlen(name) + 1; -+ if(n > len){ -+ printk("umid_file_name : buffer too short\n"); -+ return(-1); -+ } -+ -+ sprintf(buf, "%s%s/%s", uml_dir, umid, name); -+ return(0); -+} -+ -+extern int tracing_pid; -+ -+static int __init create_pid_file(void) -+{ -+ char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; -+ char pid[sizeof("nnnnn\0")]; -+ int fd, n; -+ -+ if(umid_file_name("pid", file, sizeof(file))) return 0; -+ -+ fd = os_open_file(file, of_create(of_excl(of_rdwr(OPENFLAGS()))), -+ 0644); -+ if(fd < 0){ -+ printf("Open of machine pid file \"%s\" failed - " -+ "err = %d\n", file, -fd); -+ return 0; -+ } -+ -+ sprintf(pid, "%d\n", os_getpid()); -+ n = os_write_file(fd, pid, strlen(pid)); -+ if(n != strlen(pid)) -+ printf("Write of pid file failed - err = %d\n", -n); -+ os_close_file(fd); -+ return 0; -+} -+ -+static int actually_do_remove(char *dir) -+{ -+ DIR *directory; -+ struct dirent *ent; -+ int len; -+ char file[256]; -+ -+ directory = opendir(dir); -+ if(directory == NULL){ -+ printk("actually_do_remove : couldn't open directory '%s', " -+ "errno = %d\n", dir, errno); -+ return(1); -+ } -+ while((ent = readdir(directory)) != NULL){ -+ if(!strcmp(ent->d_name, ".") || !strcmp(ent->d_name, "..")) -+ continue; -+ len = strlen(dir) + sizeof("/") + strlen(ent->d_name) + 1; -+ if(len > sizeof(file)){ -+ printk("Not deleting '%s' from '%s' - name too long\n", -+ ent->d_name, dir); -+ continue; -+ } -+ sprintf(file, "%s/%s", dir, ent->d_name); -+ if(unlink(file) < 0){ -+ printk("actually_do_remove : couldn't remove '%s' " -+ "from '%s', errno = %d\n", ent->d_name, dir, -+ errno); -+ return(1); -+ } -+ } -+ if(rmdir(dir) < 0){ -+ printk("actually_do_remove : couldn't rmdir '%s', " -+ "errno = %d\n", dir, errno); -+ return(1); -+ } -+ return(0); -+} -+ -+void remove_umid_dir(void) -+{ -+ char dir[strlen(uml_dir) + UMID_LEN + 1]; -+ if(!umid_inited) return; -+ -+ sprintf(dir, "%s%s", uml_dir, umid); -+ actually_do_remove(dir); -+} -+ -+char *get_umid(int only_if_set) -+{ -+ if(only_if_set && umid_is_random) return(NULL); -+ return(umid); -+} -+ -+int not_dead_yet(char *dir) -+{ -+ char file[strlen(uml_dir) + UMID_LEN + sizeof("/pid\0")]; -+ char pid[sizeof("nnnnn\0")], *end; -+ int dead, fd, p, n; -+ -+ sprintf(file, "%s/pid", dir); -+ dead = 0; -+ fd = os_open_file(file, of_read(OPENFLAGS()), 0); -+ if(fd < 0){ -+ if(fd != -ENOENT){ -+ printk("not_dead_yet : couldn't open pid file '%s', " -+ "err = %d\n", file, -fd); -+ return(1); -+ } -+ dead = 1; -+ } -+ if(fd > 0){ -+ n = os_read_file(fd, pid, sizeof(pid)); -+ if(n < 0){ -+ printk("not_dead_yet : couldn't read pid file '%s', " -+ "err = %d\n", file, -n); -+ return(1); -+ } -+ p = strtoul(pid, &end, 0); -+ if(end == pid){ -+ printk("not_dead_yet : couldn't parse pid file '%s', " -+ "errno = %d\n", file, errno); -+ dead = 1; -+ } -+ if(((kill(p, 0) < 0) && (errno == ESRCH)) || -+ (p == CHOOSE_MODE(tracing_pid, os_getpid()))) -+ dead = 1; -+ } -+ if(!dead) return(1); -+ return(actually_do_remove(dir)); -+} -+ -+static int __init set_uml_dir(char *name, int *add) -+{ -+ if((strlen(name) > 0) && (name[strlen(name) - 1] != '/')){ -+ uml_dir = malloc(strlen(name) + 1); -+ if(uml_dir == NULL){ -+ printf("Failed to malloc uml_dir - error = %d\n", -+ errno); -+ uml_dir = name; -+ /* Return 0 here because do_initcalls doesn't look at -+ * the return value. -+ */ -+ return(0); -+ } -+ sprintf(uml_dir, "%s/", name); -+ } -+ else uml_dir = name; -+ return(0); -+} -+ -+static int __init make_uml_dir(void) -+{ -+ char dir[MAXPATHLEN + 1] = { '\0' }; -+ int len; -+ -+ if(*uml_dir == '~'){ -+ char *home = getenv("HOME"); -+ -+ if(home == NULL){ -+ printf("make_uml_dir : no value in environment for " -+ "$HOME\n"); -+ exit(1); -+ } -+ strncpy(dir, home, sizeof(dir)); -+ uml_dir++; -+ } -+ len = strlen(dir); -+ strncat(dir, uml_dir, sizeof(dir) - len); -+ len = strlen(dir); -+ if((len > 0) && (len < sizeof(dir) - 1) && (dir[len - 1] != '/')){ -+ dir[len] = '/'; -+ dir[len + 1] = '\0'; -+ } -+ -+ uml_dir = malloc(strlen(dir) + 1); -+ if(uml_dir == NULL){ -+ printf("make_uml_dir : malloc failed, errno = %d\n", errno); -+ exit(1); -+ } -+ strcpy(uml_dir, dir); -+ -+ if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){ -+ printf("Failed to mkdir %s - errno = %i\n", uml_dir, errno); -+ return(-1); -+ } -+ return 0; -+} -+ -+static int __init make_umid(int (*printer)(const char *fmt, ...)) -+{ -+ int fd, err; -+ char tmp[strlen(uml_dir) + UMID_LEN + 1]; -+ -+ strncpy(tmp, uml_dir, sizeof(tmp) - 1); -+ tmp[sizeof(tmp) - 1] = '\0'; -+ -+ if(!umid_inited){ -+ strcat(tmp, "XXXXXX"); -+ fd = mkstemp(tmp); -+ if(fd < 0){ -+ (*printer)("make_umid - mkstemp failed, errno = %d\n", -+ errno); -+ return(1); -+ } -+ -+ os_close_file(fd); -+ /* There's a nice tiny little race between this unlink and -+ * the mkdir below. It'd be nice if there were a mkstemp -+ * for directories. -+ */ -+ unlink(tmp); -+ set_umid(&tmp[strlen(uml_dir)], 1, printer); -+ } -+ -+ sprintf(tmp, "%s%s", uml_dir, umid); -+ -+ err = mkdir(tmp, 0777); -+ if(err < 0){ -+ if(errno == EEXIST){ -+ if(not_dead_yet(tmp)){ -+ (*printer)("umid '%s' is in use\n", umid); -+ return(-1); -+ } -+ err = mkdir(tmp, 0777); -+ } -+ } -+ if(err < 0){ -+ (*printer)("Failed to create %s - errno = %d\n", umid, errno); -+ return(-1); -+ } -+ -+ return(0); -+} -+ -+__uml_setup("uml_dir=", set_uml_dir, -+"uml_dir=<directory>\n" -+" The location to place the pid and umid files.\n\n" -+); -+ -+__uml_postsetup(make_uml_dir); -+ -+static int __init make_umid_setup(void) -+{ -+ return(make_umid(printf)); -+} -+ -+__uml_postsetup(make_umid_setup); -+__uml_postsetup(create_pid_file); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/kernel/user_syms.c um/arch/um/kernel/user_syms.c ---- orig/arch/um/kernel/user_syms.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/user_syms.c 2004-01-23 00:44:09.000000000 -0500 -@@ -0,0 +1,118 @@ -+#include <stdio.h> -+#include <unistd.h> -+#include <dirent.h> -+#include <fcntl.h> -+#include <errno.h> -+#include <utime.h> -+#include <string.h> -+#include <sys/stat.h> -+#include <sys/vfs.h> -+#include <sys/ioctl.h> -+#include "user_util.h" -+#include "mem_user.h" -+ -+/* XXX All the __CONFIG_* stuff is broken because this file can't include -+ * config.h -+ */ -+ -+/* Had to steal this from linux/module.h because that file can't be included -+ * since this includes various user-level headers. -+ */ -+ -+struct module_symbol -+{ -+ unsigned long value; -+ const char *name; -+}; -+ -+/* Indirect stringification. */ -+ -+#define __MODULE_STRING_1(x) #x -+#define __MODULE_STRING(x) __MODULE_STRING_1(x) -+ -+#if !defined(__AUTOCONF_INCLUDED__) -+ -+#define __EXPORT_SYMBOL(sym,str) error config_must_be_included_before_module -+#define EXPORT_SYMBOL(var) error config_must_be_included_before_module -+#define EXPORT_SYMBOL_NOVERS(var) error config_must_be_included_before_module -+ -+#elif !defined(__CONFIG_MODULES__) -+ -+#define __EXPORT_SYMBOL(sym,str) -+#define EXPORT_SYMBOL(var) -+#define EXPORT_SYMBOL_NOVERS(var) -+ -+#else -+ -+#define __EXPORT_SYMBOL(sym, str) \ -+const char __kstrtab_##sym[] \ -+__attribute__((section(".kstrtab"))) = str; \ -+const struct module_symbol __ksymtab_##sym \ -+__attribute__((section("__ksymtab"))) = \ -+{ (unsigned long)&sym, __kstrtab_##sym } -+ -+#if defined(__MODVERSIONS__) || !defined(__CONFIG_MODVERSIONS__) -+#define EXPORT_SYMBOL(var) __EXPORT_SYMBOL(var, __MODULE_STRING(var)) -+#else -+#define EXPORT_SYMBOL(var) __EXPORT_SYMBOL(var, __MODULE_STRING(__VERSIONED_SYMBOL(var))) -+#endif -+ -+#define EXPORT_SYMBOL_NOVERS(var) __EXPORT_SYMBOL(var, __MODULE_STRING(var)) -+ -+#endif -+ -+EXPORT_SYMBOL(__errno_location); -+ -+EXPORT_SYMBOL(access); -+EXPORT_SYMBOL(open); -+EXPORT_SYMBOL(open64); -+EXPORT_SYMBOL(close); -+EXPORT_SYMBOL(read); -+EXPORT_SYMBOL(write); -+EXPORT_SYMBOL(dup2); -+EXPORT_SYMBOL(__xstat); -+EXPORT_SYMBOL(__lxstat); -+EXPORT_SYMBOL(__lxstat64); -+EXPORT_SYMBOL(lseek); -+EXPORT_SYMBOL(lseek64); -+EXPORT_SYMBOL(chown); -+EXPORT_SYMBOL(truncate); -+EXPORT_SYMBOL(utime); -+EXPORT_SYMBOL(chmod); -+EXPORT_SYMBOL(rename); -+EXPORT_SYMBOL(__xmknod); -+ -+EXPORT_SYMBOL(symlink); -+EXPORT_SYMBOL(link); -+EXPORT_SYMBOL(unlink); -+EXPORT_SYMBOL(readlink); -+ -+EXPORT_SYMBOL(mkdir); -+EXPORT_SYMBOL(rmdir); -+EXPORT_SYMBOL(opendir); -+EXPORT_SYMBOL(readdir); -+EXPORT_SYMBOL(closedir); -+EXPORT_SYMBOL(seekdir); -+EXPORT_SYMBOL(telldir); -+ -+EXPORT_SYMBOL(ioctl); -+ -+extern ssize_t pread64 (int __fd, void *__buf, size_t __nbytes, -+ __off64_t __offset); -+extern ssize_t pwrite64 (int __fd, __const void *__buf, size_t __n, -+ __off64_t __offset); -+EXPORT_SYMBOL(pread64); -+EXPORT_SYMBOL(pwrite64); -+ -+EXPORT_SYMBOL(statfs); -+EXPORT_SYMBOL(statfs64); -+ -+EXPORT_SYMBOL(memcpy); -+EXPORT_SYMBOL(getuid); -+ -+EXPORT_SYMBOL(memset); -+EXPORT_SYMBOL(strstr); -+EXPORT_SYMBOL(strlen); -+EXPORT_SYMBOL(printf); -+ -+EXPORT_SYMBOL(find_iomem); -diff -Naur -X ../exclude-files orig/arch/um/kernel/user_util.c um/arch/um/kernel/user_util.c ---- orig/arch/um/kernel/user_util.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/kernel/user_util.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,164 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <stdio.h> -+#include <stdlib.h> -+#include <unistd.h> -+#include <limits.h> -+#include <sys/mman.h> -+#include <sys/stat.h> -+#include <sys/ptrace.h> -+#include <sys/utsname.h> -+#include <sys/param.h> -+#include <sys/time.h> -+#include "asm/types.h" -+#include <ctype.h> -+#include <signal.h> -+#include <wait.h> -+#include <errno.h> -+#include <stdarg.h> -+#include <sched.h> -+#include <termios.h> -+#include <string.h> -+#include "user_util.h" -+#include "kern_util.h" -+#include "user.h" -+#include "mem_user.h" -+#include "init.h" -+#include "helper.h" -+#include "uml-config.h" -+ -+#define COMMAND_LINE_SIZE _POSIX_ARG_MAX -+ -+/* Changed in linux_main and setup_arch, which run before SMP is started */ -+char saved_command_line[COMMAND_LINE_SIZE] = { 0 }; -+char command_line[COMMAND_LINE_SIZE] = { 0 }; -+ -+void add_arg(char *cmd_line, char *arg) -+{ -+ if (strlen(cmd_line) + strlen(arg) + 1 > COMMAND_LINE_SIZE) { -+ printf("add_arg: Too much command line!\n"); -+ exit(1); -+ } -+ if(strlen(cmd_line) > 0) strcat(cmd_line, " "); -+ strcat(cmd_line, arg); -+} -+ -+void stop(void) -+{ -+ while(1) sleep(1000000); -+} -+ -+void stack_protections(unsigned long address) -+{ -+ int prot = PROT_READ | PROT_WRITE | PROT_EXEC; -+ -+ if(mprotect((void *) address, page_size(), prot) < 0) -+ panic("protecting stack failed, errno = %d", errno); -+} -+ -+void task_protections(unsigned long address) -+{ -+ unsigned long guard = address + page_size(); -+ unsigned long stack = guard + page_size(); -+ int prot = 0, pages; -+#ifdef notdef -+ if(mprotect((void *) guard, page_size(), prot) < 0) -+ panic("protecting guard page failed, errno = %d", errno); -+#endif -+ pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER) - 2; -+ prot = PROT_READ | PROT_WRITE | PROT_EXEC; -+ if(mprotect((void *) stack, pages * page_size(), prot) < 0) -+ panic("protecting stack failed, errno = %d", errno); -+} -+ -+int wait_for_stop(int pid, int sig, int cont_type, void *relay) -+{ -+ sigset_t *relay_signals = relay; -+ int status, ret; -+ -+ while(1){ -+ ret = waitpid(pid, &status, WUNTRACED); -+ if((ret < 0) || -+ !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){ -+ if(ret < 0){ -+ if(errno == EINTR) continue; -+ printk("wait failed, errno = %d\n", -+ errno); -+ } -+ else if(WIFEXITED(status)) -+ printk("process exited with status %d\n", -+ WEXITSTATUS(status)); -+ else if(WIFSIGNALED(status)) -+ printk("process exited with signal %d\n", -+ WTERMSIG(status)); -+ else if((WSTOPSIG(status) == SIGVTALRM) || -+ (WSTOPSIG(status) == SIGALRM) || -+ (WSTOPSIG(status) == SIGIO) || -+ (WSTOPSIG(status) == SIGPROF) || -+ (WSTOPSIG(status) == SIGCHLD) || -+ (WSTOPSIG(status) == SIGWINCH) || -+ (WSTOPSIG(status) == SIGINT)){ -+ ptrace(cont_type, pid, 0, WSTOPSIG(status)); -+ continue; -+ } -+ else if((relay_signals != NULL) && -+ sigismember(relay_signals, WSTOPSIG(status))){ -+ ptrace(cont_type, pid, 0, WSTOPSIG(status)); -+ continue; -+ } -+ else printk("process stopped with signal %d\n", -+ WSTOPSIG(status)); -+ panic("wait_for_stop failed to wait for %d to stop " -+ "with %d\n", pid, sig); -+ } -+ return(status); -+ } -+} -+ -+int raw(int fd, int complain) -+{ -+ struct termios tt; -+ int err; -+ -+ tcgetattr(fd, &tt); -+ cfmakeraw(&tt); -+ err = tcsetattr(fd, TCSANOW, &tt); -+ if((err < 0) && complain){ -+ printk("tcsetattr failed, errno = %d\n", errno); -+ return(-errno); -+ } -+ return(0); -+} -+ -+void setup_machinename(char *machine_out) -+{ -+ struct utsname host; -+ -+ uname(&host); -+ strcpy(machine_out, host.machine); -+} -+ -+char host_info[(_UTSNAME_LENGTH + 1) * 4 + _UTSNAME_NODENAME_LENGTH + 1]; -+ -+void setup_hostinfo(void) -+{ -+ struct utsname host; -+ -+ uname(&host); -+ sprintf(host_info, "%s %s %s %s %s", host.sysname, host.nodename, -+ host.release, host.version, host.machine); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/link.ld.in um/arch/um/link.ld.in ---- orig/arch/um/link.ld.in 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/link.ld.in 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,94 @@ -+OUTPUT_FORMAT("ELF_FORMAT") -+OUTPUT_ARCH(ELF_ARCH) -+ENTRY(_start) -+ -+SECTIONS -+{ -+ . = START() + SIZEOF_HEADERS; -+ -+ __binary_start = .; -+ifdef(`MODE_TT', ` -+ .thread_private : { -+ __start_thread_private = .; -+ errno = .; -+ . += 4; -+ arch/um/kernel/tt/unmap_fin.o (.data) -+ __end_thread_private = .; -+ } -+ . = ALIGN(4096); -+ .remap : { arch/um/kernel/tt/unmap_fin.o (.text) } -+') -+ . = ALIGN(4096); /* Init code and data */ -+ _stext = .; -+ __init_begin = .; -+ .text.init : { *(.text.init) } -+ . = ALIGN(4096); -+ .text : -+ { -+ *(.text) -+ /* .gnu.warning sections are handled specially by elf32.em. */ -+ *(.gnu.warning) -+ *(.gnu.linkonce.t*) -+ } -+ .fini : { *(.fini) } =0x9090 -+ .rodata : { *(.rodata) *(.gnu.linkonce.r*) } -+ .rodata1 : { *(.rodata1) } -+ _etext = .; -+ PROVIDE (etext = .); -+ -+ . = ALIGN(4096); -+ PROVIDE (_sdata = .); -+ -+include(`arch/um/common.ld.in') -+ -+ .data : -+ { -+ . = ALIGN(KERNEL_STACK_SIZE); /* init_task */ -+ *(.data.init_task) -+ *(.data) -+ *(.gnu.linkonce.d*) -+ CONSTRUCTORS -+ } -+ .data1 : { *(.data1) } -+ .ctors : -+ { -+ *(.ctors) -+ } -+ .dtors : -+ { -+ *(.dtors) -+ } -+ -+ .got : { *(.got.plt) *(.got) } -+ .dynamic : { *(.dynamic) } -+ /* We want the small data sections together, so single-instruction offsets -+ can access them all, and initialized data all before uninitialized, so -+ we can shorten the on-disk segment size. */ -+ .sdata : { *(.sdata) } -+ _edata = .; -+ PROVIDE (edata = .); -+ . = ALIGN(0x1000); -+ .sbss : -+ { -+ __bss_start = .; -+ PROVIDE(_bss_start = .); -+ *(.sbss) -+ *(.scommon) -+ } -+ .bss : -+ { -+ *(.dynbss) -+ *(.bss) -+ *(COMMON) -+ } -+ _end = . ; -+ PROVIDE (end = .); -+ /* Stabs debugging sections. */ -+ .stab 0 : { *(.stab) } -+ .stabstr 0 : { *(.stabstr) } -+ .stab.excl 0 : { *(.stab.excl) } -+ .stab.exclstr 0 : { *(.stab.exclstr) } -+ .stab.index 0 : { *(.stab.index) } -+ .stab.indexstr 0 : { *(.stab.indexstr) } -+ .comment 0 : { *(.comment) } -+} -diff -Naur -X ../exclude-files orig/arch/um/main.c um/arch/um/main.c ---- orig/arch/um/main.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/main.c 2004-01-29 00:48:42.000000000 -0500 -@@ -0,0 +1,199 @@ -+/* -+ * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <unistd.h> -+#include <stdio.h> -+#include <stdlib.h> -+#include <string.h> -+#include <signal.h> -+#include <errno.h> -+#include <sys/resource.h> -+#include <sys/mman.h> -+#include <sys/user.h> -+#include <asm/page.h> -+#include "user_util.h" -+#include "kern_util.h" -+#include "mem_user.h" -+#include "signal_user.h" -+#include "user.h" -+#include "init.h" -+#include "mode.h" -+#include "choose-mode.h" -+#include "uml-config.h" -+ -+/* Set in set_stklim, which is called from main and __wrap_malloc. -+ * __wrap_malloc only calls it if main hasn't started. -+ */ -+unsigned long stacksizelim; -+ -+/* Set in main */ -+char *linux_prog; -+ -+#define PGD_BOUND (4 * 1024 * 1024) -+#define STACKSIZE (8 * 1024 * 1024) -+#define THREAD_NAME_LEN (256) -+ -+static void set_stklim(void) -+{ -+ struct rlimit lim; -+ -+ if(getrlimit(RLIMIT_STACK, &lim) < 0){ -+ perror("getrlimit"); -+ exit(1); -+ } -+ if((lim.rlim_cur == RLIM_INFINITY) || (lim.rlim_cur > STACKSIZE)){ -+ lim.rlim_cur = STACKSIZE; -+ if(setrlimit(RLIMIT_STACK, &lim) < 0){ -+ perror("setrlimit"); -+ exit(1); -+ } -+ } -+ stacksizelim = (lim.rlim_cur + PGD_BOUND - 1) & ~(PGD_BOUND - 1); -+} -+ -+static __init void do_uml_initcalls(void) -+{ -+ initcall_t *call; -+ -+ call = &__uml_initcall_start; -+ while (call < &__uml_initcall_end){; -+ (*call)(); -+ call++; -+ } -+} -+ -+static void last_ditch_exit(int sig) -+{ -+ CHOOSE_MODE(kmalloc_ok = 0, (void) 0); -+ signal(SIGINT, SIG_DFL); -+ signal(SIGTERM, SIG_DFL); -+ signal(SIGHUP, SIG_DFL); -+ uml_cleanup(); -+ exit(1); -+} -+ -+extern int uml_exitcode; -+ -+int main(int argc, char **argv, char **envp) -+{ -+ char **new_argv; -+ sigset_t mask; -+ int ret, i; -+ -+ /* Enable all signals except SIGIO - in some environments, we can -+ * enter with some signals blocked -+ */ -+ -+ sigemptyset(&mask); -+ sigaddset(&mask, SIGIO); -+ if(sigprocmask(SIG_SETMASK, &mask, NULL) < 0){ -+ perror("sigprocmask"); -+ exit(1); -+ } -+ -+#ifdef UML_CONFIG_MODE_TT -+ /* Allocate memory for thread command lines */ -+ if(argc < 2 || strlen(argv[1]) < THREAD_NAME_LEN - 1){ -+ -+ char padding[THREAD_NAME_LEN] = { -+ [ 0 ... THREAD_NAME_LEN - 2] = ' ', '\0' -+ }; -+ -+ new_argv = malloc((argc + 2) * sizeof(char*)); -+ if(!new_argv) { -+ perror("Allocating extended argv"); -+ exit(1); -+ } -+ -+ new_argv[0] = argv[0]; -+ new_argv[1] = padding; -+ -+ for(i = 2; i <= argc; i++) -+ new_argv[i] = argv[i - 1]; -+ new_argv[argc + 1] = NULL; -+ -+ execvp(new_argv[0], new_argv); -+ perror("execing with extended args"); -+ exit(1); -+ } -+#endif -+ -+ linux_prog = argv[0]; -+ -+ set_stklim(); -+ -+ new_argv = malloc((argc + 1) * sizeof(char *)); -+ if(new_argv == NULL){ -+ perror("Mallocing argv"); -+ exit(1); -+ } -+ for(i=0;i<argc;i++){ -+ new_argv[i] = strdup(argv[i]); -+ if(new_argv[i] == NULL){ -+ perror("Mallocing an arg"); -+ exit(1); -+ } -+ } -+ new_argv[argc] = NULL; -+ -+ set_handler(SIGINT, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1); -+ set_handler(SIGTERM, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1); -+ set_handler(SIGHUP, last_ditch_exit, SA_ONESHOT | SA_NODEFER, -1); -+ -+ do_uml_initcalls(); -+ ret = linux_main(argc, argv); -+ -+ /* Reboot */ -+ if(ret){ -+ printf("\n"); -+ -+ execvp(new_argv[0], new_argv); -+ perror("Failed to exec kernel"); -+ ret = 1; -+ } -+ printf("\n"); -+ return(uml_exitcode); -+} -+ -+#define CAN_KMALLOC() \ -+ (kmalloc_ok && CHOOSE_MODE((getpid() != tracing_pid), 1)) -+ -+extern void *__real_malloc(int); -+ -+void *__wrap_malloc(int size) -+{ -+ if(CAN_KMALLOC()) -+ return(um_kmalloc(size)); -+ else -+ return(__real_malloc(size)); -+} -+ -+void *__wrap_calloc(int n, int size) -+{ -+ void *ptr = __wrap_malloc(n * size); -+ -+ if(ptr == NULL) return(NULL); -+ memset(ptr, 0, n * size); -+ return(ptr); -+} -+ -+extern void __real_free(void *); -+ -+void __wrap_free(void *ptr) -+{ -+ if(CAN_KMALLOC()) kfree(ptr); -+ else __real_free(ptr); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/Makefile um/arch/um/Makefile ---- orig/arch/um/Makefile 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/Makefile 2004-02-14 06:26:41.000000000 -0500 -@@ -0,0 +1,174 @@ -+# -+# Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+# Licensed under the GPL -+# -+ -+OS := $(shell uname -s) -+ -+ARCH_DIR = arch/um -+ -+core-y := kernel sys-$(SUBARCH) os-$(OS) -+drivers-y := fs drivers -+subdir-y := $(core-y) $(drivers-y) -+SUBDIRS += $(foreach dir,$(subdir-y),$(ARCH_DIR)/$(dir)) -+ -+CORE_FILES += $(foreach dir,$(core-y),$(ARCH_DIR)/$(dir)/built-in.o) -+DRIVERS += $(foreach dir,$(drivers-y),$(ARCH_DIR)/$(dir)/built-in.o) -+ -+include $(ARCH_DIR)/Makefile-$(SUBARCH) -+include $(ARCH_DIR)/Makefile-os-$(OS) -+ -+MAKEFILE-$(CONFIG_MODE_TT) += Makefile-tt -+MAKEFILE-$(CONFIG_MODE_SKAS) += Makefile-skas -+ -+ifneq ($(MAKEFILE-y),) -+ include $(addprefix $(ARCH_DIR)/,$(MAKEFILE-y)) -+endif -+ -+EXTRAVERSION := $(EXTRAVERSION)-1um -+ -+include/linux/version.h: arch/$(ARCH)/Makefile -+ -+# Recalculate MODLIB to reflect the EXTRAVERSION changes (via KERNELRELEASE) -+# The way the toplevel Makefile is written EXTRAVERSION is not supposed -+# to be changed outside the toplevel Makefile, but recalculating MODLIB is -+# a sufficient workaround until we no longer need architecture dependent -+# EXTRAVERSION... -+MODLIB := $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE) -+ -+ifeq ($(CONFIG_DEBUGSYM),y) -+CFLAGS := $(subst -fomit-frame-pointer,,$(CFLAGS)) -+endif -+ -+CFLAGS-$(CONFIG_DEBUGSYM) += -g -+ -+ARCH_INCLUDE = -I$(TOPDIR)/$(ARCH_DIR)/include -+ -+# -Derrno=kernel_errno - This turns all kernel references to errno into -+# kernel_errno to separate them from the libc errno. This allows -fno-common -+# in CFLAGS. Otherwise, it would cause ld to complain about the two different -+# errnos. -+ -+CFLAGS += $(ARCH_CFLAGS) $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \ -+ -D_LARGEFILE64_SOURCE $(ARCH_INCLUDE) -Derrno=kernel_errno \ -+ $(MODE_INCLUDE) -+ -+LINKFLAGS += -r -+ -+LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc -+ -+# These are needed for clean and mrproper, since in that case .config is not -+# included; the values here are meaningless -+ -+CONFIG_NEST_LEVEL ?= 0 -+CONFIG_KERNEL_HALF_GIGS ?= 0 -+ -+SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000) -+ -+# These aren't in Makefile-tt because they are needed in the !CONFIG_MODE_TT + -+# CONFIG_MODE_SKAS + CONFIG_STATIC_LINK case. -+ -+LINK_TT = -static -+LD_SCRIPT_TT := link.ld -+ -+ifeq ($(CONFIG_STATIC_LINK),y) -+ LINK-y += $(LINK_TT) -+ LD_SCRIPT-y := $(LD_SCRIPT_TT) -+else -+ifeq ($(CONFIG_MODE_TT),y) -+ LINK-y += $(LINK_TT) -+ LD_SCRIPT-y := $(LD_SCRIPT_TT) -+else -+ifeq ($(CONFIG_MODE_SKAS),y) -+ LINK-y += $(LINK_SKAS) -+ LD_SCRIPT-y := $(LD_SCRIPT_SKAS) -+endif -+endif -+endif -+ -+LD_SCRIPT-y := $(ARCH_DIR)/$(LD_SCRIPT-y) -+M4_MODE_TT := $(shell [ "$(CONFIG_MODE_TT)" = "y" ] && echo -DMODE_TT) -+ -+$(LD_SCRIPT-y): $(LD_SCRIPT-y).in -+ pages=$$(( 1 << $(CONFIG_KERNEL_STACK_ORDER) )) ; \ -+ m4 -DSTART=$$(($(TOP_ADDR) - $(SIZE))) -DELF_ARCH=$(ELF_ARCH) \ -+ -DELF_FORMAT=$(ELF_FORMAT) $(M4_MODE_TT) \ -+ -DKERNEL_STACK_SIZE=$$(( 4096 * $$pages )) $< > $@ -+ -+SYMLINK_HEADERS = archparam.h system.h sigcontext.h processor.h ptrace.h \ -+ arch-signal.h -+SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header)) -+ -+ARCH_SYMLINKS = include/asm-um/arch arch/um/include/sysdep arch/um/os \ -+ $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h -+ -+ifeq ($(CONFIG_MODE_SKAS), y) -+$(SYS_HEADERS) : $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h -+endif -+ -+GEN_HEADERS += $(ARCH_DIR)/include/task.h $(ARCH_DIR)/include/kern_constants.h -+ -+setup: $(ARCH_SYMLINKS) $(SYS_HEADERS) $(GEN_HEADERS) -+ -+linux: setup $(ARCH_DIR)/main.o vmlinux $(LD_SCRIPT-y) -+ mv vmlinux vmlinux.o -+ $(CC) -Wl,-T,$(LD_SCRIPT-y) $(LINK-y) $(LINK_WRAPS) \ -+ -o linux $(ARCH_DIR)/main.o vmlinux.o -L/usr/lib -lutil -+ -+USER_CFLAGS := $(patsubst -I%,,$(CFLAGS)) -+USER_CFLAGS := $(patsubst -Derrno=kernel_errno,,$(USER_CFLAGS)) -+USER_CFLAGS := $(patsubst -D__KERNEL__,,$(USER_CFLAGS)) $(ARCH_INCLUDE) \ -+ $(MODE_INCLUDE) -+ -+# To get a definition of F_SETSIG -+USER_CFLAGS += -D_GNU_SOURCE -+ -+CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/link.ld $(ARCH_DIR)/dyn_link.ld \ -+ $(GEN_HEADERS) $(ARCH_DIR)/include/uml-config.h -+ -+$(ARCH_DIR)/main.o: $(ARCH_DIR)/main.c -+ $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $< -+ -+archmrproper: -+ rm -f $(SYMLINK_HEADERS) $(ARCH_SYMLINKS) include/asm \ -+ $(LD_SCRIPT) $(addprefix $(ARCH_DIR)/kernel/,$(KERN_SYMLINKS)) -+ -+archclean: sysclean -+ find . \( -name '*.bb' -o -name '*.bbg' -o -name '*.da' \ -+ -o -name '*.gcov' \) -type f -print | xargs rm -f -+ cd $(ARCH_DIR) ; \ -+ for dir in $(subdir-y) util ; do $(MAKE) -C $$dir clean; done -+ -+archdep: -+ -+$(SYMLINK_HEADERS): -+ cd $(TOPDIR)/$(dir $@) ; \ -+ ln -sf $(basename $(notdir $@))-$(SUBARCH)$(suffix $@) $(notdir $@) -+ -+include/asm-um/arch: -+ cd $(TOPDIR)/include/asm-um && ln -sf ../asm-$(SUBARCH) arch -+ -+arch/um/include/sysdep: -+ cd $(TOPDIR)/arch/um/include && ln -sf sysdep-$(SUBARCH) sysdep -+ -+arch/um/os: -+ cd $(ARCH_DIR) && ln -sf os-$(OS) os -+ -+$(ARCH_DIR)/include/task.h : $(ARCH_DIR)/util/mk_task -+ $< > $@ -+ -+$(ARCH_DIR)/include/kern_constants.h : $(ARCH_DIR)/util/mk_constants -+ $< > $@ -+ -+$(ARCH_DIR)/include/uml-config.h : $(TOPDIR)/include/linux/autoconf.h -+ sed 's/ CONFIG/ UML_CONFIG/' $(TOPDIR)/include/linux/autoconf.h > $@ -+ -+$(ARCH_DIR)/util/mk_task : $(ARCH_DIR)/util/mk_task_user.c \ -+ $(ARCH_DIR)/util/mk_task_kern.c $(SYS_HEADERS) -+ $(MAKE) $(MFLAGS) -C $(ARCH_DIR)/util mk_task -+ -+$(ARCH_DIR)/util/mk_constants : $(ARCH_DIR)/util/mk_constants_user.c \ -+ $(ARCH_DIR)/util/mk_constants_kern.c -+ $(MAKE) $(MFLAGS) -C $(ARCH_DIR)/util mk_constants -+ -+export SUBARCH USER_CFLAGS OS -diff -Naur -X ../exclude-files orig/arch/um/Makefile-i386 um/arch/um/Makefile-i386 ---- orig/arch/um/Makefile-i386 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/Makefile-i386 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,35 @@ -+ifeq ($(CONFIG_HOST_2G_2G), y) -+TOP_ADDR = 0x80000000 -+else -+TOP_ADDR = 0xc0000000 -+endif -+ -+ARCH_CFLAGS = -U__$(SUBARCH)__ -U$(SUBARCH) -DUM_FASTCALL -+ELF_ARCH = $(SUBARCH) -+ELF_FORMAT = elf32-$(SUBARCH) -+ -+I386_H = $(ARCH_DIR)/include/sysdep-i386 -+SYS = $(ARCH_DIR)/sys-i386 -+UTIL = $(SYS)/util -+SUBDIRS += $(UTIL) -+ -+SYS_HEADERS = $(I386_H)/sc.h $(I386_H)/thread.h -+ -+$(I386_H)/sc.h : $(UTIL)/mk_sc -+ $(UTIL)/mk_sc > $@ -+ -+$(I386_H)/thread.h : $(UTIL)/mk_thread -+ $(UTIL)/mk_thread > $@ -+ -+$(UTIL)/mk_sc : $(UTIL)/mk_sc.c -+ $(MAKE) -C $(UTIL) mk_sc -+ -+$(UTIL)/mk_thread : $(UTIL)/mk_thread_user.c $(UTIL)/mk_thread_kern.c \ -+ $(I386_H)/sc.h -+ $(MAKE) -C $(UTIL) mk_thread -+ -+sysclean : -+ rm -f $(SYS_HEADERS) -+ $(MAKE) -C $(UTIL) clean -+ $(MAKE) -C $(SYS) clean -+ -diff -Naur -X ../exclude-files orig/arch/um/Makefile-ia64 um/arch/um/Makefile-ia64 ---- orig/arch/um/Makefile-ia64 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/Makefile-ia64 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1 @@ -+START_ADDR = 0x1000000000000000 -diff -Naur -X ../exclude-files orig/arch/um/Makefile-os-Linux um/arch/um/Makefile-os-Linux ---- orig/arch/um/Makefile-os-Linux 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/Makefile-os-Linux 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,7 @@ -+# -+# Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+# Licensed under the GPL -+# -+ -+SUBDIRS += $(ARCH_DIR)/os-$(OS)/drivers -+DRIVERS += $(ARCH_DIR)/os-$(OS)/drivers/drivers.o -diff -Naur -X ../exclude-files orig/arch/um/Makefile-ppc um/arch/um/Makefile-ppc ---- orig/arch/um/Makefile-ppc 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/Makefile-ppc 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,9 @@ -+ifeq ($(CONFIG_HOST_2G_2G), y) -+START_ADDR = 0x80000000 -+else -+START_ADDR = 0xc0000000 -+endif -+ARCH_CFLAGS = -U__powerpc__ -D__UM_PPC__ -+ -+# The arch is ppc, but the elf32 name is powerpc -+ELF_SUBARCH = powerpc -diff -Naur -X ../exclude-files orig/arch/um/Makefile-skas um/arch/um/Makefile-skas ---- orig/arch/um/Makefile-skas 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/Makefile-skas 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,20 @@ -+# -+# Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+# Licensed under the GPL -+# -+ -+PROFILE += -pg -+ -+CFLAGS-$(CONFIG_GCOV) += -fprofile-arcs -ftest-coverage -+CFLAGS-$(CONFIG_GPROF) += $(PROFILE) -+LINK-$(CONFIG_GPROF) += $(PROFILE) -+ -+MODE_INCLUDE += -I$(TOPDIR)/$(ARCH_DIR)/kernel/skas/include -+ -+LINK_SKAS = -Wl,-rpath,/lib -+LD_SCRIPT_SKAS = dyn_link.ld -+ -+GEN_HEADERS += $(ARCH_DIR)/kernel/skas/include/skas_ptregs.h -+ -+$(ARCH_DIR)/kernel/skas/include/skas_ptregs.h : -+ $(MAKE) -C $(ARCH_DIR)/kernel/skas include/skas_ptregs.h -diff -Naur -X ../exclude-files orig/arch/um/Makefile-tt um/arch/um/Makefile-tt ---- orig/arch/um/Makefile-tt 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/Makefile-tt 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,7 @@ -+# -+# Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+# Licensed under the GPL -+# -+ -+MODE_INCLUDE += -I$(TOPDIR)/$(ARCH_DIR)/kernel/tt/include -+ -diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/etap.h um/arch/um/os-Linux/drivers/etap.h ---- orig/arch/um/os-Linux/drivers/etap.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/os-Linux/drivers/etap.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,27 @@ -+/* -+ * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "net_user.h" -+ -+struct ethertap_data { -+ char *dev_name; -+ char *gate_addr; -+ int data_fd; -+ int control_fd; -+ void *dev; -+}; -+ -+extern struct net_user_info ethertap_user_info; -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/ethertap_kern.c um/arch/um/os-Linux/drivers/ethertap_kern.c ---- orig/arch/um/os-Linux/drivers/ethertap_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/os-Linux/drivers/ethertap_kern.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,122 @@ -+/* -+ * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and -+ * James Leu (jleu@mindspring.net). -+ * Copyright (C) 2001 by various other people who didn't put their name here. -+ * Licensed under the GPL. -+ */ -+ -+#include "linux/init.h" -+#include "linux/netdevice.h" -+#include "linux/etherdevice.h" -+#include "linux/init.h" -+#include "net_kern.h" -+#include "net_user.h" -+#include "etap.h" -+ -+struct ethertap_init { -+ char *dev_name; -+ char *gate_addr; -+}; -+ -+static void etap_init(struct net_device *dev, void *data) -+{ -+ struct uml_net_private *pri; -+ struct ethertap_data *epri; -+ struct ethertap_init *init = data; -+ -+ init_etherdev(dev, 0); -+ pri = dev->priv; -+ epri = (struct ethertap_data *) pri->user; -+ *epri = ((struct ethertap_data) -+ { .dev_name = init->dev_name, -+ .gate_addr = init->gate_addr, -+ .data_fd = -1, -+ .control_fd = -1, -+ .dev = dev }); -+ -+ printk("ethertap backend - %s", epri->dev_name); -+ if(epri->gate_addr != NULL) -+ printk(", IP = %s", epri->gate_addr); -+ printk("\n"); -+} -+ -+static int etap_read(int fd, struct sk_buff **skb, struct uml_net_private *lp) -+{ -+ int len; -+ -+ *skb = ether_adjust_skb(*skb, ETH_HEADER_ETHERTAP); -+ if(*skb == NULL) return(-ENOMEM); -+ len = net_recvfrom(fd, (*skb)->mac.raw, -+ (*skb)->dev->mtu + 2 * ETH_HEADER_ETHERTAP); -+ if(len <= 0) return(len); -+ skb_pull(*skb, 2); -+ len -= 2; -+ return(len); -+} -+ -+static int etap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp) -+{ -+ if(skb_headroom(*skb) < 2){ -+ struct sk_buff *skb2; -+ -+ skb2 = skb_realloc_headroom(*skb, 2); -+ dev_kfree_skb(*skb); -+ if (skb2 == NULL) return(-ENOMEM); -+ *skb = skb2; -+ } -+ skb_push(*skb, 2); -+ return(net_send(fd, (*skb)->data, (*skb)->len)); -+} -+ -+struct net_kern_info ethertap_kern_info = { -+ .init = etap_init, -+ .protocol = eth_protocol, -+ .read = etap_read, -+ .write = etap_write, -+}; -+ -+int ethertap_setup(char *str, char **mac_out, void *data) -+{ -+ struct ethertap_init *init = data; -+ -+ *init = ((struct ethertap_init) -+ { .dev_name = NULL, -+ .gate_addr = NULL }); -+ if(tap_setup_common(str, "ethertap", &init->dev_name, mac_out, -+ &init->gate_addr)) -+ return(0); -+ if(init->dev_name == NULL){ -+ printk("ethertap_setup : Missing tap device name\n"); -+ return(0); -+ } -+ -+ return(1); -+} -+ -+static struct transport ethertap_transport = { -+ .list = LIST_HEAD_INIT(ethertap_transport.list), -+ .name = "ethertap", -+ .setup = ethertap_setup, -+ .user = ðertap_user_info, -+ .kern = ðertap_kern_info, -+ .private_size = sizeof(struct ethertap_data), -+}; -+ -+static int register_ethertap(void) -+{ -+ register_transport(ðertap_transport); -+ return(1); -+} -+ -+__initcall(register_ethertap); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/ethertap_user.c um/arch/um/os-Linux/drivers/ethertap_user.c ---- orig/arch/um/os-Linux/drivers/ethertap_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/os-Linux/drivers/ethertap_user.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,238 @@ -+/* -+ * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and -+ * James Leu (jleu@mindspring.net). -+ * Copyright (C) 2001 by various other people who didn't put their name here. -+ * Licensed under the GPL. -+ */ -+ -+#include <stdio.h> -+#include <unistd.h> -+#include <stddef.h> -+#include <stdlib.h> -+#include <sys/errno.h> -+#include <sys/socket.h> -+#include <sys/wait.h> -+#include <sys/un.h> -+#include <net/if.h> -+#include "user.h" -+#include "kern_util.h" -+#include "net_user.h" -+#include "etap.h" -+#include "helper.h" -+#include "os.h" -+ -+#define MAX_PACKET ETH_MAX_PACKET -+ -+void etap_user_init(void *data, void *dev) -+{ -+ struct ethertap_data *pri = data; -+ -+ pri->dev = dev; -+} -+ -+struct addr_change { -+ enum { ADD_ADDR, DEL_ADDR } what; -+ unsigned char addr[4]; -+ unsigned char netmask[4]; -+}; -+ -+static void etap_change(int op, unsigned char *addr, unsigned char *netmask, -+ int fd) -+{ -+ struct addr_change change; -+ void *output; -+ int n; -+ -+ change.what = op; -+ memcpy(change.addr, addr, sizeof(change.addr)); -+ memcpy(change.netmask, netmask, sizeof(change.netmask)); -+ n = os_write_file(fd, &change, sizeof(change)); -+ if(n != sizeof(change)) -+ printk("etap_change - request failed, err = %d\n", -n); -+ output = um_kmalloc(page_size()); -+ if(output == NULL) -+ printk("etap_change : Failed to allocate output buffer\n"); -+ read_output(fd, output, page_size()); -+ if(output != NULL){ -+ printk("%s", output); -+ kfree(output); -+ } -+} -+ -+static void etap_open_addr(unsigned char *addr, unsigned char *netmask, -+ void *arg) -+{ -+ etap_change(ADD_ADDR, addr, netmask, *((int *) arg)); -+} -+ -+static void etap_close_addr(unsigned char *addr, unsigned char *netmask, -+ void *arg) -+{ -+ etap_change(DEL_ADDR, addr, netmask, *((int *) arg)); -+} -+ -+struct etap_pre_exec_data { -+ int control_remote; -+ int control_me; -+ int data_me; -+}; -+ -+static void etap_pre_exec(void *arg) -+{ -+ struct etap_pre_exec_data *data = arg; -+ -+ dup2(data->control_remote, 1); -+ os_close_file(data->data_me); -+ os_close_file(data->control_me); -+} -+ -+static int etap_tramp(char *dev, char *gate, int control_me, -+ int control_remote, int data_me, int data_remote) -+{ -+ struct etap_pre_exec_data pe_data; -+ int pid, status, err, n; -+ char version_buf[sizeof("nnnnn\0")]; -+ char data_fd_buf[sizeof("nnnnnn\0")]; -+ char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")]; -+ char *setup_args[] = { "uml_net", version_buf, "ethertap", dev, -+ data_fd_buf, gate_buf, NULL }; -+ char *nosetup_args[] = { "uml_net", version_buf, "ethertap", -+ dev, data_fd_buf, NULL }; -+ char **args, c; -+ -+ sprintf(data_fd_buf, "%d", data_remote); -+ sprintf(version_buf, "%d", UML_NET_VERSION); -+ if(gate != NULL){ -+ strcpy(gate_buf, gate); -+ args = setup_args; -+ } -+ else args = nosetup_args; -+ -+ err = 0; -+ pe_data.control_remote = control_remote; -+ pe_data.control_me = control_me; -+ pe_data.data_me = data_me; -+ pid = run_helper(etap_pre_exec, &pe_data, args, NULL); -+ -+ if(pid < 0) err = pid; -+ os_close_file(data_remote); -+ os_close_file(control_remote); -+ n = os_read_file(control_me, &c, sizeof(c)); -+ if(n != sizeof(c)){ -+ printk("etap_tramp : read of status failed, err = %d\n", -n); -+ return(-EINVAL); -+ } -+ if(c != 1){ -+ printk("etap_tramp : uml_net failed\n"); -+ err = -EINVAL; -+ if(waitpid(pid, &status, 0) < 0) -+ err = -errno; -+ else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1)) -+ printk("uml_net didn't exit with status 1\n"); -+ } -+ return(err); -+} -+ -+static int etap_open(void *data) -+{ -+ struct ethertap_data *pri = data; -+ char *output; -+ int data_fds[2], control_fds[2], err, output_len; -+ -+ err = tap_open_common(pri->dev, pri->gate_addr); -+ if(err) return(err); -+ -+ err = os_pipe(data_fds, 0, 0); -+ if(err < 0){ -+ printk("data os_pipe failed - err = %d\n", -err); -+ return(err); -+ } -+ -+ err = os_pipe(control_fds, 1, 0); -+ if(err < 0){ -+ printk("control os_pipe failed - err = %d\n", -err); -+ return(err); -+ } -+ -+ err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0], -+ control_fds[1], data_fds[0], data_fds[1]); -+ output_len = page_size(); -+ output = um_kmalloc(output_len); -+ read_output(control_fds[0], output, output_len); -+ -+ if(output == NULL) -+ printk("etap_open : failed to allocate output buffer\n"); -+ else { -+ printk("%s", output); -+ kfree(output); -+ } -+ -+ if(err < 0){ -+ printk("etap_tramp failed - err = %d\n", -err); -+ return(err); -+ } -+ -+ pri->data_fd = data_fds[0]; -+ pri->control_fd = control_fds[0]; -+ iter_addresses(pri->dev, etap_open_addr, &pri->control_fd); -+ return(data_fds[0]); -+} -+ -+static void etap_close(int fd, void *data) -+{ -+ struct ethertap_data *pri = data; -+ -+ iter_addresses(pri->dev, etap_close_addr, &pri->control_fd); -+ os_close_file(fd); -+ os_shutdown_socket(pri->data_fd, 1, 1); -+ os_close_file(pri->data_fd); -+ pri->data_fd = -1; -+ os_close_file(pri->control_fd); -+ pri->control_fd = -1; -+} -+ -+static int etap_set_mtu(int mtu, void *data) -+{ -+ return(mtu); -+} -+ -+static void etap_add_addr(unsigned char *addr, unsigned char *netmask, -+ void *data) -+{ -+ struct ethertap_data *pri = data; -+ -+ tap_check_ips(pri->gate_addr, addr); -+ if(pri->control_fd == -1) return; -+ etap_open_addr(addr, netmask, &pri->control_fd); -+} -+ -+static void etap_del_addr(unsigned char *addr, unsigned char *netmask, -+ void *data) -+{ -+ struct ethertap_data *pri = data; -+ -+ if(pri->control_fd == -1) return; -+ etap_close_addr(addr, netmask, &pri->control_fd); -+} -+ -+struct net_user_info ethertap_user_info = { -+ .init = etap_user_init, -+ .open = etap_open, -+ .close = etap_close, -+ .remove = NULL, -+ .set_mtu = etap_set_mtu, -+ .add_address = etap_add_addr, -+ .delete_address = etap_del_addr, -+ .max_packet = MAX_PACKET - ETH_HEADER_ETHERTAP -+}; -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/Makefile um/arch/um/os-Linux/drivers/Makefile ---- orig/arch/um/os-Linux/drivers/Makefile 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/os-Linux/drivers/Makefile 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,31 @@ -+# -+# Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com) -+# Licensed under the GPL -+# -+ -+O_TARGET := drivers.o -+ -+list-multi := tuntap.o ethertap.o -+ -+ethertap-objs := ethertap_kern.o ethertap_user.o -+tuntap-objs := tuntap_kern.o tuntap_user.o -+ -+obj-y = -+obj-$(CONFIG_UML_NET_ETHERTAP) += ethertap.o -+obj-$(CONFIG_UML_NET_TUNTAP) += tuntap.o -+ -+USER_SINGLE_OBJS = $(foreach f,$(patsubst %.o,%,$(obj-y)),$($(f)-objs)) -+ -+USER_OBJS = $(filter %_user.o,$(obj-y) $(USER_SINGLE_OBJS)) -+ -+include $(TOPDIR)/Rules.make -+ -+$(USER_OBJS) : %.o: %.c -+ $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $< -+ -+ethertap.o : $(ethertap-objs) -+ -+tuntap.o : $(tuntap-objs) -+ -+$(list-multi) : # This doesn't work, but should : '%.o : $(%-objs)' -+ $(LD) $(LD_RFLAG) -r -o $@ $($(patsubst %.o,%,$@)-objs) -diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/tuntap.h um/arch/um/os-Linux/drivers/tuntap.h ---- orig/arch/um/os-Linux/drivers/tuntap.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/os-Linux/drivers/tuntap.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,32 @@ -+/* -+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __UM_TUNTAP_H -+#define __UM_TUNTAP_H -+ -+#include "net_user.h" -+ -+struct tuntap_data { -+ char *dev_name; -+ int fixed_config; -+ char *gate_addr; -+ int fd; -+ void *dev; -+}; -+ -+extern struct net_user_info tuntap_user_info; -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/tuntap_kern.c um/arch/um/os-Linux/drivers/tuntap_kern.c ---- orig/arch/um/os-Linux/drivers/tuntap_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/os-Linux/drivers/tuntap_kern.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,105 @@ -+/* -+ * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/stddef.h" -+#include "linux/netdevice.h" -+#include "linux/etherdevice.h" -+#include "linux/skbuff.h" -+#include "linux/init.h" -+#include "asm/errno.h" -+#include "net_kern.h" -+#include "net_user.h" -+#include "tuntap.h" -+ -+struct tuntap_init { -+ char *dev_name; -+ char *gate_addr; -+}; -+ -+static void tuntap_init(struct net_device *dev, void *data) -+{ -+ struct uml_net_private *pri; -+ struct tuntap_data *tpri; -+ struct tuntap_init *init = data; -+ -+ init_etherdev(dev, 0); -+ pri = dev->priv; -+ tpri = (struct tuntap_data *) pri->user; -+ *tpri = ((struct tuntap_data) -+ { .dev_name = init->dev_name, -+ .fixed_config = (init->dev_name != NULL), -+ .gate_addr = init->gate_addr, -+ .fd = -1, -+ .dev = dev }); -+ printk("TUN/TAP backend - "); -+ if(tpri->gate_addr != NULL) -+ printk("IP = %s", tpri->gate_addr); -+ printk("\n"); -+} -+ -+static int tuntap_read(int fd, struct sk_buff **skb, -+ struct uml_net_private *lp) -+{ -+ *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); -+ if(*skb == NULL) return(-ENOMEM); -+ return(net_read(fd, (*skb)->mac.raw, -+ (*skb)->dev->mtu + ETH_HEADER_OTHER)); -+} -+ -+static int tuntap_write(int fd, struct sk_buff **skb, -+ struct uml_net_private *lp) -+{ -+ return(net_write(fd, (*skb)->data, (*skb)->len)); -+} -+ -+struct net_kern_info tuntap_kern_info = { -+ .init = tuntap_init, -+ .protocol = eth_protocol, -+ .read = tuntap_read, -+ .write = tuntap_write, -+}; -+ -+int tuntap_setup(char *str, char **mac_out, void *data) -+{ -+ struct tuntap_init *init = data; -+ -+ *init = ((struct tuntap_init) -+ { .dev_name = NULL, -+ .gate_addr = NULL }); -+ if(tap_setup_common(str, "tuntap", &init->dev_name, mac_out, -+ &init->gate_addr)) -+ return(0); -+ -+ return(1); -+} -+ -+static struct transport tuntap_transport = { -+ .list = LIST_HEAD_INIT(tuntap_transport.list), -+ .name = "tuntap", -+ .setup = tuntap_setup, -+ .user = &tuntap_user_info, -+ .kern = &tuntap_kern_info, -+ .private_size = sizeof(struct tuntap_data), -+ .setup_size = sizeof(struct tuntap_init), -+}; -+ -+static int register_tuntap(void) -+{ -+ register_transport(&tuntap_transport); -+ return(1); -+} -+ -+__initcall(register_tuntap); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/os-Linux/drivers/tuntap_user.c um/arch/um/os-Linux/drivers/tuntap_user.c ---- orig/arch/um/os-Linux/drivers/tuntap_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/os-Linux/drivers/tuntap_user.c 2003-11-12 00:02:30.000000000 -0500 -@@ -0,0 +1,224 @@ -+/* -+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <stdio.h> -+#include <stddef.h> -+#include <stdlib.h> -+#include <unistd.h> -+#include <errno.h> -+#include <sys/wait.h> -+#include <sys/socket.h> -+#include <sys/un.h> -+#include <sys/uio.h> -+#include <sys/ioctl.h> -+#include <net/if.h> -+#include <linux/if_tun.h> -+#include "net_user.h" -+#include "tuntap.h" -+#include "kern_util.h" -+#include "user.h" -+#include "helper.h" -+#include "os.h" -+ -+#define MAX_PACKET ETH_MAX_PACKET -+ -+void tuntap_user_init(void *data, void *dev) -+{ -+ struct tuntap_data *pri = data; -+ -+ pri->dev = dev; -+} -+ -+static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask, -+ void *data) -+{ -+ struct tuntap_data *pri = data; -+ -+ tap_check_ips(pri->gate_addr, addr); -+ if((pri->fd == -1) || pri->fixed_config) return; -+ open_addr(addr, netmask, pri->dev_name); -+} -+ -+static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask, -+ void *data) -+{ -+ struct tuntap_data *pri = data; -+ -+ if((pri->fd == -1) || pri->fixed_config) return; -+ close_addr(addr, netmask, pri->dev_name); -+} -+ -+struct tuntap_pre_exec_data { -+ int stdout; -+ int close_me; -+}; -+ -+static void tuntap_pre_exec(void *arg) -+{ -+ struct tuntap_pre_exec_data *data = arg; -+ -+ dup2(data->stdout, 1); -+ os_close_file(data->close_me); -+} -+ -+static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote, -+ char *buffer, int buffer_len, int *used_out) -+{ -+ struct tuntap_pre_exec_data data; -+ char version_buf[sizeof("nnnnn\0")]; -+ char *argv[] = { "uml_net", version_buf, "tuntap", "up", gate, -+ NULL }; -+ char buf[CMSG_SPACE(sizeof(*fd_out))]; -+ struct msghdr msg; -+ struct cmsghdr *cmsg; -+ struct iovec iov; -+ int pid, n; -+ -+ sprintf(version_buf, "%d", UML_NET_VERSION); -+ -+ data.stdout = remote; -+ data.close_me = me; -+ -+ pid = run_helper(tuntap_pre_exec, &data, argv, NULL); -+ -+ if(pid < 0) return(-pid); -+ -+ os_close_file(remote); -+ -+ msg.msg_name = NULL; -+ msg.msg_namelen = 0; -+ if(buffer != NULL){ -+ iov = ((struct iovec) { buffer, buffer_len }); -+ msg.msg_iov = &iov; -+ msg.msg_iovlen = 1; -+ } -+ else { -+ msg.msg_iov = NULL; -+ msg.msg_iovlen = 0; -+ } -+ msg.msg_control = buf; -+ msg.msg_controllen = sizeof(buf); -+ msg.msg_flags = 0; -+ n = recvmsg(me, &msg, 0); -+ *used_out = n; -+ if(n < 0){ -+ printk("tuntap_open_tramp : recvmsg failed - errno = %d\n", -+ errno); -+ return(-errno); -+ } -+ waitpid(pid, NULL, 0); -+ -+ cmsg = CMSG_FIRSTHDR(&msg); -+ if(cmsg == NULL){ -+ printk("tuntap_open_tramp : didn't receive a message\n"); -+ return(-EINVAL); -+ } -+ if((cmsg->cmsg_level != SOL_SOCKET) || -+ (cmsg->cmsg_type != SCM_RIGHTS)){ -+ printk("tuntap_open_tramp : didn't receive a descriptor\n"); -+ return(-EINVAL); -+ } -+ *fd_out = ((int *) CMSG_DATA(cmsg))[0]; -+ return(0); -+} -+ -+static int tuntap_open(void *data) -+{ -+ struct ifreq ifr; -+ struct tuntap_data *pri = data; -+ char *output, *buffer; -+ int err, fds[2], len, used; -+ -+ err = tap_open_common(pri->dev, pri->gate_addr); -+ if(err < 0) -+ return(err); -+ -+ if(pri->fixed_config){ -+ pri->fd = os_open_file("/dev/net/tun", of_rdwr(OPENFLAGS()), 0); -+ if(pri->fd < 0){ -+ printk("Failed to open /dev/net/tun, err = %d\n", -+ -pri->fd); -+ return(pri->fd); -+ } -+ memset(&ifr, 0, sizeof(ifr)); -+ ifr.ifr_flags = IFF_TAP | IFF_NO_PI; -+ strncpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name) - 1); -+ if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){ -+ printk("TUNSETIFF failed, errno = %d\n", errno); -+ os_close_file(pri->fd); -+ return(-errno); -+ } -+ } -+ else { -+ err = os_pipe(fds, 0, 0); -+ if(err < 0){ -+ printk("tuntap_open : os_pipe failed - err = %d\n", -+ -err); -+ return(err); -+ } -+ -+ buffer = get_output_buffer(&len); -+ if(buffer != NULL) len--; -+ used = 0; -+ -+ err = tuntap_open_tramp(pri->gate_addr, &pri->fd, fds[0], -+ fds[1], buffer, len, &used); -+ -+ output = buffer; -+ if(err < 0) { -+ printk("%s", output); -+ free_output_buffer(buffer); -+ printk("tuntap_open_tramp failed - err = %d\n", -err); -+ return(err); -+ } -+ -+ pri->dev_name = uml_strdup(buffer); -+ output += IFNAMSIZ; -+ printk("%s", output); -+ free_output_buffer(buffer); -+ -+ os_close_file(fds[0]); -+ iter_addresses(pri->dev, open_addr, pri->dev_name); -+ } -+ -+ return(pri->fd); -+} -+ -+static void tuntap_close(int fd, void *data) -+{ -+ struct tuntap_data *pri = data; -+ -+ if(!pri->fixed_config) -+ iter_addresses(pri->dev, close_addr, pri->dev_name); -+ os_close_file(fd); -+ pri->fd = -1; -+} -+ -+static int tuntap_set_mtu(int mtu, void *data) -+{ -+ return(mtu); -+} -+ -+struct net_user_info tuntap_user_info = { -+ .init = tuntap_user_init, -+ .open = tuntap_open, -+ .close = tuntap_close, -+ .remove = NULL, -+ .set_mtu = tuntap_set_mtu, -+ .add_address = tuntap_add_addr, -+ .delete_address = tuntap_del_addr, -+ .max_packet = MAX_PACKET -+}; -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/os-Linux/file.c um/arch/um/os-Linux/file.c ---- orig/arch/um/os-Linux/file.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/os-Linux/file.c 2004-01-10 06:52:24.000000000 -0500 -@@ -0,0 +1,668 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <stdio.h> -+#include <unistd.h> -+#include <errno.h> -+#include <fcntl.h> -+#include <signal.h> -+#include <sys/types.h> -+#include <sys/stat.h> -+#include <sys/socket.h> -+#include <sys/un.h> -+#include <sys/ioctl.h> -+#include <sys/mount.h> -+#include <sys/uio.h> -+#include "os.h" -+#include "user.h" -+#include "kern_util.h" -+ -+static void copy_stat(struct uml_stat *dst, struct stat64 *src) -+{ -+ *dst = ((struct uml_stat) { -+ .ust_dev = src->st_dev, /* device */ -+ .ust_ino = src->st_ino, /* inode */ -+ .ust_mode = src->st_mode, /* protection */ -+ .ust_nlink = src->st_nlink, /* number of hard links */ -+ .ust_uid = src->st_uid, /* user ID of owner */ -+ .ust_gid = src->st_gid, /* group ID of owner */ -+ .ust_size = src->st_size, /* total size, in bytes */ -+ .ust_blksize = src->st_blksize, /* blocksize for filesys I/O */ -+ .ust_blocks = src->st_blocks, /* number of blocks allocated */ -+ .ust_atime = src->st_atime, /* time of last access */ -+ .ust_mtime = src->st_mtime, /* time of last modification */ -+ .ust_ctime = src->st_ctime, /* time of last change */ -+ }); -+} -+ -+int os_stat_fd(const int fd, struct uml_stat *ubuf) -+{ -+ struct stat64 sbuf; -+ int err; -+ -+ do { -+ err = fstat64(fd, &sbuf); -+ } while((err < 0) && (errno == EINTR)) ; -+ -+ if(err < 0) -+ return(-errno); -+ -+ if(ubuf != NULL) -+ copy_stat(ubuf, &sbuf); -+ return(err); -+} -+ -+int os_stat_file(const char *file_name, struct uml_stat *ubuf) -+{ -+ struct stat64 sbuf; -+ int err; -+ -+ do { -+ err = stat64(file_name, &sbuf); -+ } while((err < 0) && (errno == EINTR)) ; -+ -+ if(err < 0) -+ return(-errno); -+ -+ if(ubuf != NULL) -+ copy_stat(ubuf, &sbuf); -+ return(err); -+} -+ -+int os_access(const char* file, int mode) -+{ -+ int amode, err; -+ -+ amode=(mode&OS_ACC_R_OK ? R_OK : 0) | (mode&OS_ACC_W_OK ? W_OK : 0) | -+ (mode&OS_ACC_X_OK ? X_OK : 0) | (mode&OS_ACC_F_OK ? F_OK : 0) ; -+ -+ err = access(file, amode); -+ if(err < 0) -+ return(-errno); -+ -+ return(0); -+} -+ -+void os_print_error(int error, const char* str) -+{ -+ errno = error < 0 ? -error : error; -+ -+ perror(str); -+} -+ -+/* FIXME? required only by hostaudio (because it passes ioctls verbatim) */ -+int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg) -+{ -+ int err; -+ -+ err = ioctl(fd, cmd, arg); -+ if(err < 0) -+ return(-errno); -+ -+ return(err); -+} -+ -+int os_window_size(int fd, int *rows, int *cols) -+{ -+ struct winsize size; -+ -+ if(ioctl(fd, TIOCGWINSZ, &size) < 0) -+ return(-errno); -+ -+ *rows = size.ws_row; -+ *cols = size.ws_col; -+ -+ return(0); -+} -+ -+int os_new_tty_pgrp(int fd, int pid) -+{ -+ if(ioctl(fd, TIOCSCTTY, 0) < 0){ -+ printk("TIOCSCTTY failed, errno = %d\n", errno); -+ return(-errno); -+ } -+ -+ if(tcsetpgrp(fd, pid) < 0){ -+ printk("tcsetpgrp failed, errno = %d\n", errno); -+ return(-errno); -+ } -+ -+ return(0); -+} -+ -+/* FIXME: ensure namebuf in os_get_if_name is big enough */ -+int os_get_ifname(int fd, char* namebuf) -+{ -+ if(ioctl(fd, SIOCGIFNAME, namebuf) < 0) -+ return(-errno); -+ -+ return(0); -+} -+ -+int os_set_slip(int fd) -+{ -+ int disc, sencap; -+ -+ disc = N_SLIP; -+ if(ioctl(fd, TIOCSETD, &disc) < 0){ -+ printk("Failed to set slip line discipline - " -+ "errno = %d\n", errno); -+ return(-errno); -+ } -+ -+ sencap = 0; -+ if(ioctl(fd, SIOCSIFENCAP, &sencap) < 0){ -+ printk("Failed to set slip encapsulation - " -+ "errno = %d\n", errno); -+ return(-errno); -+ } -+ -+ return(0); -+} -+ -+int os_set_owner(int fd, int pid) -+{ -+ if(fcntl(fd, F_SETOWN, pid) < 0){ -+ int save_errno = errno; -+ -+ if(fcntl(fd, F_GETOWN, 0) != pid) -+ return(-save_errno); -+ } -+ -+ return(0); -+} -+ -+/* FIXME? moved wholesale from sigio_user.c to get fcntls out of that file */ -+int os_sigio_async(int master, int slave) -+{ -+ int flags; -+ -+ flags = fcntl(master, F_GETFL); -+ if(flags < 0) { -+ printk("fcntl F_GETFL failed, errno = %d\n", errno); -+ return(-errno); -+ } -+ -+ if((fcntl(master, F_SETFL, flags | O_NONBLOCK | O_ASYNC) < 0) || -+ (fcntl(master, F_SETOWN, os_getpid()) < 0)){ -+ printk("fcntl F_SETFL or F_SETOWN failed, errno = %d\n", errno); -+ return(-errno); -+ } -+ -+ if((fcntl(slave, F_SETFL, flags | O_NONBLOCK) < 0)){ -+ printk("fcntl F_SETFL failed, errno = %d\n", errno); -+ return(-errno); -+ } -+ -+ return(0); -+} -+ -+int os_mode_fd(int fd, int mode) -+{ -+ int err; -+ -+ do { -+ err = fchmod(fd, mode); -+ } while((err < 0) && (errno==EINTR)) ; -+ -+ if(err < 0) -+ return(-errno); -+ -+ return(0); -+} -+ -+int os_file_type(char *file) -+{ -+ struct uml_stat buf; -+ int err; -+ -+ err = os_stat_file(file, &buf); -+ if(err < 0) -+ return(err); -+ -+ if(S_ISDIR(buf.ust_mode)) return(OS_TYPE_DIR); -+ else if(S_ISLNK(buf.ust_mode)) return(OS_TYPE_SYMLINK); -+ else if(S_ISCHR(buf.ust_mode)) return(OS_TYPE_CHARDEV); -+ else if(S_ISBLK(buf.ust_mode)) return(OS_TYPE_BLOCKDEV); -+ else if(S_ISFIFO(buf.ust_mode)) return(OS_TYPE_FIFO); -+ else if(S_ISSOCK(buf.ust_mode)) return(OS_TYPE_SOCK); -+ else return(OS_TYPE_FILE); -+} -+ -+int os_file_mode(char *file, struct openflags *mode_out) -+{ -+ int err; -+ -+ *mode_out = OPENFLAGS(); -+ -+ err = os_access(file, OS_ACC_W_OK); -+ if((err < 0) && (err != -EACCES)) -+ return(err); -+ -+ *mode_out = of_write(*mode_out); -+ -+ err = os_access(file, OS_ACC_R_OK); -+ if((err < 0) && (err != -EACCES)) -+ return(err); -+ -+ *mode_out = of_read(*mode_out); -+ -+ return(0); -+} -+ -+int os_open_file(char *file, struct openflags flags, int mode) -+{ -+ int fd, f = 0; -+ -+ if(flags.r && flags.w) f = O_RDWR; -+ else if(flags.r) f = O_RDONLY; -+ else if(flags.w) f = O_WRONLY; -+ else f = 0; -+ -+ if(flags.s) f |= O_SYNC; -+ if(flags.c) f |= O_CREAT; -+ if(flags.t) f |= O_TRUNC; -+ if(flags.e) f |= O_EXCL; -+ -+ fd = open64(file, f, mode); -+ if(fd < 0) -+ return(-errno); -+ -+ if(flags.cl && fcntl(fd, F_SETFD, 1)){ -+ os_close_file(fd); -+ return(-errno); -+ } -+ -+ return(fd); -+} -+ -+int os_connect_socket(char *name) -+{ -+ struct sockaddr_un sock; -+ int fd, err; -+ -+ sock.sun_family = AF_UNIX; -+ snprintf(sock.sun_path, sizeof(sock.sun_path), "%s", name); -+ -+ fd = socket(AF_UNIX, SOCK_STREAM, 0); -+ if(fd < 0) -+ return(fd); -+ -+ err = connect(fd, (struct sockaddr *) &sock, sizeof(sock)); -+ if(err) -+ return(-errno); -+ -+ return(fd); -+} -+ -+void os_close_file(int fd) -+{ -+ close(fd); -+} -+ -+int os_seek_file(int fd, __u64 offset) -+{ -+ __u64 actual; -+ -+ actual = lseek64(fd, offset, SEEK_SET); -+ if(actual != offset) return(-errno); -+ return(0); -+} -+ -+static int fault_buffer(void *start, int len, -+ int (*copy_proc)(void *addr, void *buf, int len)) -+{ -+ int page = getpagesize(), i; -+ char c; -+ -+ for(i = 0; i < len; i += page){ -+ if((*copy_proc)(start + i, &c, sizeof(c))) -+ return(-EFAULT); -+ } -+ if((len % page) != 0){ -+ if((*copy_proc)(start + len - 1, &c, sizeof(c))) -+ return(-EFAULT); -+ } -+ return(0); -+} -+ -+static int file_io(int fd, void *buf, int len, -+ int (*io_proc)(int fd, void *buf, int len), -+ int (*copy_user_proc)(void *addr, void *buf, int len)) -+{ -+ int n, err; -+ -+ do { -+ n = (*io_proc)(fd, buf, len); -+ if((n < 0) && (errno == EFAULT)){ -+ err = fault_buffer(buf, len, copy_user_proc); -+ if(err) -+ return(err); -+ n = (*io_proc)(fd, buf, len); -+ } -+ } while((n < 0) && (errno == EINTR)); -+ -+ if(n < 0) -+ return(-errno); -+ return(n); -+} -+ -+int os_read_file(int fd, void *buf, int len) -+{ -+ return(file_io(fd, buf, len, (int (*)(int, void *, int)) read, -+ copy_from_user_proc)); -+} -+ -+int os_write_file(int fd, const void *buf, int len) -+{ -+ return(file_io(fd, (void *) buf, len, -+ (int (*)(int, void *, int)) write, copy_to_user_proc)); -+} -+ -+int os_file_size(char *file, long long *size_out) -+{ -+ struct uml_stat buf; -+ int err; -+ -+ err = os_stat_file(file, &buf); -+ if(err < 0){ -+ printk("Couldn't stat \"%s\" : err = %d\n", file, -err); -+ return(err); -+ } -+ -+ if(S_ISBLK(buf.ust_mode)){ -+ int fd, blocks; -+ -+ fd = os_open_file(file, of_read(OPENFLAGS()), 0); -+ if(fd < 0){ -+ printk("Couldn't open \"%s\", errno = %d\n", file, -fd); -+ return(fd); -+ } -+ if(ioctl(fd, BLKGETSIZE, &blocks) < 0){ -+ printk("Couldn't get the block size of \"%s\", " -+ "errno = %d\n", file, errno); -+ err = -errno; -+ os_close_file(fd); -+ return(err); -+ } -+ *size_out = ((long long) blocks) * 512; -+ os_close_file(fd); -+ return(0); -+ } -+ *size_out = buf.ust_size; -+ return(0); -+} -+ -+int os_file_modtime(char *file, unsigned long *modtime) -+{ -+ struct uml_stat buf; -+ int err; -+ -+ err = os_stat_file(file, &buf); -+ if(err < 0){ -+ printk("Couldn't stat \"%s\" : err = %d\n", file, -err); -+ return(err); -+ } -+ -+ *modtime = buf.ust_mtime; -+ return(0); -+} -+ -+int os_get_exec_close(int fd, int* close_on_exec) -+{ -+ int ret; -+ -+ do { -+ ret = fcntl(fd, F_GETFD); -+ } while((ret < 0) && (errno == EINTR)) ; -+ -+ if(ret < 0) -+ return(-errno); -+ -+ *close_on_exec = (ret&FD_CLOEXEC) ? 1 : 0; -+ return(ret); -+} -+ -+int os_set_exec_close(int fd, int close_on_exec) -+{ -+ int flag, err; -+ -+ if(close_on_exec) flag = FD_CLOEXEC; -+ else flag = 0; -+ -+ do { -+ err = fcntl(fd, F_SETFD, flag); -+ } while((err < 0) && (errno == EINTR)) ; -+ -+ if(err < 0) -+ return(-errno); -+ return(err); -+} -+ -+int os_pipe(int *fds, int stream, int close_on_exec) -+{ -+ int err, type = stream ? SOCK_STREAM : SOCK_DGRAM; -+ -+ err = socketpair(AF_UNIX, type, 0, fds); -+ if(err < 0) -+ return(-errno); -+ -+ if(!close_on_exec) -+ return(0); -+ -+ err = os_set_exec_close(fds[0], 1); -+ if(err < 0) -+ goto error; -+ -+ err = os_set_exec_close(fds[1], 1); -+ if(err < 0) -+ goto error; -+ -+ return(0); -+ -+ error: -+ printk("os_pipe : Setting FD_CLOEXEC failed, err = %d\n", -err); -+ os_close_file(fds[1]); -+ os_close_file(fds[0]); -+ return(err); -+} -+ -+int os_set_fd_async(int fd, int owner) -+{ -+ /* XXX This should do F_GETFL first */ -+ if(fcntl(fd, F_SETFL, O_ASYNC | O_NONBLOCK) < 0){ -+ printk("os_set_fd_async : failed to set O_ASYNC and " -+ "O_NONBLOCK on fd # %d, errno = %d\n", fd, errno); -+ return(-errno); -+ } -+#ifdef notdef -+ if(fcntl(fd, F_SETFD, 1) < 0){ -+ printk("os_set_fd_async : Setting FD_CLOEXEC failed, " -+ "errno = %d\n", errno); -+ } -+#endif -+ -+ if((fcntl(fd, F_SETSIG, SIGIO) < 0) || -+ (fcntl(fd, F_SETOWN, owner) < 0)){ -+ printk("os_set_fd_async : Failed to fcntl F_SETOWN " -+ "(or F_SETSIG) fd %d to pid %d, errno = %d\n", fd, -+ owner, errno); -+ return(-errno); -+ } -+ -+ return(0); -+} -+ -+int os_set_fd_block(int fd, int blocking) -+{ -+ int flags; -+ -+ flags = fcntl(fd, F_GETFL); -+ -+ if(blocking) flags &= ~O_NONBLOCK; -+ else flags |= O_NONBLOCK; -+ -+ if(fcntl(fd, F_SETFL, flags) < 0){ -+ printk("Failed to change blocking on fd # %d, errno = %d\n", -+ fd, errno); -+ return(-errno); -+ } -+ return(0); -+} -+ -+int os_accept_connection(int fd) -+{ -+ int new; -+ -+ new = accept(fd, NULL, 0); -+ if(new < 0) -+ return(-errno); -+ return(new); -+} -+ -+#ifndef SHUT_RD -+#define SHUT_RD 0 -+#endif -+ -+#ifndef SHUT_WR -+#define SHUT_WR 1 -+#endif -+ -+#ifndef SHUT_RDWR -+#define SHUT_RDWR 2 -+#endif -+ -+int os_shutdown_socket(int fd, int r, int w) -+{ -+ int what, err; -+ -+ if(r && w) what = SHUT_RDWR; -+ else if(r) what = SHUT_RD; -+ else if(w) what = SHUT_WR; -+ else { -+ printk("os_shutdown_socket : neither r or w was set\n"); -+ return(-EINVAL); -+ } -+ err = shutdown(fd, what); -+ if(err < 0) -+ return(-errno); -+ return(0); -+} -+ -+int os_rcv_fd(int fd, int *helper_pid_out) -+{ -+ int new, n; -+ char buf[CMSG_SPACE(sizeof(new))]; -+ struct msghdr msg; -+ struct cmsghdr *cmsg; -+ struct iovec iov; -+ -+ msg.msg_name = NULL; -+ msg.msg_namelen = 0; -+ iov = ((struct iovec) { .iov_base = helper_pid_out, -+ .iov_len = sizeof(*helper_pid_out) }); -+ msg.msg_iov = &iov; -+ msg.msg_iovlen = 1; -+ msg.msg_control = buf; -+ msg.msg_controllen = sizeof(buf); -+ msg.msg_flags = 0; -+ -+ n = recvmsg(fd, &msg, 0); -+ if(n < 0) -+ return(-errno); -+ -+ else if(n != sizeof(iov.iov_len)) -+ *helper_pid_out = -1; -+ -+ cmsg = CMSG_FIRSTHDR(&msg); -+ if(cmsg == NULL){ -+ printk("rcv_fd didn't receive anything, error = %d\n", errno); -+ return(-1); -+ } -+ if((cmsg->cmsg_level != SOL_SOCKET) || -+ (cmsg->cmsg_type != SCM_RIGHTS)){ -+ printk("rcv_fd didn't receive a descriptor\n"); -+ return(-1); -+ } -+ -+ new = ((int *) CMSG_DATA(cmsg))[0]; -+ return(new); -+} -+ -+int os_create_unix_socket(char *file, int len, int close_on_exec) -+{ -+ struct sockaddr_un addr; -+ int sock, err; -+ -+ sock = socket(PF_UNIX, SOCK_DGRAM, 0); -+ if (sock < 0){ -+ printk("create_unix_socket - socket failed, errno = %d\n", -+ errno); -+ return(-errno); -+ } -+ -+ if(close_on_exec) { -+ err = os_set_exec_close(sock, 1); -+ if(err < 0) -+ printk("create_unix_socket : close_on_exec failed, " -+ "err = %d", -err); -+ } -+ -+ addr.sun_family = AF_UNIX; -+ -+ /* XXX Be more careful about overflow */ -+ snprintf(addr.sun_path, len, "%s", file); -+ -+ err = bind(sock, (struct sockaddr *) &addr, sizeof(addr)); -+ if (err < 0){ -+ printk("create_listening_socket at '%s' - bind failed, " -+ "errno = %d\n", file, errno); -+ return(-errno); -+ } -+ -+ return(sock); -+} -+ -+void os_flush_stdout(void) -+{ -+ fflush(stdout); -+} -+ -+int os_lock_file(int fd, int excl) -+{ -+ int type = excl ? F_WRLCK : F_RDLCK; -+ struct flock lock = ((struct flock) { .l_type = type, -+ .l_whence = SEEK_SET, -+ .l_start = 0, -+ .l_len = 0 } ); -+ int err, save; -+ -+ err = fcntl(fd, F_SETLK, &lock); -+ if(!err) -+ goto out; -+ -+ save = -errno; -+ err = fcntl(fd, F_GETLK, &lock); -+ if(err){ -+ err = -errno; -+ goto out; -+ } -+ -+ printk("F_SETLK failed, file already locked by pid %d\n", lock.l_pid); -+ err = save; -+ out: -+ return(err); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/os-Linux/include/file.h um/arch/um/os-Linux/include/file.h ---- orig/arch/um/os-Linux/include/file.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/os-Linux/include/file.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,22 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __OS_FILE_H__ -+#define __OS_FILE_H__ -+ -+#define DEV_NULL "/dev/null" -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/os-Linux/Makefile um/arch/um/os-Linux/Makefile ---- orig/arch/um/os-Linux/Makefile 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/os-Linux/Makefile 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,17 @@ -+# -+# Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+# Licensed under the GPL -+# -+ -+O_TARGET = built-in.o -+ -+obj-y = file.o process.o tty.o -+ -+include $(TOPDIR)/Rules.make -+ -+$(obj-y) : %.o: %.c -+ $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $< -+ -+clean : -+ -+archmrproper: -diff -Naur -X ../exclude-files orig/arch/um/os-Linux/process.c um/arch/um/os-Linux/process.c ---- orig/arch/um/os-Linux/process.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/os-Linux/process.c 2004-01-10 06:53:44.000000000 -0500 -@@ -0,0 +1,148 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@addtoit.com) -+ * Licensed under the GPL -+ */ -+ -+#include <unistd.h> -+#include <stdio.h> -+#include <errno.h> -+#include <signal.h> -+#include <sys/mman.h> -+#include <sys/wait.h> -+#include "os.h" -+#include "user.h" -+ -+#define ARBITRARY_ADDR -1 -+#define FAILURE_PID -1 -+ -+unsigned long os_process_pc(int pid) -+{ -+ char proc_stat[sizeof("/proc/#####/stat\0")], buf[256]; -+ unsigned long pc; -+ int fd, err; -+ -+ sprintf(proc_stat, "/proc/%d/stat", pid); -+ fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0); -+ if(fd < 0){ -+ printk("os_process_pc - couldn't open '%s', err = %d\n", -+ proc_stat, -fd); -+ return(ARBITRARY_ADDR); -+ } -+ err = os_read_file(fd, buf, sizeof(buf)); -+ if(err < 0){ -+ printk("os_process_pc - couldn't read '%s', err = %d\n", -+ proc_stat, -err); -+ os_close_file(fd); -+ return(ARBITRARY_ADDR); -+ } -+ os_close_file(fd); -+ pc = ARBITRARY_ADDR; -+ if(sscanf(buf, "%*d %*s %*c %*d %*d %*d %*d %*d %*d %*d %*d " -+ "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d " -+ "%*d %*d %*d %*d %ld", &pc) != 1){ -+ printk("os_process_pc - couldn't find pc in '%s'\n", buf); -+ } -+ return(pc); -+} -+ -+int os_process_parent(int pid) -+{ -+ char stat[sizeof("/proc/nnnnn/stat\0")]; -+ char data[256]; -+ int parent, n, fd; -+ -+ if(pid == -1) return(-1); -+ -+ snprintf(stat, sizeof(stat), "/proc/%d/stat", pid); -+ fd = os_open_file(stat, of_read(OPENFLAGS()), 0); -+ if(fd < 0){ -+ printk("Couldn't open '%s', err = %d\n", stat, -fd); -+ return(FAILURE_PID); -+ } -+ -+ n = os_read_file(fd, data, sizeof(data)); -+ os_close_file(fd); -+ -+ if(n < 0){ -+ printk("Couldn't read '%s', err = %d\n", stat, -n); -+ return(FAILURE_PID); -+ } -+ -+ parent = FAILURE_PID; -+ /* XXX This will break if there is a space in the command */ -+ n = sscanf(data, "%*d %*s %*c %d", &parent); -+ if(n != 1) -+ printk("Failed to scan '%s'\n", data); -+ -+ return(parent); -+} -+ -+void os_stop_process(int pid) -+{ -+ kill(pid, SIGSTOP); -+} -+ -+void os_kill_process(int pid, int reap_child) -+{ -+ kill(pid, SIGKILL); -+ if(reap_child) -+ waitpid(pid, NULL, 0); -+ -+} -+ -+void os_usr1_process(int pid) -+{ -+ kill(pid, SIGUSR1); -+} -+ -+int os_getpid(void) -+{ -+ return(getpid()); -+} -+ -+int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len, -+ int r, int w, int x) -+{ -+ void *loc; -+ int prot; -+ -+ prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | -+ (x ? PROT_EXEC : 0); -+ -+ loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED, -+ fd, off); -+ if(loc == MAP_FAILED) -+ return(-errno); -+ return(0); -+} -+ -+int os_protect_memory(void *addr, unsigned long len, int r, int w, int x) -+{ -+ int prot = ((r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | -+ (x ? PROT_EXEC : 0)); -+ -+ if(mprotect(addr, len, prot) < 0) -+ return(-errno); -+ return(0); -+} -+ -+int os_unmap_memory(void *addr, int len) -+{ -+ int err; -+ -+ err = munmap(addr, len); -+ if(err < 0) -+ return(-errno); -+ return(0); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/os-Linux/tty.c um/arch/um/os-Linux/tty.c ---- orig/arch/um/os-Linux/tty.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/os-Linux/tty.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,61 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <stdlib.h> -+#include <errno.h> -+#include "os.h" -+#include "user.h" -+#include "kern_util.h" -+ -+struct grantpt_info { -+ int fd; -+ int res; -+ int err; -+}; -+ -+static void grantpt_cb(void *arg) -+{ -+ struct grantpt_info *info = arg; -+ -+ info->res = grantpt(info->fd); -+ info->err = errno; -+} -+ -+int get_pty(void) -+{ -+ struct grantpt_info info; -+ int fd; -+ -+ fd = os_open_file("/dev/ptmx", of_rdwr(OPENFLAGS()), 0); -+ if(fd < 0){ -+ printk("get_pty : Couldn't open /dev/ptmx - err = %d\n", -fd); -+ return(fd); -+ } -+ -+ info.fd = fd; -+ initial_thread_cb(grantpt_cb, &info); -+ -+ if(info.res < 0){ -+ printk("get_pty : Couldn't grant pty - errno = %d\n", -+ -info.err); -+ return(-1); -+ } -+ if(unlockpt(fd) < 0){ -+ printk("get_pty : Couldn't unlock pty - errno = %d\n", errno); -+ return(-1); -+ } -+ return(fd); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/sys-i386/bugs.c um/arch/um/sys-i386/bugs.c ---- orig/arch/um/sys-i386/bugs.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/sys-i386/bugs.c 2004-01-21 22:42:39.000000000 -0500 -@@ -0,0 +1,222 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <unistd.h> -+#include <errno.h> -+#include <string.h> -+#include <sys/signal.h> -+#include <asm/ldt.h> -+#include "kern_util.h" -+#include "user.h" -+#include "sysdep/ptrace.h" -+#include "task.h" -+#include "os.h" -+ -+#define MAXTOKEN 64 -+ -+/* Set during early boot */ -+int host_has_cmov = 1; -+int host_has_xmm = 0; -+ -+static char token(int fd, char *buf, int len, char stop) -+{ -+ int n; -+ char *ptr, *end, c; -+ -+ ptr = buf; -+ end = &buf[len]; -+ do { -+ n = os_read_file(fd, ptr, sizeof(*ptr)); -+ c = *ptr++; -+ if(n != sizeof(*ptr)){ -+ if(n == 0) return(0); -+ printk("Reading /proc/cpuinfo failed, err = %d\n", -n); -+ if(n < 0) -+ return(n); -+ else -+ return(-EIO); -+ } -+ } while((c != '\n') && (c != stop) && (ptr < end)); -+ -+ if(ptr == end){ -+ printk("Failed to find '%c' in /proc/cpuinfo\n", stop); -+ return(-1); -+ } -+ *(ptr - 1) = '\0'; -+ return(c); -+} -+ -+static int find_cpuinfo_line(int fd, char *key, char *scratch, int len) -+{ -+ int n; -+ char c; -+ -+ scratch[len - 1] = '\0'; -+ while(1){ -+ c = token(fd, scratch, len - 1, ':'); -+ if(c <= 0) -+ return(0); -+ else if(c != ':'){ -+ printk("Failed to find ':' in /proc/cpuinfo\n"); -+ return(0); -+ } -+ -+ if(!strncmp(scratch, key, strlen(key))) -+ return(1); -+ -+ do { -+ n = os_read_file(fd, &c, sizeof(c)); -+ if(n != sizeof(c)){ -+ printk("Failed to find newline in " -+ "/proc/cpuinfo, err = %d\n", -n); -+ return(0); -+ } -+ } while(c != '\n'); -+ } -+ return(0); -+} -+ -+int cpu_feature(char *what, char *buf, int len) -+{ -+ int fd, ret = 0; -+ -+ fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0); -+ if(fd < 0){ -+ printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd); -+ return(0); -+ } -+ -+ if(!find_cpuinfo_line(fd, what, buf, len)){ -+ printk("Couldn't find '%s' line in /proc/cpuinfo\n", what); -+ goto out_close; -+ } -+ -+ token(fd, buf, len, '\n'); -+ ret = 1; -+ -+ out_close: -+ os_close_file(fd); -+ return(ret); -+} -+ -+static int check_cpu_flag(char *feature, int *have_it) -+{ -+ char buf[MAXTOKEN], c; -+ int fd, len = sizeof(buf)/sizeof(buf[0]); -+ -+ printk("Checking for host processor %s support...", feature); -+ fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0); -+ if(fd < 0){ -+ printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd); -+ return(0); -+ } -+ -+ *have_it = 0; -+ if(!find_cpuinfo_line(fd, "flags", buf, sizeof(buf) / sizeof(buf[0]))) -+ goto out; -+ -+ c = token(fd, buf, len - 1, ' '); -+ if(c < 0) goto out; -+ else if(c != ' '){ -+ printk("Failed to find ' ' in /proc/cpuinfo\n"); -+ goto out; -+ } -+ -+ while(1){ -+ c = token(fd, buf, len - 1, ' '); -+ if(c < 0) goto out; -+ else if(c == '\n') break; -+ -+ if(!strcmp(buf, feature)){ -+ *have_it = 1; -+ goto out; -+ } -+ } -+ out: -+ if(*have_it == 0) printk("No\n"); -+ else if(*have_it == 1) printk("Yes\n"); -+ os_close_file(fd); -+ return(1); -+} -+ -+#if 0 /* This doesn't work in tt mode, plus it's causing compilation problems -+ * for some people. -+ */ -+static void disable_lcall(void) -+{ -+ struct modify_ldt_ldt_s ldt; -+ int err; -+ -+ bzero(&ldt, sizeof(ldt)); -+ ldt.entry_number = 7; -+ ldt.base_addr = 0; -+ ldt.limit = 0; -+ err = modify_ldt(1, &ldt, sizeof(ldt)); -+ if(err) -+ printk("Failed to disable lcall7 - errno = %d\n", errno); -+} -+#endif -+ -+void arch_init_thread(void) -+{ -+#if 0 -+ disable_lcall(); -+#endif -+} -+ -+void arch_check_bugs(void) -+{ -+ int have_it; -+ -+ if(os_access("/proc/cpuinfo", OS_ACC_R_OK) < 0){ -+ printk("/proc/cpuinfo not available - skipping CPU capability " -+ "checks\n"); -+ return; -+ } -+ if(check_cpu_flag("cmov", &have_it)) -+ host_has_cmov = have_it; -+ if(check_cpu_flag("xmm", &have_it)) -+ host_has_xmm = have_it; -+} -+ -+int arch_handle_signal(int sig, union uml_pt_regs *regs) -+{ -+ unsigned char tmp[2]; -+ -+ /* This is testing for a cmov (0x0f 0x4x) instruction causing a -+ * SIGILL in init. -+ */ -+ if((sig != SIGILL) || (TASK_PID(get_current()) != 1)) return(0); -+ -+ if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2)) -+ panic("SIGILL in init, could not read instructions!\n"); -+ if((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40)) -+ return(0); -+ -+ if(host_has_cmov == 0) -+ panic("SIGILL caused by cmov, which this processor doesn't " -+ "implement, boot a filesystem compiled for older " -+ "processors"); -+ else if(host_has_cmov == 1) -+ panic("SIGILL caused by cmov, which this processor claims to " -+ "implement"); -+ else if(host_has_cmov == -1) -+ panic("SIGILL caused by cmov, couldn't tell if this processor " -+ "implements it, boot a filesystem compiled for older " -+ "processors"); -+ else panic("Bad value for host_has_cmov (%d)", host_has_cmov); -+ return(0); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/sys-i386/checksum.S um/arch/um/sys-i386/checksum.S ---- orig/arch/um/sys-i386/checksum.S 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/sys-i386/checksum.S 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,460 @@ -+/* -+ * INET An implementation of the TCP/IP protocol suite for the LINUX -+ * operating system. INET is implemented using the BSD Socket -+ * interface as the means of communication with the user level. -+ * -+ * IP/TCP/UDP checksumming routines -+ * -+ * Authors: Jorge Cwik, <jorge@laser.satlink.net> -+ * Arnt Gulbrandsen, <agulbra@nvg.unit.no> -+ * Tom May, <ftom@netcom.com> -+ * Pentium Pro/II routines: -+ * Alexander Kjeldaas <astor@guardian.no> -+ * Finn Arne Gangstad <finnag@guardian.no> -+ * Lots of code moved from tcp.c and ip.c; see those files -+ * for more names. -+ * -+ * Changes: Ingo Molnar, converted csum_partial_copy() to 2.1 exception -+ * handling. -+ * Andi Kleen, add zeroing on error -+ * converted to pure assembler -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+ -+#include <linux/config.h> -+#include <asm/errno.h> -+ -+/* -+ * computes a partial checksum, e.g. for TCP/UDP fragments -+ */ -+ -+/* -+unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum) -+ */ -+ -+.text -+.align 4 -+.globl arch_csum_partial -+ -+#ifndef CONFIG_X86_USE_PPRO_CHECKSUM -+ -+ /* -+ * Experiments with Ethernet and SLIP connections show that buff -+ * is aligned on either a 2-byte or 4-byte boundary. We get at -+ * least a twofold speedup on 486 and Pentium if it is 4-byte aligned. -+ * Fortunately, it is easy to convert 2-byte alignment to 4-byte -+ * alignment for the unrolled loop. -+ */ -+arch_csum_partial: -+ pushl %esi -+ pushl %ebx -+ movl 20(%esp),%eax # Function arg: unsigned int sum -+ movl 16(%esp),%ecx # Function arg: int len -+ movl 12(%esp),%esi # Function arg: unsigned char *buff -+ testl $2, %esi # Check alignment. -+ jz 2f # Jump if alignment is ok. -+ subl $2, %ecx # Alignment uses up two bytes. -+ jae 1f # Jump if we had at least two bytes. -+ addl $2, %ecx # ecx was < 2. Deal with it. -+ jmp 4f -+1: movw (%esi), %bx -+ addl $2, %esi -+ addw %bx, %ax -+ adcl $0, %eax -+2: -+ movl %ecx, %edx -+ shrl $5, %ecx -+ jz 2f -+ testl %esi, %esi -+1: movl (%esi), %ebx -+ adcl %ebx, %eax -+ movl 4(%esi), %ebx -+ adcl %ebx, %eax -+ movl 8(%esi), %ebx -+ adcl %ebx, %eax -+ movl 12(%esi), %ebx -+ adcl %ebx, %eax -+ movl 16(%esi), %ebx -+ adcl %ebx, %eax -+ movl 20(%esi), %ebx -+ adcl %ebx, %eax -+ movl 24(%esi), %ebx -+ adcl %ebx, %eax -+ movl 28(%esi), %ebx -+ adcl %ebx, %eax -+ lea 32(%esi), %esi -+ dec %ecx -+ jne 1b -+ adcl $0, %eax -+2: movl %edx, %ecx -+ andl $0x1c, %edx -+ je 4f -+ shrl $2, %edx # This clears CF -+3: adcl (%esi), %eax -+ lea 4(%esi), %esi -+ dec %edx -+ jne 3b -+ adcl $0, %eax -+4: andl $3, %ecx -+ jz 7f -+ cmpl $2, %ecx -+ jb 5f -+ movw (%esi),%cx -+ leal 2(%esi),%esi -+ je 6f -+ shll $16,%ecx -+5: movb (%esi),%cl -+6: addl %ecx,%eax -+ adcl $0, %eax -+7: -+ popl %ebx -+ popl %esi -+ ret -+ -+#else -+ -+/* Version for PentiumII/PPro */ -+ -+arch_csum_partial: -+ pushl %esi -+ pushl %ebx -+ movl 20(%esp),%eax # Function arg: unsigned int sum -+ movl 16(%esp),%ecx # Function arg: int len -+ movl 12(%esp),%esi # Function arg: const unsigned char *buf -+ -+ testl $2, %esi -+ jnz 30f -+10: -+ movl %ecx, %edx -+ movl %ecx, %ebx -+ andl $0x7c, %ebx -+ shrl $7, %ecx -+ addl %ebx,%esi -+ shrl $2, %ebx -+ negl %ebx -+ lea 45f(%ebx,%ebx,2), %ebx -+ testl %esi, %esi -+ jmp *%ebx -+ -+ # Handle 2-byte-aligned regions -+20: addw (%esi), %ax -+ lea 2(%esi), %esi -+ adcl $0, %eax -+ jmp 10b -+ -+30: subl $2, %ecx -+ ja 20b -+ je 32f -+ movzbl (%esi),%ebx # csumming 1 byte, 2-aligned -+ addl %ebx, %eax -+ adcl $0, %eax -+ jmp 80f -+32: -+ addw (%esi), %ax # csumming 2 bytes, 2-aligned -+ adcl $0, %eax -+ jmp 80f -+ -+40: -+ addl -128(%esi), %eax -+ adcl -124(%esi), %eax -+ adcl -120(%esi), %eax -+ adcl -116(%esi), %eax -+ adcl -112(%esi), %eax -+ adcl -108(%esi), %eax -+ adcl -104(%esi), %eax -+ adcl -100(%esi), %eax -+ adcl -96(%esi), %eax -+ adcl -92(%esi), %eax -+ adcl -88(%esi), %eax -+ adcl -84(%esi), %eax -+ adcl -80(%esi), %eax -+ adcl -76(%esi), %eax -+ adcl -72(%esi), %eax -+ adcl -68(%esi), %eax -+ adcl -64(%esi), %eax -+ adcl -60(%esi), %eax -+ adcl -56(%esi), %eax -+ adcl -52(%esi), %eax -+ adcl -48(%esi), %eax -+ adcl -44(%esi), %eax -+ adcl -40(%esi), %eax -+ adcl -36(%esi), %eax -+ adcl -32(%esi), %eax -+ adcl -28(%esi), %eax -+ adcl -24(%esi), %eax -+ adcl -20(%esi), %eax -+ adcl -16(%esi), %eax -+ adcl -12(%esi), %eax -+ adcl -8(%esi), %eax -+ adcl -4(%esi), %eax -+45: -+ lea 128(%esi), %esi -+ adcl $0, %eax -+ dec %ecx -+ jge 40b -+ movl %edx, %ecx -+50: andl $3, %ecx -+ jz 80f -+ -+ # Handle the last 1-3 bytes without jumping -+ notl %ecx # 1->2, 2->1, 3->0, higher bits are masked -+ movl $0xffffff,%ebx # by the shll and shrl instructions -+ shll $3,%ecx -+ shrl %cl,%ebx -+ andl -128(%esi),%ebx # esi is 4-aligned so should be ok -+ addl %ebx,%eax -+ adcl $0,%eax -+80: -+ popl %ebx -+ popl %esi -+ ret -+ -+#endif -+ -+/* -+unsigned int csum_partial_copy_generic (const char *src, char *dst, -+ int len, int sum, int *src_err_ptr, int *dst_err_ptr) -+ */ -+ -+/* -+ * Copy from ds while checksumming, otherwise like csum_partial -+ * -+ * The macros SRC and DST specify the type of access for the instruction. -+ * thus we can call a custom exception handler for all access types. -+ * -+ * FIXME: could someone double-check whether I haven't mixed up some SRC and -+ * DST definitions? It's damn hard to trigger all cases. I hope I got -+ * them all but there's no guarantee. -+ */ -+ -+#define SRC(y...) \ -+ 9999: y; \ -+ .section __ex_table, "a"; \ -+ .long 9999b, 6001f ; \ -+ .previous -+ -+#define DST(y...) \ -+ 9999: y; \ -+ .section __ex_table, "a"; \ -+ .long 9999b, 6002f ; \ -+ .previous -+ -+.align 4 -+.globl csum_partial_copy_generic_i386 -+ -+#ifndef CONFIG_X86_USE_PPRO_CHECKSUM -+ -+#define ARGBASE 16 -+#define FP 12 -+ -+csum_partial_copy_generic_i386: -+ subl $4,%esp -+ pushl %edi -+ pushl %esi -+ pushl %ebx -+ movl ARGBASE+16(%esp),%eax # sum -+ movl ARGBASE+12(%esp),%ecx # len -+ movl ARGBASE+4(%esp),%esi # src -+ movl ARGBASE+8(%esp),%edi # dst -+ -+ testl $2, %edi # Check alignment. -+ jz 2f # Jump if alignment is ok. -+ subl $2, %ecx # Alignment uses up two bytes. -+ jae 1f # Jump if we had at least two bytes. -+ addl $2, %ecx # ecx was < 2. Deal with it. -+ jmp 4f -+SRC(1: movw (%esi), %bx ) -+ addl $2, %esi -+DST( movw %bx, (%edi) ) -+ addl $2, %edi -+ addw %bx, %ax -+ adcl $0, %eax -+2: -+ movl %ecx, FP(%esp) -+ shrl $5, %ecx -+ jz 2f -+ testl %esi, %esi -+SRC(1: movl (%esi), %ebx ) -+SRC( movl 4(%esi), %edx ) -+ adcl %ebx, %eax -+DST( movl %ebx, (%edi) ) -+ adcl %edx, %eax -+DST( movl %edx, 4(%edi) ) -+ -+SRC( movl 8(%esi), %ebx ) -+SRC( movl 12(%esi), %edx ) -+ adcl %ebx, %eax -+DST( movl %ebx, 8(%edi) ) -+ adcl %edx, %eax -+DST( movl %edx, 12(%edi) ) -+ -+SRC( movl 16(%esi), %ebx ) -+SRC( movl 20(%esi), %edx ) -+ adcl %ebx, %eax -+DST( movl %ebx, 16(%edi) ) -+ adcl %edx, %eax -+DST( movl %edx, 20(%edi) ) -+ -+SRC( movl 24(%esi), %ebx ) -+SRC( movl 28(%esi), %edx ) -+ adcl %ebx, %eax -+DST( movl %ebx, 24(%edi) ) -+ adcl %edx, %eax -+DST( movl %edx, 28(%edi) ) -+ -+ lea 32(%esi), %esi -+ lea 32(%edi), %edi -+ dec %ecx -+ jne 1b -+ adcl $0, %eax -+2: movl FP(%esp), %edx -+ movl %edx, %ecx -+ andl $0x1c, %edx -+ je 4f -+ shrl $2, %edx # This clears CF -+SRC(3: movl (%esi), %ebx ) -+ adcl %ebx, %eax -+DST( movl %ebx, (%edi) ) -+ lea 4(%esi), %esi -+ lea 4(%edi), %edi -+ dec %edx -+ jne 3b -+ adcl $0, %eax -+4: andl $3, %ecx -+ jz 7f -+ cmpl $2, %ecx -+ jb 5f -+SRC( movw (%esi), %cx ) -+ leal 2(%esi), %esi -+DST( movw %cx, (%edi) ) -+ leal 2(%edi), %edi -+ je 6f -+ shll $16,%ecx -+SRC(5: movb (%esi), %cl ) -+DST( movb %cl, (%edi) ) -+6: addl %ecx, %eax -+ adcl $0, %eax -+7: -+5000: -+ -+# Exception handler: -+.section .fixup, "ax" -+ -+6001: -+ movl ARGBASE+20(%esp), %ebx # src_err_ptr -+ movl $-EFAULT, (%ebx) -+ -+ # zero the complete destination - computing the rest -+ # is too much work -+ movl ARGBASE+8(%esp), %edi # dst -+ movl ARGBASE+12(%esp), %ecx # len -+ xorl %eax,%eax -+ rep ; stosb -+ -+ jmp 5000b -+ -+6002: -+ movl ARGBASE+24(%esp), %ebx # dst_err_ptr -+ movl $-EFAULT,(%ebx) -+ jmp 5000b -+ -+.previous -+ -+ popl %ebx -+ popl %esi -+ popl %edi -+ popl %ecx # equivalent to addl $4,%esp -+ ret -+ -+#else -+ -+/* Version for PentiumII/PPro */ -+ -+#define ROUND1(x) \ -+ SRC(movl x(%esi), %ebx ) ; \ -+ addl %ebx, %eax ; \ -+ DST(movl %ebx, x(%edi) ) ; -+ -+#define ROUND(x) \ -+ SRC(movl x(%esi), %ebx ) ; \ -+ adcl %ebx, %eax ; \ -+ DST(movl %ebx, x(%edi) ) ; -+ -+#define ARGBASE 12 -+ -+csum_partial_copy_generic_i386: -+ pushl %ebx -+ pushl %edi -+ pushl %esi -+ movl ARGBASE+4(%esp),%esi #src -+ movl ARGBASE+8(%esp),%edi #dst -+ movl ARGBASE+12(%esp),%ecx #len -+ movl ARGBASE+16(%esp),%eax #sum -+# movl %ecx, %edx -+ movl %ecx, %ebx -+ movl %esi, %edx -+ shrl $6, %ecx -+ andl $0x3c, %ebx -+ negl %ebx -+ subl %ebx, %esi -+ subl %ebx, %edi -+ lea -1(%esi),%edx -+ andl $-32,%edx -+ lea 3f(%ebx,%ebx), %ebx -+ testl %esi, %esi -+ jmp *%ebx -+1: addl $64,%esi -+ addl $64,%edi -+ SRC(movb -32(%edx),%bl) ; SRC(movb (%edx),%bl) -+ ROUND1(-64) ROUND(-60) ROUND(-56) ROUND(-52) -+ ROUND (-48) ROUND(-44) ROUND(-40) ROUND(-36) -+ ROUND (-32) ROUND(-28) ROUND(-24) ROUND(-20) -+ ROUND (-16) ROUND(-12) ROUND(-8) ROUND(-4) -+3: adcl $0,%eax -+ addl $64, %edx -+ dec %ecx -+ jge 1b -+4: movl ARGBASE+12(%esp),%edx #len -+ andl $3, %edx -+ jz 7f -+ cmpl $2, %edx -+ jb 5f -+SRC( movw (%esi), %dx ) -+ leal 2(%esi), %esi -+DST( movw %dx, (%edi) ) -+ leal 2(%edi), %edi -+ je 6f -+ shll $16,%edx -+5: -+SRC( movb (%esi), %dl ) -+DST( movb %dl, (%edi) ) -+6: addl %edx, %eax -+ adcl $0, %eax -+7: -+.section .fixup, "ax" -+6001: movl ARGBASE+20(%esp), %ebx # src_err_ptr -+ movl $-EFAULT, (%ebx) -+ # zero the complete destination (computing the rest is too much work) -+ movl ARGBASE+8(%esp),%edi # dst -+ movl ARGBASE+12(%esp),%ecx # len -+ xorl %eax,%eax -+ rep; stosb -+ jmp 7b -+6002: movl ARGBASE+24(%esp), %ebx # dst_err_ptr -+ movl $-EFAULT, (%ebx) -+ jmp 7b -+.previous -+ -+ popl %esi -+ popl %edi -+ popl %ebx -+ ret -+ -+#undef ROUND -+#undef ROUND1 -+ -+#endif -diff -Naur -X ../exclude-files orig/arch/um/sys-i386/fault.c um/arch/um/sys-i386/fault.c ---- orig/arch/um/sys-i386/fault.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/sys-i386/fault.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,34 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <signal.h> -+#include "sysdep/ptrace.h" -+#include "sysdep/sigcontext.h" -+ -+extern unsigned long search_exception_table(unsigned long addr); -+ -+int arch_fixup(unsigned long address, void *sc_ptr) -+{ -+ struct sigcontext *sc = sc_ptr; -+ unsigned long fixup; -+ -+ fixup = search_exception_table(address); -+ if(fixup != 0){ -+ sc->eip = fixup; -+ return(1); -+ } -+ return(0); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ksyms.c um/arch/um/sys-i386/ksyms.c ---- orig/arch/um/sys-i386/ksyms.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/sys-i386/ksyms.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,17 @@ -+#include "linux/module.h" -+#include "linux/in6.h" -+#include "linux/rwsem.h" -+#include "asm/byteorder.h" -+#include "asm/semaphore.h" -+#include "asm/uaccess.h" -+#include "asm/checksum.h" -+#include "asm/errno.h" -+ -+EXPORT_SYMBOL(__down_failed); -+EXPORT_SYMBOL(__down_failed_interruptible); -+EXPORT_SYMBOL(__down_failed_trylock); -+EXPORT_SYMBOL(__up_wakeup); -+ -+/* Networking helper routines. */ -+EXPORT_SYMBOL(csum_partial_copy_from); -+EXPORT_SYMBOL(csum_partial_copy_to); -diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ldt.c um/arch/um/sys-i386/ldt.c ---- orig/arch/um/sys-i386/ldt.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/sys-i386/ldt.c 2004-01-19 04:01:11.000000000 -0500 -@@ -0,0 +1,94 @@ -+/* -+ * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/config.h" -+#include "linux/slab.h" -+#include "asm/uaccess.h" -+#include "asm/ptrace.h" -+#include "choose-mode.h" -+#include "kern.h" -+ -+#ifdef CONFIG_MODE_TT -+extern int modify_ldt(int func, void *ptr, unsigned long bytecount); -+ -+/* XXX this needs copy_to_user and copy_from_user */ -+ -+int sys_modify_ldt_tt(int func, void *ptr, unsigned long bytecount) -+{ -+ if(verify_area(VERIFY_READ, ptr, bytecount)) return(-EFAULT); -+ return(modify_ldt(func, ptr, bytecount)); -+} -+#endif -+ -+#ifdef CONFIG_MODE_SKAS -+extern int userspace_pid; -+ -+int sys_modify_ldt_skas(int func, void *ptr, unsigned long bytecount) -+{ -+ struct ptrace_ldt ldt; -+ void *buf; -+ int res, n; -+ -+ buf = kmalloc(bytecount, GFP_KERNEL); -+ if(buf == NULL) -+ return(-ENOMEM); -+ -+ res = 0; -+ -+ switch(func){ -+ case 1: -+ case 0x11: -+ res = copy_from_user(buf, ptr, bytecount); -+ break; -+ } -+ -+ if(res != 0){ -+ res = -EFAULT; -+ goto out; -+ } -+ -+ ldt = ((struct ptrace_ldt) { .func = func, -+ .ptr = buf, -+ .bytecount = bytecount }); -+ res = ptrace(PTRACE_LDT, userspace_pid, 0, (unsigned long) &ldt); -+ if(res < 0) -+ goto out; -+ -+ switch(func){ -+ case 0: -+ case 2: -+ n = res; -+ res = copy_to_user(ptr, buf, n); -+ if(res != 0) -+ res = -EFAULT; -+ else -+ res = n; -+ break; -+ } -+ -+ out: -+ kfree(buf); -+ return(res); -+} -+#endif -+ -+int sys_modify_ldt(int func, void *ptr, unsigned long bytecount) -+{ -+ return(CHOOSE_MODE_PROC(sys_modify_ldt_tt, sys_modify_ldt_skas, func, -+ ptr, bytecount)); -+} -+ -+ -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/sys-i386/Makefile um/arch/um/sys-i386/Makefile ---- orig/arch/um/sys-i386/Makefile 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/sys-i386/Makefile 2003-11-09 11:55:24.000000000 -0500 -@@ -0,0 +1,46 @@ -+# -+# Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+# Licensed under the GPL -+# -+ -+O_TARGET = built-in.o -+ -+obj-y = bugs.o checksum.o extable.o fault.o ksyms.o ldt.o ptrace.o \ -+ ptrace_user.o semaphore.o sigcontext.o syscalls.o sysrq.o time.o -+export-objs = ksyms.o -+ -+USER_OBJS = bugs.o ptrace_user.o sigcontext.o fault.o -+ -+SYMLINKS = semaphore.c extable.c -+ -+semaphore.c-dir = kernel -+extable.c-dir = mm -+ -+include $(TOPDIR)/Rules.make -+ -+$(USER_OBJS) : %.o: %.c -+ $(CC) $(CFLAGS_$@) $(USER_CFLAGS) -c -o $@ $< -+ -+define make_link -+ -rm -f $1 -+ ln -sf $(TOPDIR)/arch/i386/$($1-dir)/$1 $1 -+endef -+ -+$(SYMLINKS): -+ $(call make_link,$@) -+ -+clean: -+ $(MAKE) -C util clean -+ rm -f $(SYMLINKS) -+ -+fastdep: -+ -+dep: -+ -+archmrproper: -+ -+archclean: -+ -+archdep: -+ -+modules: -diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ptrace.c um/arch/um/sys-i386/ptrace.c ---- orig/arch/um/sys-i386/ptrace.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/sys-i386/ptrace.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,365 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/sched.h" -+#include "asm/elf.h" -+#include "asm/ptrace.h" -+#include "asm/uaccess.h" -+#include "ptrace_user.h" -+#include "sysdep/sigcontext.h" -+#include "sysdep/sc.h" -+ -+void arch_switch(void) -+{ -+ update_debugregs(current->thread.arch.debugregs_seq); -+} -+ -+int is_syscall(unsigned long addr) -+{ -+ unsigned short instr; -+ int n; -+ -+ n = copy_from_user(&instr, (void *) addr, sizeof(instr)); -+ if(n){ -+ printk("is_syscall : failed to read instruction from 0x%lu\n", -+ addr); -+ return(0); -+ } -+ return(instr == 0x80cd); -+} -+ -+/* determines which flags the user has access to. */ -+/* 1 = access 0 = no access */ -+#define FLAG_MASK 0x00044dd5 -+ -+int putreg(struct task_struct *child, int regno, unsigned long value) -+{ -+ regno >>= 2; -+ switch (regno) { -+ case FS: -+ if (value && (value & 3) != 3) -+ return -EIO; -+ PT_REGS_FS(&child->thread.regs) = value; -+ return 0; -+ case GS: -+ if (value && (value & 3) != 3) -+ return -EIO; -+ PT_REGS_GS(&child->thread.regs) = value; -+ return 0; -+ case DS: -+ case ES: -+ if (value && (value & 3) != 3) -+ return -EIO; -+ value &= 0xffff; -+ break; -+ case SS: -+ case CS: -+ if ((value & 3) != 3) -+ return -EIO; -+ value &= 0xffff; -+ break; -+ case EFL: -+ value &= FLAG_MASK; -+ value |= PT_REGS_EFLAGS(&child->thread.regs); -+ break; -+ } -+ PT_REGS_SET(&child->thread.regs, regno, value); -+ return 0; -+} -+ -+unsigned long getreg(struct task_struct *child, int regno) -+{ -+ unsigned long retval = ~0UL; -+ -+ regno >>= 2; -+ switch (regno) { -+ case FS: -+ case GS: -+ case DS: -+ case ES: -+ case SS: -+ case CS: -+ retval = 0xffff; -+ /* fall through */ -+ default: -+ retval &= PT_REG(&child->thread.regs, regno); -+ } -+ return retval; -+} -+ -+struct i387_fxsave_struct { -+ unsigned short cwd; -+ unsigned short swd; -+ unsigned short twd; -+ unsigned short fop; -+ long fip; -+ long fcs; -+ long foo; -+ long fos; -+ long mxcsr; -+ long reserved; -+ long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */ -+ long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */ -+ long padding[56]; -+}; -+ -+/* -+ * FPU tag word conversions. -+ */ -+ -+static inline unsigned short twd_i387_to_fxsr( unsigned short twd ) -+{ -+ unsigned int tmp; /* to avoid 16 bit prefixes in the code */ -+ -+ /* Transform each pair of bits into 01 (valid) or 00 (empty) */ -+ tmp = ~twd; -+ tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */ -+ /* and move the valid bits to the lower byte. */ -+ tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */ -+ tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */ -+ tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */ -+ return tmp; -+} -+ -+static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave ) -+{ -+ struct _fpxreg *st = NULL; -+ unsigned long twd = (unsigned long) fxsave->twd; -+ unsigned long tag; -+ unsigned long ret = 0xffff0000; -+ int i; -+ -+#define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16); -+ -+ for ( i = 0 ; i < 8 ; i++ ) { -+ if ( twd & 0x1 ) { -+ st = (struct _fpxreg *) FPREG_ADDR( fxsave, i ); -+ -+ switch ( st->exponent & 0x7fff ) { -+ case 0x7fff: -+ tag = 2; /* Special */ -+ break; -+ case 0x0000: -+ if ( !st->significand[0] && -+ !st->significand[1] && -+ !st->significand[2] && -+ !st->significand[3] ) { -+ tag = 1; /* Zero */ -+ } else { -+ tag = 2; /* Special */ -+ } -+ break; -+ default: -+ if ( st->significand[3] & 0x8000 ) { -+ tag = 0; /* Valid */ -+ } else { -+ tag = 2; /* Special */ -+ } -+ break; -+ } -+ } else { -+ tag = 3; /* Empty */ -+ } -+ ret |= (tag << (2 * i)); -+ twd = twd >> 1; -+ } -+ return ret; -+} -+ -+/* -+ * FXSR floating point environment conversions. -+ */ -+ -+#ifdef CONFIG_MODE_TT -+static inline int convert_fxsr_to_user_tt(struct _fpstate *buf, -+ struct pt_regs *regs) -+{ -+ struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs)); -+ unsigned long env[7]; -+ struct _fpreg *to; -+ struct _fpxreg *from; -+ int i; -+ -+ env[0] = (unsigned long)fxsave->cwd | 0xffff0000; -+ env[1] = (unsigned long)fxsave->swd | 0xffff0000; -+ env[2] = twd_fxsr_to_i387(fxsave); -+ env[3] = fxsave->fip; -+ env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16); -+ env[5] = fxsave->foo; -+ env[6] = fxsave->fos; -+ -+ if ( __copy_to_user( buf, env, 7 * sizeof(unsigned long) ) ) -+ return 1; -+ -+ to = &buf->_st[0]; -+ from = (struct _fpxreg *) &fxsave->st_space[0]; -+ for ( i = 0 ; i < 8 ; i++, to++, from++ ) { -+ if ( __copy_to_user( to, from, sizeof(*to) ) ) -+ return 1; -+ } -+ return 0; -+} -+#endif -+ -+static inline int convert_fxsr_to_user(struct _fpstate *buf, -+ struct pt_regs *regs) -+{ -+ return(CHOOSE_MODE(convert_fxsr_to_user_tt(buf, regs), 0)); -+} -+ -+#ifdef CONFIG_MODE_TT -+static inline int convert_fxsr_from_user_tt(struct pt_regs *regs, -+ struct _fpstate *buf) -+{ -+ struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs)); -+ unsigned long env[7]; -+ struct _fpxreg *to; -+ struct _fpreg *from; -+ int i; -+ -+ if ( __copy_from_user( env, buf, 7 * sizeof(long) ) ) -+ return 1; -+ -+ fxsave->cwd = (unsigned short)(env[0] & 0xffff); -+ fxsave->swd = (unsigned short)(env[1] & 0xffff); -+ fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff)); -+ fxsave->fip = env[3]; -+ fxsave->fop = (unsigned short)((env[4] & 0xffff0000) >> 16); -+ fxsave->fcs = (env[4] & 0xffff); -+ fxsave->foo = env[5]; -+ fxsave->fos = env[6]; -+ -+ to = (struct _fpxreg *) &fxsave->st_space[0]; -+ from = &buf->_st[0]; -+ for ( i = 0 ; i < 8 ; i++, to++, from++ ) { -+ if ( __copy_from_user( to, from, sizeof(*from) ) ) -+ return 1; -+ } -+ return 0; -+} -+#endif -+ -+static inline int convert_fxsr_from_user(struct pt_regs *regs, -+ struct _fpstate *buf) -+{ -+ return(CHOOSE_MODE(convert_fxsr_from_user_tt(regs, buf), 0)); -+} -+ -+int get_fpregs(unsigned long buf, struct task_struct *child) -+{ -+ int err; -+ -+ err = convert_fxsr_to_user((struct _fpstate *) buf, -+ &child->thread.regs); -+ if(err) return(-EFAULT); -+ else return(0); -+} -+ -+int set_fpregs(unsigned long buf, struct task_struct *child) -+{ -+ int err; -+ -+ err = convert_fxsr_from_user(&child->thread.regs, -+ (struct _fpstate *) buf); -+ if(err) return(-EFAULT); -+ else return(0); -+} -+ -+#ifdef CONFIG_MODE_TT -+int get_fpxregs_tt(unsigned long buf, struct task_struct *tsk) -+{ -+ struct pt_regs *regs = &tsk->thread.regs; -+ struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs)); -+ int err; -+ -+ err = __copy_to_user((void *) buf, fxsave, -+ sizeof(struct user_fxsr_struct)); -+ if(err) return -EFAULT; -+ else return 0; -+} -+#endif -+ -+int get_fpxregs(unsigned long buf, struct task_struct *tsk) -+{ -+ return(CHOOSE_MODE(get_fpxregs_tt(buf, tsk), 0)); -+} -+ -+#ifdef CONFIG_MODE_TT -+int set_fpxregs_tt(unsigned long buf, struct task_struct *tsk) -+{ -+ struct pt_regs *regs = &tsk->thread.regs; -+ struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs)); -+ int err; -+ -+ err = __copy_from_user(fxsave, (void *) buf, -+ sizeof(struct user_fxsr_struct) ); -+ if(err) return -EFAULT; -+ else return 0; -+} -+#endif -+ -+int set_fpxregs(unsigned long buf, struct task_struct *tsk) -+{ -+ return(CHOOSE_MODE(set_fpxregs_tt(buf, tsk), 0)); -+} -+ -+#ifdef notdef -+int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu) -+{ -+ fpu->cwd = (((SC_FP_CW(PT_REGS_SC(regs)) & 0xffff) << 16) | -+ (SC_FP_SW(PT_REGS_SC(regs)) & 0xffff)); -+ fpu->swd = SC_FP_CSSEL(PT_REGS_SC(regs)) & 0xffff; -+ fpu->twd = SC_FP_IPOFF(PT_REGS_SC(regs)); -+ fpu->fip = SC_FP_CSSEL(PT_REGS_SC(regs)) & 0xffff; -+ fpu->fcs = SC_FP_DATAOFF(PT_REGS_SC(regs)); -+ fpu->foo = SC_FP_DATASEL(PT_REGS_SC(regs)); -+ fpu->fos = 0; -+ memcpy(fpu->st_space, (void *) SC_FP_ST(PT_REGS_SC(regs)), -+ sizeof(fpu->st_space)); -+ return(1); -+} -+#endif -+ -+#ifdef CONFIG_MODE_TT -+static inline void copy_fpu_fxsave_tt(struct pt_regs *regs, -+ struct user_i387_struct *buf) -+{ -+ struct i387_fxsave_struct *fpu = SC_FXSR_ENV(PT_REGS_SC(regs)); -+ unsigned short *to; -+ unsigned short *from; -+ int i; -+ -+ memcpy( buf, fpu, 7 * sizeof(long) ); -+ -+ to = (unsigned short *) &buf->st_space[0]; -+ from = (unsigned short *) &fpu->st_space[0]; -+ for ( i = 0 ; i < 8 ; i++, to += 5, from += 8 ) { -+ memcpy( to, from, 5 * sizeof(unsigned short) ); -+ } -+} -+#endif -+ -+static inline void copy_fpu_fxsave(struct pt_regs *regs, -+ struct user_i387_struct *buf) -+{ -+ (void) CHOOSE_MODE(copy_fpu_fxsave_tt(regs, buf), 0); -+} -+ -+int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu ) -+{ -+ copy_fpu_fxsave(regs, (struct user_i387_struct *) fpu); -+ return(1); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/sys-i386/ptrace_user.c um/arch/um/sys-i386/ptrace_user.c ---- orig/arch/um/sys-i386/ptrace_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/sys-i386/ptrace_user.c 2003-12-17 01:33:17.000000000 -0500 -@@ -0,0 +1,117 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <stdio.h> -+#include <errno.h> -+#include <unistd.h> -+#include <linux/stddef.h> -+#include <sys/ptrace.h> -+#include <asm/ptrace.h> -+#include <asm/user.h> -+#include "kern_util.h" -+#include "sysdep/thread.h" -+#include "user.h" -+#include "os.h" -+ -+int ptrace_getregs(long pid, unsigned long *regs_out) -+{ -+ return(ptrace(PTRACE_GETREGS, pid, 0, regs_out)); -+} -+ -+int ptrace_setregs(long pid, unsigned long *regs) -+{ -+ return(ptrace(PTRACE_SETREGS, pid, 0, regs)); -+} -+ -+int ptrace_getfpregs(long pid, unsigned long *regs) -+{ -+ return(ptrace(PTRACE_GETFPREGS, pid, 0, regs)); -+} -+ -+static void write_debugregs(int pid, unsigned long *regs) -+{ -+ struct user *dummy; -+ int nregs, i; -+ -+ dummy = NULL; -+ nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]); -+ for(i = 0; i < nregs; i++){ -+ if((i == 4) || (i == 5)) continue; -+ if(ptrace(PTRACE_POKEUSER, pid, &dummy->u_debugreg[i], -+ regs[i]) < 0) -+ printk("write_debugregs - ptrace failed on " -+ "register %d, errno = %d\n", errno); -+ } -+} -+ -+static void read_debugregs(int pid, unsigned long *regs) -+{ -+ struct user *dummy; -+ int nregs, i; -+ -+ dummy = NULL; -+ nregs = sizeof(dummy->u_debugreg)/sizeof(dummy->u_debugreg[0]); -+ for(i = 0; i < nregs; i++){ -+ regs[i] = ptrace(PTRACE_PEEKUSER, pid, -+ &dummy->u_debugreg[i], 0); -+ } -+} -+ -+/* Accessed only by the tracing thread */ -+static unsigned long kernel_debugregs[8] = { [ 0 ... 7 ] = 0 }; -+static int debugregs_seq = 0; -+ -+void arch_enter_kernel(void *task, int pid) -+{ -+ read_debugregs(pid, TASK_DEBUGREGS(task)); -+ write_debugregs(pid, kernel_debugregs); -+} -+ -+void arch_leave_kernel(void *task, int pid) -+{ -+ read_debugregs(pid, kernel_debugregs); -+ write_debugregs(pid, TASK_DEBUGREGS(task)); -+} -+ -+void ptrace_pokeuser(unsigned long addr, unsigned long data) -+{ -+ if((addr < offsetof(struct user, u_debugreg[0])) || -+ (addr > offsetof(struct user, u_debugreg[7]))) -+ return; -+ addr -= offsetof(struct user, u_debugreg[0]); -+ addr = addr >> 2; -+ if(kernel_debugregs[addr] == data) return; -+ -+ kernel_debugregs[addr] = data; -+ debugregs_seq++; -+} -+ -+static void update_debugregs_cb(void *arg) -+{ -+ int pid = *((int *) arg); -+ -+ write_debugregs(pid, kernel_debugregs); -+} -+ -+void update_debugregs(int seq) -+{ -+ int me; -+ -+ if(seq == debugregs_seq) return; -+ -+ me = os_getpid(); -+ initial_thread_cb(update_debugregs_cb, &me); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/sys-i386/sigcontext.c um/arch/um/sys-i386/sigcontext.c ---- orig/arch/um/sys-i386/sigcontext.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/sys-i386/sigcontext.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,80 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include <stddef.h> -+#include <string.h> -+#include <asm/ptrace.h> -+#include <asm/sigcontext.h> -+#include "sysdep/ptrace.h" -+#include "kern_util.h" -+#include "frame_user.h" -+ -+int sc_size(void *data) -+{ -+ struct arch_frame_data *arch = data; -+ -+ return(sizeof(struct sigcontext) + arch->fpstate_size); -+} -+ -+void sc_to_sc(void *to_ptr, void *from_ptr) -+{ -+ struct sigcontext *to = to_ptr, *from = from_ptr; -+ int size = sizeof(*to) + signal_frame_sc.common.arch.fpstate_size; -+ -+ memcpy(to, from, size); -+ if(from->fpstate != NULL) to->fpstate = (struct _fpstate *) (to + 1); -+} -+ -+unsigned long *sc_sigmask(void *sc_ptr) -+{ -+ struct sigcontext *sc = sc_ptr; -+ -+ return(&sc->oldmask); -+} -+ -+int sc_get_fpregs(unsigned long buf, void *sc_ptr) -+{ -+ struct sigcontext *sc = sc_ptr; -+ struct _fpstate *from = sc->fpstate, *to = (struct _fpstate *) buf; -+ int err = 0; -+ -+ if(from == NULL){ -+ err |= clear_user_proc(&to->cw, sizeof(to->cw)); -+ err |= clear_user_proc(&to->sw, sizeof(to->sw)); -+ err |= clear_user_proc(&to->tag, sizeof(to->tag)); -+ err |= clear_user_proc(&to->ipoff, sizeof(to->ipoff)); -+ err |= clear_user_proc(&to->cssel, sizeof(to->cssel)); -+ err |= clear_user_proc(&to->dataoff, sizeof(to->dataoff)); -+ err |= clear_user_proc(&to->datasel, sizeof(to->datasel)); -+ err |= clear_user_proc(&to->_st, sizeof(to->_st)); -+ } -+ else { -+ err |= copy_to_user_proc(&to->cw, &from->cw, sizeof(to->cw)); -+ err |= copy_to_user_proc(&to->sw, &from->sw, sizeof(to->sw)); -+ err |= copy_to_user_proc(&to->tag, &from->tag, -+ sizeof(to->tag)); -+ err |= copy_to_user_proc(&to->ipoff, &from->ipoff, -+ sizeof(to->ipoff)); -+ err |= copy_to_user_proc(&to->cssel,& from->cssel, -+ sizeof(to->cssel)); -+ err |= copy_to_user_proc(&to->dataoff, &from->dataoff, -+ sizeof(to->dataoff)); -+ err |= copy_to_user_proc(&to->datasel, &from->datasel, -+ sizeof(to->datasel)); -+ err |= copy_to_user_proc(to->_st, from->_st, sizeof(to->_st)); -+ } -+ return(err); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/sys-i386/syscalls.c um/arch/um/sys-i386/syscalls.c ---- orig/arch/um/sys-i386/syscalls.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/sys-i386/syscalls.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,68 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "asm/mman.h" -+#include "asm/uaccess.h" -+#include "asm/unistd.h" -+ -+/* -+ * Perform the select(nd, in, out, ex, tv) and mmap() system -+ * calls. Linux/i386 didn't use to be able to handle more than -+ * 4 system call parameters, so these system calls used a memory -+ * block for parameter passing.. -+ */ -+ -+struct mmap_arg_struct { -+ unsigned long addr; -+ unsigned long len; -+ unsigned long prot; -+ unsigned long flags; -+ unsigned long fd; -+ unsigned long offset; -+}; -+ -+extern int old_mmap(unsigned long addr, unsigned long len, -+ unsigned long prot, unsigned long flags, -+ unsigned long fd, unsigned long offset); -+ -+int old_mmap_i386(struct mmap_arg_struct *arg) -+{ -+ struct mmap_arg_struct a; -+ int err = -EFAULT; -+ -+ if (copy_from_user(&a, arg, sizeof(a))) -+ goto out; -+ -+ err = old_mmap(a.addr, a.len, a.prot, a.flags, a.fd, a.offset); -+ out: -+ return err; -+} -+ -+struct sel_arg_struct { -+ unsigned long n; -+ fd_set *inp, *outp, *exp; -+ struct timeval *tvp; -+}; -+ -+int old_select(struct sel_arg_struct *arg) -+{ -+ struct sel_arg_struct a; -+ -+ if (copy_from_user(&a, arg, sizeof(a))) -+ return -EFAULT; -+ /* sys_select() does the appropriate kernel locking */ -+ return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/sys-i386/sysrq.c um/arch/um/sys-i386/sysrq.c ---- orig/arch/um/sys-i386/sysrq.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/sys-i386/sysrq.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,30 @@ -+#include "linux/kernel.h" -+#include "linux/smp.h" -+#include "linux/sched.h" -+#include "asm/ptrace.h" -+#include "sysrq.h" -+ -+void show_regs(struct pt_regs *regs) -+{ -+ printk("\n"); -+ printk("EIP: %04lx:[<%08lx>] CPU: %d %s", -+ 0xffff & PT_REGS_CS(regs), PT_REGS_IP(regs), -+ smp_processor_id(), print_tainted()); -+ if (PT_REGS_CS(regs) & 3) -+ printk(" ESP: %04lx:%08lx", 0xffff & PT_REGS_SS(regs), -+ PT_REGS_SP(regs)); -+ printk(" EFLAGS: %08lx\n %s\n", PT_REGS_EFLAGS(regs), -+ print_tainted()); -+ printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", -+ PT_REGS_EAX(regs), PT_REGS_EBX(regs), -+ PT_REGS_ECX(regs), -+ PT_REGS_EDX(regs)); -+ printk("ESI: %08lx EDI: %08lx EBP: %08lx", -+ PT_REGS_ESI(regs), PT_REGS_EDI(regs), -+ PT_REGS_EBP(regs)); -+ printk(" DS: %04lx ES: %04lx\n", -+ 0xffff & PT_REGS_DS(regs), -+ 0xffff & PT_REGS_ES(regs)); -+ -+ show_trace((unsigned long *) ®s); -+} -diff -Naur -X ../exclude-files orig/arch/um/sys-i386/time.c um/arch/um/sys-i386/time.c ---- orig/arch/um/sys-i386/time.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/sys-i386/time.c 2003-11-10 01:46:49.000000000 -0500 -@@ -0,0 +1,24 @@ -+/* -+ * sys-i386/time.c -+ * Created 25.9.2002 Sapan Bhatia -+ * -+ */ -+ -+unsigned long long time_stamp(void) -+{ -+ unsigned long low, high; -+ -+ asm("rdtsc" : "=a" (low), "=d" (high)); -+ return((((unsigned long long) high) << 32) + low); -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/sys-i386/util/Makefile um/arch/um/sys-i386/util/Makefile ---- orig/arch/um/sys-i386/util/Makefile 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/sys-i386/util/Makefile 2003-11-08 08:26:40.000000000 -0500 -@@ -0,0 +1,28 @@ -+EXE = mk_sc mk_thread -+ -+include $(TOPDIR)/Rules.make -+ -+all : $(EXE) -+ -+mk_sc : mk_sc.o -+ $(HOSTCC) -o mk_sc mk_sc.o -+ -+mk_sc.o : mk_sc.c -+ $(HOSTCC) -c $< -+ -+mk_thread : mk_thread_user.o mk_thread_kern.o -+ $(HOSTCC) -o mk_thread mk_thread_user.o mk_thread_kern.o -+ -+mk_thread_user.o : mk_thread_user.c -+ $(HOSTCC) -c $< -+ -+mk_thread_kern.o : mk_thread_kern.c -+ $(HOSTCC) $(CFLAGS) -c $< -+ -+clean : -+ $(RM) $(EXE) *.o -+ -+archmrproper : clean -+ -+fastdep : -+ -diff -Naur -X ../exclude-files orig/arch/um/sys-i386/util/mk_sc.c um/arch/um/sys-i386/util/mk_sc.c ---- orig/arch/um/sys-i386/util/mk_sc.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/sys-i386/util/mk_sc.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,52 @@ -+#include <stdio.h> -+#include <signal.h> -+#include <linux/stddef.h> -+ -+#define SC_OFFSET(name, field) \ -+ printf("#define " name "(sc) *((unsigned long *) &(((char *) (sc))[%d]))\n",\ -+ offsetof(struct sigcontext, field)) -+ -+#define SC_FP_OFFSET(name, field) \ -+ printf("#define " name \ -+ "(sc) *((unsigned long *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\ -+ offsetof(struct _fpstate, field)) -+ -+#define SC_FP_OFFSET_PTR(name, field, type) \ -+ printf("#define " name \ -+ "(sc) ((" type " *) &(((char *) (SC_FPSTATE(sc)))[%d]))\n",\ -+ offsetof(struct _fpstate, field)) -+ -+int main(int argc, char **argv) -+{ -+ SC_OFFSET("SC_IP", eip); -+ SC_OFFSET("SC_SP", esp); -+ SC_OFFSET("SC_FS", fs); -+ SC_OFFSET("SC_GS", gs); -+ SC_OFFSET("SC_DS", ds); -+ SC_OFFSET("SC_ES", es); -+ SC_OFFSET("SC_SS", ss); -+ SC_OFFSET("SC_CS", cs); -+ SC_OFFSET("SC_EFLAGS", eflags); -+ SC_OFFSET("SC_EAX", eax); -+ SC_OFFSET("SC_EBX", ebx); -+ SC_OFFSET("SC_ECX", ecx); -+ SC_OFFSET("SC_EDX", edx); -+ SC_OFFSET("SC_EDI", edi); -+ SC_OFFSET("SC_ESI", esi); -+ SC_OFFSET("SC_EBP", ebp); -+ SC_OFFSET("SC_TRAPNO", trapno); -+ SC_OFFSET("SC_ERR", err); -+ SC_OFFSET("SC_CR2", cr2); -+ SC_OFFSET("SC_FPSTATE", fpstate); -+ SC_OFFSET("SC_SIGMASK", oldmask); -+ SC_FP_OFFSET("SC_FP_CW", cw); -+ SC_FP_OFFSET("SC_FP_SW", sw); -+ SC_FP_OFFSET("SC_FP_TAG", tag); -+ SC_FP_OFFSET("SC_FP_IPOFF", ipoff); -+ SC_FP_OFFSET("SC_FP_CSSEL", cssel); -+ SC_FP_OFFSET("SC_FP_DATAOFF", dataoff); -+ SC_FP_OFFSET("SC_FP_DATASEL", datasel); -+ SC_FP_OFFSET_PTR("SC_FP_ST", _st, "struct _fpstate"); -+ SC_FP_OFFSET_PTR("SC_FXSR_ENV", _fxsr_env, "void"); -+ return(0); -+} -diff -Naur -X ../exclude-files orig/arch/um/sys-i386/util/mk_thread_kern.c um/arch/um/sys-i386/util/mk_thread_kern.c ---- orig/arch/um/sys-i386/util/mk_thread_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/sys-i386/util/mk_thread_kern.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,22 @@ -+#include "linux/config.h" -+#include "linux/stddef.h" -+#include "linux/sched.h" -+ -+extern void print_head(void); -+extern void print_constant_ptr(char *name, int value); -+extern void print_constant(char *name, char *type, int value); -+extern void print_tail(void); -+ -+#define THREAD_OFFSET(field) offsetof(struct task_struct, thread.field) -+ -+int main(int argc, char **argv) -+{ -+ print_head(); -+ print_constant_ptr("TASK_DEBUGREGS", THREAD_OFFSET(arch.debugregs)); -+#ifdef CONFIG_MODE_TT -+ print_constant("TASK_EXTERN_PID", "int", THREAD_OFFSET(mode.tt.extern_pid)); -+#endif -+ print_tail(); -+ return(0); -+} -+ -diff -Naur -X ../exclude-files orig/arch/um/sys-i386/util/mk_thread_user.c um/arch/um/sys-i386/util/mk_thread_user.c ---- orig/arch/um/sys-i386/util/mk_thread_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/sys-i386/util/mk_thread_user.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,30 @@ -+#include <stdio.h> -+ -+void print_head(void) -+{ -+ printf("/*\n"); -+ printf(" * Generated by mk_thread\n"); -+ printf(" */\n"); -+ printf("\n"); -+ printf("#ifndef __UM_THREAD_H\n"); -+ printf("#define __UM_THREAD_H\n"); -+ printf("\n"); -+} -+ -+void print_constant_ptr(char *name, int value) -+{ -+ printf("#define %s(task) ((unsigned long *) " -+ "&(((char *) (task))[%d]))\n", name, value); -+} -+ -+void print_constant(char *name, char *type, int value) -+{ -+ printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type, -+ value); -+} -+ -+void print_tail(void) -+{ -+ printf("\n"); -+ printf("#endif\n"); -+} -diff -Naur -X ../exclude-files orig/arch/um/sys-ia64/Makefile um/arch/um/sys-ia64/Makefile ---- orig/arch/um/sys-ia64/Makefile 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/sys-ia64/Makefile 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,26 @@ -+OBJ = sys.o -+ -+OBJS = -+ -+all: $(OBJ) -+ -+$(OBJ): $(OBJS) -+ rm -f $@ -+ $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@ -+clean: -+ rm -f $(OBJS) -+ -+fastdep: -+ -+archmrproper: -+ -+archclean: -+ rm -f link.ld -+ @$(MAKEBOOT) clean -+ -+archdep: -+ @$(MAKEBOOT) dep -+ -+modules: -+ -+include $(TOPDIR)/Rules.make -diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/Makefile um/arch/um/sys-ppc/Makefile ---- orig/arch/um/sys-ppc/Makefile 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/sys-ppc/Makefile 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,80 @@ -+OBJ = sys.o -+ -+.S.o: -+ $(CC) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o -+ -+OBJS = ptrace.o sigcontext.o semaphore.o checksum.o miscthings.o misc.o \ -+ ptrace_user.o sysrq.o -+ -+EXTRA_AFLAGS := -DCONFIG_ALL_PPC -I. -I$(TOPDIR)/arch/ppc/kernel -+ -+all: $(OBJ) -+ -+$(OBJ): $(OBJS) -+ rm -f $@ -+ $(LD) $(LINKFLAGS) --start-group $^ --end-group -o $@ -+ -+ptrace_user.o: ptrace_user.c -+ $(CC) -D__KERNEL__ $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $< -+ -+sigcontext.o: sigcontext.c -+ $(CC) $(USER_CFLAGS) $(EXTRA_CFLAGS) -c -o $@ $< -+ -+semaphore.c: -+ rm -f $@ -+ ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@ -+ -+checksum.S: -+ rm -f $@ -+ ln -s $(TOPDIR)/arch/ppc/lib/$@ $@ -+ -+mk_defs.c: -+ rm -f $@ -+ ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@ -+ -+ppc_defs.head: -+ rm -f $@ -+ ln -s $(TOPDIR)/arch/ppc/kernel/$@ $@ -+ -+ppc_defs.h: mk_defs.c ppc_defs.head \ -+ $(TOPDIR)/include/asm-ppc/mmu.h \ -+ $(TOPDIR)/include/asm-ppc/processor.h \ -+ $(TOPDIR)/include/asm-ppc/pgtable.h \ -+ $(TOPDIR)/include/asm-ppc/ptrace.h -+# $(CC) $(CFLAGS) -S mk_defs.c -+ cp ppc_defs.head ppc_defs.h -+# for bk, this way we can write to the file even if it's not checked out -+ echo '#define THREAD 608' >> ppc_defs.h -+ echo '#define PT_REGS 8' >> ppc_defs.h -+ echo '#define CLONE_VM 256' >> ppc_defs.h -+# chmod u+w ppc_defs.h -+# grep '^#define' mk_defs.s >> ppc_defs.h -+# rm mk_defs.s -+ -+# the asm link is horrible, and breaks the other targets. This is also -+# not going to work with parallel makes. -+ -+checksum.o: checksum.S -+ rm -f asm -+ ln -s $(TOPDIR)/include/asm-ppc asm -+ $(CC) $(EXTRA_AFLAGS) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o -+ rm -f asm -+ -+misc.o: misc.S ppc_defs.h -+ rm -f asm -+ ln -s $(TOPDIR)/include/asm-ppc asm -+ $(CC) $(EXTRA_AFLAGS) $(AFLAGS) -D__ASSEMBLY__ -D__UM_PPC__ -c $< -o $*.o -+ rm -f asm -+ -+clean: -+ rm -f $(OBJS) -+ rm -f ppc_defs.h -+ rm -f checksum.S semaphore.c mk_defs.c -+ -+fastdep: -+ -+dep: -+ -+modules: -+ -+include $(TOPDIR)/Rules.make -diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/misc.S um/arch/um/sys-ppc/misc.S ---- orig/arch/um/sys-ppc/misc.S 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/sys-ppc/misc.S 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,116 @@ -+/* -+ * This file contains miscellaneous low-level functions. -+ * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) -+ * -+ * Largely rewritten by Cort Dougan (cort@cs.nmt.edu) -+ * and Paul Mackerras. -+ * -+ * A couple of functions stolen from arch/ppc/kernel/misc.S for UML -+ * by Chris Emerson. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ * -+ */ -+ -+#include <linux/config.h> -+#include <asm/processor.h> -+#include "ppc_asm.h" -+ -+#if defined(CONFIG_4xx) || defined(CONFIG_8xx) -+#define CACHE_LINE_SIZE 16 -+#define LG_CACHE_LINE_SIZE 4 -+#define MAX_COPY_PREFETCH 1 -+#elif !defined(CONFIG_PPC64BRIDGE) -+#define CACHE_LINE_SIZE 32 -+#define LG_CACHE_LINE_SIZE 5 -+#define MAX_COPY_PREFETCH 4 -+#else -+#define CACHE_LINE_SIZE 128 -+#define LG_CACHE_LINE_SIZE 7 -+#define MAX_COPY_PREFETCH 1 -+#endif /* CONFIG_4xx || CONFIG_8xx */ -+ -+ .text -+ -+/* -+ * Clear a page using the dcbz instruction, which doesn't cause any -+ * memory traffic (except to write out any cache lines which get -+ * displaced). This only works on cacheable memory. -+ */ -+_GLOBAL(clear_page) -+ li r0,4096/CACHE_LINE_SIZE -+ mtctr r0 -+#ifdef CONFIG_8xx -+ li r4, 0 -+1: stw r4, 0(r3) -+ stw r4, 4(r3) -+ stw r4, 8(r3) -+ stw r4, 12(r3) -+#else -+1: dcbz 0,r3 -+#endif -+ addi r3,r3,CACHE_LINE_SIZE -+ bdnz 1b -+ blr -+ -+/* -+ * Copy a whole page. We use the dcbz instruction on the destination -+ * to reduce memory traffic (it eliminates the unnecessary reads of -+ * the destination into cache). This requires that the destination -+ * is cacheable. -+ */ -+#define COPY_16_BYTES \ -+ lwz r6,4(r4); \ -+ lwz r7,8(r4); \ -+ lwz r8,12(r4); \ -+ lwzu r9,16(r4); \ -+ stw r6,4(r3); \ -+ stw r7,8(r3); \ -+ stw r8,12(r3); \ -+ stwu r9,16(r3) -+ -+_GLOBAL(copy_page) -+ addi r3,r3,-4 -+ addi r4,r4,-4 -+ li r5,4 -+ -+#ifndef CONFIG_8xx -+#if MAX_COPY_PREFETCH > 1 -+ li r0,MAX_COPY_PREFETCH -+ li r11,4 -+ mtctr r0 -+11: dcbt r11,r4 -+ addi r11,r11,CACHE_LINE_SIZE -+ bdnz 11b -+#else /* MAX_COPY_PREFETCH == 1 */ -+ dcbt r5,r4 -+ li r11,CACHE_LINE_SIZE+4 -+#endif /* MAX_COPY_PREFETCH */ -+#endif /* CONFIG_8xx */ -+ -+ li r0,4096/CACHE_LINE_SIZE -+ mtctr r0 -+1: -+#ifndef CONFIG_8xx -+ dcbt r11,r4 -+ dcbz r5,r3 -+#endif -+ COPY_16_BYTES -+#if CACHE_LINE_SIZE >= 32 -+ COPY_16_BYTES -+#if CACHE_LINE_SIZE >= 64 -+ COPY_16_BYTES -+ COPY_16_BYTES -+#if CACHE_LINE_SIZE >= 128 -+ COPY_16_BYTES -+ COPY_16_BYTES -+ COPY_16_BYTES -+ COPY_16_BYTES -+#endif -+#endif -+#endif -+ bdnz 1b -+ blr -diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/miscthings.c um/arch/um/sys-ppc/miscthings.c ---- orig/arch/um/sys-ppc/miscthings.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/sys-ppc/miscthings.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,53 @@ -+#include "linux/threads.h" -+#include "linux/stddef.h" // for NULL -+#include "linux/elf.h" // for AT_NULL -+ -+/* The following function nicked from arch/ppc/kernel/process.c and -+ * adapted slightly */ -+/* -+ * XXX ld.so expects the auxiliary table to start on -+ * a 16-byte boundary, so we have to find it and -+ * move it up. :-( -+ */ -+void shove_aux_table(unsigned long sp) -+{ -+ int argc; -+ char *p; -+ unsigned long e; -+ unsigned long aux_start, offset; -+ -+ argc = *(int *)sp; -+ sp += sizeof(int) + (argc + 1) * sizeof(char *); -+ /* skip over the environment pointers */ -+ do { -+ p = *(char **)sp; -+ sp += sizeof(char *); -+ } while (p != NULL); -+ aux_start = sp; -+ /* skip to the end of the auxiliary table */ -+ do { -+ e = *(unsigned long *)sp; -+ sp += 2 * sizeof(unsigned long); -+ } while (e != AT_NULL); -+ offset = ((aux_start + 15) & ~15) - aux_start; -+ if (offset != 0) { -+ do { -+ sp -= sizeof(unsigned long); -+ e = *(unsigned long *)sp; -+ *(unsigned long *)(sp + offset) = e; -+ } while (sp > aux_start); -+ } -+} -+/* END stuff taken from arch/ppc/kernel/process.c */ -+ -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/ptrace.c um/arch/um/sys-ppc/ptrace.c ---- orig/arch/um/sys-ppc/ptrace.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/sys-ppc/ptrace.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,28 @@ -+#include "linux/sched.h" -+#include "asm/ptrace.h" -+ -+int putreg(struct task_struct *child, unsigned long regno, -+ unsigned long value) -+{ -+ child->thread.process_regs.regs[regno >> 2] = value; -+ return 0; -+} -+ -+unsigned long getreg(struct task_struct *child, unsigned long regno) -+{ -+ unsigned long retval = ~0UL; -+ -+ retval &= child->thread.process_regs.regs[regno >> 2]; -+ return retval; -+} -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/ptrace_user.c um/arch/um/sys-ppc/ptrace_user.c ---- orig/arch/um/sys-ppc/ptrace_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/sys-ppc/ptrace_user.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,40 @@ -+#include <sys/ptrace.h> -+#include <errno.h> -+#include <asm/ptrace.h> -+#include "sysdep/ptrace.h" -+ -+int ptrace_getregs(long pid, unsigned long *regs_out) -+{ -+ int i; -+ for (i=0; i < sizeof(struct sys_pt_regs)/sizeof(PPC_REG); ++i) { -+ errno = 0; -+ regs_out->regs[i] = ptrace(PTRACE_PEEKUSER, pid, i*4, 0); -+ if (errno) { -+ return -errno; -+ } -+ } -+ return 0; -+} -+ -+int ptrace_setregs(long pid, unsigned long *regs_in) -+{ -+ int i; -+ for (i=0; i < sizeof(struct sys_pt_regs)/sizeof(PPC_REG); ++i) { -+ if (i != 34 /* FIXME: PT_ORIG_R3 */ && i <= PT_MQ) { -+ if (ptrace(PTRACE_POKEUSER, pid, i*4, regs_in->regs[i]) < 0) { -+ return -errno; -+ } -+ } -+ } -+ return 0; -+} -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/sigcontext.c um/arch/um/sys-ppc/sigcontext.c ---- orig/arch/um/sys-ppc/sigcontext.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/sys-ppc/sigcontext.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,15 @@ -+#include "asm/ptrace.h" -+#include "asm/sigcontext.h" -+#include "sysdep/ptrace.h" -+#include "user_util.h" -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/sys-ppc/sysrq.c um/arch/um/sys-ppc/sysrq.c ---- orig/arch/um/sys-ppc/sysrq.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/sys-ppc/sysrq.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,43 @@ -+/* -+ * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/kernel.h" -+#include "linux/smp.h" -+#include "asm/ptrace.h" -+#include "sysrq.h" -+ -+void show_regs(struct pt_regs_subarch *regs) -+{ -+ printk("\n"); -+ printk("show_regs(): insert regs here.\n"); -+#if 0 -+ printk("\n"); -+ printk("EIP: %04x:[<%08lx>] CPU: %d",0xffff & regs->xcs, regs->eip, -+ smp_processor_id()); -+ if (regs->xcs & 3) -+ printk(" ESP: %04x:%08lx",0xffff & regs->xss, regs->esp); -+ printk(" EFLAGS: %08lx\n", regs->eflags); -+ printk("EAX: %08lx EBX: %08lx ECX: %08lx EDX: %08lx\n", -+ regs->eax, regs->ebx, regs->ecx, regs->edx); -+ printk("ESI: %08lx EDI: %08lx EBP: %08lx", -+ regs->esi, regs->edi, regs->ebp); -+ printk(" DS: %04x ES: %04x\n", -+ 0xffff & regs->xds, 0xffff & regs->xes); -+#endif -+ -+ show_trace(®s->gpr[1]); -+} -+ -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/arch/um/util/Makefile um/arch/um/util/Makefile ---- orig/arch/um/util/Makefile 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/util/Makefile 2003-11-08 02:51:30.000000000 -0500 -@@ -0,0 +1,26 @@ -+ALL = mk_task mk_constants -+ -+all : $(ALL) -+ -+mk_task : mk_task_user.o mk_task_kern.o -+ $(HOSTCC) -o mk_task mk_task_user.o mk_task_kern.o -+ -+mk_task_user.o : mk_task_user.c -+ $(HOSTCC) -c $< -+ -+mk_task_kern.o : mk_task_kern.c -+ $(HOSTCC) $(CFLAGS) -c $< -+ -+mk_constants : mk_constants_user.o mk_constants_kern.o -+ $(HOSTCC) -o mk_constants mk_constants_user.o mk_constants_kern.o -+ -+mk_constants_user.o : mk_constants_user.c -+ $(HOSTCC) -c $< -+ -+mk_constants_kern.o : mk_constants_kern.c -+ $(HOSTCC) $(CFLAGS) -c $< -+ -+clean : -+ $(RM) $(ALL) *.o *~ -+ -+archmrproper : clean -diff -Naur -X ../exclude-files orig/arch/um/util/mk_constants_kern.c um/arch/um/util/mk_constants_kern.c ---- orig/arch/um/util/mk_constants_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/util/mk_constants_kern.c 2004-01-10 06:54:51.000000000 -0500 -@@ -0,0 +1,25 @@ -+#include "linux/kernel.h" -+#include "linux/stringify.h" -+#include "asm/page.h" -+ -+extern void print_head(void); -+extern void print_constant_str(char *name, char *value); -+extern void print_constant_int(char *name, int value); -+extern void print_tail(void); -+ -+int main(int argc, char **argv) -+{ -+ print_head(); -+ print_constant_int("UM_KERN_PAGE_SIZE", PAGE_SIZE); -+ -+ print_constant_str("UM_KERN_EMERG", KERN_EMERG); -+ print_constant_str("UM_KERN_ALERT", KERN_ALERT); -+ print_constant_str("UM_KERN_CRIT", KERN_CRIT); -+ print_constant_str("UM_KERN_ERR", KERN_ERR); -+ print_constant_str("UM_KERN_WARNING", KERN_WARNING); -+ print_constant_str("UM_KERN_NOTICE", KERN_NOTICE); -+ print_constant_str("UM_KERN_INFO", KERN_INFO); -+ print_constant_str("UM_KERN_DEBUG", KERN_DEBUG); -+ print_tail(); -+ return(0); -+} -diff -Naur -X ../exclude-files orig/arch/um/util/mk_constants_user.c um/arch/um/util/mk_constants_user.c ---- orig/arch/um/util/mk_constants_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/util/mk_constants_user.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,28 @@ -+#include <stdio.h> -+ -+void print_head(void) -+{ -+ printf("/*\n"); -+ printf(" * Generated by mk_constants\n"); -+ printf(" */\n"); -+ printf("\n"); -+ printf("#ifndef __UM_CONSTANTS_H\n"); -+ printf("#define __UM_CONSTANTS_H\n"); -+ printf("\n"); -+} -+ -+void print_constant_str(char *name, char *value) -+{ -+ printf("#define %s \"%s\"\n", name, value); -+} -+ -+void print_constant_int(char *name, int value) -+{ -+ printf("#define %s %d\n", name, value); -+} -+ -+void print_tail(void) -+{ -+ printf("\n"); -+ printf("#endif\n"); -+} -diff -Naur -X ../exclude-files orig/arch/um/util/mk_task_kern.c um/arch/um/util/mk_task_kern.c ---- orig/arch/um/util/mk_task_kern.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/util/mk_task_kern.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,17 @@ -+#include "linux/sched.h" -+#include "linux/stddef.h" -+ -+extern void print(char *name, char *type, int offset); -+extern void print_ptr(char *name, char *type, int offset); -+extern void print_head(void); -+extern void print_tail(void); -+ -+int main(int argc, char **argv) -+{ -+ print_head(); -+ print_ptr("TASK_REGS", "union uml_pt_regs", -+ offsetof(struct task_struct, thread.regs)); -+ print("TASK_PID", "int", offsetof(struct task_struct, pid)); -+ print_tail(); -+ return(0); -+} -diff -Naur -X ../exclude-files orig/arch/um/util/mk_task_user.c um/arch/um/util/mk_task_user.c ---- orig/arch/um/util/mk_task_user.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/arch/um/util/mk_task_user.c 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,30 @@ -+#include <stdio.h> -+ -+void print(char *name, char *type, int offset) -+{ -+ printf("#define %s(task) *((%s *) &(((char *) (task))[%d]))\n", name, type, -+ offset); -+} -+ -+void print_ptr(char *name, char *type, int offset) -+{ -+ printf("#define %s(task) ((%s *) &(((char *) (task))[%d]))\n", name, type, -+ offset); -+} -+ -+void print_head(void) -+{ -+ printf("/*\n"); -+ printf(" * Generated by mk_task\n"); -+ printf(" */\n"); -+ printf("\n"); -+ printf("#ifndef __TASK_H\n"); -+ printf("#define __TASK_H\n"); -+ printf("\n"); -+} -+ -+void print_tail(void) -+{ -+ printf("\n"); -+ printf("#endif\n"); -+} -diff -Naur -X ../exclude-files orig/CREDITS um/CREDITS ---- orig/CREDITS 2003-12-16 22:16:23.000000000 -0500 -+++ um/CREDITS 2003-12-16 22:17:22.000000000 -0500 -@@ -434,6 +434,7 @@ - E: lars@nocrew.org - W: http://lars.nocrew.org/ - D: dsp56k device driver -+D: ptrace proxy in user mode kernel port - S: Kopmansg 2 - S: 411 13 Goteborg - S: Sweden -@@ -719,7 +720,7 @@ - E: jdike@karaya.com - W: http://user-mode-linux.sourceforge.net - D: User mode kernel port --S: RR1 Box 67C -+S: 375 Tubbs Hill Rd - S: Deering NH 03244 - S: USA - -diff -Naur -X ../exclude-files orig/Documentation/Configure.help um/Documentation/Configure.help ---- orig/Documentation/Configure.help 2003-12-16 22:16:23.000000000 -0500 -+++ um/Documentation/Configure.help 2003-12-16 22:17:22.000000000 -0500 -@@ -15821,6 +15821,63 @@ - The module will be called speedtch.o. If you want to compile it as - a module, say M here and read <file:Documentation/modules.txt>. - -+Support for /proc/mm -+CONFIG_PROC_MM -+ Enables support for address space separation through /proc/mm. -+ A host kernel needs to have this enabled in order for UML to -+ run in skas mode. UML kernels do not need to have this option -+ unless they will host sub-UMLs. -+ -+ If you don't know what this does just say Y. -+ -+Separate Kernel Address Space support -+CONFIG_MODE_SKAS -+ This option controls whether skas (separate kernel address space) -+ support is compiled in. If you have applied the skas patch to the -+ host and enabled support for /proc/mm in the host kernel, then you -+ certainly want to say Y here (and consider saying N to -+ CONFIG_MODE_TT). Otherwise, it is safe to say Y. Disabling this -+ option will shrink the UML binary slightly. -+ -+Tracing thread support -+CONFIG_MODE_TT -+ This option controls whether tracing thread support is compiled -+ into UML. Normally, this should be set to Y. If you intend to -+ use only skas mode (and the host has the skas patch applied to it), -+ then it is OK to say N here. -+ -+Force a static link -+CONFIG_STATIC_LINK -+ If CONFIG_MODE_TT is disabled, then this option gives you the ability -+ to force a static link of UML. Normally, if only skas mode is built -+ in to UML, it will be linked as a shared binary. This is inconvenient -+ for use in a chroot jail. So, if you intend to run UML inside a -+ chroot, and you disable CONFIG_MODE_TT, you probably want to say Y -+ here. -+ -+2G/2G host address space split -+CONFIG_HOST_2G_2G -+ Most Linux machines are configured so that the kernel occupies the -+ upper 1G of the 4G address space and processes use the lower 3G. -+ However, some machine are configured with a 2G/2G split, with the -+ kernel occupying the upper 2G and processes using the lower 2G. -+ -+ To allow UML to run on a such host you have to say Y here. N should be -+ a safe choice most of the time. -+ -+Kernel stack size order -+CONFIG_KERNEL_STACK_ORDER -+ This option determines the size of UML kernel stacks. They will -+ be 1 << order pages. The default is OK unless you're running Valgrind -+ on UML, in which case, set this to 3. -+ -+UML ubd block driver -+CONFIG_BLK_DEV_UBD -+ The User-Mode Linux port includes a driver called UBD which will let -+ you access arbitrary files on the host computer as block devices. -+ Unless you know that you do not need such virtual block devices say -+ Y here. -+ - CONFIG_USB_GADGET - USB is a master/slave protocol, organized with one master - host (such as a PC) controlling up to 127 peripheral devices. -@@ -15905,17 +15962,15 @@ - - Always do synchronous disk IO for UBD - CONFIG_BLK_DEV_UBD_SYNC -- The User-Mode Linux port includes a driver called UBD which will let -- you access arbitrary files on the host computer as block devices. -- Writes to such a block device are not immediately written to the -- host's disk; this may cause problems if, for example, the User-Mode -- Linux 'Virtual Machine' uses a journalling file system and the host -- computer crashes. -+ Writes to the virtual block device are not immediately written to the host's -+ disk; this may cause problems if, for example, the User-Mode Linux -+ 'Virtual Machine' uses a journalling filesystem and the host computer -+ crashes. - - Synchronous operation (i.e. always writing data to the host's disk - immediately) is configurable on a per-UBD basis by using a special - kernel command line option. Alternatively, you can say Y here to -- turn on synchronous operation by default for all block. -+ turn on synchronous operation by default for all block devices. - - If you're running a journalling file system (like reiserfs, for - example) in your virtual machine, you will want to say Y here. If -@@ -15927,6 +15982,7 @@ - CONFIG_PT_PROXY - This option enables a debugging interface which allows gdb to debug - the kernel without needing to actually attach to kernel threads. -+ CONFIG_XTERM_CHAN must be enabled in order to enable CONFIG_PT_PROXY. - If you want to do kernel debugging, say Y here; otherwise say N. - - Management console -@@ -15959,7 +16015,7 @@ - This option allows developers to retrieve coverage data from a UML - session. - -- See <http://user-mode-linux.sourceforge.net/gcov.html> for more -+ See <http://user-mode-linux.sourceforge.net/gprof.html> for more - details. - - If you're involved in UML kernel development and want to use gcov, -@@ -15996,6 +16052,19 @@ - If you'd like to be able to work with files stored on the host, - say Y or M here; otherwise say N. - -+HoneyPot ProcFS -+CONFIG_HPPFS -+ hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc -+ entries to be overridden, removed, or fabricated from the host. -+ Its purpose is to allow a UML to appear to be a physical machine -+ by removing or changing anything in /proc which gives away the -+ identity of a UML. -+ -+ See <http://user-mode-linux.sf.net/hppfs.html> for more information. -+ -+ You only need this if you are setting up a UML honeypot. Otherwise, -+ it is safe to say 'N' here. -+ - Example IO Memory driver - CONFIG_MMAPPER - The User-Mode Linux port can provide support for IO Memory -@@ -16011,6 +16080,21 @@ - If you'd like to be able to provide a simulated IO port space for - User-Mode Linux processes, say Y. If unsure, say N. - -+Anonymous Memory support -+CONFIG_DEV_ANON -+ Don't ask. Just say Y. -+ -+Support for software watchdog inside UML -+CONFIG_UML_WATCHDOG -+ Support for a virtual hardware watchdog. It's safe to say N here. -+ -+COW block device -+CONFIG_COW -+ This is a layered driver which sits above two other block devices. -+ One is read-only, and the other is a read-write layer which stores -+ all changes. This provides the illusion that the read-only layer -+ can be mounted read-write and changed. -+ - Virtual Serial Line - CONFIG_SSL - The User-Mode Linux environment allows you to create virtual serial -@@ -16121,26 +16205,197 @@ - - SLIP transport - CONFIG_UML_NET_SLIP -- The Slip User-Mode Linux network transport allows a running UML to -+ The slip User-Mode Linux network transport allows a running UML to - network with its host over a point-to-point link. Unlike Ethertap, - which can carry any Ethernet frame (and hence even non-IP packets), -- the Slip transport can only carry IP packets. -+ the slip transport can only carry IP packets. - -- To use this, your host must support Slip devices. -+ To use this, your host must support slip devices. - - For more information, see - <http://user-mode-linux.sourceforge.net/networking.html>. That site -- has examples of the UML command line to use to enable Slip -+ has examples of the UML command line to use to enable slip - networking, and details of a few quirks with it. - -- The Ethertap Transport is preferred over Slip because of its -- limitation. If you prefer Slip, however, say Y here. Otherwise -+ The Ethertap Transport is preferred over slip because of its -+ limitations. If you prefer slip, however, say Y here. Otherwise - choose the Multicast transport (to network multiple UMLs on - multiple hosts), Ethertap (to network with the host and the - outside world), and/or the Daemon transport (to network multiple - UMLs on a single host). You may choose more than one without - conflict. If you don't need UML networking, say N. - -+SLiRP transport -+CONFIG_UML_NET_SLIRP -+ The SLiRP User-Mode Linux network transport allows a running UML -+ to network by invoking a program that can handle SLIP encapsulated -+ packets. This is commonly (but not limited to) the application -+ known as SLiRP, a program that can re-socket IP packets back onto -+ the host on which it is run. Only IP packets are supported, -+ unlike other network transports that can handle all Ethernet -+ frames. In general, slirp allows the UML the same IP connectivity -+ to the outside world that the host user is permitted, and unlike -+ other transports, SLiRP works without the need of root level -+ privleges, setuid binaries, or SLIP devices on the host. This -+ also means not every type of connection is possible, but most -+ situations can be accomodated with carefully crafted slirp -+ commands that can be passed along as part of the network device's -+ setup string. The effect of this transport on the UML is similar -+ that of a host behind a firewall that masquerades all network -+ connections passing through it (but is less secure). -+ -+ To use this you should first have slirp compiled somewhere -+ accessible on the host, and have read its documentation. If you -+ don't need UML networking, say N. -+ -+ Startup example: "eth0=slirp,FE:FD:01:02:03:04,/usr/local/bin/slirp" -+ -+pcap transport -+CONFIG_UML_NET_PCAP -+ The pcap transport makes a pcap packet stream on the host look -+ like an ethernet device inside UML. This is useful for making -+ UML act as a network monitor for the host. You must have libcap -+ installed in order to build the pcap transport into UML. -+ -+ For more information, see -+ <http://user-mode-linux.sourceforge.net/networking.html> That site -+ has examples of the UML command line to use to enable this option. -+ -+ If you intend to use UML as a network monitor for the host, say -+ Y here. Otherwise, say N. -+ -+Default main console channel initialization -+CONFIG_CON_ZERO_CHAN -+ This is the string describing the channel to which the main console -+ will be attached by default. This value can be overridden from the -+ command line. The default value is "fd:0,fd:1", which attaches the -+ main console to stdin and stdout. -+ It is safe to leave this unchanged. -+ -+Default console channel initialization -+CONFIG_CON_CHAN -+ This is the string describing the channel to which all consoles -+ except the main console will be attached by default. This value can -+ be overridden from the command line. The default value is "xterm", -+ which brings them up in xterms. -+ It is safe to leave this unchanged, although you may wish to change -+ this if you expect the UML that you build to be run in environments -+ which don't have X or xterm available. -+ -+Default serial line channel initialization -+CONFIG_SSL_CHAN -+ This is the string describing the channel to which the serial lines -+ will be attached by default. This value can be overridden from the -+ command line. The default value is "pty", which attaches them to -+ traditional pseudo-terminals. -+ It is safe to leave this unchanged, although you may wish to change -+ this if you expect the UML that you build to be run in environments -+ which don't have a set of /dev/pty* devices. -+ -+Nesting level -+CONFIG_NEST_LEVEL -+ This is set to the number of layers of UMLs that this UML will be run -+ in. Normally, this is zero, meaning that it will run directly on the -+ host. Setting it to one will build a UML that can run inside a UML -+ that is running on the host. Generally, if you intend this UML to run -+ inside another UML, set CONFIG_NEST_LEVEL to one more than the host UML. -+ Note that if the hosting UML has its CONFIG_KERNEL_HALF_GIGS set to -+ greater than one, then the guest UML should have its CONFIG_NEST_LEVEL -+ set to the host's CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS. -+ Only change this if you are running nested UMLs. -+ -+Kernel address space size (in .5G units) -+CONFIG_KERNEL_HALF_GIGS -+ This determines the amount of address space that UML will allocate for -+ its own, measured in half Gigabyte units. The default is 1. -+ Change this only if you need to boot UML with an unusually large amount -+ of physical memory. -+ -+UML sound support -+CONFIG_UML_SOUND -+ This option enables UML sound support. If enabled, it will pull in -+ soundcore and the UML hostaudio relay, which acts as a intermediary -+ between the host's dsp and mixer devices and the UML sound system. -+ It is safe to say 'Y' here. -+ -+UML SMP support -+CONFIG_UML_SMP -+ This option enables UML SMP support. UML implements virtual SMP by -+ allowing as many processes to run simultaneously on the host as -+ there are virtual processors configured. Obviously, if the host is -+ a uniprocessor, those processes will timeshare, but, inside UML, -+ will appear to be running simultaneously. If the host is a -+ multiprocessor, then UML processes may run simultaneously, depending -+ on the host scheduler. -+ CONFIG_SMP will be set to whatever this option is set to. -+ It is safe to leave this unchanged. -+ -+file descriptor channel support -+CONFIG_FD_CHAN -+ This option enables support for attaching UML consoles and serial -+ lines to already set up file descriptors. Generally, the main -+ console is attached to file descriptors 0 and 1 (stdin and stdout), -+ so it would be wise to leave this enabled unless you intend to -+ attach it to some other host device. -+ -+null device channel support -+CONFIG_NULL_CHAN -+ This option enables support for attaching UML consoles and serial -+ lines to a device similar to /dev/null. Data written to it disappears -+ and there is never any data to be read. -+ -+port channel support -+CONFIG_PORT_CHAN -+ This option enables support for attaching UML consoles and serial -+ lines to host portals. They may be accessed with 'telnet <host> -+ <port number>'. Any number of consoles and serial lines may be -+ attached to a single portal, although what UML device you get when -+ you telnet to that portal will be unpredictable. -+ It is safe to say 'Y' here. -+ -+pty channel support -+CONFIG_PTY_CHAN -+ This option enables support for attaching UML consoles and serial -+ lines to host pseudo-terminals. Access to both traditional -+ pseudo-terminals (/dev/pty*) and pts pseudo-terminals are controlled -+ with this option. The assignment of UML devices to host devices -+ will be announced in the kernel message log. -+ It is safe to say 'Y' here. -+ -+tty channel support -+CONFIG_TTY_CHAN -+ This option enables support for attaching UML consoles and serial -+ lines to host terminals. Access to both virtual consoles -+ (/dev/tty*) and the slave side of pseudo-terminals (/dev/ttyp* and -+ /dev/pts/*) are controlled by this option. -+ It is safe to say 'Y' here. -+ -+xterm channel support -+CONFIG_XTERM_CHAN -+ This option enables support for attaching UML consoles and serial -+ lines to xterms. Each UML device so assigned will be brought up in -+ its own xterm. -+ If you disable this option, then CONFIG_PT_PROXY will be disabled as -+ well, since UML's gdb currently requires an xterm. -+ It is safe to say 'Y' here. -+ -+tty logging -+CONFIG_TTY_LOG -+ This option enables logging of all data going through pseudo-terminals -+ to the host. This is primarily useful for honeypots, where you want -+ secure keystroke logging that can't be detected or disabled by root. -+ Say 'N' unless you are setting up a UML honeypot or otherwise know that -+ you want this option. -+ -+UML real-time clock support -+CONFIG_UML_REAL_TIME_CLOCK -+ This option ties the UML clock to the host clock, so that time passes at -+ the same rate as on the host, regardless of how much CPU time the UML is -+ getting. This should normally be enabled. The exception would be if you're -+ debugging UML. In this case, time spent staring at the debugger with UML -+ stopped will cause lots of timer ticks to be backed up, and UML will spent -+ lots of time calling the timer when it is finally continued. -+ - Microtek USB scanner support - CONFIG_USB_MICROTEK - Say Y here if you want support for the Microtek X6USB and -diff -Naur -X ../exclude-files orig/drivers/char/Makefile um/drivers/char/Makefile ---- orig/drivers/char/Makefile 2003-12-16 22:16:26.000000000 -0500 -+++ um/drivers/char/Makefile 2003-12-16 22:17:25.000000000 -0500 -@@ -109,6 +109,12 @@ - endif - endif - -+ifeq ($(ARCH),um) -+ KEYMAP = -+ KEYBD = -+ CONSOLE = -+endif -+ - ifeq ($(ARCH),sh) - KEYMAP = - KEYBD = -diff -Naur -X ../exclude-files orig/drivers/char/mem.c um/drivers/char/mem.c ---- orig/drivers/char/mem.c 2003-12-16 22:16:27.000000000 -0500 -+++ um/drivers/char/mem.c 2004-01-05 11:23:32.000000000 -0500 -@@ -220,7 +220,8 @@ - ssize_t read = 0; - ssize_t virtr = 0; - char * kbuf; /* k-addr because vread() takes vmlist_lock rwlock */ -- -+ -+ p = (unsigned long) __va(p); - if (p < (unsigned long) high_memory) { - read = count; - if (count > (unsigned long) high_memory - p) -@@ -269,7 +270,7 @@ - } - free_page((unsigned long)kbuf); - } -- *ppos = p; -+ *ppos = __pa((void *) p); - return virtr + read; - } - -@@ -664,6 +665,8 @@ - write: write_full, - }; - -+extern struct file_operations anon_file_operations; -+ - static int memory_open(struct inode * inode, struct file * filp) - { - switch (MINOR(inode->i_rdev)) { -@@ -693,6 +696,9 @@ - case 9: - filp->f_op = &urandom_fops; - break; -+ case 10: -+ filp->f_op = &anon_file_operations; -+ break; - default: - return -ENXIO; - } -@@ -719,7 +725,8 @@ - {5, "zero", S_IRUGO | S_IWUGO, &zero_fops}, - {7, "full", S_IRUGO | S_IWUGO, &full_fops}, - {8, "random", S_IRUGO | S_IWUSR, &random_fops}, -- {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops} -+ {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops}, -+ {10, "anon", S_IRUGO | S_IWUSR, &anon_file_operations}, - }; - int i; - -diff -Naur -X ../exclude-files orig/drivers/char/tty_io.c um/drivers/char/tty_io.c ---- orig/drivers/char/tty_io.c 2003-12-16 22:16:27.000000000 -0500 -+++ um/drivers/char/tty_io.c 2003-12-16 22:17:25.000000000 -0500 -@@ -649,6 +649,23 @@ - wake_up_interruptible(&tty->write_wait); - } - -+#ifdef CONFIG_TTY_LOG -+ -+int (*open_log)(void *, void *) = NULL; -+int (*write_log)(int, const char *, int, void *, int) = NULL; -+void (*close_log)(int, void *) = NULL; -+ -+void register_tty_logger(int (*opener)(void *, void *), -+ int (*writer)(int, const char *, int, void *, int), -+ void (*closer)(int, void *)) -+{ -+ open_log = opener; -+ write_log = writer; -+ close_log = closer; -+} -+ -+#endif -+ - static ssize_t tty_read(struct file * file, char * buf, size_t count, - loff_t *ppos) - { -@@ -689,8 +706,13 @@ - else - i = -EIO; - unlock_kernel(); -- if (i > 0) -+ if (i > 0){ - inode->i_atime = CURRENT_TIME; -+#ifdef CONFIG_TTY_LOG -+ if((tty->log_fd >= 0) && (write_log != NULL)) -+ (*write_log)(tty->log_fd, buf, i, tty, 1); -+#endif -+ } - return i; - } - -@@ -744,6 +766,10 @@ - if (written) { - file->f_dentry->d_inode->i_mtime = CURRENT_TIME; - ret = written; -+#ifdef CONFIG_TTY_LOG -+ if((tty->log_fd >= 0) && (write_log != NULL)) -+ (*write_log)(tty->log_fd, buf - ret, ret, tty, 0); -+#endif - } - up(&tty->atomic_write); - return ret; -@@ -971,6 +997,7 @@ - goto release_mem_out; - } - } -+ - goto success; - - /* -@@ -1290,6 +1317,11 @@ - run_task_queue(&tq_timer); - flush_scheduled_tasks(); - -+#ifdef CONFIG_TTY_LOG -+ if((tty->log_fd >= 0) && (close_log != NULL)) -+ (*close_log)(tty->log_fd, tty); -+#endif -+ - /* - * The release_mem function takes care of the details of clearing - * the slots and preserving the termios structure. -@@ -1448,6 +1480,11 @@ - nr_warns++; - } - } -+ -+#ifdef CONFIG_TTY_LOG -+ if((tty->log_fd < 0) && (open_log != NULL)) -+ tty->log_fd = (*open_log)(tty, current->tty); -+#endif - return 0; - } - -@@ -2047,6 +2084,9 @@ - spin_lock_init(&tty->read_lock); - INIT_LIST_HEAD(&tty->tty_files); - INIT_TQUEUE(&tty->SAK_tq, 0, 0); -+#ifdef CONFIG_TTY_LOG -+ tty->log_fd = -1; -+#endif - } - - /* -diff -Naur -X ../exclude-files orig/drivers/net/setup.c um/drivers/net/setup.c ---- orig/drivers/net/setup.c 2002-09-15 12:13:19.000000000 -0400 -+++ um/drivers/net/setup.c 2003-10-21 03:26:07.000000000 -0400 -@@ -28,7 +28,6 @@ - extern int lmc_setup(void); - - extern int madgemc_probe(void); --extern int uml_net_probe(void); - - /* Pad device name to IFNAMSIZ=16. F.e. __PAD6 is string of 9 zeros. */ - #define __PAD6 "\0\0\0\0\0\0\0\0\0" -@@ -103,9 +102,6 @@ - #ifdef CONFIG_MADGEMC - {madgemc_probe, 0}, - #endif --#ifdef CONFIG_UML_NET -- {uml_net_probe, 0}, --#endif - - {NULL, 0}, - }; -diff -Naur -X ../exclude-files orig/fs/bad_inode.c um/fs/bad_inode.c ---- orig/fs/bad_inode.c 2002-08-21 11:47:27.000000000 -0400 -+++ um/fs/bad_inode.c 2003-10-21 03:26:07.000000000 -0400 -@@ -83,6 +83,7 @@ - - void make_bad_inode(struct inode * inode) - { -+ inode->i_state = 0; - inode->i_mode = S_IFREG; - inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; - inode->i_op = &bad_inode_ops; -diff -Naur -X ../exclude-files orig/include/asm-i386/hardirq.h um/include/asm-i386/hardirq.h ---- orig/include/asm-i386/hardirq.h 2004-01-11 22:46:12.000000000 -0500 -+++ um/include/asm-i386/hardirq.h 2004-02-14 06:28:59.000000000 -0500 -@@ -4,6 +4,7 @@ - #include <linux/config.h> - #include <linux/threads.h> - #include <linux/irq.h> -+#include <asm/processor.h> /* for cpu_relax */ - - /* assembly code in softirq.h is sensitive to the offsets of these fields */ - typedef struct { -diff -Naur -X ../exclude-files orig/include/asm-um/a.out.h um/include/asm-um/a.out.h ---- orig/include/asm-um/a.out.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/a.out.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,20 @@ -+#ifndef __UM_A_OUT_H -+#define __UM_A_OUT_H -+ -+#include "linux/config.h" -+#include "asm/arch/a.out.h" -+#include "choose-mode.h" -+ -+#undef STACK_TOP -+ -+extern unsigned long stacksizelim; -+ -+extern unsigned long host_task_size; -+ -+#define STACK_ROOM (stacksizelim) -+ -+extern int honeypot; -+#define STACK_TOP \ -+ CHOOSE_MODE((honeypot ? host_task_size : task_size), task_size) -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/archparam-i386.h um/include/asm-um/archparam-i386.h ---- orig/include/asm-um/archparam-i386.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/archparam-i386.h 2003-12-16 08:50:39.000000000 -0500 -@@ -0,0 +1,80 @@ -+/* -+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __UM_ARCHPARAM_I386_H -+#define __UM_ARCHPARAM_I386_H -+ -+/********* Bits for asm-um/elf.h ************/ -+ -+#include "user.h" -+ -+#define ELF_PLATFORM "i586" -+ -+#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) -+ -+typedef struct user_i387_struct elf_fpregset_t; -+typedef unsigned long elf_greg_t; -+ -+#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) -+typedef elf_greg_t elf_gregset_t[ELF_NGREG]; -+ -+#define ELF_DATA ELFDATA2LSB -+#define ELF_ARCH EM_386 -+ -+#define ELF_PLAT_INIT(regs, load_addr) do { \ -+ PT_REGS_EBX(regs) = 0; \ -+ PT_REGS_ECX(regs) = 0; \ -+ PT_REGS_EDX(regs) = 0; \ -+ PT_REGS_ESI(regs) = 0; \ -+ PT_REGS_EDI(regs) = 0; \ -+ PT_REGS_EBP(regs) = 0; \ -+ PT_REGS_EAX(regs) = 0; \ -+} while(0) -+ -+/* Shamelessly stolen from include/asm-i386/elf.h */ -+ -+#define ELF_CORE_COPY_REGS(pr_reg, regs) do { \ -+ pr_reg[0] = PT_REGS_EBX(regs); \ -+ pr_reg[1] = PT_REGS_ECX(regs); \ -+ pr_reg[2] = PT_REGS_EDX(regs); \ -+ pr_reg[3] = PT_REGS_ESI(regs); \ -+ pr_reg[4] = PT_REGS_EDI(regs); \ -+ pr_reg[5] = PT_REGS_EBP(regs); \ -+ pr_reg[6] = PT_REGS_EAX(regs); \ -+ pr_reg[7] = PT_REGS_DS(regs); \ -+ pr_reg[8] = PT_REGS_ES(regs); \ -+ /* fake once used fs and gs selectors? */ \ -+ pr_reg[9] = PT_REGS_DS(regs); \ -+ pr_reg[10] = PT_REGS_DS(regs); \ -+ pr_reg[11] = PT_REGS_SYSCALL_NR(regs); \ -+ pr_reg[12] = PT_REGS_IP(regs); \ -+ pr_reg[13] = PT_REGS_CS(regs); \ -+ pr_reg[14] = PT_REGS_EFLAGS(regs); \ -+ pr_reg[15] = PT_REGS_SP(regs); \ -+ pr_reg[16] = PT_REGS_SS(regs); \ -+} while(0); -+ -+/********* Bits for asm-um/delay.h **********/ -+ -+typedef unsigned long um_udelay_t; -+ -+/********* Nothing for asm-um/hardirq.h **********/ -+ -+/********* Nothing for asm-um/hw_irq.h **********/ -+ -+/********* Nothing for asm-um/string.h **********/ -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/include/asm-um/archparam-ppc.h um/include/asm-um/archparam-ppc.h ---- orig/include/asm-um/archparam-ppc.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/archparam-ppc.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,41 @@ -+#ifndef __UM_ARCHPARAM_PPC_H -+#define __UM_ARCHPARAM_PPC_H -+ -+/********* Bits for asm-um/elf.h ************/ -+ -+#define ELF_PLATFORM (0) -+ -+#define ELF_ET_DYN_BASE (0x08000000) -+ -+/* the following stolen from asm-ppc/elf.h */ -+#define ELF_NGREG 48 /* includes nip, msr, lr, etc. */ -+#define ELF_NFPREG 33 /* includes fpscr */ -+/* General registers */ -+typedef unsigned long elf_greg_t; -+typedef elf_greg_t elf_gregset_t[ELF_NGREG]; -+ -+/* Floating point registers */ -+typedef double elf_fpreg_t; -+typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG]; -+ -+#define ELF_DATA ELFDATA2MSB -+#define ELF_ARCH EM_PPC -+ -+/********* Bits for asm-um/delay.h **********/ -+ -+typedef unsigned int um_udelay_t; -+ -+/********* Bits for asm-um/hw_irq.h **********/ -+ -+struct hw_interrupt_type; -+ -+/********* Bits for asm-um/hardirq.h **********/ -+ -+#define irq_enter(cpu, irq) hardirq_enter(cpu) -+#define irq_exit(cpu, irq) hardirq_exit(cpu) -+ -+/********* Bits for asm-um/string.h **********/ -+ -+#define __HAVE_ARCH_STRRCHR -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/arch-signal-i386.h um/include/asm-um/arch-signal-i386.h ---- orig/include/asm-um/arch-signal-i386.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/arch-signal-i386.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,24 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __UM_ARCH_SIGNAL_I386_H -+#define __UM_ARCH_SIGNAL_I386_H -+ -+struct arch_signal_context { -+ unsigned long extrasigs[_NSIG_WORDS]; -+}; -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/include/asm-um/atomic.h um/include/asm-um/atomic.h ---- orig/include/asm-um/atomic.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/atomic.h 2004-02-14 06:28:59.000000000 -0500 -@@ -0,0 +1,6 @@ -+#ifndef __UM_ATOMIC_H -+#define __UM_ATOMIC_H -+ -+#include "asm/arch/atomic.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/bitops.h um/include/asm-um/bitops.h ---- orig/include/asm-um/bitops.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/bitops.h 2004-02-14 06:28:59.000000000 -0500 -@@ -0,0 +1,6 @@ -+#ifndef __UM_BITOPS_H -+#define __UM_BITOPS_H -+ -+#include "asm/arch/bitops.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/boot.h um/include/asm-um/boot.h ---- orig/include/asm-um/boot.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/boot.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_BOOT_H -+#define __UM_BOOT_H -+ -+#include "asm/arch/boot.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/bugs.h um/include/asm-um/bugs.h ---- orig/include/asm-um/bugs.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/bugs.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_BUGS_H -+#define __UM_BUGS_H -+ -+void check_bugs(void); -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/byteorder.h um/include/asm-um/byteorder.h ---- orig/include/asm-um/byteorder.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/byteorder.h 2004-01-16 03:32:58.000000000 -0500 -@@ -0,0 +1,6 @@ -+#ifndef __UM_BYTEORDER_H -+#define __UM_BYTEORDER_H -+ -+#include "asm/arch/byteorder.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/cache.h um/include/asm-um/cache.h ---- orig/include/asm-um/cache.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/cache.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_CACHE_H -+#define __UM_CACHE_H -+ -+#define L1_CACHE_BYTES 32 -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/checksum.h um/include/asm-um/checksum.h ---- orig/include/asm-um/checksum.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/checksum.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_CHECKSUM_H -+#define __UM_CHECKSUM_H -+ -+#include "sysdep/checksum.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/cobalt.h um/include/asm-um/cobalt.h ---- orig/include/asm-um/cobalt.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/cobalt.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_COBALT_H -+#define __UM_COBALT_H -+ -+#include "asm/arch/cobalt.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/current.h um/include/asm-um/current.h ---- orig/include/asm-um/current.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/current.h 2004-02-14 06:28:59.000000000 -0500 -@@ -0,0 +1,34 @@ -+/* -+ * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __UM_CURRENT_H -+#define __UM_CURRENT_H -+ -+#ifndef __ASSEMBLY__ -+ -+#include "linux/config.h" -+#include "asm/page.h" -+ -+struct task_struct; -+ -+#define CURRENT_TASK(dummy) (((unsigned long) &dummy) & \ -+ (PAGE_MASK << CONFIG_KERNEL_STACK_ORDER)) -+ -+#define current ({ int dummy; (struct task_struct *) CURRENT_TASK(dummy); }) -+ -+#endif /* __ASSEMBLY__ */ -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/include/asm-um/delay.h um/include/asm-um/delay.h ---- orig/include/asm-um/delay.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/delay.h 2003-12-16 22:26:58.000000000 -0500 -@@ -0,0 +1,7 @@ -+#ifndef __UM_DELAY_H -+#define __UM_DELAY_H -+ -+#include "asm/arch/delay.h" -+#include "asm/archparam.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/desc.h um/include/asm-um/desc.h ---- orig/include/asm-um/desc.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/desc.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_DESC_H -+#define __UM_DESC_H -+ -+#include "asm/arch/desc.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/div64.h um/include/asm-um/div64.h ---- orig/include/asm-um/div64.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/div64.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef _UM_DIV64_H -+#define _UM_DIV64_H -+ -+#include "asm/arch/div64.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/dma.h um/include/asm-um/dma.h ---- orig/include/asm-um/dma.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/dma.h 2004-01-16 03:32:59.000000000 -0500 -@@ -0,0 +1,10 @@ -+#ifndef __UM_DMA_H -+#define __UM_DMA_H -+ -+#include "asm/io.h" -+ -+extern unsigned long uml_physmem; -+ -+#define MAX_DMA_ADDRESS (uml_physmem) -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/elf.h um/include/asm-um/elf.h ---- orig/include/asm-um/elf.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/elf.h 2003-12-16 22:29:20.000000000 -0500 -@@ -0,0 +1,18 @@ -+#ifndef __UM_ELF_H -+#define __UM_ELF_H -+ -+#include "asm/archparam.h" -+ -+#define ELF_HWCAP (0) -+ -+#define SET_PERSONALITY(ex, ibcs2) do ; while(0) -+ -+#define ELF_EXEC_PAGESIZE 4096 -+ -+#define elf_check_arch(x) (1) -+ -+#define ELF_CLASS ELFCLASS32 -+ -+#define USE_ELF_CORE_DUMP -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/errno.h um/include/asm-um/errno.h ---- orig/include/asm-um/errno.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/errno.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_ERRNO_H -+#define __UM_ERRNO_H -+ -+#include "asm/arch/errno.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/fcntl.h um/include/asm-um/fcntl.h ---- orig/include/asm-um/fcntl.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/fcntl.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_FCNTL_H -+#define __UM_FCNTL_H -+ -+#include "asm/arch/fcntl.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/fixmap.h um/include/asm-um/fixmap.h ---- orig/include/asm-um/fixmap.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/fixmap.h 2004-02-14 06:29:00.000000000 -0500 -@@ -0,0 +1,89 @@ -+#ifndef __UM_FIXMAP_H -+#define __UM_FIXMAP_H -+ -+#include <linux/config.h> -+#include <asm/kmap_types.h> -+ -+/* -+ * Here we define all the compile-time 'special' virtual -+ * addresses. The point is to have a constant address at -+ * compile time, but to set the physical address only -+ * in the boot process. We allocate these special addresses -+ * from the end of virtual memory (0xfffff000) backwards. -+ * Also this lets us do fail-safe vmalloc(), we -+ * can guarantee that these special addresses and -+ * vmalloc()-ed addresses never overlap. -+ * -+ * these 'compile-time allocated' memory buffers are -+ * fixed-size 4k pages. (or larger if used with an increment -+ * highger than 1) use fixmap_set(idx,phys) to associate -+ * physical memory with fixmap indices. -+ * -+ * TLB entries of such buffers will not be flushed across -+ * task switches. -+ */ -+ -+/* -+ * on UP currently we will have no trace of the fixmap mechanizm, -+ * no page table allocations, etc. This might change in the -+ * future, say framebuffers for the console driver(s) could be -+ * fix-mapped? -+ */ -+enum fixed_addresses { -+#ifdef CONFIG_HIGHMEM -+ FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */ -+ FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1, -+#endif -+ __end_of_fixed_addresses -+}; -+ -+extern void __set_fixmap (enum fixed_addresses idx, -+ unsigned long phys, pgprot_t flags); -+ -+#define set_fixmap(idx, phys) \ -+ __set_fixmap(idx, phys, PAGE_KERNEL) -+/* -+ * Some hardware wants to get fixmapped without caching. -+ */ -+#define set_fixmap_nocache(idx, phys) \ -+ __set_fixmap(idx, phys, PAGE_KERNEL_NOCACHE) -+/* -+ * used by vmalloc.c. -+ * -+ * Leave one empty page between vmalloc'ed areas and -+ * the start of the fixmap, and leave one page empty -+ * at the top of mem.. -+ */ -+extern unsigned long get_kmem_end(void); -+ -+#define FIXADDR_TOP (get_kmem_end() - 0x2000) -+#define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) -+#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) -+ -+#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT)) -+ -+extern void __this_fixmap_does_not_exist(void); -+ -+/* -+ * 'index to address' translation. If anyone tries to use the idx -+ * directly without tranlation, we catch the bug with a NULL-deference -+ * kernel oops. Illegal ranges of incoming indices are caught too. -+ */ -+static inline unsigned long fix_to_virt(const unsigned int idx) -+{ -+ /* -+ * this branch gets completely eliminated after inlining, -+ * except when someone tries to use fixaddr indices in an -+ * illegal way. (such as mixing up address types or using -+ * out-of-range indices). -+ * -+ * If it doesn't get removed, the linker will complain -+ * loudly with a reasonably clear error message.. -+ */ -+ if (idx >= __end_of_fixed_addresses) -+ __this_fixmap_does_not_exist(); -+ -+ return __fix_to_virt(idx); -+} -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/floppy.h um/include/asm-um/floppy.h ---- orig/include/asm-um/floppy.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/floppy.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_FLOPPY_H -+#define __UM_FLOPPY_H -+ -+#include "asm/arch/floppy.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/hardirq.h um/include/asm-um/hardirq.h ---- orig/include/asm-um/hardirq.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/hardirq.h 2004-02-14 06:28:59.000000000 -0500 -@@ -0,0 +1,6 @@ -+#ifndef __UM_HARDIRQ_H -+#define __UM_HARDIRQ_H -+ -+#include "asm/arch/hardirq.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/hdreg.h um/include/asm-um/hdreg.h ---- orig/include/asm-um/hdreg.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/hdreg.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_HDREG_H -+#define __UM_HDREG_H -+ -+#include "asm/arch/hdreg.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/highmem.h um/include/asm-um/highmem.h ---- orig/include/asm-um/highmem.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/highmem.h 2004-02-14 06:29:00.000000000 -0500 -@@ -0,0 +1,12 @@ -+#ifndef __UM_HIGHMEM_H -+#define __UM_HIGHMEM_H -+ -+#include "asm/page.h" -+#include "asm/fixmap.h" -+#include "asm/arch/highmem.h" -+ -+#undef PKMAP_BASE -+ -+#define PKMAP_BASE ((FIXADDR_START - LAST_PKMAP * PAGE_SIZE) & PMD_MASK) -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/hw_irq.h um/include/asm-um/hw_irq.h ---- orig/include/asm-um/hw_irq.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/hw_irq.h 2003-12-16 22:26:55.000000000 -0500 -@@ -0,0 +1,10 @@ -+#ifndef _ASM_UM_HW_IRQ_H -+#define _ASM_UM_HW_IRQ_H -+ -+#include "asm/irq.h" -+#include "asm/archparam.h" -+ -+static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) -+{} -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/ide.h um/include/asm-um/ide.h ---- orig/include/asm-um/ide.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/ide.h 2004-01-16 23:40:52.000000000 -0500 -@@ -0,0 +1,6 @@ -+#ifndef __UM_IDE_H -+#define __UM_IDE_H -+ -+#include "asm/arch/ide.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/init.h um/include/asm-um/init.h ---- orig/include/asm-um/init.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/init.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,11 @@ -+#ifndef _UM_INIT_H -+#define _UM_INIT_H -+ -+#ifdef notdef -+#define __init -+#define __initdata -+#define __initfunc(__arginit) __arginit -+#define __cacheline_aligned -+#endif -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/ioctl.h um/include/asm-um/ioctl.h ---- orig/include/asm-um/ioctl.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/ioctl.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_IOCTL_H -+#define __UM_IOCTL_H -+ -+#include "asm/arch/ioctl.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/ioctls.h um/include/asm-um/ioctls.h ---- orig/include/asm-um/ioctls.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/ioctls.h 2003-11-07 02:10:43.000000000 -0500 -@@ -0,0 +1,6 @@ -+#ifndef __UM_IOCTLS_H -+#define __UM_IOCTLS_H -+ -+#include "asm/arch/ioctls.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/io.h um/include/asm-um/io.h ---- orig/include/asm-um/io.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/io.h 2004-01-16 03:32:59.000000000 -0500 -@@ -0,0 +1,25 @@ -+#ifndef __UM_IO_H -+#define __UM_IO_H -+ -+#include "asm/page.h" -+ -+#define IO_SPACE_LIMIT 0xdeadbeef /* Sure hope nothing uses this */ -+ -+static inline int inb(unsigned long i) { return(0); } -+static inline void outb(char c, unsigned long i) { } -+ -+/* -+ * Change virtual addresses to physical addresses and vv. -+ * These are pretty trivial -+ */ -+static inline unsigned long virt_to_phys(volatile void * address) -+{ -+ return __pa((void *) address); -+} -+ -+static inline void * phys_to_virt(unsigned long address) -+{ -+ return __va(address); -+} -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/ipcbuf.h um/include/asm-um/ipcbuf.h ---- orig/include/asm-um/ipcbuf.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/ipcbuf.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_IPCBUF_H -+#define __UM_IPCBUF_H -+ -+#include "asm/arch/ipcbuf.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/ipc.h um/include/asm-um/ipc.h ---- orig/include/asm-um/ipc.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/ipc.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_IPC_H -+#define __UM_IPC_H -+ -+#include "asm/arch/ipc.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/irq.h um/include/asm-um/irq.h ---- orig/include/asm-um/irq.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/irq.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,22 @@ -+#ifndef __UM_IRQ_H -+#define __UM_IRQ_H -+ -+#define TIMER_IRQ 0 -+#define UMN_IRQ 1 -+#define CONSOLE_IRQ 2 -+#define CONSOLE_WRITE_IRQ 3 -+#define UBD_IRQ 4 -+#define UM_ETH_IRQ 5 -+#define SSL_IRQ 6 -+#define SSL_WRITE_IRQ 7 -+#define ACCEPT_IRQ 8 -+#define MCONSOLE_IRQ 9 -+#define WINCH_IRQ 10 -+#define SIGIO_WRITE_IRQ 11 -+#define TELNETD_IRQ 12 -+#define XTERM_IRQ 13 -+ -+#define LAST_IRQ XTERM_IRQ -+#define NR_IRQS (LAST_IRQ + 1) -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/keyboard.h um/include/asm-um/keyboard.h ---- orig/include/asm-um/keyboard.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/keyboard.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_KEYBOARD_H -+#define __UM_KEYBOARD_H -+ -+#include "asm/arch/keyboard.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/kmap_types.h um/include/asm-um/kmap_types.h ---- orig/include/asm-um/kmap_types.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/kmap_types.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,11 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __UM_KMAP_TYPES_H -+#define __UM_KMAP_TYPES_H -+ -+#include "asm/arch/kmap_types.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/linux_logo.h um/include/asm-um/linux_logo.h ---- orig/include/asm-um/linux_logo.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/linux_logo.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_LINUX_LOGO_H -+#define __UM_LINUX_LOGO_H -+ -+#include "asm/arch/linux_logo.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/locks.h um/include/asm-um/locks.h ---- orig/include/asm-um/locks.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/locks.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_LOCKS_H -+#define __UM_LOCKS_H -+ -+#include "asm/arch/locks.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/mca_dma.h um/include/asm-um/mca_dma.h ---- orig/include/asm-um/mca_dma.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/mca_dma.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef mca___UM_DMA_H -+#define mca___UM_DMA_H -+ -+#include "asm/arch/mca_dma.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/mman.h um/include/asm-um/mman.h ---- orig/include/asm-um/mman.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/mman.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_MMAN_H -+#define __UM_MMAN_H -+ -+#include "asm/arch/mman.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/mmu_context.h um/include/asm-um/mmu_context.h ---- orig/include/asm-um/mmu_context.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/mmu_context.h 2004-02-14 06:28:59.000000000 -0500 -@@ -0,0 +1,72 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __UM_MMU_CONTEXT_H -+#define __UM_MMU_CONTEXT_H -+ -+#include "linux/sched.h" -+#include "choose-mode.h" -+ -+#define get_mmu_context(task) do ; while(0) -+#define activate_context(tsk) do ; while(0) -+ -+static inline void activate_mm(struct mm_struct *old, struct mm_struct *new) -+{ -+} -+ -+extern void switch_mm_skas(int mm_fd); -+ -+static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, -+ struct task_struct *tsk, unsigned cpu) -+{ -+ if(prev != next){ -+ clear_bit(cpu, &prev->cpu_vm_mask); -+ set_bit(cpu, &next->cpu_vm_mask); -+ if(next != &init_mm) -+ CHOOSE_MODE((void) 0, -+ switch_mm_skas(next->context.skas.mm_fd)); -+ } -+} -+ -+static inline void enter_lazy_tlb(struct mm_struct *mm, -+ struct task_struct *tsk, unsigned cpu) -+{ -+} -+ -+extern int init_new_context_skas(struct task_struct *task, -+ struct mm_struct *mm); -+ -+static inline int init_new_context_tt(struct task_struct *task, -+ struct mm_struct *mm) -+{ -+ return(0); -+} -+ -+static inline int init_new_context(struct task_struct *task, -+ struct mm_struct *mm) -+{ -+ return(CHOOSE_MODE_PROC(init_new_context_tt, init_new_context_skas, -+ task, mm)); -+} -+ -+extern void destroy_context_skas(struct mm_struct *mm); -+ -+static inline void destroy_context(struct mm_struct *mm) -+{ -+ CHOOSE_MODE((void) 0, destroy_context_skas(mm)); -+} -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/include/asm-um/mmu.h um/include/asm-um/mmu.h ---- orig/include/asm-um/mmu.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/mmu.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,22 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __MMU_H -+#define __MMU_H -+ -+#include "um_mmu.h" -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/include/asm-um/module.h um/include/asm-um/module.h ---- orig/include/asm-um/module.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/module.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_MODULE_H -+#define __UM_MODULE_H -+ -+#include "asm/arch/module.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/msgbuf.h um/include/asm-um/msgbuf.h ---- orig/include/asm-um/msgbuf.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/msgbuf.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_MSGBUF_H -+#define __UM_MSGBUF_H -+ -+#include "asm/arch/msgbuf.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/mtrr.h um/include/asm-um/mtrr.h ---- orig/include/asm-um/mtrr.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/mtrr.h 2004-02-12 05:46:29.000000000 -0500 -@@ -0,0 +1,6 @@ -+#ifndef __UM_MTRR_H -+#define __UM_MTRR_H -+ -+#include "asm/arch/mtrr.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/namei.h um/include/asm-um/namei.h ---- orig/include/asm-um/namei.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/namei.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_NAMEI_H -+#define __UM_NAMEI_H -+ -+#include "asm/arch/namei.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/page.h um/include/asm-um/page.h ---- orig/include/asm-um/page.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/page.h 2004-01-16 03:32:58.000000000 -0500 -@@ -0,0 +1,68 @@ -+/* -+ * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __UM_PAGE_H -+#define __UM_PAGE_H -+ -+struct page; -+ -+#include "asm/arch/page.h" -+ -+#undef BUG -+#undef PAGE_BUG -+#undef __pa -+#undef __va -+#undef virt_to_page -+#undef VALID_PAGE -+#undef PAGE_OFFSET -+#undef KERNELBASE -+ -+extern unsigned long uml_physmem; -+ -+#define PAGE_OFFSET (uml_physmem) -+#define KERNELBASE PAGE_OFFSET -+ -+#ifndef __ASSEMBLY__ -+ -+extern void stop(void); -+ -+#define BUG() do { \ -+ panic("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ -+} while (0) -+ -+#define PAGE_BUG(page) do { \ -+ BUG(); \ -+} while (0) -+ -+#endif /* __ASSEMBLY__ */ -+ -+#define __va_space (8*1024*1024) -+ -+extern unsigned long to_phys(void *virt); -+extern void *to_virt(unsigned long phys); -+ -+#define __pa(virt) to_phys((void *) virt) -+#define __va(phys) to_virt((unsigned long) phys) -+ -+#define VALID_PAGE(page) ((page - mem_map) < max_mapnr) -+ -+extern struct page *arch_validate(struct page *page, int mask, int order); -+#define HAVE_ARCH_VALIDATE -+ -+extern void arch_free_page(struct page *page, int order); -+#define HAVE_ARCH_FREE_PAGE -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/include/asm-um/page_offset.h um/include/asm-um/page_offset.h ---- orig/include/asm-um/page_offset.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/page_offset.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1 @@ -+#define PAGE_OFFSET_RAW (uml_physmem) -diff -Naur -X ../exclude-files orig/include/asm-um/param.h um/include/asm-um/param.h ---- orig/include/asm-um/param.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/param.h 2004-02-13 02:26:52.000000000 -0500 -@@ -0,0 +1,22 @@ -+#ifndef _UM_PARAM_H -+#define _UM_PARAM_H -+ -+#define HZ 100 -+ -+#define EXEC_PAGESIZE 4096 -+ -+#ifndef NGROUPS -+#define NGROUPS 32 -+#endif -+ -+#ifndef NOGROUP -+#define NOGROUP (-1) -+#endif -+ -+#define MAXHOSTNAMELEN 64 /* max length of hostname */ -+ -+#ifdef __KERNEL__ -+# define CLOCKS_PER_SEC 100 /* frequency at which times() counts */ -+#endif -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/pci.h um/include/asm-um/pci.h ---- orig/include/asm-um/pci.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/pci.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_PCI_H -+#define __UM_PCI_H -+ -+#define PCI_DMA_BUS_IS_PHYS (1) -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/pgalloc.h um/include/asm-um/pgalloc.h ---- orig/include/asm-um/pgalloc.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/pgalloc.h 2004-02-14 06:29:00.000000000 -0500 -@@ -0,0 +1,164 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Derived from include/asm-i386/pgalloc.h and include/asm-i386/pgtable.h -+ * Licensed under the GPL -+ */ -+ -+#ifndef __UM_PGALLOC_H -+#define __UM_PGALLOC_H -+ -+#include "linux/config.h" -+#include "linux/mm.h" -+#include "asm/fixmap.h" -+#include "choose-mode.h" -+ -+#define pgd_quicklist (current_cpu_data.pgd_quick) -+#define pmd_quicklist (current_cpu_data.pmd_quick) -+#define pte_quicklist (current_cpu_data.pte_quick) -+#define pgtable_cache_size (current_cpu_data.pgtable_cache_sz) -+ -+#define pmd_populate(mm, pmd, pte) set_pmd(pmd, __pmd(_PAGE_TABLE + __pa(pte))) -+ -+/* -+ * Allocate and free page tables. -+ */ -+ -+static inline pgd_t *get_pgd_slow_tt(void) -+{ -+ pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL); -+ -+ if (pgd) { -+ memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); -+ memcpy(pgd + USER_PTRS_PER_PGD, -+ swapper_pg_dir + USER_PTRS_PER_PGD, -+ (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); -+ } -+ return pgd; -+} -+ -+static inline pgd_t *get_pgd_slow_skas(void) -+{ -+ pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL); -+ -+ if (pgd) -+ memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); -+ return pgd; -+} -+ -+static inline pgd_t *get_pgd_slow(void) -+{ -+ return(CHOOSE_MODE(get_pgd_slow_tt(), get_pgd_slow_skas())); -+} -+ -+static inline pgd_t *get_pgd_fast(void) -+{ -+ unsigned long *ret; -+ -+ ret = pgd_quicklist; -+ if (ret != NULL) { -+ pgd_quicklist = (unsigned long *)(*ret); -+ ret[0] = 0; -+ pgtable_cache_size--; -+ } else -+ ret = (unsigned long *)get_pgd_slow(); -+ return (pgd_t *)ret; -+} -+ -+static inline void free_pgd_fast(pgd_t *pgd) -+{ -+ *(unsigned long *)pgd = (unsigned long) pgd_quicklist; -+ pgd_quicklist = (unsigned long *) pgd; -+ pgtable_cache_size++; -+} -+ -+static inline void free_pgd_slow(pgd_t *pgd) -+{ -+ free_page((unsigned long)pgd); -+} -+ -+static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address) -+{ -+ pte_t *pte; -+ -+ pte = (pte_t *) __get_free_page(GFP_KERNEL); -+ if (pte) -+ clear_page(pte); -+ return pte; -+} -+ -+static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm, unsigned long address) -+{ -+ unsigned long *ret; -+ -+ ret = (unsigned long *)pte_quicklist; -+ if (ret != NULL) { -+ pte_quicklist = (unsigned long *)(*ret); -+ ret[0] = ret[1]; -+ pgtable_cache_size--; -+ } -+ return (pte_t *)ret; -+} -+ -+static inline void pte_free_fast(pte_t *pte) -+{ -+ *(unsigned long *)pte = (unsigned long) pte_quicklist; -+ pte_quicklist = (unsigned long *) pte; -+ pgtable_cache_size++; -+} -+ -+static inline void pte_free_slow(pte_t *pte) -+{ -+ free_page((unsigned long)pte); -+} -+ -+#define pte_free(pte) pte_free_fast(pte) -+#define pgd_free(pgd) free_pgd_slow(pgd) -+#define pgd_alloc(mm) get_pgd_fast() -+ -+/* -+ * allocating and freeing a pmd is trivial: the 1-entry pmd is -+ * inside the pgd, so has no extra memory associated with it. -+ */ -+ -+#define pmd_alloc_one_fast(mm, addr) ({ BUG(); ((pmd_t *)1); }) -+#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); }) -+#define pmd_free_slow(x) do { } while (0) -+#define pmd_free_fast(x) do { } while (0) -+#define pmd_free(x) do { } while (0) -+#define pgd_populate(mm, pmd, pte) BUG() -+ -+/* -+ * TLB flushing: -+ * -+ * - flush_tlb() flushes the current mm struct TLBs -+ * - flush_tlb_all() flushes all processes TLBs -+ * - flush_tlb_mm(mm) flushes the specified mm context TLB's -+ * - flush_tlb_page(vma, vmaddr) flushes one page -+ * - flush_tlb_kernel_vm() flushes the kernel vm area -+ * - flush_tlb_range(mm, start, end) flushes a range of pages -+ * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables -+ */ -+ -+extern void flush_tlb_all(void); -+extern void flush_tlb_mm(struct mm_struct *mm); -+extern void flush_tlb_range(struct mm_struct *mm, unsigned long start, -+ unsigned long end); -+extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr); -+extern void flush_tlb_kernel_vm(void); -+ -+static inline void flush_tlb_pgtables(struct mm_struct *mm, -+ unsigned long start, unsigned long end) -+{ -+} -+ -+#endif -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/include/asm-um/pgtable.h um/include/asm-um/pgtable.h ---- orig/include/asm-um/pgtable.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/pgtable.h 2004-02-14 06:28:59.000000000 -0500 -@@ -0,0 +1,413 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Derived from include/asm-i386/pgtable.h -+ * Licensed under the GPL -+ */ -+ -+#ifndef __UM_PGTABLE_H -+#define __UM_PGTABLE_H -+ -+#include "linux/sched.h" -+#include "asm/processor.h" -+#include "asm/page.h" -+ -+extern pgd_t swapper_pg_dir[1024]; -+ -+#define flush_cache_all() do ; while (0) -+#define flush_cache_mm(mm) do ; while (0) -+#define flush_cache_range(vma, start, end) do ; while (0) -+#define flush_cache_page(vma, vmaddr) do ; while (0) -+#define flush_page_to_ram(page) do ; while (0) -+#define flush_dcache_page(page) do ; while (0) -+#define flush_icache_range(from, to) do ; while (0) -+#define flush_icache_page(vma,pg) do ; while (0) -+#define flush_icache_user_range(vma,pg,adr,len) do ; while (0) -+ -+extern void __flush_tlb_one(unsigned long addr); -+ -+extern void pte_free(pte_t *pte); -+ -+extern void pgd_free(pgd_t *pgd); -+ -+extern int do_check_pgt_cache(int, int); -+ -+extern void *um_virt_to_phys(struct task_struct *task, unsigned long virt, -+ pte_t *pte_out); -+ -+/* zero page used for uninitialized stuff */ -+extern unsigned long *empty_zero_page; -+ -+#define pgtable_cache_init() do ; while (0) -+ -+/* PMD_SHIFT determines the size of the area a second-level page table can map */ -+#define PMD_SHIFT 22 -+#define PMD_SIZE (1UL << PMD_SHIFT) -+#define PMD_MASK (~(PMD_SIZE-1)) -+ -+/* PGDIR_SHIFT determines what a third-level page table entry can map */ -+#define PGDIR_SHIFT 22 -+#define PGDIR_SIZE (1UL << PGDIR_SHIFT) -+#define PGDIR_MASK (~(PGDIR_SIZE-1)) -+ -+/* -+ * entries per page directory level: the i386 is two-level, so -+ * we don't really have any PMD directory physically. -+ */ -+#define PTRS_PER_PTE 1024 -+#define PTRS_PER_PMD 1 -+#define PTRS_PER_PGD 1024 -+#define USER_PTRS_PER_PGD (TASK_SIZE/PGDIR_SIZE) -+#define FIRST_USER_PGD_NR 0 -+ -+#define pte_ERROR(e) \ -+ printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) -+#define pmd_ERROR(e) \ -+ printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) -+#define pgd_ERROR(e) \ -+ printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) -+ -+/* -+ * pgd entries used up by user/kernel: -+ */ -+ -+#define USER_PGD_PTRS (TASK_SIZE >> PGDIR_SHIFT) -+#define KERNEL_PGD_PTRS (PTRS_PER_PGD-USER_PGD_PTRS) -+ -+#ifndef __ASSEMBLY__ -+/* Just any arbitrary offset to the start of the vmalloc VM area: the -+ * current 8MB value just means that there will be a 8MB "hole" after the -+ * physical memory until the kernel virtual memory starts. That means that -+ * any out-of-bounds memory accesses will hopefully be caught. -+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced -+ * area for the same reason. ;) -+ */ -+ -+extern unsigned long end_iomem; -+ -+#define VMALLOC_OFFSET (__va_space) -+#define VMALLOC_START ((end_iomem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) -+#define VMALLOC_VMADDR(x) ((unsigned long)(x)) -+ -+#if CONFIG_HIGHMEM -+# define VMALLOC_END (PKMAP_BASE-2*PAGE_SIZE) -+#else -+# define VMALLOC_END (FIXADDR_START-2*PAGE_SIZE) -+#endif -+ -+#define _PAGE_PRESENT 0x001 -+#define _PAGE_NEWPAGE 0x002 -+#define _PAGE_PROTNONE 0x004 /* If not present */ -+#define _PAGE_RW 0x008 -+#define _PAGE_USER 0x010 -+#define _PAGE_ACCESSED 0x020 -+#define _PAGE_DIRTY 0x040 -+#define _PAGE_NEWPROT 0x080 -+ -+#define REGION_MASK 0xf0000000 -+#define REGION_SHIFT 28 -+ -+#define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY) -+#define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) -+#define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) -+ -+#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) -+#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED) -+#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) -+#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) -+#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) -+#define PAGE_KERNEL_RO __pgprot(_PAGE_PRESENT | _PAGE_DIRTY | _PAGE_ACCESSED) -+ -+/* -+ * The i386 can't do page protection for execute, and considers that the same are read. -+ * Also, write permissions imply read permissions. This is the closest we can get.. -+ */ -+#define __P000 PAGE_NONE -+#define __P001 PAGE_READONLY -+#define __P010 PAGE_COPY -+#define __P011 PAGE_COPY -+#define __P100 PAGE_READONLY -+#define __P101 PAGE_READONLY -+#define __P110 PAGE_COPY -+#define __P111 PAGE_COPY -+ -+#define __S000 PAGE_NONE -+#define __S001 PAGE_READONLY -+#define __S010 PAGE_SHARED -+#define __S011 PAGE_SHARED -+#define __S100 PAGE_READONLY -+#define __S101 PAGE_READONLY -+#define __S110 PAGE_SHARED -+#define __S111 PAGE_SHARED -+ -+/* -+ * Define this if things work differently on an i386 and an i486: -+ * it will (on an i486) warn about kernel memory accesses that are -+ * done without a 'verify_area(VERIFY_WRITE,..)' -+ */ -+#undef TEST_VERIFY_AREA -+ -+/* page table for 0-4MB for everybody */ -+extern unsigned long pg0[1024]; -+ -+/* -+ * BAD_PAGETABLE is used when we need a bogus page-table, while -+ * BAD_PAGE is used for a bogus page. -+ * -+ * ZERO_PAGE is a global shared page that is always zero: used -+ * for zero-mapped memory areas etc.. -+ */ -+extern pte_t __bad_page(void); -+extern pte_t * __bad_pagetable(void); -+ -+#define BAD_PAGETABLE __bad_pagetable() -+#define BAD_PAGE __bad_page() -+ -+#define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page) -+ -+/* number of bits that fit into a memory pointer */ -+#define BITS_PER_PTR (8*sizeof(unsigned long)) -+ -+/* to align the pointer to a pointer address */ -+#define PTR_MASK (~(sizeof(void*)-1)) -+ -+/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */ -+/* 64-bit machines, beware! SRB. */ -+#define SIZEOF_PTR_LOG2 2 -+ -+/* to find an entry in a page-table */ -+#define PAGE_PTR(address) \ -+((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK) -+ -+#define pte_none(x) !(pte_val(x) & ~_PAGE_NEWPAGE) -+#define pte_present(x) (pte_val(x) & (_PAGE_PRESENT | _PAGE_PROTNONE)) -+ -+#define pte_clear(xp) do { pte_val(*(xp)) = _PAGE_NEWPAGE; } while (0) -+ -+#define pmd_none(x) (!(pmd_val(x) & ~_PAGE_NEWPAGE)) -+#define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE) -+#define pmd_present(x) (pmd_val(x) & _PAGE_PRESENT) -+#define pmd_clear(xp) do { pmd_val(*(xp)) = _PAGE_NEWPAGE; } while (0) -+ -+#define pmd_newpage(x) (pmd_val(x) & _PAGE_NEWPAGE) -+#define pmd_mkuptodate(x) (pmd_val(x) &= ~_PAGE_NEWPAGE) -+ -+/* -+ * The "pgd_xxx()" functions here are trivial for a folded two-level -+ * setup: the pgd is never bad, and a pmd always exists (as it's folded -+ * into the pgd entry) -+ */ -+static inline int pgd_none(pgd_t pgd) { return 0; } -+static inline int pgd_bad(pgd_t pgd) { return 0; } -+static inline int pgd_present(pgd_t pgd) { return 1; } -+static inline void pgd_clear(pgd_t * pgdp) { } -+ -+#define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) -+ -+#define pte_page(pte) virt_to_page(__va(pte_val(pte))) -+#define pmd_page(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) -+ -+extern struct page *phys_to_page(const unsigned long phys); -+extern struct page *__virt_to_page(const unsigned long virt); -+#define virt_to_page(addr) __virt_to_page((const unsigned long) addr) -+ -+static inline pte_t pte_mknewprot(pte_t pte) -+{ -+ pte_val(pte) |= _PAGE_NEWPROT; -+ return(pte); -+} -+ -+static inline pte_t pte_mknewpage(pte_t pte) -+{ -+ pte_val(pte) |= _PAGE_NEWPAGE; -+ return(pte); -+} -+ -+static inline void set_pte(pte_t *pteptr, pte_t pteval) -+{ -+ /* If it's a swap entry, it needs to be marked _PAGE_NEWPAGE so -+ * fix_range knows to unmap it. _PAGE_NEWPROT is specific to -+ * mapped pages. -+ */ -+ *pteptr = pte_mknewpage(pteval); -+ if(pte_present(*pteptr)) *pteptr = pte_mknewprot(*pteptr); -+} -+ -+/* -+ * (pmds are folded into pgds so this doesnt get actually called, -+ * but the define is needed for a generic inline function.) -+ */ -+#define set_pmd(pmdptr, pmdval) (*(pmdptr) = pmdval) -+#define set_pgd(pgdptr, pgdval) (*(pgdptr) = pgdval) -+ -+/* -+ * The following only work if pte_present() is true. -+ * Undefined behaviour if not.. -+ */ -+static inline int pte_read(pte_t pte) -+{ -+ return((pte_val(pte) & _PAGE_USER) && -+ !(pte_val(pte) & _PAGE_PROTNONE)); -+} -+ -+static inline int pte_exec(pte_t pte){ -+ return((pte_val(pte) & _PAGE_USER) && -+ !(pte_val(pte) & _PAGE_PROTNONE)); -+} -+ -+static inline int pte_write(pte_t pte) -+{ -+ return((pte_val(pte) & _PAGE_RW) && -+ !(pte_val(pte) & _PAGE_PROTNONE)); -+} -+ -+static inline int pte_dirty(pte_t pte) { return pte_val(pte) & _PAGE_DIRTY; } -+static inline int pte_young(pte_t pte) { return pte_val(pte) & _PAGE_ACCESSED; } -+static inline int pte_newpage(pte_t pte) { return pte_val(pte) & _PAGE_NEWPAGE; } -+static inline int pte_newprot(pte_t pte) -+{ -+ return(pte_present(pte) && (pte_val(pte) & _PAGE_NEWPROT)); -+} -+ -+static inline pte_t pte_rdprotect(pte_t pte) -+{ -+ pte_val(pte) &= ~_PAGE_USER; -+ return(pte_mknewprot(pte)); -+} -+ -+static inline pte_t pte_exprotect(pte_t pte) -+{ -+ pte_val(pte) &= ~_PAGE_USER; -+ return(pte_mknewprot(pte)); -+} -+ -+static inline pte_t pte_mkclean(pte_t pte) -+{ -+ pte_val(pte) &= ~_PAGE_DIRTY; -+ return(pte); -+} -+ -+static inline pte_t pte_mkold(pte_t pte) -+{ -+ pte_val(pte) &= ~_PAGE_ACCESSED; -+ return(pte); -+} -+ -+static inline pte_t pte_wrprotect(pte_t pte) -+{ -+ pte_val(pte) &= ~_PAGE_RW; -+ return(pte_mknewprot(pte)); -+} -+ -+static inline pte_t pte_mkread(pte_t pte) -+{ -+ pte_val(pte) |= _PAGE_USER; -+ return(pte_mknewprot(pte)); -+} -+ -+static inline pte_t pte_mkexec(pte_t pte) -+{ -+ pte_val(pte) |= _PAGE_USER; -+ return(pte_mknewprot(pte)); -+} -+ -+static inline pte_t pte_mkdirty(pte_t pte) -+{ -+ pte_val(pte) |= _PAGE_DIRTY; -+ return(pte); -+} -+ -+static inline pte_t pte_mkyoung(pte_t pte) -+{ -+ pte_val(pte) |= _PAGE_ACCESSED; -+ return(pte); -+} -+ -+static inline pte_t pte_mkwrite(pte_t pte) -+{ -+ pte_val(pte) |= _PAGE_RW; -+ return(pte_mknewprot(pte)); -+} -+ -+static inline pte_t pte_mkuptodate(pte_t pte) -+{ -+ pte_val(pte) &= ~_PAGE_NEWPAGE; -+ if(pte_present(pte)) pte_val(pte) &= ~_PAGE_NEWPROT; -+ return(pte); -+} -+ -+extern unsigned long page_to_phys(struct page *page); -+ -+/* -+ * Conversion functions: convert a page and protection to a page entry, -+ * and a page entry and page directory to the page they refer to. -+ */ -+ -+extern pte_t mk_pte(struct page *page, pgprot_t pgprot); -+ -+/* This takes a physical page address that is used by the remapping -+ * functions -+ */ -+#define mk_pte_phys(phys, pgprot) \ -+ (pte_mknewpage(mk_pte(virt_to_page(__va(phys)), pgprot))) -+ -+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) -+{ -+ pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); -+ if(pte_present(pte)) pte = pte_mknewpage(pte_mknewprot(pte)); -+ return pte; -+} -+ -+/* to find an entry in a page-table-directory. */ -+#define pgd_index(address) ((address >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) -+#define __pgd_offset(address) pgd_index(address) -+ -+/* to find an entry in a page-table-directory */ -+#define pgd_offset(mm, address) \ -+((mm)->pgd + ((address) >> PGDIR_SHIFT)) -+ -+/* to find an entry in a kernel page-table-directory */ -+#define pgd_offset_k(address) pgd_offset(&init_mm, address) -+ -+#define __pmd_offset(address) \ -+ (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) -+ -+/* Find an entry in the second-level page table.. */ -+static inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) -+{ -+ return (pmd_t *) dir; -+} -+ -+/* Find an entry in the third-level page table.. */ -+#define pte_offset(pmd, address) \ -+ ((pte_t *) (pmd_page(*pmd) + ((address>>10) & ((PTRS_PER_PTE-1)<<2)))) -+ -+#define update_mmu_cache(vma,address,pte) do ; while (0) -+ -+/* Encode and de-code a swap entry */ -+#define SWP_TYPE(x) (((x).val >> 3) & 0x7f) -+#define SWP_OFFSET(x) ((x).val >> 10) -+ -+#define SWP_ENTRY(type, offset) \ -+ ((swp_entry_t) { ((type) << 3) | ((offset) << 10) }) -+#define pte_to_swp_entry(pte) \ -+ ((swp_entry_t) { pte_val(pte_mkuptodate(pte)) }) -+#define swp_entry_to_pte(x) ((pte_t) { (x).val }) -+ -+#define PageSkip(x) (0) -+#define kern_addr_valid(addr) (1) -+ -+#include <asm-generic/pgtable.h> -+ -+#endif -+ -+#endif -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/include/asm-um/poll.h um/include/asm-um/poll.h ---- orig/include/asm-um/poll.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/poll.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_POLL_H -+#define __UM_POLL_H -+ -+#include "asm/arch/poll.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/posix_types.h um/include/asm-um/posix_types.h ---- orig/include/asm-um/posix_types.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/posix_types.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_POSIX_TYPES_H -+#define __UM_POSIX_TYPES_H -+ -+#include "asm/arch/posix_types.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/processor-generic.h um/include/asm-um/processor-generic.h ---- orig/include/asm-um/processor-generic.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/processor-generic.h 2004-02-14 06:28:59.000000000 -0500 -@@ -0,0 +1,177 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __UM_PROCESSOR_GENERIC_H -+#define __UM_PROCESSOR_GENERIC_H -+ -+struct pt_regs; -+ -+struct task_struct; -+ -+#include "linux/config.h" -+#include "linux/signal.h" -+#include "asm/ptrace.h" -+#include "asm/siginfo.h" -+#include "choose-mode.h" -+ -+struct mm_struct; -+ -+#define current_text_addr() ((void *) 0) -+ -+#define cpu_relax() do ; while (0) -+ -+struct thread_struct { -+ int forking; -+ unsigned long kernel_stack; -+ int nsyscalls; -+ struct pt_regs regs; -+ unsigned long cr2; -+ int err; -+ unsigned long trap_no; -+ void *fault_addr; -+ void *fault_catcher; -+ struct task_struct *prev_sched; -+ unsigned long temp_stack; -+ void *exec_buf; -+ struct arch_thread arch; -+ union { -+#ifdef CONFIG_MODE_TT -+ struct { -+ int extern_pid; -+ int tracing; -+ int switch_pipe[2]; -+ int singlestep_syscall; -+ int vm_seq; -+ } tt; -+#endif -+#ifdef CONFIG_MODE_SKAS -+ struct { -+ void *switch_buf; -+ void *fork_buf; -+ int mm_count; -+ } skas; -+#endif -+ } mode; -+ struct { -+ int op; -+ union { -+ struct { -+ int pid; -+ } fork, exec; -+ struct { -+ int (*proc)(void *); -+ void *arg; -+ } thread; -+ struct { -+ void (*proc)(void *); -+ void *arg; -+ } cb; -+ } u; -+ } request; -+}; -+ -+#define INIT_THREAD \ -+{ \ -+ .forking = 0, \ -+ .kernel_stack = 0, \ -+ .nsyscalls = 0, \ -+ .regs = EMPTY_REGS, \ -+ .cr2 = 0, \ -+ .err = 0, \ -+ .fault_addr = NULL, \ -+ .prev_sched = NULL, \ -+ .temp_stack = 0, \ -+ .exec_buf = NULL, \ -+ .arch = INIT_ARCH_THREAD, \ -+ .request = { 0 } \ -+} -+ -+#define THREAD_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE) -+ -+typedef struct { -+ unsigned long seg; -+} mm_segment_t; -+ -+extern struct task_struct *alloc_task_struct(void); -+extern void free_task_struct(struct task_struct *task); -+ -+#define get_task_struct(tsk) atomic_inc(&virt_to_page(tsk)->count) -+ -+extern void release_thread(struct task_struct *); -+extern int arch_kernel_thread(int (*fn)(void *), void * arg, -+ unsigned long flags); -+extern void dump_thread(struct pt_regs *regs, struct user *u); -+ -+extern unsigned long thread_saved_pc(struct thread_struct *t); -+ -+static inline void mm_copy_segments(struct mm_struct *from_mm, -+ struct mm_struct *new_mm) -+{ -+} -+ -+static inline void copy_segments(struct task_struct *p, -+ struct mm_struct *new_mm) -+{ -+} -+ -+static inline void release_segments(struct mm_struct *mm) -+{ -+} -+ -+#define init_task (init_task_union.task) -+#define init_stack (init_task_union.stack) -+ -+/* -+ * User space process size: 3GB (default). -+ */ -+extern unsigned long task_size; -+ -+#define TASK_SIZE (task_size) -+ -+/* This decides where the kernel will search for a free chunk of vm -+ * space during mmap's. -+ */ -+#define TASK_UNMAPPED_BASE (0x40000000) -+ -+extern void start_thread(struct pt_regs *regs, unsigned long entry, -+ unsigned long stack); -+ -+struct cpuinfo_um { -+ unsigned long loops_per_jiffy; -+ unsigned long *pgd_quick; -+ unsigned long *pmd_quick; -+ unsigned long *pte_quick; -+ unsigned long pgtable_cache_sz; -+ int ipi_pipe[2]; -+}; -+ -+extern struct cpuinfo_um boot_cpu_data; -+ -+#define my_cpu_data cpu_data[smp_processor_id()] -+ -+#ifdef CONFIG_SMP -+extern struct cpuinfo_um cpu_data[]; -+#define current_cpu_data cpu_data[smp_processor_id()] -+#else -+#define cpu_data (&boot_cpu_data) -+#define current_cpu_data boot_cpu_data -+#endif -+ -+#define KSTK_EIP(tsk) (PT_REGS_IP(&tsk->thread.regs)) -+#define KSTK_ESP(tsk) (PT_REGS_SP(&tsk->thread.regs)) -+#define get_wchan(p) (0) -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/include/asm-um/processor-i386.h um/include/asm-um/processor-i386.h ---- orig/include/asm-um/processor-i386.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/processor-i386.h 2004-02-14 06:28:59.000000000 -0500 -@@ -0,0 +1,35 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __UM_PROCESSOR_I386_H -+#define __UM_PROCESSOR_I386_H -+ -+extern int cpu_has_xmm; -+extern int cpu_has_cmov; -+ -+struct arch_thread { -+ unsigned long debugregs[8]; -+ int debugregs_seq; -+}; -+ -+#define INIT_ARCH_THREAD { .debugregs = { [ 0 ... 7 ] = 0 }, \ -+ .debugregs_seq = 0 } -+ -+#include "asm/arch/user.h" -+ -+#include "asm/processor-generic.h" -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/include/asm-um/processor-ppc.h um/include/asm-um/processor-ppc.h ---- orig/include/asm-um/processor-ppc.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/processor-ppc.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,15 @@ -+#ifndef __UM_PROCESSOR_PPC_H -+#define __UM_PROCESSOR_PPC_H -+ -+#if defined(__ASSEMBLY__) -+ -+#define CONFIG_ALL_PPC -+#include "arch/processor.h" -+ -+#else -+ -+#include "asm/processor-generic.h" -+ -+#endif -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/ptrace-generic.h um/include/asm-um/ptrace-generic.h ---- orig/include/asm-um/ptrace-generic.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/ptrace-generic.h 2004-02-14 06:28:59.000000000 -0500 -@@ -0,0 +1,74 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __UM_PTRACE_GENERIC_H -+#define __UM_PTRACE_GENERIC_H -+ -+#ifndef __ASSEMBLY__ -+ -+#include "linux/config.h" -+ -+#include "asm/current.h" -+ -+#define pt_regs pt_regs_subarch -+#define show_regs show_regs_subarch -+ -+#include "asm/arch/ptrace.h" -+ -+#undef pt_regs -+#undef show_regs -+#undef user_mode -+#undef instruction_pointer -+ -+#include "sysdep/ptrace.h" -+#include "skas_ptrace.h" -+ -+struct pt_regs { -+ union uml_pt_regs regs; -+}; -+ -+#define EMPTY_REGS { regs : EMPTY_UML_PT_REGS } -+ -+#define PT_REGS_IP(r) UPT_IP(&(r)->regs) -+#define PT_REGS_SP(r) UPT_SP(&(r)->regs) -+ -+#define PT_REG(r, reg) UPT_REG(&(r)->regs, reg) -+#define PT_REGS_SET(r, reg, val) UPT_SET(&(r)->regs, reg, val) -+ -+#define PT_REGS_SET_SYSCALL_RETURN(r, res) \ -+ UPT_SET_SYSCALL_RETURN(&(r)->regs, res) -+#define PT_REGS_RESTART_SYSCALL(r) UPT_RESTART_SYSCALL(&(r)->regs) -+ -+#define PT_REGS_SYSCALL_NR(r) UPT_SYSCALL_NR(&(r)->regs) -+ -+#define PT_REGS_SC(r) UPT_SC(&(r)->regs) -+ -+struct task_struct; -+ -+extern unsigned long getreg(struct task_struct *child, int regno); -+extern int putreg(struct task_struct *child, int regno, unsigned long value); -+extern int get_fpregs(unsigned long buf, struct task_struct *child); -+extern int set_fpregs(unsigned long buf, struct task_struct *child); -+extern int get_fpxregs(unsigned long buf, struct task_struct *child); -+extern int set_fpxregs(unsigned long buf, struct task_struct *tsk); -+ -+extern void show_regs(struct pt_regs *regs); -+ -+#define INIT_TASK_SIZE ((1 << CONFIG_KERNEL_STACK_ORDER) * PAGE_SIZE) -+ -+#endif -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/include/asm-um/ptrace-i386.h um/include/asm-um/ptrace-i386.h ---- orig/include/asm-um/ptrace-i386.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/ptrace-i386.h 2004-02-14 06:28:59.000000000 -0500 -@@ -0,0 +1,46 @@ -+/* -+ * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __UM_PTRACE_I386_H -+#define __UM_PTRACE_I386_H -+ -+#include "sysdep/ptrace.h" -+#include "asm/ptrace-generic.h" -+ -+#define PT_REGS_EAX(r) UPT_EAX(&(r)->regs) -+#define PT_REGS_EBX(r) UPT_EBX(&(r)->regs) -+#define PT_REGS_ECX(r) UPT_ECX(&(r)->regs) -+#define PT_REGS_EDX(r) UPT_EDX(&(r)->regs) -+#define PT_REGS_ESI(r) UPT_ESI(&(r)->regs) -+#define PT_REGS_EDI(r) UPT_EDI(&(r)->regs) -+#define PT_REGS_EBP(r) UPT_EBP(&(r)->regs) -+ -+#define PT_REGS_CS(r) UPT_CS(&(r)->regs) -+#define PT_REGS_SS(r) UPT_SS(&(r)->regs) -+#define PT_REGS_DS(r) UPT_DS(&(r)->regs) -+#define PT_REGS_ES(r) UPT_ES(&(r)->regs) -+#define PT_REGS_FS(r) UPT_FS(&(r)->regs) -+#define PT_REGS_GS(r) UPT_GS(&(r)->regs) -+ -+#define PT_REGS_EFLAGS(r) UPT_EFLAGS(&(r)->regs) -+ -+#define PT_REGS_ORIG_SYSCALL(r) PT_REGS_EAX(r) -+#define PT_REGS_SYSCALL_RET(r) PT_REGS_EAX(r) -+#define PT_FIX_EXEC_STACK(sp) do ; while(0) -+ -+#define user_mode(r) UPT_IS_USER(&(r)->regs) -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/include/asm-um/resource.h um/include/asm-um/resource.h ---- orig/include/asm-um/resource.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/resource.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_RESOURCE_H -+#define __UM_RESOURCE_H -+ -+#include "asm/arch/resource.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/rwlock.h um/include/asm-um/rwlock.h ---- orig/include/asm-um/rwlock.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/rwlock.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_RWLOCK_H -+#define __UM_RWLOCK_H -+ -+#include "asm/arch/rwlock.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/rwsem.h um/include/asm-um/rwsem.h ---- orig/include/asm-um/rwsem.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/rwsem.h 2004-02-14 06:28:59.000000000 -0500 -@@ -0,0 +1,10 @@ -+#ifndef __UM_RWSEM_H__ -+#define __UM_RWSEM_H__ -+ -+#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 96) -+#define __builtin_expect(exp,c) (exp) -+#endif -+ -+#include "asm/arch/rwsem.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/scatterlist.h um/include/asm-um/scatterlist.h ---- orig/include/asm-um/scatterlist.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/scatterlist.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_SCATTERLIST_H -+#define __UM_SCATTERLIST_H -+ -+#include "asm/arch/scatterlist.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/segment.h um/include/asm-um/segment.h ---- orig/include/asm-um/segment.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/segment.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,4 @@ -+#ifndef __UM_SEGMENT_H -+#define __UM_SEGMENT_H -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/semaphore.h um/include/asm-um/semaphore.h ---- orig/include/asm-um/semaphore.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/semaphore.h 2004-02-14 06:28:59.000000000 -0500 -@@ -0,0 +1,6 @@ -+#ifndef __UM_SEMAPHORE_H -+#define __UM_SEMAPHORE_H -+ -+#include "asm/arch/semaphore.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/sembuf.h um/include/asm-um/sembuf.h ---- orig/include/asm-um/sembuf.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/sembuf.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_SEMBUF_H -+#define __UM_SEMBUF_H -+ -+#include "asm/arch/sembuf.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/serial.h um/include/asm-um/serial.h ---- orig/include/asm-um/serial.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/serial.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_SERIAL_H -+#define __UM_SERIAL_H -+ -+#include "asm/arch/serial.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/shmbuf.h um/include/asm-um/shmbuf.h ---- orig/include/asm-um/shmbuf.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/shmbuf.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_SHMBUF_H -+#define __UM_SHMBUF_H -+ -+#include "asm/arch/shmbuf.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/shmparam.h um/include/asm-um/shmparam.h ---- orig/include/asm-um/shmparam.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/shmparam.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_SHMPARAM_H -+#define __UM_SHMPARAM_H -+ -+#include "asm/arch/shmparam.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/sigcontext-generic.h um/include/asm-um/sigcontext-generic.h ---- orig/include/asm-um/sigcontext-generic.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/sigcontext-generic.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_SIGCONTEXT_GENERIC_H -+#define __UM_SIGCONTEXT_GENERIC_H -+ -+#include "asm/arch/sigcontext.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/sigcontext-i386.h um/include/asm-um/sigcontext-i386.h ---- orig/include/asm-um/sigcontext-i386.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/sigcontext-i386.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_SIGCONTEXT_I386_H -+#define __UM_SIGCONTEXT_I386_H -+ -+#include "asm/sigcontext-generic.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/sigcontext-ppc.h um/include/asm-um/sigcontext-ppc.h ---- orig/include/asm-um/sigcontext-ppc.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/sigcontext-ppc.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,10 @@ -+#ifndef __UM_SIGCONTEXT_PPC_H -+#define __UM_SIGCONTEXT_PPC_H -+ -+#define pt_regs sys_pt_regs -+ -+#include "asm/sigcontext-generic.h" -+ -+#undef pt_regs -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/siginfo.h um/include/asm-um/siginfo.h ---- orig/include/asm-um/siginfo.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/siginfo.h 2004-02-14 06:28:59.000000000 -0500 -@@ -0,0 +1,6 @@ -+#ifndef __UM_SIGINFO_H -+#define __UM_SIGINFO_H -+ -+#include "asm/arch/siginfo.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/signal.h um/include/asm-um/signal.h ---- orig/include/asm-um/signal.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/signal.h 2004-02-14 06:28:59.000000000 -0500 -@@ -0,0 +1,22 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __UM_SIGNAL_H -+#define __UM_SIGNAL_H -+ -+#include "asm/arch/signal.h" -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/include/asm-um/smp.h um/include/asm-um/smp.h ---- orig/include/asm-um/smp.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/smp.h 2004-02-14 06:28:59.000000000 -0500 -@@ -0,0 +1,19 @@ -+#ifndef __UM_SMP_H -+#define __UM_SMP_H -+ -+#ifdef CONFIG_SMP -+ -+#include "linux/config.h" -+#include "asm/current.h" -+ -+#define smp_processor_id() (current->processor) -+#define cpu_logical_map(n) (n) -+#define cpu_number_map(n) (n) -+#define PROC_CHANGE_PENALTY 15 /* Pick a number, any number */ -+extern int hard_smp_processor_id(void); -+extern unsigned long cpu_online_map; -+#define NO_PROC_ID -1 -+ -+#endif -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/smplock.h um/include/asm-um/smplock.h ---- orig/include/asm-um/smplock.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/smplock.h 2004-02-14 06:28:59.000000000 -0500 -@@ -0,0 +1,6 @@ -+#ifndef __UM_SMPLOCK_H -+#define __UM_SMPLOCK_H -+ -+#include "asm/arch/smplock.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/socket.h um/include/asm-um/socket.h ---- orig/include/asm-um/socket.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/socket.h 2003-11-07 02:10:43.000000000 -0500 -@@ -0,0 +1,6 @@ -+#ifndef __UM_SOCKET_H -+#define __UM_SOCKET_H -+ -+#include "asm/arch/socket.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/sockios.h um/include/asm-um/sockios.h ---- orig/include/asm-um/sockios.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/sockios.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_SOCKIOS_H -+#define __UM_SOCKIOS_H -+ -+#include "asm/arch/sockios.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/softirq.h um/include/asm-um/softirq.h ---- orig/include/asm-um/softirq.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/softirq.h 2004-02-14 06:28:59.000000000 -0500 -@@ -0,0 +1,13 @@ -+#ifndef __UM_SOFTIRQ_H -+#define __UM_SOFTIRQ_H -+ -+#include "linux/smp.h" -+#include "asm/system.h" -+#include "asm/processor.h" -+ -+/* A gratuitous name change */ -+#define i386_bh_lock um_bh_lock -+#include "asm/arch/softirq.h" -+#undef i386_bh_lock -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/spinlock.h um/include/asm-um/spinlock.h ---- orig/include/asm-um/spinlock.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/spinlock.h 2004-02-14 06:28:59.000000000 -0500 -@@ -0,0 +1,10 @@ -+#ifndef __UM_SPINLOCK_H -+#define __UM_SPINLOCK_H -+ -+#include "linux/config.h" -+ -+#ifdef CONFIG_SMP -+#include "asm/arch/spinlock.h" -+#endif -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/statfs.h um/include/asm-um/statfs.h ---- orig/include/asm-um/statfs.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/statfs.h 2004-02-14 06:28:59.000000000 -0500 -@@ -0,0 +1,6 @@ -+#ifndef _UM_STATFS_H -+#define _UM_STATFS_H -+ -+#include "asm/arch/statfs.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/stat.h um/include/asm-um/stat.h ---- orig/include/asm-um/stat.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/stat.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_STAT_H -+#define __UM_STAT_H -+ -+#include "asm/arch/stat.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/string.h um/include/asm-um/string.h ---- orig/include/asm-um/string.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/string.h 2004-01-16 03:32:58.000000000 -0500 -@@ -0,0 +1,7 @@ -+#ifndef __UM_STRING_H -+#define __UM_STRING_H -+ -+#include "asm/arch/string.h" -+#include "asm/archparam.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/system-generic.h um/include/asm-um/system-generic.h ---- orig/include/asm-um/system-generic.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/system-generic.h 2004-02-14 06:28:59.000000000 -0500 -@@ -0,0 +1,50 @@ -+#ifndef __UM_SYSTEM_GENERIC_H -+#define __UM_SYSTEM_GENERIC_H -+ -+#include "asm/arch/system.h" -+ -+#undef prepare_to_switch -+#undef switch_to -+#undef __save_flags -+#undef save_flags -+#undef __restore_flags -+#undef restore_flags -+#undef __cli -+#undef __sti -+#undef cli -+#undef sti -+#undef local_irq_save -+#undef local_irq_restore -+#undef local_irq_disable -+#undef local_irq_enable -+ -+#define prepare_to_switch() do ; while(0) -+ -+void *_switch_to(void *prev, void *next); -+ -+#define switch_to(prev, next, last) prev = _switch_to(prev, next) -+ -+extern int get_signals(void); -+extern int set_signals(int enable); -+extern void block_signals(void); -+extern void unblock_signals(void); -+ -+#define local_irq_save(flags) do { (flags) = set_signals(0); } while(0) -+ -+#define local_irq_restore(flags) do { set_signals(flags); } while(0) -+ -+#define local_irq_enable() unblock_signals() -+#define local_irq_disable() block_signals() -+ -+#define __sti() unblock_signals() -+#define sti() unblock_signals() -+#define __cli() block_signals() -+#define cli() block_signals() -+ -+#define __save_flags(x) do { (x) = get_signals(); } while(0) -+#define save_flags(x) __save_flags(x) -+ -+#define __restore_flags(x) local_irq_restore(x) -+#define restore_flags(x) __restore_flags(x) -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/system-i386.h um/include/asm-um/system-i386.h ---- orig/include/asm-um/system-i386.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/system-i386.h 2004-02-14 06:28:59.000000000 -0500 -@@ -0,0 +1,39 @@ -+#ifndef __UM_SYSTEM_I386_H -+#define __UM_SYSTEM_I386_H -+ -+#include "asm/system-generic.h" -+ -+#define __HAVE_ARCH_CMPXCHG 1 -+ -+static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, -+ unsigned long new, int size) -+{ -+ unsigned long prev; -+ switch (size) { -+ case 1: -+ __asm__ __volatile__(LOCK_PREFIX "cmpxchgb %b1,%2" -+ : "=a"(prev) -+ : "q"(new), "m"(*__xg(ptr)), "0"(old) -+ : "memory"); -+ return prev; -+ case 2: -+ __asm__ __volatile__(LOCK_PREFIX "cmpxchgw %w1,%2" -+ : "=a"(prev) -+ : "q"(new), "m"(*__xg(ptr)), "0"(old) -+ : "memory"); -+ return prev; -+ case 4: -+ __asm__ __volatile__(LOCK_PREFIX "cmpxchgl %1,%2" -+ : "=a"(prev) -+ : "q"(new), "m"(*__xg(ptr)), "0"(old) -+ : "memory"); -+ return prev; -+ } -+ return old; -+} -+ -+#define cmpxchg(ptr,o,n)\ -+ ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\ -+ (unsigned long)(n),sizeof(*(ptr)))) -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/system-ppc.h um/include/asm-um/system-ppc.h ---- orig/include/asm-um/system-ppc.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/system-ppc.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,12 @@ -+#ifndef __UM_SYSTEM_PPC_H -+#define __UM_SYSTEM_PPC_H -+ -+#define _switch_to _ppc_switch_to -+ -+#include "asm/arch/system.h" -+ -+#undef _switch_to -+ -+#include "asm/system-generic.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/termbits.h um/include/asm-um/termbits.h ---- orig/include/asm-um/termbits.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/termbits.h 2003-11-07 02:10:43.000000000 -0500 -@@ -0,0 +1,6 @@ -+#ifndef __UM_TERMBITS_H -+#define __UM_TERMBITS_H -+ -+#include "asm/arch/termbits.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/termios.h um/include/asm-um/termios.h ---- orig/include/asm-um/termios.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/termios.h 2003-12-16 22:26:55.000000000 -0500 -@@ -0,0 +1,6 @@ -+#ifndef __UM_TERMIOS_H -+#define __UM_TERMIOS_H -+ -+#include "asm/arch/termios.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/timex.h um/include/asm-um/timex.h ---- orig/include/asm-um/timex.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/timex.h 2004-02-14 06:28:59.000000000 -0500 -@@ -0,0 +1,18 @@ -+#ifndef __UM_TIMEX_H -+#define __UM_TIMEX_H -+ -+#include "linux/time.h" -+ -+typedef unsigned long cycles_t; -+ -+#define cacheflush_time (0) -+ -+static inline cycles_t get_cycles (void) -+{ -+ return 0; -+} -+ -+#define vxtime_lock() do ; while (0) -+#define vxtime_unlock() do ; while (0) -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/tlb.h um/include/asm-um/tlb.h ---- orig/include/asm-um/tlb.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/tlb.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1 @@ -+#include <asm-generic/tlb.h> -diff -Naur -X ../exclude-files orig/include/asm-um/types.h um/include/asm-um/types.h ---- orig/include/asm-um/types.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/types.h 2004-01-16 03:32:58.000000000 -0500 -@@ -0,0 +1,6 @@ -+#ifndef __UM_TYPES_H -+#define __UM_TYPES_H -+ -+#include "asm/arch/types.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/uaccess.h um/include/asm-um/uaccess.h ---- orig/include/asm-um/uaccess.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/uaccess.h 2004-02-14 06:28:59.000000000 -0500 -@@ -0,0 +1,99 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __UM_UACCESS_H -+#define __UM_UACCESS_H -+ -+#include "linux/sched.h" -+ -+#define VERIFY_READ 0 -+#define VERIFY_WRITE 1 -+ -+/* -+ * The fs value determines whether argument validity checking should be -+ * performed or not. If get_fs() == USER_DS, checking is performed, with -+ * get_fs() == KERNEL_DS, checking is bypassed. -+ * -+ * For historical reasons, these macros are grossly misnamed. -+ */ -+ -+#define MAKE_MM_SEG(s) ((mm_segment_t) { (s) }) -+ -+#define KERNEL_DS MAKE_MM_SEG(0xFFFFFFFF) -+#define USER_DS MAKE_MM_SEG(TASK_SIZE) -+ -+#define get_ds() (KERNEL_DS) -+#define get_fs() (current->addr_limit) -+#define set_fs(x) (current->addr_limit = (x)) -+ -+#define segment_eq(a, b) ((a).seg == (b).seg) -+ -+#include "um_uaccess.h" -+ -+#define __copy_from_user(to, from, n) copy_from_user(to, from, n) -+ -+#define __copy_to_user(to, from, n) copy_to_user(to, from, n) -+ -+#define __get_user(x, ptr) \ -+({ \ -+ const __typeof__(ptr) __private_ptr = ptr; \ -+ __typeof__(*(__private_ptr)) __private_val; \ -+ int __private_ret = -EFAULT; \ -+ (x) = 0; \ -+ if (__copy_from_user(&__private_val, (__private_ptr), \ -+ sizeof(*(__private_ptr))) == 0) {\ -+ (x) = (__typeof__(*(__private_ptr))) __private_val; \ -+ __private_ret = 0; \ -+ } \ -+ __private_ret; \ -+}) -+ -+#define get_user(x, ptr) \ -+({ \ -+ const __typeof__((*ptr)) *private_ptr = (ptr); \ -+ (access_ok(VERIFY_READ, private_ptr, sizeof(*private_ptr)) ? \ -+ __get_user(x, private_ptr) : ((x) = 0, -EFAULT)); \ -+}) -+ -+#define __put_user(x, ptr) \ -+({ \ -+ __typeof__(ptr) __private_ptr = ptr; \ -+ __typeof__(*(__private_ptr)) __private_val; \ -+ int __private_ret = -EFAULT; \ -+ __private_val = (__typeof__(*(__private_ptr))) (x); \ -+ if (__copy_to_user((__private_ptr), &__private_val, \ -+ sizeof(*(__private_ptr))) == 0) { \ -+ __private_ret = 0; \ -+ } \ -+ __private_ret; \ -+}) -+ -+#define put_user(x, ptr) \ -+({ \ -+ __typeof__(*(ptr)) *private_ptr = (ptr); \ -+ (access_ok(VERIFY_WRITE, private_ptr, sizeof(*private_ptr)) ? \ -+ __put_user(x, private_ptr) : -EFAULT); \ -+}) -+ -+#define strlen_user(str) strnlen_user(str, ~0UL >> 1) -+ -+struct exception_table_entry -+{ -+ unsigned long insn; -+ unsigned long fixup; -+}; -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/include/asm-um/ucontext.h um/include/asm-um/ucontext.h ---- orig/include/asm-um/ucontext.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/ucontext.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef _ASM_UM_UCONTEXT_H -+#define _ASM_UM_UCONTEXT_H -+ -+#include "asm/arch/ucontext.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/unaligned.h um/include/asm-um/unaligned.h ---- orig/include/asm-um/unaligned.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/unaligned.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_UNALIGNED_H -+#define __UM_UNALIGNED_H -+ -+#include "asm/arch/unaligned.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/unistd.h um/include/asm-um/unistd.h ---- orig/include/asm-um/unistd.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/unistd.h 2004-02-14 06:29:00.000000000 -0500 -@@ -0,0 +1,121 @@ -+/* -+ * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef _UM_UNISTD_H_ -+#define _UM_UNISTD_H_ -+ -+#include "linux/resource.h" -+#include "asm/uaccess.h" -+ -+extern long sys_open(const char *filename, int flags, int mode); -+extern long sys_dup(unsigned int fildes); -+extern long sys_close(unsigned int fd); -+extern int um_execve(const char *file, char *const argv[], char *const env[]); -+extern long sys_setsid(void); -+extern long sys_waitpid(pid_t pid, unsigned int * stat_addr, int options); -+extern long sys_wait4(pid_t pid,unsigned int *stat_addr, int options, -+ struct rusage *ru); -+extern long sys_mount(char *dev_name, char *dir_name, char *type, -+ unsigned long flags, void *data); -+extern long sys_select(int n, fd_set *inp, fd_set *outp, fd_set *exp, -+ struct timeval *tvp); -+extern long sys_lseek(unsigned int fildes, unsigned long offset, int whence); -+extern long sys_read(unsigned int fildes, char *buf, int len); -+extern long sys_write(unsigned int fildes, char *buf, int len); -+ -+#ifdef __KERNEL_SYSCALLS__ -+ -+#define KERNEL_CALL(ret_t, sys, args...) \ -+ mm_segment_t fs = get_fs(); \ -+ ret_t ret; \ -+ set_fs(KERNEL_DS); \ -+ ret = sys(args); \ -+ set_fs(fs); \ -+ if (ret >= 0) \ -+ return ret; \ -+ errno = -(long)ret; \ -+ return -1; -+ -+static inline long open(const char *pathname, int flags, int mode) -+{ -+ KERNEL_CALL(int, sys_open, pathname, flags, mode) -+} -+ -+static inline long dup(unsigned int fd) -+{ -+ KERNEL_CALL(int, sys_dup, fd); -+} -+ -+static inline long close(unsigned int fd) -+{ -+ KERNEL_CALL(int, sys_close, fd); -+} -+ -+static inline int execve(const char *filename, char *const argv[], -+ char *const envp[]) -+{ -+ KERNEL_CALL(int, um_execve, filename, argv, envp); -+} -+ -+static inline long waitpid(pid_t pid, unsigned int *status, int options) -+{ -+ KERNEL_CALL(pid_t, sys_wait4, pid, status, options, NULL) -+} -+ -+static inline pid_t wait(int *status) -+{ -+ KERNEL_CALL(pid_t, sys_wait4, -1, status, 0, NULL) -+} -+ -+static inline pid_t setsid(void) -+{ -+ KERNEL_CALL(pid_t, sys_setsid) -+} -+ -+static inline long lseek(unsigned int fd, off_t offset, unsigned int whence) -+{ -+ KERNEL_CALL(long, sys_lseek, fd, offset, whence) -+} -+ -+static inline int read(unsigned int fd, char * buf, int len) -+{ -+ KERNEL_CALL(int, sys_read, fd, buf, len) -+} -+ -+static inline int write(unsigned int fd, char * buf, int len) -+{ -+ KERNEL_CALL(int, sys_write, fd, buf, len) -+} -+ -+#endif -+ -+/* Save the value of __KERNEL_SYSCALLS__, undefine it, include the underlying -+ * arch's unistd.h for the system call numbers, and restore the old -+ * __KERNEL_SYSCALLS__. -+ */ -+ -+#ifdef __KERNEL_SYSCALLS__ -+#define __SAVE_KERNEL_SYSCALLS__ __KERNEL_SYSCALLS__ -+#endif -+ -+#undef __KERNEL_SYSCALLS__ -+#include "asm/arch/unistd.h" -+ -+#ifdef __KERNEL_SYSCALLS__ -+#define __KERNEL_SYSCALLS__ __SAVE_KERNEL_SYSCALLS__ -+#endif -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/include/asm-um/user.h um/include/asm-um/user.h ---- orig/include/asm-um/user.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/user.h 2004-02-14 06:31:38.000000000 -0500 -@@ -0,0 +1,6 @@ -+#ifndef __UM_USER_H -+#define __UM_USER_H -+ -+#include "asm/arch/user.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/vga.h um/include/asm-um/vga.h ---- orig/include/asm-um/vga.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/vga.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_VGA_H -+#define __UM_VGA_H -+ -+#include "asm/arch/vga.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/asm-um/xor.h um/include/asm-um/xor.h ---- orig/include/asm-um/xor.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/asm-um/xor.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,6 @@ -+#ifndef __UM_XOR_H -+#define __UM_XOR_H -+ -+#include "asm-generic/xor.h" -+ -+#endif -diff -Naur -X ../exclude-files orig/include/linux/blk.h um/include/linux/blk.h ---- orig/include/linux/blk.h 2004-01-11 22:46:30.000000000 -0500 -+++ um/include/linux/blk.h 2004-02-14 06:29:18.000000000 -0500 -@@ -320,6 +320,24 @@ - #define DEVICE_REQUEST do_ida_request - #define DEVICE_NR(device) (MINOR(device) >> 4) - -+#elif (MAJOR_NR == UBD_MAJOR) -+ -+#define DEVICE_NAME "User-mode block device" -+#define DEVICE_INTR do_ubd -+#define DEVICE_REQUEST do_ubd_request -+#define DEVICE_NR(device) (MINOR(device) >> UBD_SHIFT) -+#define DEVICE_ON(device) -+#define DEVICE_OFF(device) -+ -+#elif (MAJOR_NR == COW_MAJOR) -+ -+#define DEVICE_NAME "COW device" -+#define DEVICE_INTR do_cow -+#define DEVICE_REQUEST do_cow_request -+#define DEVICE_NR(device) (MINOR(device) >> COW_SHIFT) -+#define DEVICE_ON(device) -+#define DEVICE_OFF(device) -+ - #endif /* MAJOR_NR == whatever */ - - /* provide DEVICE_xxx defaults, if not explicitly defined -diff -Naur -X ../exclude-files orig/include/linux/fs.h um/include/linux/fs.h ---- orig/include/linux/fs.h 2003-12-16 22:16:36.000000000 -0500 -+++ um/include/linux/fs.h 2004-02-14 06:28:59.000000000 -0500 -@@ -320,6 +320,8 @@ - #include <linux/ncp_fs_i.h> - #include <linux/proc_fs_i.h> - #include <linux/usbdev_fs_i.h> -+#include <linux/hostfs_fs_i.h> -+#include <linux/hppfs_fs_i.h> - #include <linux/jffs2_fs_i.h> - #include <linux/cramfs_fs_sb.h> - -@@ -516,7 +518,9 @@ - struct proc_inode_info proc_i; - struct socket socket_i; - struct usbdev_inode_info usbdev_i; -- struct jffs2_inode_info jffs2_i; -+ struct hostfs_inode_info hostfs_i; -+ struct hppfs_inode_info hppfs_i; -+ struct jffs2_inode_info jffs2_i; - void *generic_ip; - } u; - }; -@@ -864,6 +868,8 @@ - unsigned int (*poll) (struct file *, struct poll_table_struct *); - int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); - int (*mmap) (struct file *, struct vm_area_struct *); -+ void (*munmap) (struct file *, struct vm_area_struct *, -+ unsigned long start, unsigned long len); - int (*open) (struct inode *, struct file *); - int (*flush) (struct file *); - int (*release) (struct inode *, struct file *); -diff -Naur -X ../exclude-files orig/include/linux/ghash.h um/include/linux/ghash.h ---- orig/include/linux/ghash.h 1997-07-07 11:24:28.000000000 -0400 -+++ um/include/linux/ghash.h 2003-10-21 03:26:07.000000000 -0400 -@@ -153,6 +153,26 @@ - return NULL;\ - } - -+/* LINKAGE - empty or "static", depending on whether you want the definitions to -+ * be public or not -+ * NAME - a string to stick in names to make this hash table type distinct from -+ * any others -+ * HASHSIZE - number of buckets -+ * TYPE - type of data contained in the buckets - must be a structure, one -+ * field is of type NAME_ptrs, another is the hash key -+ * PTRS - TYPE must contain a field of type NAME_ptrs, PTRS is the name of that -+ * field -+ * KEYTYPE - type of the key field within TYPE -+ * KEY - name of the key field within TYPE -+ * KEYCMP - pointer to function that compares KEYTYPEs to each other - the -+ * prototype is int KEYCMP(KEYTYPE, KEYTYPE), it returns zero for equal, -+ * non-zero for not equal -+ * HASHFN - the hash function - the prototype is int HASHFN(KEYTYPE), -+ * it returns a number in the range 0 ... HASHSIZE - 1 -+ * Call DEF_HASH_STRUCTS, define your hash table as a NAME_table, then call -+ * DEF_HASH. -+ */ -+ - #define DEF_HASH_STRUCTS(NAME,HASHSIZE,TYPE) \ - \ - struct NAME##_table {\ -@@ -165,7 +185,7 @@ - TYPE * prev_hash;\ - }; - --#define DEF_HASH(LINKAGE,NAME,HASHSIZE,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,KEYEQ,HASHFN)\ -+#define DEF_HASH(LINKAGE,NAME,TYPE,PTRS,KEYTYPE,KEY,KEYCMP,HASHFN)\ - \ - LINKAGE void insert_##NAME##_hash(struct NAME##_table * tbl, TYPE * elem)\ - {\ -@@ -206,12 +226,10 @@ - \ - LINKAGE TYPE * find_##NAME##_hash(struct NAME##_table * tbl, KEYTYPE pos)\ - {\ -- int ix = hashfn(pos);\ -+ int ix = HASHFN(pos);\ - TYPE * ptr = tbl->hashtable[ix];\ - while(ptr && KEYCMP(ptr->KEY, pos))\ - ptr = ptr->PTRS.next_hash;\ -- if(ptr && !KEYEQ(ptr->KEY, pos))\ -- ptr = NULL;\ - return ptr;\ - } - -diff -Naur -X ../exclude-files orig/include/linux/hostfs_fs_i.h um/include/linux/hostfs_fs_i.h ---- orig/include/linux/hostfs_fs_i.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/linux/hostfs_fs_i.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,21 @@ -+#ifndef _HOSTFS_FS_I -+#define _HOSTFS_FS_I -+ -+struct hostfs_inode_info { -+ char *host_filename; -+ int fd; -+ int mode; -+}; -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/include/linux/hppfs_fs_i.h um/include/linux/hppfs_fs_i.h ---- orig/include/linux/hppfs_fs_i.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/linux/hppfs_fs_i.h 2003-10-21 03:26:07.000000000 -0400 -@@ -0,0 +1,19 @@ -+#ifndef _HPPFS_FS_I -+#define _HPPFS_FS_I -+ -+struct hppfs_inode_info { -+ struct dentry *proc_dentry; -+}; -+ -+#endif -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/include/linux/kernel.h um/include/linux/kernel.h ---- orig/include/linux/kernel.h 2004-01-11 22:46:12.000000000 -0500 -+++ um/include/linux/kernel.h 2004-02-14 06:28:59.000000000 -0500 -@@ -49,7 +49,7 @@ - # define ATTRIB_NORET __attribute__((noreturn)) - # define NORET_AND noreturn, - --#ifdef __i386__ -+#if defined(__i386__) || defined(UM_FASTCALL) - #define FASTCALL(x) x __attribute__((regparm(3))) - #else - #define FASTCALL(x) x -diff -Naur -X ../exclude-files orig/include/linux/kernel_stat.h um/include/linux/kernel_stat.h ---- orig/include/linux/kernel_stat.h 2004-01-11 22:46:12.000000000 -0500 -+++ um/include/linux/kernel_stat.h 2004-02-14 06:28:59.000000000 -0500 -@@ -12,7 +12,7 @@ - * used by rstatd/perfmeter - */ - --#define DK_MAX_MAJOR 16 -+#define DK_MAX_MAJOR 99 - #define DK_MAX_DISK 16 - - struct kernel_stat { -diff -Naur -X ../exclude-files orig/include/linux/mm.h um/include/linux/mm.h ---- orig/include/linux/mm.h 2003-12-16 22:16:36.000000000 -0500 -+++ um/include/linux/mm.h 2004-02-14 06:28:59.000000000 -0500 -@@ -438,6 +438,18 @@ - extern struct page * FASTCALL(__alloc_pages(unsigned int gfp_mask, unsigned int order, zonelist_t *zonelist)); - extern struct page * alloc_pages_node(int nid, unsigned int gfp_mask, unsigned int order); - -+#ifndef HAVE_ARCH_VALIDATE -+static inline struct page *arch_validate(struct page *page, -+ unsigned int gfp_mask, int order) -+{ -+ return(page); -+} -+#endif -+ -+#ifndef HAVE_ARCH_FREE_PAGE -+static inline void arch_free_page(struct page *page, int order) { } -+#endif -+ - static inline struct page * alloc_pages(unsigned int gfp_mask, unsigned int order) - { - /* -@@ -445,7 +457,7 @@ - */ - if (order >= MAX_ORDER) - return NULL; -- return _alloc_pages(gfp_mask, order); -+ return arch_validate(_alloc_pages(gfp_mask, order), gfp_mask, order); - } - - #define alloc_page(gfp_mask) alloc_pages(gfp_mask, 0) -@@ -505,6 +517,9 @@ - int get_user_pages(struct task_struct *tsk, struct mm_struct *mm, unsigned long start, - int len, int write, int force, struct page **pages, struct vm_area_struct **vmas); - -+extern long do_mprotect(struct mm_struct *mm, unsigned long start, -+ size_t len, unsigned long prot); -+ - /* - * On a two-level page table, this ends up being trivial. Thus the - * inlining and the symmetry break with pte_alloc() that does all -@@ -552,9 +567,10 @@ - - extern unsigned long get_unmapped_area(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); - --extern unsigned long do_mmap_pgoff(struct file *file, unsigned long addr, -- unsigned long len, unsigned long prot, -- unsigned long flag, unsigned long pgoff); -+extern unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file *file, -+ unsigned long addr, unsigned long len, -+ unsigned long prot, unsigned long flag, -+ unsigned long pgoff); - - static inline unsigned long do_mmap(struct file *file, unsigned long addr, - unsigned long len, unsigned long prot, -@@ -564,7 +580,8 @@ - if ((offset + PAGE_ALIGN(len)) < offset) - goto out; - if (!(offset & ~PAGE_MASK)) -- ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT); -+ ret = do_mmap_pgoff(current->mm, file, addr, len, prot, flag, -+ offset >> PAGE_SHIFT); - out: - return ret; - } -diff -Naur -X ../exclude-files orig/include/linux/proc_mm.h um/include/linux/proc_mm.h ---- orig/include/linux/proc_mm.h 1969-12-31 19:00:00.000000000 -0500 -+++ um/include/linux/proc_mm.h 2004-02-14 06:30:22.000000000 -0500 -@@ -0,0 +1,48 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#ifndef __PROC_MM_H -+#define __PROC_MM_H -+ -+#include "linux/sched.h" -+ -+#define MM_MMAP 54 -+#define MM_MUNMAP 55 -+#define MM_MPROTECT 56 -+#define MM_COPY_SEGMENTS 57 -+ -+struct mm_mmap { -+ unsigned long addr; -+ unsigned long len; -+ unsigned long prot; -+ unsigned long flags; -+ unsigned long fd; -+ unsigned long offset; -+}; -+ -+struct mm_munmap { -+ unsigned long addr; -+ unsigned long len; -+}; -+ -+struct mm_mprotect { -+ unsigned long addr; -+ unsigned long len; -+ unsigned int prot; -+}; -+ -+struct proc_mm_op { -+ int op; -+ union { -+ struct mm_mmap mmap; -+ struct mm_munmap munmap; -+ struct mm_mprotect mprotect; -+ int copy_segments; -+ } u; -+}; -+ -+extern struct mm_struct *proc_mm_get_mm(int fd); -+ -+#endif -diff -Naur -X ../exclude-files orig/include/linux/shmem_fs.h um/include/linux/shmem_fs.h ---- orig/include/linux/shmem_fs.h 2003-09-02 15:44:03.000000000 -0400 -+++ um/include/linux/shmem_fs.h 2003-12-09 00:03:31.000000000 -0500 -@@ -22,6 +22,8 @@ - unsigned long next_index; - swp_entry_t i_direct[SHMEM_NR_DIRECT]; /* for the first blocks */ - void **i_indirect; /* indirect blocks */ -+ unsigned long map_direct[SHMEM_NR_DIRECT]; -+ void **map_indirect; - unsigned long swapped; /* data pages assigned to swap */ - unsigned long flags; - struct list_head list; -diff -Naur -X ../exclude-files orig/include/linux/tty.h um/include/linux/tty.h ---- orig/include/linux/tty.h 2004-01-11 22:46:12.000000000 -0500 -+++ um/include/linux/tty.h 2004-02-14 06:28:59.000000000 -0500 -@@ -309,6 +309,9 @@ - spinlock_t read_lock; - /* If the tty has a pending do_SAK, queue it here - akpm */ - struct tq_struct SAK_tq; -+#ifdef CONFIG_TTY_LOG -+ int log_fd; -+#endif - }; - - /* tty magic number */ -@@ -365,6 +368,7 @@ - extern int specialix_init(void); - extern int espserial_init(void); - extern int macserial_init(void); -+extern int stdio_init(void); - extern int a2232board_init(void); - - extern int tty_paranoia_check(struct tty_struct *tty, kdev_t device, -@@ -420,5 +424,7 @@ - extern int vt_ioctl(struct tty_struct *tty, struct file * file, - unsigned int cmd, unsigned long arg); - -+extern void stdio_console_init(void); -+ - #endif /* __KERNEL__ */ - #endif -diff -Naur -X ../exclude-files orig/init/do_mounts.c um/init/do_mounts.c ---- orig/init/do_mounts.c 2003-12-16 22:16:36.000000000 -0500 -+++ um/init/do_mounts.c 2003-12-16 22:17:32.000000000 -0500 -@@ -154,6 +154,22 @@ - { "pf", 0x2f00 }, - { "apblock", APBLOCK_MAJOR << 8}, - { "ddv", DDV_MAJOR << 8}, -+ { "ubd0", UBD_MAJOR << 8 | 0 << 4}, -+ { "ubda", UBD_MAJOR << 8 | 0 << 4}, -+ { "ubd1", UBD_MAJOR << 8 | 1 << 4}, -+ { "ubdb", UBD_MAJOR << 8 | 1 << 4}, -+ { "ubd2", UBD_MAJOR << 8 | 2 << 4}, -+ { "ubdc", UBD_MAJOR << 8 | 2 << 4}, -+ { "ubd3", UBD_MAJOR << 8 | 3 << 4}, -+ { "ubdd", UBD_MAJOR << 8 | 3 << 4}, -+ { "ubd4", UBD_MAJOR << 8 | 4 << 4}, -+ { "ubde", UBD_MAJOR << 8 | 4 << 4}, -+ { "ubd5", UBD_MAJOR << 8 | 5 << 4}, -+ { "ubdf", UBD_MAJOR << 8 | 5 << 4}, -+ { "ubd6", UBD_MAJOR << 8 | 6 << 4}, -+ { "ubdg", UBD_MAJOR << 8 | 6 << 4}, -+ { "ubd7", UBD_MAJOR << 8 | 7 << 4}, -+ { "ubdh", UBD_MAJOR << 8 | 7 << 4}, - { "jsfd", JSFD_MAJOR << 8}, - #if defined(CONFIG_ARCH_S390) - { "dasda", (DASD_MAJOR << MINORBITS) }, -diff -Naur -X ../exclude-files orig/kernel/panic.c um/kernel/panic.c ---- orig/kernel/panic.c 2003-12-16 22:16:36.000000000 -0500 -+++ um/kernel/panic.c 2003-12-16 22:17:32.000000000 -0500 -@@ -74,7 +74,7 @@ - smp_send_stop(); - #endif - -- notifier_call_chain(&panic_notifier_list, 0, NULL); -+ notifier_call_chain(&panic_notifier_list, 0, buf); - - if (panic_timeout > 0) - { -diff -Naur -X ../exclude-files orig/MAINTAINERS um/MAINTAINERS ---- orig/MAINTAINERS 2003-12-16 22:16:23.000000000 -0500 -+++ um/MAINTAINERS 2003-12-16 22:17:22.000000000 -0500 -@@ -2055,6 +2055,14 @@ - L: linux-usb-devel@lists.sourceforge.net - W: http://usb.in.tum.de - S: Maintained -+ -+USER-MODE PORT -+P: Jeff Dike -+M: jdike@karaya.com -+L: user-mode-linux-devel@lists.sourceforge.net -+L: user-mode-linux-user@lists.sourceforge.net -+W: http://user-mode-linux.sourceforge.net -+S: Maintained - - USB "USBNET" DRIVER - P: David Brownell -diff -Naur -X ../exclude-files orig/Makefile um/Makefile ---- orig/Makefile 2004-02-14 06:26:12.000000000 -0500 -+++ um/Makefile 2004-02-14 06:26:19.000000000 -0500 -@@ -5,7 +5,15 @@ - - KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) - --ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) -+# SUBARCH tells the usermode build what the underlying arch is. That is set -+# first, and if a usermode build is happening, the "ARCH=um" on the command -+# line overrides the setting of ARCH below. If a native build is happening, -+# then ARCH is assigned, getting whatever value it gets normally, and -+# SUBARCH is subsequently ignored. -+ -+SUBARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) -+ARCH := $(SUBARCH) -+ - KERNELPATH=kernel-$(shell echo $(KERNELRELEASE) | sed -e "s/-//g") - - CONFIG_SHELL := $(shell if [ -x "$$BASH" ]; then echo $$BASH; \ -diff -Naur -X ../exclude-files orig/mm/Makefile um/mm/Makefile ---- orig/mm/Makefile 2002-08-21 11:47:43.000000000 -0400 -+++ um/mm/Makefile 2003-10-21 03:26:08.000000000 -0400 -@@ -17,5 +17,6 @@ - shmem.o - - obj-$(CONFIG_HIGHMEM) += highmem.o -+obj-$(CONFIG_PROC_MM) += proc_mm.o - - include $(TOPDIR)/Rules.make -diff -Naur -X ../exclude-files orig/mm/mmap.c um/mm/mmap.c ---- orig/mm/mmap.c 2003-12-16 22:16:36.000000000 -0500 -+++ um/mm/mmap.c 2003-12-16 22:17:32.000000000 -0500 -@@ -390,10 +390,11 @@ - return 0; - } - --unsigned long do_mmap_pgoff(struct file * file, unsigned long addr, unsigned long len, -- unsigned long prot, unsigned long flags, unsigned long pgoff) -+unsigned long do_mmap_pgoff(struct mm_struct *mm, struct file * file, -+ unsigned long addr, unsigned long len, -+ unsigned long prot, unsigned long flags, -+ unsigned long pgoff) - { -- struct mm_struct * mm = current->mm; - struct vm_area_struct * vma, * prev; - unsigned int vm_flags; - int correct_wcount = 0; -@@ -994,6 +995,11 @@ - remove_shared_vm_struct(mpnt); - mm->map_count--; - -+ if((mpnt->vm_file != NULL) && (mpnt->vm_file->f_op != NULL) && -+ (mpnt->vm_file->f_op->munmap != NULL)) -+ mpnt->vm_file->f_op->munmap(mpnt->vm_file, mpnt, st, -+ size); -+ - zap_page_range(mm, st, size); - - /* -diff -Naur -X ../exclude-files orig/mm/mprotect.c um/mm/mprotect.c ---- orig/mm/mprotect.c 2003-12-16 22:16:36.000000000 -0500 -+++ um/mm/mprotect.c 2003-12-16 22:17:32.000000000 -0500 -@@ -264,7 +264,8 @@ - return 0; - } - --asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot) -+long do_mprotect(struct mm_struct *mm, unsigned long start, size_t len, -+ unsigned long prot) - { - unsigned long nstart, end, tmp; - struct vm_area_struct * vma, * next, * prev; -@@ -281,9 +282,9 @@ - if (end == start) - return 0; - -- down_write(¤t->mm->mmap_sem); -+ down_write(&mm->mmap_sem); - -- vma = find_vma_prev(current->mm, start, &prev); -+ vma = find_vma_prev(mm, start, &prev); - error = -ENOMEM; - if (!vma || vma->vm_start > start) - goto out; -@@ -332,6 +333,11 @@ - prev->vm_mm->map_count--; - } - out: -- up_write(¤t->mm->mmap_sem); -+ up_write(&mm->mmap_sem); - return error; - } -+ -+asmlinkage long sys_mprotect(unsigned long start, size_t len, unsigned long prot) -+{ -+ return(do_mprotect(current->mm, start, len, prot)); -+} -diff -Naur -X ../exclude-files orig/mm/page_alloc.c um/mm/page_alloc.c ---- orig/mm/page_alloc.c 2003-12-16 22:16:36.000000000 -0500 -+++ um/mm/page_alloc.c 2003-12-16 22:17:32.000000000 -0500 -@@ -89,6 +89,7 @@ - struct page *base; - zone_t *zone; - -+ arch_free_page(page, order); - /* - * Yes, think what happens when other parts of the kernel take - * a reference to a page in order to pin it for io. -ben -diff -Naur -X ../exclude-files orig/mm/proc_mm.c um/mm/proc_mm.c ---- orig/mm/proc_mm.c 1969-12-31 19:00:00.000000000 -0500 -+++ um/mm/proc_mm.c 2003-10-21 03:26:08.000000000 -0400 -@@ -0,0 +1,173 @@ -+/* -+ * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) -+ * Licensed under the GPL -+ */ -+ -+#include "linux/init.h" -+#include "linux/proc_fs.h" -+#include "linux/proc_mm.h" -+#include "linux/file.h" -+#include "asm/uaccess.h" -+#include "asm/mmu_context.h" -+ -+static struct file_operations proc_mm_fops; -+ -+struct mm_struct *proc_mm_get_mm(int fd) -+{ -+ struct mm_struct *ret = ERR_PTR(-EBADF); -+ struct file *file; -+ -+ file = fget(fd); -+ if (!file) -+ goto out; -+ -+ ret = ERR_PTR(-EINVAL); -+ if(file->f_op != &proc_mm_fops) -+ goto out_fput; -+ -+ ret = file->private_data; -+ out_fput: -+ fput(file); -+ out: -+ return(ret); -+} -+ -+extern long do_mmap2(struct mm_struct *mm, unsigned long addr, -+ unsigned long len, unsigned long prot, -+ unsigned long flags, unsigned long fd, -+ unsigned long pgoff); -+ -+static ssize_t write_proc_mm(struct file *file, const char *buffer, -+ size_t count, loff_t *ppos) -+{ -+ struct mm_struct *mm = file->private_data; -+ struct proc_mm_op req; -+ int n, ret; -+ -+ if(count > sizeof(req)) -+ return(-EINVAL); -+ -+ n = copy_from_user(&req, buffer, count); -+ if(n != 0) -+ return(-EFAULT); -+ -+ ret = count; -+ switch(req.op){ -+ case MM_MMAP: { -+ struct mm_mmap *map = &req.u.mmap; -+ -+ ret = do_mmap2(mm, map->addr, map->len, map->prot, -+ map->flags, map->fd, map->offset >> PAGE_SHIFT); -+ if((ret & ~PAGE_MASK) == 0) -+ ret = count; -+ -+ break; -+ } -+ case MM_MUNMAP: { -+ struct mm_munmap *unmap = &req.u.munmap; -+ -+ down_write(&mm->mmap_sem); -+ ret = do_munmap(mm, unmap->addr, unmap->len); -+ up_write(&mm->mmap_sem); -+ -+ if(ret == 0) -+ ret = count; -+ break; -+ } -+ case MM_MPROTECT: { -+ struct mm_mprotect *protect = &req.u.mprotect; -+ -+ ret = do_mprotect(mm, protect->addr, protect->len, -+ protect->prot); -+ if(ret == 0) -+ ret = count; -+ break; -+ } -+ -+ case MM_COPY_SEGMENTS: { -+ struct mm_struct *from = proc_mm_get_mm(req.u.copy_segments); -+ -+ if(IS_ERR(from)){ -+ ret = PTR_ERR(from); -+ break; -+ } -+ -+ mm_copy_segments(from, mm); -+ break; -+ } -+ default: -+ ret = -EINVAL; -+ break; -+ } -+ -+ return(ret); -+} -+ -+static int open_proc_mm(struct inode *inode, struct file *file) -+{ -+ struct mm_struct *mm = mm_alloc(); -+ int ret; -+ -+ ret = -ENOMEM; -+ if(mm == NULL) -+ goto out_mem; -+ -+ ret = init_new_context(current, mm); -+ if(ret) -+ goto out_free; -+ -+ spin_lock(&mmlist_lock); -+ list_add(&mm->mmlist, ¤t->mm->mmlist); -+ mmlist_nr++; -+ spin_unlock(&mmlist_lock); -+ -+ file->private_data = mm; -+ -+ return(0); -+ -+ out_free: -+ mmput(mm); -+ out_mem: -+ return(ret); -+} -+ -+static int release_proc_mm(struct inode *inode, struct file *file) -+{ -+ struct mm_struct *mm = file->private_data; -+ -+ mmput(mm); -+ return(0); -+} -+ -+static struct file_operations proc_mm_fops = { -+ .open = open_proc_mm, -+ .release = release_proc_mm, -+ .write = write_proc_mm, -+}; -+ -+static int make_proc_mm(void) -+{ -+ struct proc_dir_entry *ent; -+ -+ ent = create_proc_entry("mm", 0222, &proc_root); -+ if(ent == NULL){ -+ printk("make_proc_mm : Failed to register /proc/mm\n"); -+ return(0); -+ } -+ ent->proc_fops = &proc_mm_fops; -+ -+ return(0); -+} -+ -+__initcall(make_proc_mm); -+ -+/* -+ * Overrides for Emacs so that we follow Linus's tabbing style. -+ * Emacs will notice this stuff at the end of the file and automatically -+ * adjust the settings for this buffer only. This must remain at the end -+ * of the file. -+ * --------------------------------------------------------------------------- -+ * Local variables: -+ * c-file-style: "linux" -+ * End: -+ */ -diff -Naur -X ../exclude-files orig/mm/shmem.c um/mm/shmem.c ---- orig/mm/shmem.c 2003-12-16 22:16:36.000000000 -0500 -+++ um/mm/shmem.c 2003-12-16 22:17:32.000000000 -0500 -@@ -128,16 +128,17 @@ - * +-> 48-51 - * +-> 52-55 - */ --static swp_entry_t *shmem_swp_entry(struct shmem_inode_info *info, unsigned long index, unsigned long *page) -+static void *shmem_block(unsigned long index, unsigned long *page, -+ unsigned long *direct, void ***indirect) - { - unsigned long offset; - void **dir; - - if (index < SHMEM_NR_DIRECT) -- return info->i_direct+index; -- if (!info->i_indirect) { -+ return direct+index; -+ if (!*indirect) { - if (page) { -- info->i_indirect = (void **) *page; -+ *indirect = (void **) *page; - *page = 0; - } - return NULL; /* need another page */ -@@ -146,7 +147,7 @@ - index -= SHMEM_NR_DIRECT; - offset = index % ENTRIES_PER_PAGE; - index /= ENTRIES_PER_PAGE; -- dir = info->i_indirect; -+ dir = *indirect; - - if (index >= ENTRIES_PER_PAGE/2) { - index -= ENTRIES_PER_PAGE/2; -@@ -169,7 +170,21 @@ - *dir = (void *) *page; - *page = 0; - } -- return (swp_entry_t *) *dir + offset; -+ return (unsigned long **) *dir + offset; -+} -+ -+static swp_entry_t *shmem_swp_entry(struct shmem_inode_info *info, unsigned long index, unsigned long *page) -+{ -+ return((swp_entry_t *) shmem_block(index, page, -+ (unsigned long *) info->i_direct, -+ &info->i_indirect)); -+} -+ -+static unsigned long *shmem_map_count(struct shmem_inode_info *info, -+ unsigned long index, unsigned long *page) -+{ -+ return((unsigned long *) shmem_block(index, page, info->map_direct, -+ &info->map_indirect)); - } - - /* -@@ -838,6 +853,7 @@ - ops = &shmem_vm_ops; - if (!S_ISREG(inode->i_mode)) - return -EACCES; -+ - UPDATE_ATIME(inode); - vma->vm_ops = ops; - return 0; -@@ -1723,4 +1739,125 @@ - return 0; - } - -+static int adjust_map_counts(struct shmem_inode_info *info, -+ unsigned long offset, unsigned long len, -+ int adjust) -+{ -+ unsigned long idx, i, *count, page = 0; -+ -+ spin_lock(&info->lock); -+ offset >>= PAGE_SHIFT; -+ len >>= PAGE_SHIFT; -+ for(i = 0; i < len; i++){ -+ idx = (i + offset) >> (PAGE_CACHE_SHIFT - PAGE_SHIFT); -+ -+ while((count = shmem_map_count(info, idx, &page)) == NULL){ -+ spin_unlock(&info->lock); -+ page = get_zeroed_page(GFP_KERNEL); -+ if(page == 0) -+ return(-ENOMEM); -+ spin_lock(&info->lock); -+ } -+ -+ if(page != 0) -+ free_page(page); -+ -+ *count += adjust; -+ } -+ spin_unlock(&info->lock); -+ return(0); -+} -+ - EXPORT_SYMBOL(shmem_file_setup); -+ -+struct file_operations anon_file_operations; -+ -+static int anon_mmap(struct file *file, struct vm_area_struct *vma) -+{ -+ struct file *new; -+ struct inode *inode; -+ loff_t size = vma->vm_end - vma->vm_start; -+ int err; -+ -+ if(file->private_data == NULL){ -+ new = shmem_file_setup("dev/anon", size); -+ if(IS_ERR(new)) -+ return(PTR_ERR(new)); -+ -+ new->f_op = &anon_file_operations; -+ file->private_data = new; -+ } -+ -+ if (vma->vm_file) -+ fput(vma->vm_file); -+ vma->vm_file = file->private_data; -+ get_file(vma->vm_file); -+ -+ inode = vma->vm_file->f_dentry->d_inode; -+ err = adjust_map_counts(SHMEM_I(inode), vma->vm_pgoff, size, 1); -+ if(err) -+ return(err); -+ -+ vma->vm_ops = &shmem_vm_ops; -+ return 0; -+} -+ -+static void anon_munmap(struct file *file, struct vm_area_struct *vma, -+ unsigned long start, unsigned long len) -+{ -+ struct inode *inode = file->f_dentry->d_inode; -+ struct shmem_inode_info *info = SHMEM_I(inode); -+ pgd_t *pgd; -+ pmd_t *pmd; -+ pte_t *pte; -+ struct page *page; -+ unsigned long addr, idx, *count; -+ -+ for(addr = start; addr < start + len; addr += PAGE_SIZE){ -+ idx = (addr - vma->vm_start + vma->vm_pgoff); -+ idx >>= PAGE_CACHE_SHIFT; -+ -+ count = shmem_map_count(info, idx, NULL); -+ BUG_ON(count == NULL); -+ -+ (*count)--; -+ if(*count > 0) -+ continue; -+ -+ pgd = pgd_offset(vma->vm_mm, addr); -+ if(pgd_none(*pgd)) -+ continue; -+ -+ pmd = pmd_offset(pgd, addr); -+ if(pmd_none(*pmd)) -+ continue; -+ -+ pte = pte_offset(pmd, addr); -+ if(!pte_present(*pte)) /* XXX need to handle swapped pages */ -+ continue; -+ -+ *pte = pte_mkclean(*pte); -+ -+ page = pte_page(*pte); -+ LockPage(page); -+ lru_cache_del(page); -+ ClearPageDirty(page); -+ remove_inode_page(page); -+ UnlockPage(page); -+ -+ page_cache_release(page); -+ } -+} -+ -+int anon_release(struct inode *inode, struct file *file) -+{ -+ if(file->private_data != NULL) -+ fput(file->private_data); -+ return(0); -+} -+ -+struct file_operations anon_file_operations = { -+ .mmap = anon_mmap, -+ .munmap = anon_munmap, -+ .release = anon_release, -+}; diff --git a/lustre/kernel_patches/patches/vfs-pdirops-2.4.24.patch b/lustre/kernel_patches/patches/vfs-pdirops-2.4.24.patch deleted file mode 100644 index d545988..0000000 --- a/lustre/kernel_patches/patches/vfs-pdirops-2.4.24.patch +++ /dev/null @@ -1,271 +0,0 @@ - fs/inode.c | 1 - fs/namei.c | 66 ++++++++++++++++++++++++++++++++++++++--------------- - include/linux/fs.h | 11 ++++---- - 3 files changed, 54 insertions(+), 24 deletions(-) - -Index: linux-2.4.24/fs/namei.c -=================================================================== ---- linux-2.4.24.orig/fs/namei.c 2004-06-24 09:08:27.000000000 +0400 -+++ linux-2.4.24/fs/namei.c 2004-06-27 21:32:00.000000000 +0400 -@@ -103,6 +103,38 @@ - } - EXPORT_SYMBOL(intent_release); - -+void *lock_dir(struct inode *dir, struct qstr *name) -+{ -+ unsigned long hash; -+ -+ if (!IS_PDIROPS(dir)) { -+ down(&dir->i_sem); -+ return 0; -+ } -+ -+ /* OK. fs understands parallel directory operations. -+ * so, we try to acquire lock for hash of requested -+ * filename in order to prevent any operations with -+ * same name in same time -bzzz */ -+ -+ /* calculate name hash */ -+ hash = full_name_hash(name->name, name->len); -+ -+ /* lock this hash */ -+ return dynlock_lock(&dir->i_dcache_lock, hash, 1, GFP_ATOMIC); -+} -+EXPORT_SYMBOL(lock_dir); -+ -+void unlock_dir(struct inode *dir, void *lock) -+{ -+ if (!IS_PDIROPS(dir)) { -+ up(&dir->i_sem); -+ return; -+ } -+ dynlock_unlock(&dir->i_dcache_lock, lock); -+} -+EXPORT_SYMBOL(unlock_dir); -+ - /* In order to reduce some races, while at the same time doing additional - * checking and hopefully speeding things up, we copy filenames to the - * kernel data space before using them.. -@@ -307,10 +339,11 @@ - struct dentry * result; - struct inode *dir = parent->d_inode; - int counter = 0; -+ void *lock; - - again: - counter++; -- down(&dir->i_sem); -+ lock = lock_dir(dir, name); - /* - * First re-do the cached lookup just in case it was created - * while we waited for the directory semaphore.. -@@ -334,7 +367,7 @@ - else - result = dentry; - } -- up(&dir->i_sem); -+ unlock_dir(dir, lock); - return result; - } - -@@ -342,7 +375,7 @@ - * Uhhuh! Nasty case: the cache was re-populated while - * we waited on the semaphore. Need to revalidate. - */ -- up(&dir->i_sem); -+ unlock_dir(dir, lock); - if (result->d_op && result->d_op->d_revalidate) { - if (!result->d_op->d_revalidate(result, flags) && !d_invalidate(result)) { - dput(result); -@@ -1174,13 +1207,13 @@ - goto exit; - - dir = nd->dentry; -- down(&dir->d_inode->i_sem); -+ nd->lock = lock_dir(dir->d_inode, &nd->last); - dentry = lookup_hash_it(&nd->last, nd->dentry, nd, it); - - do_last: - error = PTR_ERR(dentry); - if (IS_ERR(dentry)) { -- up(&dir->d_inode->i_sem); -+ unlock_dir(dir->d_inode, nd->lock); - goto exit; - } - -@@ -1189,7 +1222,7 @@ - if (!dentry->d_inode) { - error = vfs_create_it(dir->d_inode, dentry, - mode & ~current->fs->umask, it); -- up(&dir->d_inode->i_sem); -+ unlock_dir(dir->d_inode, nd->lock); - dput(nd->dentry); - nd->dentry = dentry; - if (error) -@@ -1203,7 +1236,7 @@ - /* - * It already exists. - */ -- up(&dir->d_inode->i_sem); -+ unlock_dir(dir->d_inode, nd->lock); - - error = -EEXIST; - if (flag & O_EXCL) -@@ -1350,7 +1383,7 @@ - goto exit; - } - dir = nd->dentry; -- down(&dir->d_inode->i_sem); -+ nd->lock = lock_dir(dir->d_inode, &nd->last); - dentry = lookup_hash_it(&nd->last, nd->dentry, nd, it); - putname(nd->last.name); - goto do_last; -@@ -1368,7 +1401,7 @@ - { - struct dentry *dentry; - -- down(&nd->dentry->d_inode->i_sem); -+ nd->lock = lock_dir(nd->dentry->d_inode, &nd->last); - dentry = ERR_PTR(-EEXIST); - if (nd->last_type != LAST_NORM) - goto fail; -@@ -1461,7 +1494,7 @@ - } - dput(dentry); - } -- up(&nd.dentry->d_inode->i_sem); -+ unlock_dir(nd.dentry->d_inode, nd.lock); - out2: - path_release(&nd); - out: -@@ -1528,7 +1561,7 @@ - mode & ~current->fs->umask); - dput(dentry); - } -- up(&nd.dentry->d_inode->i_sem); -+ unlock_dir(nd.dentry->d_inode, nd.lock); - out2: - path_release(&nd); - out: -@@ -1638,14 +1671,14 @@ - if (error != -EOPNOTSUPP) - goto exit1; - } -- down(&nd.dentry->d_inode->i_sem); -+ nd.lock = lock_dir(nd.dentry->d_inode, &nd.last); - dentry = lookup_hash_it(&nd.last, nd.dentry, &nd, NULL); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_rmdir(nd.dentry->d_inode, dentry); - dput(dentry); - } -- up(&nd.dentry->d_inode->i_sem); -+ unlock_dir(nd.dentry->d_inode, nd.lock); - exit1: - path_release(&nd); - exit: -@@ -1704,7 +1737,7 @@ - if (error != -EOPNOTSUPP) - goto exit1; - } -- down(&nd.dentry->d_inode->i_sem); -+ nd.lock = lock_dir(nd.dentry->d_inode, &nd.last); - dentry = lookup_hash_it(&nd.last, nd.dentry, &nd, NULL); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { -@@ -1715,7 +1748,7 @@ - exit2: - dput(dentry); - } -- up(&nd.dentry->d_inode->i_sem); -+ unlock_dir(nd.dentry->d_inode, nd.lock); - exit1: - path_release(&nd); - exit: -@@ -1789,7 +1822,7 @@ - error = vfs_symlink(nd.dentry->d_inode, dentry, from); - dput(dentry); - } -- up(&nd.dentry->d_inode->i_sem); -+ unlock_dir(nd.dentry->d_inode, nd.lock); - out2: - path_release(&nd); - out: -@@ -1885,7 +1918,7 @@ - error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); - dput(new_dentry); - } -- up(&nd.dentry->d_inode->i_sem); -+ unlock_dir(nd.dentry->d_inode, nd.lock); - out_release: - path_release(&nd); - out: -Index: linux-2.4.24/fs/inode.c -=================================================================== ---- linux-2.4.24.orig/fs/inode.c 2004-06-24 09:08:27.000000000 +0400 -+++ linux-2.4.24/fs/inode.c 2004-06-24 09:08:29.000000000 +0400 -@@ -119,6 +119,7 @@ - mapping->host = inode; - mapping->gfp_mask = GFP_HIGHUSER; - inode->i_mapping = mapping; -+ dynlock_init(&inode->i_dcache_lock); - } - return inode; - } -Index: linux-2.4.24/include/linux/fs.h -=================================================================== ---- linux-2.4.24.orig/include/linux/fs.h 2004-06-24 09:08:29.000000000 +0400 -+++ linux-2.4.24/include/linux/fs.h 2004-06-24 09:08:29.000000000 +0400 -@@ -21,6 +21,7 @@ - #include <linux/cache.h> - #include <linux/stddef.h> - #include <linux/string.h> -+#include <linux/dynlocks.h> - - #include <asm/atomic.h> - #include <asm/bitops.h> -@@ -139,6 +140,7 @@ - #define S_IMMUTABLE 16 /* Immutable file */ - #define S_DEAD 32 /* removed, but still open directory */ - #define S_NOQUOTA 64 /* Inode is not counted to quota */ -+#define S_PDIROPS 256 /* Parallel directory operations */ - - /* - * Note that nosuid etc flags are inode-specific: setting some file-system -@@ -165,6 +167,7 @@ - #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE) - #define IS_NOATIME(inode) (__IS_FLG(inode, MS_NOATIME) || ((inode)->i_flags & S_NOATIME)) - #define IS_NODIRATIME(inode) __IS_FLG(inode, MS_NODIRATIME) -+#define IS_PDIROPS(inode) __IS_FLG(inode, S_PDIROPS) - - #define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD) - -@@ -500,6 +503,7 @@ - atomic_t i_writecount; - unsigned int i_attr_flags; - __u32 i_generation; -+ struct dynlock i_dcache_lock; /* for parallel directory ops */ - union { - struct minix_inode_info minix_i; - struct ext2_inode_info ext2_i; -@@ -714,6 +718,7 @@ - unsigned int flags; - int last_type; - struct lookup_intent *intent; -+ void *lock; - }; - - /* -@@ -1629,12 +1634,6 @@ - return dget(dentry->d_parent); - } - --static inline void unlock_dir(struct dentry *dir) --{ -- up(&dir->d_inode->i_sem); -- dput(dir); --} -- - /* - * Whee.. Deadlock country. Happily there are only two VFS - * operations that does this.. diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.24.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.24.patch deleted file mode 100755 index 3704ca3..0000000 --- a/lustre/kernel_patches/patches/vfs_intent-2.4.24.patch +++ /dev/null @@ -1,1963 +0,0 @@ - fs/dcache.c | 19 ++ - fs/exec.c | 17 +- - fs/namei.c | 295 +++++++++++++++++++++++++++++++++++++++------- - fs/namespace.c | 28 +++- - fs/open.c | 172 +++++++++++++++++++------- - fs/stat.c | 52 +++++--- - include/linux/dcache.h | 60 +++++++++ - include/linux/fs.h | 32 ++++ - include/linux/fs_struct.h | 4 - kernel/exit.c | 3 - kernel/fork.c | 3 - kernel/ksyms.c | 1 - 12 files changed, 558 insertions(+), 128 deletions(-) - -Index: lum/fs/dcache.c -=================================================================== ---- lum.orig/fs/dcache.c 2003-06-13 10:51:37.000000000 -0400 -+++ lum/fs/dcache.c 2004-06-07 17:19:43.000000000 -0400 -@@ -181,6 +181,13 @@ - spin_unlock(&dcache_lock); - return 0; - } -+ -+ /* network invalidation by Lustre */ -+ if (dentry->d_flags & DCACHE_LUSTRE_INVALID) { -+ spin_unlock(&dcache_lock); -+ return 0; -+ } -+ - /* - * Check whether to do a partial shrink_dcache - * to get rid of unused child entries. -@@ -830,13 +837,19 @@ - * Adds a dentry to the hash according to its name. - */ - --void d_rehash(struct dentry * entry) -+void __d_rehash(struct dentry * entry, int lock) - { - struct list_head *list = d_hash(entry->d_parent, entry->d_name.hash); - if (!list_empty(&entry->d_hash)) BUG(); -- spin_lock(&dcache_lock); -+ if (lock) spin_lock(&dcache_lock); - list_add(&entry->d_hash, list); -- spin_unlock(&dcache_lock); -+ if (lock) spin_unlock(&dcache_lock); -+} -+EXPORT_SYMBOL(__d_rehash); -+ -+void d_rehash(struct dentry * entry) -+{ -+ __d_rehash(entry, 1); - } - - #define do_switch(x,y) do { \ -Index: lum/fs/exec.c -=================================================================== ---- lum.orig/fs/exec.c 2003-11-28 13:26:21.000000000 -0500 -+++ lum/fs/exec.c 2004-06-07 17:19:43.000000000 -0400 -@@ -112,8 +112,10 @@ - struct file * file; - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_OPEN, -+ .it_flags = FMODE_READ|FMODE_EXEC }; - -- error = user_path_walk(library, &nd); -+ error = user_path_walk_it(library, &nd, &it); - if (error) - goto out; - -@@ -125,7 +127,8 @@ - if (error) - goto exit; - -- file = dentry_open(nd.dentry, nd.mnt, O_RDONLY); -+ file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it); -+ intent_release(&it); - error = PTR_ERR(file); - if (IS_ERR(file)) - goto out; -@@ -374,8 +377,10 @@ - struct inode *inode; - struct file *file; - int err = 0; -+ struct lookup_intent it = { .it_op = IT_OPEN, -+ .it_flags = FMODE_READ|FMODE_EXEC }; - -- err = path_lookup(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd); -+ err = path_lookup_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd, &it); - file = ERR_PTR(err); - if (!err) { - inode = nd.dentry->d_inode; -@@ -387,7 +392,8 @@ - err = -EACCES; - file = ERR_PTR(err); - if (!err) { -- file = dentry_open(nd.dentry, nd.mnt, O_RDONLY); -+ file = dentry_open_it(nd.dentry, nd.mnt, O_RDONLY, &it); -+ intent_release(&it); - if (!IS_ERR(file)) { - err = deny_write_access(file); - if (err) { -@@ -399,6 +405,7 @@ - return file; - } - } -+ intent_release(&it); - path_release(&nd); - } - goto out; -@@ -1132,7 +1139,7 @@ - goto close_fail; - if (!file->f_op->write) - goto close_fail; -- if (do_truncate(file->f_dentry, 0) != 0) -+ if (do_truncate(file->f_dentry, 0, 0) != 0) - goto close_fail; - - retval = binfmt->core_dump(signr, regs, file); -Index: lum/fs/namei.c -=================================================================== ---- lum.orig/fs/namei.c 2003-08-25 07:44:43.000000000 -0400 -+++ lum/fs/namei.c 2004-06-07 17:24:47.000000000 -0400 -@@ -94,6 +94,13 @@ - * XEmacs seems to be relying on it... - */ - -+void intent_release(struct lookup_intent *it) -+{ -+ if (it && it->it_op_release) -+ it->it_op_release(it); -+ -+} -+ - /* In order to reduce some races, while at the same time doing additional - * checking and hopefully speeding things up, we copy filenames to the - * kernel data space before using them.. -@@ -260,10 +267,20 @@ - * Internal lookup() using the new generic dcache. - * SMP-safe - */ --static struct dentry * cached_lookup(struct dentry * parent, struct qstr * name, int flags) -+static struct dentry *cached_lookup(struct dentry *parent, struct qstr *name, -+ int flags, struct nameidata *nd, -+ struct lookup_intent *it) - { - struct dentry * dentry = d_lookup(parent, name); - -+ if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) { -+ if (!dentry->d_op->d_revalidate_it(dentry, flags, nd, it) && -+ !d_invalidate(dentry)) { -+ dput(dentry); -+ dentry = NULL; -+ } -+ return dentry; -+ } else - if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { - if (!dentry->d_op->d_revalidate(dentry, flags) && !d_invalidate(dentry)) { - dput(dentry); -@@ -281,11 +298,16 @@ - * make sure that nobody added the entry to the dcache in the meantime.. - * SMP-safe - */ --static struct dentry * real_lookup(struct dentry * parent, struct qstr * name, int flags) -+static struct dentry *real_lookup(struct dentry *parent, struct qstr *name, -+ int flags, struct nameidata *nd, -+ struct lookup_intent *it) - { - struct dentry * result; - struct inode *dir = parent->d_inode; -+ int counter = 0; - -+again: -+ counter++; - down(&dir->i_sem); - /* - * First re-do the cached lookup just in case it was created -@@ -300,6 +322,9 @@ - result = ERR_PTR(-ENOMEM); - if (dentry) { - lock_kernel(); -+ if (dir->i_op->lookup_it) -+ result = dir->i_op->lookup_it(dir, dentry, nd, it, flags); -+ else - result = dir->i_op->lookup(dir, dentry); - unlock_kernel(); - if (result) -@@ -321,6 +346,15 @@ - dput(result); - result = ERR_PTR(-ENOENT); - } -+ } else if (result->d_op && result->d_op->d_revalidate_it) { -+ if (!result->d_op->d_revalidate_it(result, flags, nd, it) && -+ !d_invalidate(result)) { -+ dput(result); -+ if (counter > 10) -+ result = ERR_PTR(-ESTALE); -+ if (!IS_ERR(result)) -+ goto again; -+ } - } - return result; - } -@@ -332,7 +366,8 @@ - * Without that kind of total limit, nasty chains of consecutive - * symlinks can cause almost arbitrarily long lookups. - */ --static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd) -+static inline int do_follow_link(struct dentry *dentry, struct nameidata *nd, -+ struct lookup_intent *it) - { - int err; - if (current->link_count >= 5) -@@ -346,10 +381,12 @@ - current->link_count++; - current->total_link_count++; - UPDATE_ATIME(dentry->d_inode); -+ nd->intent = it; - err = dentry->d_inode->i_op->follow_link(dentry, nd); - current->link_count--; - return err; - loop: -+ intent_release(it); - path_release(nd); - return -ELOOP; - } -@@ -447,7 +484,8 @@ - * - * We expect 'base' to be positive and a directory. - */ --int link_path_walk(const char * name, struct nameidata *nd) -+int link_path_walk_it(const char *name, struct nameidata *nd, -+ struct lookup_intent *it) - { - struct dentry *dentry; - struct inode *inode; -@@ -520,9 +558,9 @@ - break; - } - /* This does the actual lookups.. */ -- dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE); -+ dentry = cached_lookup(nd->dentry, &this, LOOKUP_CONTINUE, nd, NULL); - if (!dentry) { -- dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE); -+ dentry = real_lookup(nd->dentry, &this, LOOKUP_CONTINUE, nd, NULL); - err = PTR_ERR(dentry); - if (IS_ERR(dentry)) - break; -@@ -540,7 +578,7 @@ - goto out_dput; - - if (inode->i_op->follow_link) { -- err = do_follow_link(dentry, nd); -+ err = do_follow_link(dentry, nd, NULL); - dput(dentry); - if (err) - goto return_err; -@@ -556,7 +594,7 @@ - nd->dentry = dentry; - } - err = -ENOTDIR; -- if (!inode->i_op->lookup) -+ if (!inode->i_op->lookup && !inode->i_op->lookup_it) - break; - continue; - /* here ends the main loop */ -@@ -583,9 +621,9 @@ - if (err < 0) - break; - } -- dentry = cached_lookup(nd->dentry, &this, 0); -+ dentry = cached_lookup(nd->dentry, &this, 0, nd, it); - if (!dentry) { -- dentry = real_lookup(nd->dentry, &this, 0); -+ dentry = real_lookup(nd->dentry, &this, 0, nd, it); - err = PTR_ERR(dentry); - if (IS_ERR(dentry)) - break; -@@ -595,7 +633,7 @@ - inode = dentry->d_inode; - if ((lookup_flags & LOOKUP_FOLLOW) - && inode && inode->i_op && inode->i_op->follow_link) { -- err = do_follow_link(dentry, nd); -+ err = do_follow_link(dentry, nd, it); - dput(dentry); - if (err) - goto return_err; -@@ -609,7 +647,8 @@ - goto no_inode; - if (lookup_flags & LOOKUP_DIRECTORY) { - err = -ENOTDIR; -- if (!inode->i_op || !inode->i_op->lookup) -+ if (!inode->i_op || -+ (!inode->i_op->lookup && !inode->i_op->lookup_it)) - break; - } - goto return_base; -@@ -635,6 +674,27 @@ - * Check the cached dentry for staleness. - */ - dentry = nd->dentry; -+ if (dentry && dentry->d_op && dentry->d_op->d_revalidate_it) { -+ err = -ESTALE; -+ if (!dentry->d_op->d_revalidate_it(dentry, 0, nd, it)) { -+ struct dentry *new; -+ err = permission(dentry->d_parent->d_inode, -+ MAY_EXEC); -+ if (err) -+ break; -+ new = real_lookup(dentry->d_parent, -+ &dentry->d_name, 0, nd, it); -+ if (IS_ERR(new)) { -+ err = PTR_ERR(new); -+ break; -+ } -+ d_invalidate(dentry); -+ dput(dentry); -+ nd->dentry = new; -+ } -+ if (!nd->dentry->d_inode) -+ goto no_inode; -+ } else - if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { - err = -ESTALE; - if (!dentry->d_op->d_revalidate(dentry, 0)) { -@@ -648,15 +708,28 @@ - dput(dentry); - break; - } -+ if (err) -+ intent_release(it); - path_release(nd); - return_err: - return err; - } - -+int link_path_walk(const char * name, struct nameidata *nd) -+{ -+ return link_path_walk_it(name, nd, NULL); -+} -+ -+int path_walk_it(const char * name, struct nameidata *nd, struct lookup_intent *it) -+{ -+ current->total_link_count = 0; -+ return link_path_walk_it(name, nd, it); -+} -+ - int path_walk(const char * name, struct nameidata *nd) - { - current->total_link_count = 0; -- return link_path_walk(name, nd); -+ return link_path_walk_it(name, nd, NULL); - } - - /* SMP-safe */ -@@ -741,6 +814,17 @@ - } - - /* SMP-safe */ -+int path_lookup_it(const char *path, unsigned flags, struct nameidata *nd, -+ struct lookup_intent *it) -+{ -+ int error = 0; -+ if (path_init(path, flags, nd)) -+ error = path_walk_it(path, nd, it); -+ return error; -+} -+ -+ -+/* SMP-safe */ - int path_lookup(const char *path, unsigned flags, struct nameidata *nd) - { - int error = 0; -@@ -755,6 +839,7 @@ - { - nd->last_type = LAST_ROOT; /* if there are only slashes... */ - nd->flags = flags; -+ nd->intent = NULL; - if (*name=='/') - return walk_init_root(name,nd); - read_lock(¤t->fs->lock); -@@ -769,7 +854,8 @@ - * needs parent already locked. Doesn't follow mounts. - * SMP-safe. - */ --struct dentry * lookup_hash(struct qstr *name, struct dentry * base) -+struct dentry * lookup_hash_it(struct qstr *name, struct dentry * base, -+ struct nameidata *nd, struct lookup_intent *it) - { - struct dentry * dentry; - struct inode *inode; -@@ -792,13 +878,16 @@ - goto out; - } - -- dentry = cached_lookup(base, name, 0); -+ dentry = cached_lookup(base, name, 0, nd, it); - if (!dentry) { - struct dentry *new = d_alloc(base, name); - dentry = ERR_PTR(-ENOMEM); - if (!new) - goto out; - lock_kernel(); -+ if (inode->i_op->lookup_it) -+ dentry = inode->i_op->lookup_it(inode, new, nd, it, 0); -+ else - dentry = inode->i_op->lookup(inode, new); - unlock_kernel(); - if (!dentry) -@@ -810,6 +899,13 @@ - return dentry; - } - -+struct dentry * lookup_hash(struct qstr *name, struct dentry * base, -+ struct nameidata *nd) -+{ -+ return lookup_hash_it(name, base, nd, NULL); -+} -+ -+ - /* SMP-safe */ - struct dentry * lookup_one_len(const char * name, struct dentry * base, int len) - { -@@ -831,7 +927,7 @@ - } - this.hash = end_name_hash(hash); - -- return lookup_hash(&this, base); -+ return lookup_hash_it(&this, base, NULL, NULL); - access: - return ERR_PTR(-EACCES); - } -@@ -862,6 +958,23 @@ - return err; - } - -+int __user_walk_it(const char *name, unsigned flags, struct nameidata *nd, -+ struct lookup_intent *it) -+{ -+ char *tmp; -+ int err; -+ -+ tmp = getname(name); -+ err = PTR_ERR(tmp); -+ if (!IS_ERR(tmp)) { -+ err = 0; -+ if (path_init(tmp, flags, nd)) -+ err = path_walk_it(tmp, nd, it); -+ putname(tmp); -+ } -+ return err; -+} -+ - /* - * It's inline, so penalty for filesystems that don't use sticky bit is - * minimal. -@@ -957,7 +1070,8 @@ - return retval; - } - --int vfs_create(struct inode *dir, struct dentry *dentry, int mode) -+static int vfs_create_it(struct inode *dir, struct dentry *dentry, int mode, -+ struct lookup_intent *it) - { - int error; - -@@ -970,12 +1084,15 @@ - goto exit_lock; - - error = -EACCES; /* shouldn't it be ENOSYS? */ -- if (!dir->i_op || !dir->i_op->create) -+ if (!dir->i_op || (!dir->i_op->create && !dir->i_op->create_it)) - goto exit_lock; - - DQUOT_INIT(dir); - lock_kernel(); -- error = dir->i_op->create(dir, dentry, mode); -+ if (dir->i_op->create_it) -+ error = dir->i_op->create_it(dir, dentry, mode, it); -+ else -+ error = dir->i_op->create(dir, dentry, mode); - unlock_kernel(); - exit_lock: - up(&dir->i_zombie); -@@ -984,6 +1101,11 @@ - return error; - } - -+int vfs_create(struct inode *dir, struct dentry *dentry, int mode) -+{ -+ return vfs_create_it(dir, dentry, mode, NULL); -+} -+ - /* - * open_namei() - * -@@ -998,7 +1120,8 @@ - * for symlinks (where the permissions are checked later). - * SMP-safe - */ --int open_namei(const char * pathname, int flag, int mode, struct nameidata *nd) -+int open_namei_it(const char *pathname, int flag, int mode, -+ struct nameidata *nd, struct lookup_intent *it) - { - int acc_mode, error = 0; - struct inode *inode; -@@ -1008,11 +1131,14 @@ - - acc_mode = ACC_MODE(flag); - -+ if (it) -+ it->it_flags = flag; -+ - /* - * The simplest case - just a plain lookup. - */ - if (!(flag & O_CREAT)) { -- error = path_lookup(pathname, lookup_flags(flag), nd); -+ error = path_lookup_it(pathname, lookup_flags(flag), nd, it); - if (error) - return error; - dentry = nd->dentry; -@@ -1022,6 +1148,10 @@ - /* - * Create - we need to know the parent. - */ -+ if (it) { -+ it->it_create_mode = mode; -+ it->it_op |= IT_CREAT; -+ } - error = path_lookup(pathname, LOOKUP_PARENT, nd); - if (error) - return error; -@@ -1037,7 +1167,7 @@ - - dir = nd->dentry; - down(&dir->d_inode->i_sem); -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash_it(&nd->last, nd->dentry, nd, it); - - do_last: - error = PTR_ERR(dentry); -@@ -1046,10 +1176,11 @@ - goto exit; - } - -+ it->it_create_mode = mode; - /* Negative dentry, just create the file */ - if (!dentry->d_inode) { -- error = vfs_create(dir->d_inode, dentry, -- mode & ~current->fs->umask); -+ error = vfs_create_it(dir->d_inode, dentry, -+ mode & ~current->fs->umask, it); - up(&dir->d_inode->i_sem); - dput(nd->dentry); - nd->dentry = dentry; -@@ -1153,7 +1284,7 @@ - if (!error) { - DQUOT_INIT(inode); - -- error = do_truncate(dentry, 0); -+ error = do_truncate(dentry, 0, 1); - } - put_write_access(inode); - if (error) -@@ -1165,8 +1296,10 @@ - return 0; - - exit_dput: -+ intent_release(it); - dput(dentry); - exit: -+ intent_release(it); - path_release(nd); - return error; - -@@ -1185,7 +1318,10 @@ - * are done. Procfs-like symlinks just set LAST_BIND. - */ - UPDATE_ATIME(dentry->d_inode); -+ nd->intent = it; - error = dentry->d_inode->i_op->follow_link(dentry, nd); -+ if (error) -+ intent_release(it); - dput(dentry); - if (error) - return error; -@@ -1207,13 +1343,20 @@ - } - dir = nd->dentry; - down(&dir->d_inode->i_sem); -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash_it(&nd->last, nd->dentry, nd, it); - putname(nd->last.name); - goto do_last; - } - -+int open_namei(const char *pathname, int flag, int mode, struct nameidata *nd) -+{ -+ return open_namei_it(pathname, flag, mode, nd, NULL); -+} -+ -+ - /* SMP-safe */ --static struct dentry *lookup_create(struct nameidata *nd, int is_dir) -+static struct dentry *lookup_create(struct nameidata *nd, int is_dir, -+ struct lookup_intent *it) - { - struct dentry *dentry; - -@@ -1221,7 +1364,7 @@ - dentry = ERR_PTR(-EEXIST); - if (nd->last_type != LAST_NORM) - goto fail; -- dentry = lookup_hash(&nd->last, nd->dentry); -+ dentry = lookup_hash_it(&nd->last, nd->dentry, nd, it); - if (IS_ERR(dentry)) - goto fail; - if (!is_dir && nd->last.name[nd->last.len] && !dentry->d_inode) -@@ -1277,7 +1420,20 @@ - error = path_lookup(tmp, LOOKUP_PARENT, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 0); -+ -+ if (nd.last_type != LAST_NORM) { -+ error = -EEXIST; -+ goto out2; -+ } -+ if (nd.dentry->d_inode->i_op->mknod_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->mknod_raw(&nd, mode, dev); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto out2; -+ } -+ -+ dentry = lookup_create(&nd, 0, NULL); - error = PTR_ERR(dentry); - - mode &= ~current->fs->umask; -@@ -1298,6 +1454,7 @@ - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -+out2: - path_release(&nd); - out: - putname(tmp); -@@ -1345,7 +1502,18 @@ - error = path_lookup(tmp, LOOKUP_PARENT, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 1); -+ if (nd.last_type != LAST_NORM) { -+ error = -EEXIST; -+ goto out2; -+ } -+ if (nd.dentry->d_inode->i_op->mkdir_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->mkdir_raw(&nd, mode); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto out2; -+ } -+ dentry = lookup_create(&nd, 1, NULL); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_mkdir(nd.dentry->d_inode, dentry, -@@ -1353,6 +1521,7 @@ - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -+out2: - path_release(&nd); - out: - putname(tmp); -@@ -1453,8 +1622,16 @@ - error = -EBUSY; - goto exit1; - } -+ if (nd.dentry->d_inode->i_op->rmdir_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ -+ error = op->rmdir_raw(&nd); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto exit1; -+ } - down(&nd.dentry->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash_it(&nd.last, nd.dentry, &nd, NULL); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_rmdir(nd.dentry->d_inode, dentry); -@@ -1512,8 +1689,15 @@ - error = -EISDIR; - if (nd.last_type != LAST_NORM) - goto exit1; -+ if (nd.dentry->d_inode->i_op->unlink_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->unlink_raw(&nd); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto exit1; -+ } - down(&nd.dentry->d_inode->i_sem); -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash_it(&nd.last, nd.dentry, &nd, NULL); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - /* Why not before? Because we want correct error value */ -@@ -1580,15 +1764,27 @@ - error = path_lookup(to, LOOKUP_PARENT, &nd); - if (error) - goto out; -- dentry = lookup_create(&nd, 0); -+ if (nd.last_type != LAST_NORM) { -+ error = -EEXIST; -+ goto out2; -+ } -+ if (nd.dentry->d_inode->i_op->symlink_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->symlink_raw(&nd, from); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto out2; -+ } -+ dentry = lookup_create(&nd, 0, NULL); - error = PTR_ERR(dentry); - if (!IS_ERR(dentry)) { - error = vfs_symlink(nd.dentry->d_inode, dentry, from); - dput(dentry); - } - up(&nd.dentry->d_inode->i_sem); -+ out2: - path_release(&nd); --out: -+ out: - putname(to); - } - putname(from); -@@ -1664,7 +1860,18 @@ - error = -EXDEV; - if (old_nd.mnt != nd.mnt) - goto out_release; -- new_dentry = lookup_create(&nd, 0); -+ if (nd.last_type != LAST_NORM) { -+ error = -EEXIST; -+ goto out_release; -+ } -+ if (nd.dentry->d_inode->i_op->link_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ error = op->link_raw(&old_nd, &nd); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto out_release; -+ } -+ new_dentry = lookup_create(&nd, 0, NULL); - error = PTR_ERR(new_dentry); - if (!IS_ERR(new_dentry)) { - error = vfs_link(old_nd.dentry, nd.dentry->d_inode, new_dentry); -@@ -1708,7 +1915,7 @@ - * locking]. - */ - int vfs_rename_dir(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry) - { - int error; - struct inode *target; -@@ -1787,7 +1994,7 @@ - } - - int vfs_rename_other(struct inode *old_dir, struct dentry *old_dentry, -- struct inode *new_dir, struct dentry *new_dentry) -+ struct inode *new_dir, struct dentry *new_dentry) - { - int error; - -@@ -1875,9 +2082,18 @@ - if (newnd.last_type != LAST_NORM) - goto exit2; - -+ if (old_dir->d_inode->i_op->rename_raw) { -+ lock_kernel(); -+ error = old_dir->d_inode->i_op->rename_raw(&oldnd, &newnd); -+ unlock_kernel(); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto exit2; -+ } -+ - double_lock(new_dir, old_dir); - -- old_dentry = lookup_hash(&oldnd.last, old_dir); -+ old_dentry = lookup_hash_it(&oldnd.last, old_dir, &oldnd, NULL); - error = PTR_ERR(old_dentry); - if (IS_ERR(old_dentry)) - goto exit3; -@@ -1893,16 +2109,16 @@ - if (newnd.last.name[newnd.last.len]) - goto exit4; - } -- new_dentry = lookup_hash(&newnd.last, new_dir); -+ new_dentry = lookup_hash_it(&newnd.last, new_dir, &newnd, NULL); - error = PTR_ERR(new_dentry); - if (IS_ERR(new_dentry)) - goto exit4; - -+ - lock_kernel(); - error = vfs_rename(old_dir->d_inode, old_dentry, - new_dir->d_inode, new_dentry); - unlock_kernel(); -- - dput(new_dentry); - exit4: - dput(old_dentry); -@@ -1953,20 +2169,26 @@ - } - - static inline int --__vfs_follow_link(struct nameidata *nd, const char *link) -+__vfs_follow_link(struct nameidata *nd, const char *link, -+ struct lookup_intent *it) - { - int res = 0; - char *name; - if (IS_ERR(link)) - goto fail; - -+ if (it == NULL) -+ it = nd->intent; -+ else if (it != nd->intent) -+ printk("it != nd->intent: tell phil@clusterfs.com\n"); -+ - if (*link == '/') { - path_release(nd); - if (!walk_init_root(link, nd)) - /* weird __emul_prefix() stuff did it */ - goto out; - } -- res = link_path_walk(link, nd); -+ res = link_path_walk_it(link, nd, it); - out: - if (current->link_count || res || nd->last_type!=LAST_NORM) - return res; -@@ -1990,7 +2212,13 @@ - - int vfs_follow_link(struct nameidata *nd, const char *link) - { -- return __vfs_follow_link(nd, link); -+ return __vfs_follow_link(nd, link, NULL); -+} -+ -+int vfs_follow_link_it(struct nameidata *nd, const char *link, -+ struct lookup_intent *it) -+{ -+ return __vfs_follow_link(nd, link, it); - } - - /* get the link contents into pagecache */ -@@ -2032,7 +2260,7 @@ - { - struct page *page = NULL; - char *s = page_getlink(dentry, &page); -- int res = __vfs_follow_link(nd, s); -+ int res = __vfs_follow_link(nd, s, NULL); - if (page) { - kunmap(page); - page_cache_release(page); -Index: lum/fs/namespace.c -=================================================================== ---- lum.orig/fs/namespace.c 2003-11-28 13:26:21.000000000 -0500 -+++ lum/fs/namespace.c 2004-06-07 17:19:43.000000000 -0400 -@@ -15,6 +15,7 @@ - #include <linux/quotaops.h> - #include <linux/acct.h> - #include <linux/module.h> -+#include <linux/fs.h> - - #include <asm/uaccess.h> - -@@ -48,6 +49,7 @@ - INIT_LIST_HEAD(&mnt->mnt_child); - INIT_LIST_HEAD(&mnt->mnt_mounts); - INIT_LIST_HEAD(&mnt->mnt_list); -+ INIT_LIST_HEAD(&mnt->mnt_lustre_list); - if (name) { - int size = strlen(name)+1; - char * newname = kmalloc(size, GFP_KERNEL); -@@ -98,6 +100,7 @@ - { - old_nd->dentry = mnt->mnt_mountpoint; - old_nd->mnt = mnt->mnt_parent; -+ UNPIN(old_nd->dentry, old_nd->mnt, 1); - mnt->mnt_parent = mnt; - mnt->mnt_mountpoint = mnt->mnt_root; - list_del_init(&mnt->mnt_child); -@@ -109,6 +112,7 @@ - { - mnt->mnt_parent = mntget(nd->mnt); - mnt->mnt_mountpoint = dget(nd->dentry); -+ PIN(nd->dentry, nd->mnt, 1); - list_add(&mnt->mnt_hash, mount_hashtable+hash(nd->mnt, nd->dentry)); - list_add_tail(&mnt->mnt_child, &nd->mnt->mnt_mounts); - nd->dentry->d_mounted++; -@@ -151,6 +155,9 @@ - { - struct super_block *sb = mnt->mnt_sb; - dput(mnt->mnt_root); -+ spin_lock(&dcache_lock); -+ list_del(&mnt->mnt_lustre_list); -+ spin_unlock(&dcache_lock); - free_vfsmnt(mnt); - kill_super(sb); - } -@@ -286,7 +293,7 @@ - } - } - --static int do_umount(struct vfsmount *mnt, int flags) -+int do_umount(struct vfsmount *mnt, int flags) - { - struct super_block * sb = mnt->mnt_sb; - int retval = 0; -@@ -302,6 +309,8 @@ - */ - - lock_kernel(); -+ if (sb->s_op->umount_lustre) -+ sb->s_op->umount_lustre(sb); - if( (flags&MNT_FORCE) && sb->s_op->umount_begin) - sb->s_op->umount_begin(sb); - unlock_kernel(); -@@ -488,14 +497,17 @@ - { - struct nameidata old_nd; - struct vfsmount *mnt = NULL; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int err = mount_is_safe(nd); - if (err) - return err; - if (!old_name || !*old_name) - return -EINVAL; -- err = path_lookup(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd); -- if (err) -+ err = path_lookup_it(old_name, LOOKUP_POSITIVE|LOOKUP_FOLLOW, &old_nd, &it); -+ if (err) { -+ intent_release(&it); - return err; -+ } - - down_write(¤t->namespace->sem); - err = -EINVAL; -@@ -518,6 +530,7 @@ - } - - up_write(¤t->namespace->sem); -+ intent_release(&it); - path_release(&old_nd); - return err; - } -@@ -701,6 +714,7 @@ - unsigned long flags, void *data_page) - { - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int retval = 0; - int mnt_flags = 0; - -@@ -725,9 +739,11 @@ - flags &= ~(MS_NOSUID|MS_NOEXEC|MS_NODEV); - - /* ... and get the mountpoint */ -- retval = path_lookup(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd); -- if (retval) -+ retval = path_lookup_it(dir_name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, &nd, &it); -+ if (retval) { -+ intent_release(&it); - return retval; -+ } - - if (flags & MS_REMOUNT) - retval = do_remount(&nd, flags & ~MS_REMOUNT, mnt_flags, -@@ -739,6 +755,8 @@ - else - retval = do_add_mount(&nd, type_page, flags, mnt_flags, - dev_name, data_page); -+ -+ intent_release(&it); - path_release(&nd); - return retval; - } -@@ -904,6 +922,8 @@ - { - struct vfsmount *tmp; - struct nameidata new_nd, old_nd, parent_nd, root_parent, user_nd; -+ struct lookup_intent new_it = { .it_op = IT_GETATTR }; -+ struct lookup_intent old_it = { .it_op = IT_GETATTR }; - int error; - - if (!capable(CAP_SYS_ADMIN)) -@@ -911,14 +931,14 @@ - - lock_kernel(); - -- error = __user_walk(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd); -+ error = __user_walk_it(new_root, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &new_nd, &new_it); - if (error) - goto out0; - error = -EINVAL; - if (!check_mnt(new_nd.mnt)) - goto out1; - -- error = __user_walk(put_old, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd); -+ error = __user_walk_it(put_old, LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY, &old_nd, &old_it); - if (error) - goto out1; - -@@ -973,8 +993,10 @@ - up(&old_nd.dentry->d_inode->i_zombie); - up_write(¤t->namespace->sem); - path_release(&user_nd); -+ intent_release(&old_it); - path_release(&old_nd); - out1: -+ intent_release(&new_it); - path_release(&new_nd); - out0: - unlock_kernel(); -Index: lum/fs/open.c -=================================================================== ---- lum.orig/fs/open.c 2003-08-25 07:44:43.000000000 -0400 -+++ lum/fs/open.c 2004-06-07 17:19:43.000000000 -0400 -@@ -19,6 +19,8 @@ - #include <asm/uaccess.h> - - #define special_file(m) (S_ISCHR(m)||S_ISBLK(m)||S_ISFIFO(m)||S_ISSOCK(m)) -+extern int path_walk_it(const char *name, struct nameidata *nd, -+ struct lookup_intent *it); - - int vfs_statfs(struct super_block *sb, struct statfs *buf) - { -@@ -95,9 +97,10 @@ - write_unlock(&files->file_lock); - } - --int do_truncate(struct dentry *dentry, loff_t length) -+int do_truncate(struct dentry *dentry, loff_t length, int called_from_open) - { - struct inode *inode = dentry->d_inode; -+ struct inode_operations *op = dentry->d_inode->i_op; - int error; - struct iattr newattrs; - -@@ -109,7 +112,13 @@ - down(&inode->i_sem); - newattrs.ia_size = length; - newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME; -- error = notify_change(dentry, &newattrs); -+ if (called_from_open) -+ newattrs.ia_valid |= ATTR_FROM_OPEN; -+ if (op->setattr_raw) { -+ newattrs.ia_valid |= ATTR_RAW; -+ error = op->setattr_raw(inode, &newattrs); -+ } else -+ error = notify_change(dentry, &newattrs); - up(&inode->i_sem); - up_write(&inode->i_alloc_sem); - return error; -@@ -120,12 +129,13 @@ - struct nameidata nd; - struct inode * inode; - int error; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - - error = -EINVAL; - if (length < 0) /* sorry, but loff_t says... */ - goto out; - -- error = user_path_walk(path, &nd); -+ error = user_path_walk_it(path, &nd, &it); - if (error) - goto out; - inode = nd.dentry->d_inode; -@@ -165,11 +175,13 @@ - error = locks_verify_truncate(inode, NULL, length); - if (!error) { - DQUOT_INIT(inode); -- error = do_truncate(nd.dentry, length); -+ intent_release(&it); -+ error = do_truncate(nd.dentry, length, 0); - } - put_write_access(inode); - - dput_and_out: -+ intent_release(&it); - path_release(&nd); - out: - return error; -@@ -217,7 +229,7 @@ - - error = locks_verify_truncate(inode, file, length); - if (!error) -- error = do_truncate(dentry, length); -+ error = do_truncate(dentry, length, 0); - out_putf: - fput(file); - out: -@@ -262,11 +274,13 @@ - struct inode * inode; - struct iattr newattrs; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, NULL); - if (error) - goto out; - inode = nd.dentry->d_inode; - -+ /* this is safe without a Lustre lock because it only depends -+ on the super block */ - error = -EROFS; - if (IS_RDONLY(inode)) - goto dput_and_out; -@@ -281,11 +295,25 @@ - goto dput_and_out; - - newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET; -- } else { -+ } -+ -+ if (inode->i_op->setattr_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ -+ newattrs.ia_valid |= ATTR_RAW; -+ error = op->setattr_raw(inode, &newattrs); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto dput_and_out; -+ } -+ -+ error = -EPERM; -+ if (!times) { - if (current->fsuid != inode->i_uid && - (error = permission(inode,MAY_WRITE)) != 0) - goto dput_and_out; - } -+ - error = notify_change(nd.dentry, &newattrs); - dput_and_out: - path_release(&nd); -@@ -306,12 +334,14 @@ - struct inode * inode; - struct iattr newattrs; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, NULL); - - if (error) - goto out; - inode = nd.dentry->d_inode; - -+ /* this is safe without a Lustre lock because it only depends -+ on the super block */ - error = -EROFS; - if (IS_RDONLY(inode)) - goto dput_and_out; -@@ -326,7 +356,20 @@ - newattrs.ia_atime = times[0].tv_sec; - newattrs.ia_mtime = times[1].tv_sec; - newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET; -- } else { -+ } -+ -+ if (inode->i_op->setattr_raw) { -+ struct inode_operations *op = nd.dentry->d_inode->i_op; -+ -+ newattrs.ia_valid |= ATTR_RAW; -+ error = op->setattr_raw(inode, &newattrs); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ goto dput_and_out; -+ } -+ -+ error = -EPERM; -+ if (!utimes) { - if (current->fsuid != inode->i_uid && - (error = permission(inode,MAY_WRITE)) != 0) - goto dput_and_out; -@@ -349,6 +392,7 @@ - int old_fsuid, old_fsgid; - kernel_cap_t old_cap; - int res; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - - if (mode & ~S_IRWXO) /* where's F_OK, X_OK, W_OK, R_OK? */ - return -EINVAL; -@@ -366,13 +410,14 @@ - else - current->cap_effective = current->cap_permitted; - -- res = user_path_walk(filename, &nd); -+ res = user_path_walk_it(filename, &nd, &it); - if (!res) { - res = permission(nd.dentry->d_inode, mode); - /* SuS v2 requires we report a read only fs too */ - if(!res && (mode & S_IWOTH) && IS_RDONLY(nd.dentry->d_inode) - && !special_file(nd.dentry->d_inode->i_mode)) - res = -EROFS; -+ intent_release(&it); - path_release(&nd); - } - -@@ -387,8 +432,9 @@ - { - int error; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_CHDIR }; - -- error = __user_walk(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd); -+ error = __user_walk_it(filename,LOOKUP_POSITIVE|LOOKUP_FOLLOW|LOOKUP_DIRECTORY,&nd, &it); - if (error) - goto out; - -@@ -399,6 +445,7 @@ - set_fs_pwd(current->fs, nd.mnt, nd.dentry); - - dput_and_out: -+ intent_release(&it); - path_release(&nd); - out: - return error; -@@ -438,9 +485,10 @@ - { - int error; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = __user_walk(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW | -- LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd); -+ error = __user_walk_it(filename, LOOKUP_POSITIVE | LOOKUP_FOLLOW | -+ LOOKUP_DIRECTORY | LOOKUP_NOALT, &nd, &it); - if (error) - goto out; - -@@ -456,39 +504,56 @@ - set_fs_altroot(); - error = 0; - dput_and_out: -+ intent_release(&it); - path_release(&nd); - out: - return error; - } - --asmlinkage long sys_fchmod(unsigned int fd, mode_t mode) -+int chmod_common(struct dentry *dentry, mode_t mode) - { -- struct inode * inode; -- struct dentry * dentry; -- struct file * file; -- int err = -EBADF; -+ struct inode *inode = dentry->d_inode; - struct iattr newattrs; -+ int err = -EROFS; - -- file = fget(fd); -- if (!file) -+ if (IS_RDONLY(inode)) - goto out; - -- dentry = file->f_dentry; -- inode = dentry->d_inode; -+ if (inode->i_op->setattr_raw) { -+ newattrs.ia_mode = mode; -+ newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; -+ newattrs.ia_valid |= ATTR_RAW; -+ err = inode->i_op->setattr_raw(inode, &newattrs); -+ /* the file system wants to use normal vfs path now */ -+ if (err != -EOPNOTSUPP) -+ goto out; -+ } - -- err = -EROFS; -- if (IS_RDONLY(inode)) -- goto out_putf; - err = -EPERM; - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) -- goto out_putf; -+ goto out; -+ - if (mode == (mode_t) -1) - mode = inode->i_mode; - newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); - newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; - err = notify_change(dentry, &newattrs); - --out_putf: -+out: -+ return err; -+} -+ -+asmlinkage long sys_fchmod(unsigned int fd, mode_t mode) -+{ -+ struct file * file; -+ int err = -EBADF; -+ -+ file = fget(fd); -+ if (!file) -+ goto out; -+ -+ err = chmod_common(file->f_dentry, mode); -+ - fput(file); - out: - return err; -@@ -497,30 +562,14 @@ - asmlinkage long sys_chmod(const char * filename, mode_t mode) - { - struct nameidata nd; -- struct inode * inode; - int error; -- struct iattr newattrs; - - error = user_path_walk(filename, &nd); - if (error) - goto out; -- inode = nd.dentry->d_inode; -- -- error = -EROFS; -- if (IS_RDONLY(inode)) -- goto dput_and_out; - -- error = -EPERM; -- if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) -- goto dput_and_out; -+ error = chmod_common(nd.dentry, mode); - -- if (mode == (mode_t) -1) -- mode = inode->i_mode; -- newattrs.ia_mode = (mode & S_IALLUGO) | (inode->i_mode & ~S_IALLUGO); -- newattrs.ia_valid = ATTR_MODE | ATTR_CTIME; -- error = notify_change(nd.dentry, &newattrs); -- --dput_and_out: - path_release(&nd); - out: - return error; -@@ -540,6 +589,20 @@ - error = -EROFS; - if (IS_RDONLY(inode)) - goto out; -+ -+ if (inode->i_op->setattr_raw) { -+ struct inode_operations *op = dentry->d_inode->i_op; -+ -+ newattrs.ia_uid = user; -+ newattrs.ia_gid = group; -+ newattrs.ia_valid = ATTR_UID | ATTR_GID | ATTR_CTIME; -+ newattrs.ia_valid |= ATTR_RAW; -+ error = op->setattr_raw(inode, &newattrs); -+ /* the file system wants to use normal vfs path now */ -+ if (error != -EOPNOTSUPP) -+ return error; -+ } -+ - error = -EPERM; - if (IS_IMMUTABLE(inode) || IS_APPEND(inode)) - goto out; -@@ -644,6 +707,7 @@ - { - int namei_flags, error; - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_OPEN }; - - namei_flags = flags; - if ((namei_flags+1) & O_ACCMODE) -@@ -651,14 +715,15 @@ - if (namei_flags & O_TRUNC) - namei_flags |= 2; - -- error = open_namei(filename, namei_flags, mode, &nd); -- if (!error) -- return dentry_open(nd.dentry, nd.mnt, flags); -+ error = open_namei_it(filename, namei_flags, mode, &nd, &it); -+ if (error) -+ return ERR_PTR(error); - -- return ERR_PTR(error); -+ return dentry_open_it(nd.dentry, nd.mnt, flags, &it); - } - --struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) -+struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, -+ int flags, struct lookup_intent *it) - { - struct file * f; - struct inode *inode; -@@ -695,12 +760,15 @@ - } - - if (f->f_op && f->f_op->open) { -+ f->f_it = it; - error = f->f_op->open(inode,f); -+ f->f_it = NULL; - if (error) - goto cleanup_all; - } - f->f_flags &= ~(O_CREAT | O_EXCL | O_NOCTTY | O_TRUNC); - -+ intent_release(it); - return f; - - cleanup_all: -@@ -715,11 +783,17 @@ - cleanup_file: - put_filp(f); - cleanup_dentry: -+ intent_release(it); - dput(dentry); - mntput(mnt); - return ERR_PTR(error); - } - -+struct file *dentry_open(struct dentry *dentry, struct vfsmount *mnt, int flags) -+{ -+ return dentry_open_it(dentry, mnt, flags, NULL); -+} -+ - /* - * Find an empty file descriptor entry, and mark it busy. - */ -Index: lum/fs/stat.c -=================================================================== ---- lum.orig/fs/stat.c 2003-08-25 07:44:43.000000000 -0400 -+++ lum/fs/stat.c 2004-06-07 17:19:43.000000000 -0400 -@@ -17,10 +17,12 @@ - * Revalidate the inode. This is required for proper NFS attribute caching. - */ - static __inline__ int --do_revalidate(struct dentry *dentry) -+do_revalidate(struct dentry *dentry, struct lookup_intent *it) - { - struct inode * inode = dentry->d_inode; -- if (inode->i_op && inode->i_op->revalidate) -+ if (inode->i_op && inode->i_op->revalidate_it) -+ return inode->i_op->revalidate_it(dentry, it); -+ else if (inode->i_op && inode->i_op->revalidate) - return inode->i_op->revalidate(dentry); - return 0; - } -@@ -137,13 +139,15 @@ - asmlinkage long sys_stat(char * filename, struct __old_kernel_stat * statbuf) - { - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int error; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (!error) { -- error = do_revalidate(nd.dentry); -+ error = do_revalidate(nd.dentry, &it); - if (!error) - error = cp_old_stat(nd.dentry->d_inode, statbuf); -+ intent_release(&it); - path_release(&nd); - } - return error; -@@ -153,13 +157,15 @@ - asmlinkage long sys_newstat(char * filename, struct stat * statbuf) - { - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int error; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (!error) { -- error = do_revalidate(nd.dentry); -+ error = do_revalidate(nd.dentry, &it); - if (!error) - error = cp_new_stat(nd.dentry->d_inode, statbuf); -+ intent_release(&it); - path_release(&nd); - } - return error; -@@ -174,13 +180,15 @@ - asmlinkage long sys_lstat(char * filename, struct __old_kernel_stat * statbuf) - { - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int error; - -- error = user_path_walk_link(filename, &nd); -+ error = user_path_walk_link_it(filename, &nd, &it); - if (!error) { -- error = do_revalidate(nd.dentry); -+ error = do_revalidate(nd.dentry, &it); - if (!error) - error = cp_old_stat(nd.dentry->d_inode, statbuf); -+ intent_release(&it); - path_release(&nd); - } - return error; -@@ -191,13 +199,15 @@ - asmlinkage long sys_newlstat(char * filename, struct stat * statbuf) - { - struct nameidata nd; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - int error; - -- error = user_path_walk_link(filename, &nd); -+ error = user_path_walk_link_it(filename, &nd, &it); - if (!error) { -- error = do_revalidate(nd.dentry); -+ error = do_revalidate(nd.dentry, &it); - if (!error) - error = cp_new_stat(nd.dentry->d_inode, statbuf); -+ intent_release(&it); - path_release(&nd); - } - return error; -@@ -218,7 +228,7 @@ - if (f) { - struct dentry * dentry = f->f_dentry; - -- err = do_revalidate(dentry); -+ err = do_revalidate(dentry, NULL); - if (!err) - err = cp_old_stat(dentry->d_inode, statbuf); - fput(f); -@@ -237,7 +247,7 @@ - if (f) { - struct dentry * dentry = f->f_dentry; - -- err = do_revalidate(dentry); -+ err = do_revalidate(dentry, NULL); - if (!err) - err = cp_new_stat(dentry->d_inode, statbuf); - fput(f); -@@ -259,7 +269,7 @@ - - error = -EINVAL; - if (inode->i_op && inode->i_op->readlink && -- !(error = do_revalidate(nd.dentry))) { -+ !(error = do_revalidate(nd.dentry, NULL))) { - UPDATE_ATIME(inode); - error = inode->i_op->readlink(nd.dentry, buf, bufsiz); - } -@@ -335,12 +345,14 @@ - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = user_path_walk(filename, &nd); -+ error = user_path_walk_it(filename, &nd, &it); - if (!error) { -- error = do_revalidate(nd.dentry); -+ error = do_revalidate(nd.dentry, &it); - if (!error) - error = cp_new_stat64(nd.dentry->d_inode, statbuf); -+ intent_release(&it); - path_release(&nd); - } - return error; -@@ -350,12 +362,14 @@ - { - struct nameidata nd; - int error; -+ struct lookup_intent it = { .it_op = IT_GETATTR }; - -- error = user_path_walk_link(filename, &nd); -+ error = user_path_walk_link_it(filename, &nd, &it); - if (!error) { -- error = do_revalidate(nd.dentry); -+ error = do_revalidate(nd.dentry, &it); - if (!error) - error = cp_new_stat64(nd.dentry->d_inode, statbuf); -+ intent_release(&it); - path_release(&nd); - } - return error; -@@ -370,7 +384,7 @@ - if (f) { - struct dentry * dentry = f->f_dentry; - -- err = do_revalidate(dentry); -+ err = do_revalidate(dentry, NULL); - if (!err) - err = cp_new_stat64(dentry->d_inode, statbuf); - fput(f); -Index: lum/include/linux/dcache.h -=================================================================== ---- lum.orig/include/linux/dcache.h 2002-11-28 18:53:15.000000000 -0500 -+++ lum/include/linux/dcache.h 2004-06-07 17:19:44.000000000 -0400 -@@ -6,6 +6,52 @@ - #include <asm/atomic.h> - #include <linux/mount.h> - #include <linux/kernel.h> -+#include <linux/string.h> -+ -+#define IT_OPEN 0x0001 -+#define IT_CREAT 0x0002 -+#define IT_READDIR 0x0004 -+#define IT_GETATTR 0x0008 -+#define IT_LOOKUP 0x0010 -+#define IT_UNLINK 0x0020 -+#define IT_GETXATTR 0x0040 -+#define IT_EXEC 0x0080 -+#define IT_PIN 0x0100 -+#define IT_CHDIR 0x0200 -+ -+#define IT_FL_LOCKED 0x0001 -+#define IT_FL_FOLLOWED 0x0002 /* set by vfs_follow_link */ -+ -+#define INTENT_MAGIC 0x19620323 -+ -+ -+struct lustre_intent_data { -+ int it_disposition; -+ int it_status; -+ __u64 it_lock_handle; -+ void *it_data; -+ int it_lock_mode; -+ int it_int_flags; -+}; -+struct lookup_intent { -+ int it_magic; -+ void (*it_op_release)(struct lookup_intent *); -+ int it_op; -+ int it_flags; -+ int it_create_mode; -+ union { -+ struct lustre_intent_data lustre; -+ } d; -+}; -+ -+static inline void intent_init(struct lookup_intent *it, int op, int flags) -+{ -+ memset(it, 0, sizeof(*it)); -+ it->it_magic = INTENT_MAGIC; -+ it->it_op = op; -+ it->it_flags = flags; -+} -+ - - /* - * linux/include/linux/dcache.h -@@ -84,6 +130,8 @@ - unsigned char d_iname[DNAME_INLINE_LEN]; /* small names */ - }; - -+struct nameidata; -+ - struct dentry_operations { - int (*d_revalidate)(struct dentry *, int); - int (*d_hash) (struct dentry *, struct qstr *); -@@ -91,8 +139,22 @@ - int (*d_delete)(struct dentry *); - void (*d_release)(struct dentry *); - void (*d_iput)(struct dentry *, struct inode *); -+ int (*d_revalidate_it)(struct dentry *, int, struct nameidata *, struct lookup_intent *); -+ void (*d_pin)(struct dentry *, struct vfsmount * , int); -+ void (*d_unpin)(struct dentry *, struct vfsmount *, int); - }; - -+#define PIN(de,mnt,flag) if (de && de->d_op && de->d_op->d_pin) \ -+ de->d_op->d_pin(de, mnt, flag); -+#define UNPIN(de,mnt,flag) if (de && de->d_op && de->d_op->d_unpin) \ -+ de->d_op->d_unpin(de, mnt, flag); -+ -+ -+/* defined in fs/namei.c */ -+extern void intent_release(struct lookup_intent *it); -+/* defined in fs/dcache.c */ -+extern void __d_rehash(struct dentry * entry, int lock); -+ - /* the dentry parameter passed to d_hash and d_compare is the parent - * directory of the entries to be compared. It is used in case these - * functions need any directory specific information for determining -@@ -124,6 +186,7 @@ - * s_nfsd_free_path semaphore will be down - */ - #define DCACHE_REFERENCED 0x0008 /* Recently used, don't discard. */ -+#define DCACHE_LUSTRE_INVALID 0x0010 /* Lustre invalidated */ - - extern spinlock_t dcache_lock; - -Index: lum/include/linux/fs.h -=================================================================== ---- lum.orig/include/linux/fs.h 2004-06-03 16:32:26.000000000 -0400 -+++ lum/include/linux/fs.h 2004-06-07 17:24:37.000000000 -0400 -@@ -73,6 +73,7 @@ - - #define FMODE_READ 1 - #define FMODE_WRITE 2 -+#define FMODE_EXEC 4 - - #define READ 0 - #define WRITE 1 -@@ -340,6 +341,9 @@ - #define ATTR_MTIME_SET 256 - #define ATTR_FORCE 512 /* Not a change, but a change it */ - #define ATTR_ATTR_FLAG 1024 -+#define ATTR_RAW 0x0800 /* file system, not vfs will massage attrs */ -+#define ATTR_FROM_OPEN 0x1000 /* called from open path, ie O_TRUNC */ -+#define ATTR_CTIME_SET 0x2000 - - /* - * This is the Inode Attributes structure, used for notify_change(). It -@@ -478,6 +482,7 @@ - struct pipe_inode_info *i_pipe; - struct block_device *i_bdev; - struct char_device *i_cdev; -+ void *i_filterdata; - - unsigned long i_dnotify_mask; /* Directory notify events */ - struct dnotify_struct *i_dnotify; /* for directory notifications */ -@@ -582,6 +587,7 @@ - - /* needed for tty driver, and maybe others */ - void *private_data; -+ struct lookup_intent *f_it; - - /* preallocated helper kiobuf to speedup O_DIRECT */ - struct kiobuf *f_iobuf; -@@ -702,6 +708,7 @@ - struct qstr last; - unsigned int flags; - int last_type; -+ struct lookup_intent *intent; - }; - - /* -@@ -822,7 +829,8 @@ - extern int vfs_link(struct dentry *, struct inode *, struct dentry *); - extern int vfs_rmdir(struct inode *, struct dentry *); - extern int vfs_unlink(struct inode *, struct dentry *); --extern int vfs_rename(struct inode *, struct dentry *, struct inode *, struct dentry *); -+int vfs_rename(struct inode *old_dir, struct dentry *old_dentry, -+ struct inode *new_dir, struct dentry *new_dentry); - - /* - * File types -@@ -884,21 +892,32 @@ - - struct inode_operations { - int (*create) (struct inode *,struct dentry *,int); -+ int (*create_it) (struct inode *,struct dentry *,int, struct lookup_intent *); - struct dentry * (*lookup) (struct inode *,struct dentry *); -+ struct dentry * (*lookup_it) (struct inode *,struct dentry *, struct nameidata *, struct lookup_intent *, int flags); - int (*link) (struct dentry *,struct inode *,struct dentry *); -+ int (*link_raw) (struct nameidata *,struct nameidata *); - int (*unlink) (struct inode *,struct dentry *); -+ int (*unlink_raw) (struct nameidata *); - int (*symlink) (struct inode *,struct dentry *,const char *); -+ int (*symlink_raw) (struct nameidata *,const char *); - int (*mkdir) (struct inode *,struct dentry *,int); -+ int (*mkdir_raw) (struct nameidata *,int); - int (*rmdir) (struct inode *,struct dentry *); -+ int (*rmdir_raw) (struct nameidata *); - int (*mknod) (struct inode *,struct dentry *,int,int); -+ int (*mknod_raw) (struct nameidata *,int,dev_t); - int (*rename) (struct inode *, struct dentry *, - struct inode *, struct dentry *); -+ int (*rename_raw) (struct nameidata *, struct nameidata *); - int (*readlink) (struct dentry *, char *,int); - int (*follow_link) (struct dentry *, struct nameidata *); - void (*truncate) (struct inode *); - int (*permission) (struct inode *, int); - int (*revalidate) (struct dentry *); -+ int (*revalidate_it) (struct dentry *, struct lookup_intent *); - int (*setattr) (struct dentry *, struct iattr *); -+ int (*setattr_raw) (struct inode *, struct iattr *); - int (*getattr) (struct dentry *, struct iattr *); - int (*setxattr) (struct dentry *, const char *, void *, size_t, int); - ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t); -@@ -938,6 +957,7 @@ - int (*remount_fs) (struct super_block *, int *, char *); - void (*clear_inode) (struct inode *); - void (*umount_begin) (struct super_block *); -+ void (*umount_lustre) (struct super_block *); - - /* Following are for knfsd to interact with "interesting" filesystems - * Currently just reiserfs, but possibly FAT and others later -@@ -1094,10 +1114,14 @@ - - asmlinkage long sys_open(const char *, int, int); - asmlinkage long sys_close(unsigned int); /* yes, it's really unsigned */ --extern int do_truncate(struct dentry *, loff_t start); -+extern int do_truncate(struct dentry *, loff_t start, int called_from_open); - - extern struct file *filp_open(const char *, int, int); - extern struct file * dentry_open(struct dentry *, struct vfsmount *, int); -+extern int open_namei_it(const char *filename, int namei_flags, int mode, -+ struct nameidata *nd, struct lookup_intent *it); -+extern struct file *dentry_open_it(struct dentry *dentry, struct vfsmount *mnt, -+ int flags, struct lookup_intent *it); - extern int filp_close(struct file *, fl_owner_t id); - extern char * getname(const char *); - -@@ -1386,6 +1410,7 @@ - extern loff_t default_llseek(struct file *file, loff_t offset, int origin); - - extern int FASTCALL(__user_walk(const char *, unsigned, struct nameidata *)); -+extern int FASTCALL(__user_walk_it(const char *, unsigned, struct nameidata *, struct lookup_intent *it)); - extern int FASTCALL(path_init(const char *, unsigned, struct nameidata *)); - extern int FASTCALL(path_walk(const char *, struct nameidata *)); - extern int FASTCALL(path_lookup(const char *, unsigned, struct nameidata *)); -@@ -1394,9 +1419,11 @@ - extern int follow_down(struct vfsmount **, struct dentry **); - extern int follow_up(struct vfsmount **, struct dentry **); - extern struct dentry * lookup_one_len(const char *, struct dentry *, int); --extern struct dentry * lookup_hash(struct qstr *, struct dentry *); -+extern struct dentry * lookup_hash(struct qstr *, struct dentry *, struct nameidata *); - #define user_path_walk(name,nd) __user_walk(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd) - #define user_path_walk_link(name,nd) __user_walk(name, LOOKUP_POSITIVE, nd) -+#define user_path_walk_it(name,nd,it) __user_walk_it(name, LOOKUP_FOLLOW|LOOKUP_POSITIVE, nd, it) -+#define user_path_walk_link_it(name,nd,it) __user_walk_it(name, LOOKUP_POSITIVE, nd, it) - - extern void inode_init_once(struct inode *); - extern void iput(struct inode *); -@@ -1500,6 +1527,8 @@ - - extern int vfs_readlink(struct dentry *, char *, int, const char *); - extern int vfs_follow_link(struct nameidata *, const char *); -+extern int vfs_follow_link_it(struct nameidata *, const char *, -+ struct lookup_intent *it); - extern int page_readlink(struct dentry *, char *, int); - extern int page_follow_link(struct dentry *, struct nameidata *); - extern struct inode_operations page_symlink_inode_operations; -Index: lum/include/linux/fs_struct.h -=================================================================== ---- lum.orig/include/linux/fs_struct.h 2001-07-13 18:10:44.000000000 -0400 -+++ lum/include/linux/fs_struct.h 2004-06-07 17:19:44.000000000 -0400 -@@ -34,10 +34,12 @@ - write_lock(&fs->lock); - old_root = fs->root; - old_rootmnt = fs->rootmnt; -+ PIN(dentry, mnt, 1); - fs->rootmnt = mntget(mnt); - fs->root = dget(dentry); - write_unlock(&fs->lock); - if (old_root) { -+ UNPIN(old_root, old_rootmnt, 1); - dput(old_root); - mntput(old_rootmnt); - } -@@ -57,10 +59,12 @@ - write_lock(&fs->lock); - old_pwd = fs->pwd; - old_pwdmnt = fs->pwdmnt; -+ PIN(dentry, mnt, 0); - fs->pwdmnt = mntget(mnt); - fs->pwd = dget(dentry); - write_unlock(&fs->lock); - if (old_pwd) { -+ UNPIN(old_pwd, old_pwdmnt, 0); - dput(old_pwd); - mntput(old_pwdmnt); - } -Index: lum/include/linux/mount.h -=================================================================== ---- lum.orig/include/linux/mount.h 2001-10-05 16:05:55.000000000 -0400 -+++ lum/include/linux/mount.h 2004-06-07 17:19:44.000000000 -0400 -@@ -29,6 +29,8 @@ - int mnt_flags; - char *mnt_devname; /* Name of device e.g. /dev/dsk/hda1 */ - struct list_head mnt_list; -+ struct list_head mnt_lustre_list; /* GNS mount list */ -+ unsigned long mnt_last_used; /* for GNS auto-umount (jiffies) */ - }; - - static inline struct vfsmount *mntget(struct vfsmount *mnt) -@@ -39,6 +41,7 @@ - } - - extern void __mntput(struct vfsmount *mnt); -+extern int do_umount(struct vfsmount *mnt, int flags); - - static inline void mntput(struct vfsmount *mnt) - { -Index: lum/kernel/exit.c -=================================================================== ---- lum.orig/kernel/exit.c 2002-11-28 18:53:15.000000000 -0500 -+++ lum/kernel/exit.c 2004-06-07 17:19:44.000000000 -0400 -@@ -238,11 +238,14 @@ - { - /* No need to hold fs->lock if we are killing it */ - if (atomic_dec_and_test(&fs->count)) { -+ UNPIN(fs->pwd, fs->pwdmnt, 0); -+ UNPIN(fs->root, fs->rootmnt, 1); - dput(fs->root); - mntput(fs->rootmnt); - dput(fs->pwd); - mntput(fs->pwdmnt); - if (fs->altroot) { -+ UNPIN(fs->altroot, fs->altrootmnt, 1); - dput(fs->altroot); - mntput(fs->altrootmnt); - } -Index: lum/kernel/fork.c -=================================================================== ---- lum.orig/kernel/fork.c 2003-11-28 13:26:21.000000000 -0500 -+++ lum/kernel/fork.c 2004-06-07 17:19:44.000000000 -0400 -@@ -386,10 +386,13 @@ - fs->umask = old->umask; - read_lock(&old->lock); - fs->rootmnt = mntget(old->rootmnt); -+ PIN(old->pwd, old->pwdmnt, 0); -+ PIN(old->root, old->rootmnt, 1); - fs->root = dget(old->root); - fs->pwdmnt = mntget(old->pwdmnt); - fs->pwd = dget(old->pwd); - if (old->altroot) { -+ PIN(old->altroot, old->altrootmnt, 1); - fs->altrootmnt = mntget(old->altrootmnt); - fs->altroot = dget(old->altroot); - } else { -Index: lum/kernel/ksyms.c -=================================================================== ---- lum.orig/kernel/ksyms.c 2004-06-03 16:32:26.000000000 -0400 -+++ lum/kernel/ksyms.c 2004-06-07 17:25:11.000000000 -0400 -@@ -275,6 +275,8 @@ - EXPORT_SYMBOL(mark_page_accessed); - EXPORT_SYMBOL(vfs_readlink); - EXPORT_SYMBOL(vfs_follow_link); -+EXPORT_SYMBOL(vfs_follow_link_it); -+EXPORT_SYMBOL(do_umount); - EXPORT_SYMBOL(page_readlink); - EXPORT_SYMBOL(page_follow_link); - EXPORT_SYMBOL(page_symlink_inode_operations); -Index: lum/net/unix/af_unix.c -=================================================================== ---- lum.orig/net/unix/af_unix.c 2002-11-28 18:53:16.000000000 -0500 -+++ lum/net/unix/af_unix.c 2004-06-07 17:19:44.000000000 -0400 -@@ -703,7 +703,7 @@ - /* - * Do the final lookup. - */ -- dentry = lookup_hash(&nd.last, nd.dentry); -+ dentry = lookup_hash(&nd.last, nd.dentry, &nd); - err = PTR_ERR(dentry); - if (IS_ERR(dentry)) - goto out_mknod_unlock; -Index: lum/drivers/hotplug/pci_hotplug_core.c -=================================================================== ---- lum.orig/drivers/hotplug/pci_hotplug_core.c 2003-11-28 13:26:20.000000000 -0500 -+++ lum/drivers/hotplug/pci_hotplug_core.c 2004-06-08 01:59:32.000000000 -0400 -@@ -478,7 +478,7 @@ - - down(&parent->d_inode->i_sem); - -- d = lookup_hash(&qstr,parent); -+ d = lookup_hash(&qstr,parent,NULL); - - error = PTR_ERR(d); - if (!IS_ERR(d)) { diff --git a/lustre/kernel_patches/series/vanilla-2.4.24 b/lustre/kernel_patches/series/vanilla-2.4.24 deleted file mode 100644 index ba9c372..0000000 --- a/lustre/kernel_patches/series/vanilla-2.4.24 +++ /dev/null @@ -1,53 +0,0 @@ -uml-patch-2.4.24-1.patch -uml-2.4.24-do_mmap_pgoff-fix.patch -uml-export-end_iomem-2.4.24.patch -configurable-x86-stack-2.4.24.patch -dev_read_only-2.4.24.patch -exports-2.4.24.patch -lustre_version.patch -vfs_intent-2.4.24.patch -invalidate_show-2.4.24.patch -export-truncate-2.4.24.patch -iod-stock-exports-2.4.24.patch -ext3-htree-2.4.24.patch -linux-2.4.24-xattr-0.8.54.patch -ext3-orphan_lock-2.4.24.patch -ext3-noread-2.4.24.patch -ext3-delete_thread-2.4.24.patch -extN-wantedi-2.4.24.patch -ext3-san-2.4.24.patch -ext3-map_inode_page-2.4.24.patch -ext3-error-export-2.4.24.patch -iopen-2.4.24.patch -tcp-zero-copy-2.4.24.patch -jbd-dont-account-blocks-twice-2.4.24.patch -jbd-commit-tricks-2.4.24.patch -ext3-no-write-super-2.4.24.patch -add_page_private-2.4.24.patch -nfs_export_kernel-2.4.24.patch -ext3-ea-in-inode-2.4.24.patch -listman-2.4.24.patch -ext3-trusted_ea-2.4.24.patch -ext3-extents-2.4.24.patch -ext3-extents-in-ea-2.4.24.patch -ext3-extents-in-ea-ioctl-2.4.24.patch -ext3-extents-in-ea-exports-symbol-2.4.24.patch -kernel_text_address-2.4.24-vanilla.patch -gfp_memalloc-2.4.24.patch -ext3-xattr-ptr-arith-fix-2.4.24.patch -3.5G-address-space-2.4.24-vanilla.patch -procfs-ndynamic-2.4.24.patch -ext3-truncate-buffer-head-2.4.24.patch -inode-max-readahead-2.4.24.patch -dynamic-locks-2.4.24.patch -vfs-pdirops-2.4.24.patch -ext3-pdirops-2.4.24-chaos.patch -ext3-mds-num-2.4.24.patch -export_lookup_create-2.4.24.patch -ext3-raw-lookup-pdirops-2.4.24.patch -kksymoops-2.4.24.vanilla.patch -ext3-inode-reuse-2.4.24.patch -export-zap-page-range-2.4.24.patch -export_num_siblings-2.4.24.patch -ext3-nlinks-2.4.24.patch -ext3-dentry-fid-2.4.24.patch -- 1.8.3.1